# Docker & Containerization

![Docker logo](https://content.gitbook.com/content/pyWVnmtszkUSqMcP8ips/blobs/AaJXQCZ2Xv7P3DxD5paz/image.png)

### How Docker Works in This Project

* **Isolation:** Each service (API, database, cache) runs in its own container, ensuring dependencies do not conflict and making it easy to scale or replace components.
* **Consistency:** Developers and CI/CD pipelines use the same container images, reducing "it works on my machine" issues.
* **Orchestration:** Docker Compose manages multi-container setups, allowing you to start the entire stack with a single command.

***

### Main Docker Components

#### 1. `docker-compose.yml` (Project Root)

This file orchestrates all services required for the application:

* **pool-appointment-api:** The main backend API (Node.js, Express, Prisma)
* **db:** PostgreSQL database
* **redis:** Redis cache

**Example:**

```yaml
version: '3.8'
services:
  db:
    image: postgres:16
    container_name: db
    restart: always
    environment:
      POSTGRES_DB: pool_appointments
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - nine-line-net

  redis:
    image: redis:7
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    networks:
      - nine-line-net

  pool-appointment-api:
    build:
      context: .
      dockerfile: ./apis/pool-appointment-api/Dockerfile
    container_name: pool-appointment-api
    env_file:
      - ./apis/pool-appointment-api/.env
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
    networks:
      - nine-line-net

volumes:
  db_data:

networks:
  nine-line-net:
    driver: bridge
```

***

#### 2. `apis/pool-appointment-api/Dockerfile`

This Dockerfile builds and runs the backend API. Key steps:

* **Base Image:** Uses Node.js 20 for compatibility and performance.
* **Copy Files:** Copies the monorepo’s root files, shared packages, and the API source code.
* **Install Dependencies:** Installs all dependencies at the root level for monorepo compatibility.
* **Build:** Runs Prisma client generation and builds the TypeScript code.
* **Entrypoint:** Runs a setup script that handles database migrations, seeding, and starts the API.

**Key Excerpt:**

```dockerfile
FROM node:20
WORKDIR /app
COPY package*.json ./
COPY tsconfig.json ./
COPY packages ./packages
COPY apis/pool-appointment-api ./apis/pool-appointment-api
RUN npm install
WORKDIR /app/apis/pool-appointment-api
RUN npx prisma generate
RUN npm run build
EXPOSE 3000
CMD npm run setup
```

***

#### 3. Other Dockerfiles

If you add more applications (e.g., `apps/web` for the frontend), each can have its own `Dockerfile` following a similar pattern:

* Set up the working directory
* Copy only the necessary files
* Install dependencies
* Build the application
* Expose the required port
* Set the startup command

***

### How to Use

* **Start all services:**

  ```bash
  docker-compose up --build
  ```
* **Stop all services:**

  ```bash
  docker-compose down
  ```
* **View logs:**

  ```bash
  docker-compose logs -f
  ```

***

### Benefits

* **Easy onboarding:** New developers can start all services with a single command.
* **Reproducibility:** The same environment is used in development, testing, and production.
* **Scalability:** Each service can be scaled independently.

***
