---
name: docker-compose-deployment
description: Deploy applications using Docker Compose — pull official images, configure ports/volumes, manage containers, and troubleshoot common issues.
version: 1.0.0
author: Hermes Agent
license: MIT
dependencies: ["docker", "docker compose"]
metadata:
  hermes:
    tags: [Docker, Docker Compose, Deployment, DevOps, Containers, Infrastructure]
    related_skills: []

---

# Docker Compose Deployment Skill

Deploy applications using Docker Compose v2+. Covers pulling official images, configuring services, managing ports/volumes, and troubleshooting common issues.

## Prerequisites

- Docker installed and running
- Docker Compose v2+ (`docker compose` command, not `docker-compose`)
- Network access to pull images

### Verify Installation

```bash
docker --version
docker compose version
```

## Workflow

### Step 1: Clone or Create Project

```bash
# Clone from GitHub
git clone https://github.com/author/project.git /path/to/deploy
cd /path/to/deploy

# Or create docker-compose.yml from scratch
```

### Step 2: Check Existing Configuration

```bash
# Look for existing docker-compose files
ls -la docker-compose*.yml

# Check if image exists locally
docker images | grep project-name
```

### Step 3: Configure Services

**Basic docker-compose.yml template:**

```yaml
services:
  app-name:
    image: author/image-name:latest
    container_name: app-name
    ports:
      - 'HOST_PORT:CONTAINER_PORT'
    volumes:
      - ./data:/app/data
    environment:
      - KEY=value
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:PORT"]
      interval: 30s
      timeout: 10s
      retries: 3
```

**Key Configuration Points:**

| Setting | Purpose | Example |
|---------|---------|---------|
| `ports` | Map host to container ports | `'6888:8888'` |
| `volumes` | Persist data | `./data:/app/data` |
| `environment` | App configuration | `ALLOW_PASSWORD=true` |
| `restart` | Auto-restart policy | `unless-stopped` |
| `healthcheck` | Container health monitoring | HTTP endpoint check |

### Step 4: Deploy

```bash
# Start services (detached mode)
docker compose up -d

# Or force recreate
docker compose up -d --force-recreate
```

### Step 5: Verify Deployment

```bash
# Check container status
docker ps --filter name=app-name

# Check health
curl http://localhost:HOST_PORT

# View logs
docker compose logs -f app-name

# Check resource usage
docker stats app-name
```

## Common Patterns

### Pattern 1: Use Official Image (Recommended)

```yaml
services:
  app:
    image: author/image:latest  # Pull from Docker Hub
    # No build context needed
```

**Pros:** Fast, tested, maintained by author  
**Cons:** Less customization

### Pattern 2: Build Locally

```yaml
services:
  app:
    build: .
    # Or specify Dockerfile
    build:
      context: .
      dockerfile: Dockerfile.prod
```

**Pros:** Full customization  
**Cons:** Slower, requires build tools

### Pattern 3: Multiple Services

```yaml
services:
  app:
    image: author/app:latest
    depends_on:
      - db
      - redis
  
  db:
    image: postgres:15
    volumes:
      - pgdata:/var/lib/postgresql/data
  
  redis:
    image: redis:alpine

volumes:
  pgdata:
```

## Troubleshooting

### Issue 1: Port Conflicts

**Symptom:** Container starts but port not accessible

**Check for conflicts:**
```bash
# See what's using the port
netstat -tlnp | grep PORT
# or
lsof -i :PORT
```

**Solution:** Change host port in docker-compose.yml:
```yaml
ports:
  - 'NEW_PORT:CONTAINER_PORT'  # e.g., '6888:8888'
```

### Issue 2: Override File Conflicts

**Symptom:** Multiple ports exposed, configuration not applying

**Cause:** `docker-compose.yml` + `docker-compose.override.yml` are merged

**Solution:** Remove override file or consolidate:
```bash
# Remove override to avoid conflicts
rm docker-compose.override.yml

# Or edit both files to be consistent
```

### Issue 3: Container Won't Start

```bash
# Check logs
docker compose logs app-name

# Check container state
docker inspect app-name | grep -A 10 State

# Try running interactively
docker compose up app-name  # Not detached, see output
```

### Issue 4: Image Pull Fails

```bash
# Check network
curl -I https://hub.docker.com

# Try manual pull
docker pull author/image:latest

# Check disk space
df -h /var/lib/docker
```

### Issue 5: v1 vs v2 Command

**Old:** `docker-compose up -d` (v1, separate install)  
**New:** `docker compose up -d` (v2, built into Docker)

**Check version:**
```bash
docker compose version  # Should be v2.x+
```

## Management Commands

```bash
# Start services
docker compose up -d

# Stop services
docker compose down

# Restart services
docker compose restart

# View logs
docker compose logs -f [service-name]

# Execute command in container
docker compose exec service-name /bin/sh

# View resource usage
docker stats

# Rebuild (if using build context)
docker compose build --no-cache

# Update images
docker compose pull
docker compose up -d --force-recreate
```

## Security Best Practices

### 1. Don't Hardcode Secrets

```yaml
# BAD
environment:
  - DB_PASSWORD=supersecret

# GOOD - use .env file
env_file: .env

# Or use Docker secrets (Swarm mode)
```

### 2. Use Specific Image Tags

```yaml
# BAD - can change unexpectedly
image: author/app:latest

# GOOD - pinned version
image: author/app:v1.2.3
```

### 3. Limit Network Exposure

```yaml
# Only expose to localhost
ports:
  - '127.0.0.1:8888:8888'

# Or use internal network
networks:
  - internal

networks:
  internal:
    internal: true
```

### 4. Add Health Checks

```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8888/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 10s
```

## Example: Complete Deployment

```yaml
version: '3.8'

services:
  wealth-tracker:
    image: nicejade/wealth-tracker:latest
    container_name: wealth-tracker
    ports:
      - '6888:8888'
    volumes:
      - ./data:/app/data
    environment:
      - ALLOW_PASSWORD=true
      - CAN_BE_RESET=true
      - PEPPER_SECRET=change_this_secret
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8888"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
    labels:
      - "com.app.version=4.0.0"
      - "com.app.description=Personal Asset Tracker"

volumes:
  data:
```

**Deploy:**
```bash
cd /path/to/project
docker compose up -d

# Verify
curl http://localhost:6888  # Should return HTTP 200
```

## Tips

1. **Always check existing docker-compose.yml** before creating new one
2. **Use official images** when available — faster and more reliable
3. **Remove override files** if they cause configuration conflicts
4. **Pin image versions** for production deployments
5. **Add health checks** for automatic recovery
6. **Use volumes** for data persistence
7. **Test with `docker compose up`** (not detached) first to see errors
8. **Document port mappings** for future reference
