**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.
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 -eMYSQL_ROOT_PASSWORD=S3cret -eMYSQL_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.