TEST

parents
version: '3.8'
services:
product-svc:
container_name: productservice
build: ./productSvc
ports: # use 'ports' instead of 'expose' for host access
- "8020:8020"
environment:
APP_INTERNAL_PORT: 8020
DB_ADDRESS: mysql
DB_PORT: 3306
DB_NAME: productmngm
DB_USERNAME: root
DB_PASSWORD: S3cret
depends_on:
- mysql
networks:
- my-network
mysql:
container_name: mysql
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: S3cret
MYSQL_DATABASE: productmngm
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
nginx:
container_name: nginx
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- product-svc
networks:
- my-network
product-ui:
container_name: product-ui
build: ./productApp # path to your React app Dockerfile folder
ports:
- "8030:80" # map container port 80 (nginx) to host 3000
networks:
- my-network
volumes:
mysql-data:
networks:
my-network:
driver: bridge
events {}
http {
server {
listen 80;
location /product-service/ {
proxy_pass http://productservice:8020/product-service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /product-ui/ {
proxy_pass http://product-ui:80/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
# 🐳 Docker Deployment Guide for Product Project
## 🔍 What is Docker?
**Docker** is a platform that allows developers to **build, package, and run applications in isolated environments** called **containers**. It ensures your application runs consistently across different environments—local machines, servers, or the cloud.
### 🧱 Key Docker Concepts
#### 📦 Image
A **Docker image** is a **read-only template** that includes everything needed to run an application—OS, code, libraries, etc.
> Think of it like a recipe for creating containers.
#### 🚢 Container
A **container** is a **running instance of an image**. It is isolated, lightweight, and includes everything the application needs to run.
> Think of it like a ready-made dish from a recipe (image).
#### 💾 Volume
A **volume** is used to **persist data** outside the container’s lifecycle. It ensures your data isn’t lost even if the container stops or is deleted.
> Useful for things like database storage.
---
This guide explains how to build and deploy a full-stack application using Docker. The project contains:
- 🧩 `productApp` — React frontend served via NGINX
- ⚙️ `productSvc` — Spring Boot backend API
## 📁 Project Folder Structure
```
your-project/
├── productApp/ # React frontend
│ ├── Dockerfile
│ ├── .env
│ └── nginx.conf
├── productSvc/ # Spring Boot backend
│ └── Dockerfile
├── nginx.conf # NGINX config for serving React app (optional global config)
└── docker-compose.yml # Compose file to run both services
```
📥 Clone the repository:
```bash
git clone <your-project-repo>
cd your-project
```
---
## 🚀 Deploying Individually
### 🔹 1. Deploy `productApp`
📌 **Why a Dockerfile is needed:**
To containerize the React frontend, we need a `Dockerfile` that handles two main tasks:
1. **Build the app** using Node.js (install dependencies, compile React code).
2. **Serve the static build** using NGINX (a lightweight and efficient web server).
Without a `Dockerfile`, Docker won't know how to build and serve the React application.
**Dockerfile** (`productApp/Dockerfile`)
```Dockerfile
FROM node:16-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
**Environment** `.env (productApp/.env):`
```
PUBLIC_URL=/product-ui
```
**NGINX Config** `(productApp/nginx.conf):`
```nginx
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
}
```
**Build and Run**
```bash
cd productApp
docker build -t product-ui .
docker run -p 3000:80 --name product-ui product-ui
docker ps
```
🌍 Open in browser: [http://localhost:3000](http://localhost:3000)
---
### 🔹 2. Deploy `productSvc`
📌 **Why a Dockerfile is needed:**
To containerize the Spring Boot backend, we need a `Dockerfile` that:
1. **Builds the application JAR** using Gradle.
2. **Runs the JAR** inside a lightweight Java runtime image.
This ensures the backend service is self-contained and can run the same way across all environments (local, test, production). Without the `Dockerfile`, Docker cannot build or run your backend service as a container.
**Dockerfile** (`productSvc/Dockerfile`)
```Dockerfile
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./gradlew clean build -x test
FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
```
**Build and Run**
```bash
cd productSvc
docker run -d --name mysql-db -e MYSQL_ROOT_PASSWORD=S3cret -e MYSQL_DATABASE=productmngm -p 3306:3306 mysql:latest
docker build -t product-svc .
docker run -p 8025:8025 --name product-service product-svc
docker ps
```
🌍 API/Swagger available at: [http://localhost:8025/product-service/swagger-ui/index.html#/](http://localhost:8025/product-service/swagger-ui/index.html#/)
---
## 🧪 Running Both Services with Docker Compose (Using NGINX as Reverse Proxy)
Using Docker Compose, you can start both the frontend React app and backend Spring Boot service together, along with the database and NGINX server.
### What happens here?
- **NGINX acts as a reverse proxy:** It receives all incoming web requests on port 80 and forwards them to the right service based on the URL path.
- Requests to `/product-ui/` go to the React frontend.
- Requests to `/product-service/` go to the Spring Boot backend.
- This way, users access the whole app via one address (`http://localhost`) without worrying about different ports.
### Why do this?
- **One public port:** Only port 80 is exposed, so it’s easier to manage and safer.
- **Clean URLs:** Users see simple URLs with paths like `/product-ui` and `/product-service`.
- **Internal communication:** Services talk to each other inside the Docker network using container names, keeping things organized.
- **Flexible setup:** You can add more services later and route them through NGINX without changing how users connect.
### How NGINX helps
- Forwards requests correctly depending on the URL path.
- Adds useful headers to keep track of original client info.
- Can be extended for SSL, caching, or other web server features.
---
**🌐 NGINX Configuration**
```nginx
events {}
http {
server {
listen 80;
location /product-service/ {
proxy_pass http://productservice:8020/product-service/;
}
location /product-ui/ {
proxy_pass http://product-ui:80/;
}
}
}
}
```
**docker-compose.yml**
```yaml
version: '3.8'
services:
product-svc:
container_name: productservice
build: ./productSvc
ports:
- "8020:8020"
environment:
APP_INTERNAL_PORT: 8020
DB_ADDRESS: mysql
DB_PORT: 3306
DB_NAME: productmngm
DB_USERNAME: root
DB_PASSWORD: S3cret
depends_on:
- mysql
networks:
- my-network
mysql:
container_name: mysql
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: S3cret
MYSQL_DATABASE: productmngm
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
nginx:
container_name: nginx
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- product-svc
networks:
- my-network
product-ui:
container_name: product-ui
build: ./productApp # path to your React app Dockerfile folder
ports:
- "8030:80"
networks:
- my-network
volumes:
mysql-data:
networks:
my-network:
driver: bridge
```
▶️ Start all services:
```bash
docker-compose up -d --build
docker ps
```
🛑 Stop all services:
```bash
docker-compose down
```
🌍 Product UI: [http://localhost/product-ui](http://localhost/product-ui)
🌍 API/SWAGGGER: [http://localhost/product-service/swagger-ui/index.html#/](http://localhost/product-service/swagger-ui/index.html#/)
---
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment