# Docker Compose

## What is Docker Compose?

Docker Compose is a tool that makes life easier when you use multiple containers in one project. With Docker Compose, you can run multiple services at once using just one configuration file (`docker-compose.yml`).

## **Why Use Docker Compose?**

* Can run many containers with a single command
* Configuration is cleaner and easier to understand
* Can use environment variables for flexible settings
* Easy to scale services

  


---

## **Simple Implementation**

We’ll create a simple example: a Node.js app connected to a PostgreSQL database.

### **Folder Structure:**

```javascript
my_project/
│── docker-compose.yml
│── app/
│   ├── server.js
│   ├── package.json
```

### docker-compose.yml content:

```bash
services:
  web:
    image: node:21
    container_name: web_app
    working_dir: /app
    volumes:
      - .:/app # Mount the current folder to /app in the container
    ports:
      - "3000:3000" # hostPort:containerPort
    command: "node server.js"
    depends_on:
      - db

  db:
    image: postgres:16
    container_name: postgres_db
    restart: always
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    ports:
      - "5432:5432" # hostPort:containerPort
```

### package.json content:

```javascript
{
  "name": "web-app",
  "version": "1.0.0",
  "description": "Node.js app with PostgreSQL using Docker Compose",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.3",
    "pg": "^8.11.3"
  }
}
```

### server.js content:

```javascript
const express = require('express');
const { Client } = require('pg');

const app = express();
const port = 3000;

// Database connection config
const db = new Client({
  user: 'user',
  host: 'db', // Matches the database service name in docker-compose.yml
  database: 'mydatabase',
  password: 'password',
  port: 5432,
});

// Try to connect to the database
db.connect()
  .then(() => console.log('Database connected!'))
  .catch(err => console.error('Database connection failed:', err));

// Main endpoint
app.get('/', async (req, res) => {
  try {
    const result = await db.query('SELECT NOW()');
    res.json({ message: 'Server is running!', time: result.rows[0].now });
  } catch (err) {
    res.status(500).json({ error: 'Failed to fetch time from database' });
  }
});

// Start server
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
```

### **Brief explanation:**

* **web service** → Runs the Node.js app inside a container and exposes port **3000**
* **db service** → PostgreSQL with default database settings
* **depends_on** → Ensures the database service starts before the web service


---

## Basic Docker Compose commands:

🚀 **Start all containers:**

```javascript
docker compose up -d
```

🛑 **Stop all containers:**

```javascript
docker compose down
```

📜 **View container logs:**

```javascript
docker compose logs -f
```


---

## **Scaling with Docker Compose**

If you want more than one instance of a certain service, use this command:

```javascript
docker compose up --scale web=3 -d
```

This will run **3 instances** of the `web` service, while the database remains a single instance.

---

**Documents**

- [About Me](https://wiki.carens.dev/s/9dff43a5-7aa3-48e0-9ec6-0fbbbaf1a301/doc/about-me-rUOLQ4InJh)
- [Wiki](https://wiki.carens.dev/s/9dff43a5-7aa3-48e0-9ec6-0fbbbaf1a301/doc/wiki-NtaYKKsSOi)