---
title: Docker Deployment
description: Deploy with Docker Compose
---

## Quick Start

```bash
git clone https://github.com/useplunk/plunk.git
cd plunk
cp .env.self-host.example .env
# Edit .env (see Environment Variables)
docker compose up -d
```

See [Environment Variables](/self-hosting/environment-variables) for all configuration options.

## Services

| Service | Purpose |
|---------|---------|
| `plunk` | All apps + nginx (API, Web, Landing, Wiki, SMTP) |
| `postgres` | PostgreSQL 16 database |
| `redis` | Redis 7 queue |
| `minio` | S3-compatible storage |
| `ntfy` | Notifications |

## Ports

| Port | Service |
|------|---------|
| 80 | Nginx (HTTP) |
| 465 | SMTP (implicit TLS) |
| 587 | SMTP (STARTTLS) |
| 9000 | Minio API |
| 9001 | Minio Console |

## Running Individual Services

Set `SERVICE` environment variable:

```bash
SERVICE=api    # API only
SERVICE=worker # Worker only
SERVICE=web    # Dashboard only
SERVICE=all    # Everything (default)
```

## SMTP TLS Certificates

For TLS on ports 465/587, provide certificates via one of these methods:

### Traefik acme.json (Dokploy, Coolify)

Mount the `acme.json` file and set `SMTP_DOMAIN`:

```yaml
environment:
  SMTP_DOMAIN: "smtp.yourdomain.com"
volumes:
  - /path/to/acme.json:/certs/acme.json:ro
```

Plunk automatically extracts the certificate for `SMTP_DOMAIN` from acme.json.

### PEM Files

Mount certificate files directly:

```yaml
volumes:
  - /path/to/privkey.pem:/certs/privkey.pem:ro
  - /path/to/fullchain.pem:/certs/fullchain.pem:ro
```

If no certificates are mounted, SMTP runs without TLS.

## Building from Source

```bash
docker build -t plunk:custom .
```
