# Docker Integration

Use KeyEnv with Docker and docker-compose.

Source: https://keyenv.dev/docs/guides/docker/

This guide covers using KeyEnv with Docker and docker-compose.

## Development with docker-compose

### Option 1: Pull secrets before starting

```bash
# Pull secrets to .env
keyenv pull

# Start containers (docker-compose reads .env automatically)
docker-compose up
```

Your `docker-compose.yml`:

```yaml
version: '3.8'

services:
  app:
    build: .
    env_file:
      - .env
    ports:
      - "3000:3000"
```

### Option 2: Use keyenv run

```bash
# Start with secrets injected
keyenv run -- docker-compose up
```

This injects secrets into the docker-compose process, which passes them to containers.

## Production Deployments

### Build-time vs Runtime Secrets

> **Warning**
>
> Never include secrets in Docker images. Always inject at runtime.

**Wrong** - Secrets baked into image:

```dockerfile
# DON'T DO THIS
COPY .env /app/.env
```

**Correct** - Secrets injected at runtime:

```yaml
# docker-compose.prod.yml
services:
  app:
    image: myapp:latest
    env_file:
      - .env.production
```

### CI/CD Workflow

```yaml
# .github/workflows/deploy.yml
- name: Pull production secrets
  env:
    KEYENV_TOKEN: ${{ secrets.KEYENV_TOKEN }}
  run: keyenv pull -e production -o .env.production

- name: Deploy
  run: docker-compose -f docker-compose.prod.yml up -d
```

## Docker Swarm / Kubernetes

For orchestrators, use Docker secrets or Kubernetes secrets:

### Docker Swarm

```bash
# Pull secret and create Docker secret
keyenv get DATABASE_URL -e production -q | docker secret create db_url -
```

### Kubernetes

For Kubernetes, we recommend using the **External Secrets Operator (ESO)** integration for automatic secret synchronization:

> **Note**
>
> See the [Kubernetes Integration Guide](/docs/guides/kubernetes) for complete ESO setup instructions.

For simple one-time syncs, you can use the CLI:

```bash
# Pull secrets and create K8s secret
keyenv pull -e production -o- | kubectl create secret generic app-secrets --from-env-file=/dev/stdin
```

## Multi-environment Setup

```bash
# Development
keyenv pull -e development -o .env.development

# Staging
keyenv pull -e staging -o .env.staging

# Production
keyenv pull -e production -o .env.production
```

```yaml
# docker-compose.yml
services:
  app:
    build: .
    env_file:
      - .env.${ENVIRONMENT:-development}
```

```bash
ENVIRONMENT=staging docker-compose up
```

## Best Practices

1. **Never commit .env files** - Add them to `.gitignore`
2. **Use .env.example** - Commit a template without values
3. **Pull fresh secrets** - Don't cache secrets in CI/CD
4. **Use different credentials** - Each environment should have unique secrets
