395 lines
8.4 KiB
Plaintext
395 lines
8.4 KiB
Plaintext
---
|
|
title: Docker Deployment
|
|
description: Deploy Plunk with Docker Compose
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- Docker installed
|
|
- Docker Compose installed
|
|
- Git installed
|
|
|
|
## Quick Start
|
|
|
|
### 1. Clone Repository
|
|
|
|
```bash
|
|
git clone https://github.com/useplunk/plunk.git
|
|
cd plunk
|
|
```
|
|
|
|
### 2. Copy Environment File
|
|
|
|
```bash
|
|
cp .env.self-host.example .env
|
|
```
|
|
|
|
### 3. Configure Environment
|
|
|
|
Edit `.env` and configure required variables:
|
|
|
|
```bash
|
|
# Database Password (PostgreSQL)
|
|
DB_PASSWORD="changeme123"
|
|
|
|
# JWT Secret (generate with: openssl rand -base64 32)
|
|
JWT_SECRET="your-secret-here"
|
|
|
|
# Domains (for subdomain-based routing)
|
|
API_DOMAIN="api.localhost"
|
|
DASHBOARD_DOMAIN="app.localhost"
|
|
LANDING_DOMAIN="www.localhost"
|
|
WIKI_DOMAIN="docs.localhost"
|
|
|
|
# Set to 'true' for HTTPS in production
|
|
USE_HTTPS="false"
|
|
|
|
# AWS SES (for email sending)
|
|
AWS_SES_REGION="us-east-1"
|
|
AWS_SES_ACCESS_KEY_ID="your-access-key"
|
|
AWS_SES_SECRET_ACCESS_KEY="your-secret-key"
|
|
SES_CONFIGURATION_SET="plunk-configuration-set"
|
|
|
|
# S3-compatible storage (Minio is included by default)
|
|
# Leave defaults unless using external S3
|
|
S3_ENDPOINT="http://minio:9000"
|
|
S3_ACCESS_KEY_ID="plunk"
|
|
S3_ACCESS_KEY_SECRET="plunkminiopass"
|
|
S3_BUCKET="uploads"
|
|
S3_PUBLIC_URL="http://localhost:9000/uploads"
|
|
S3_FORCE_PATH_STYLE="true"
|
|
```
|
|
|
|
### 4. Start Services
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
This starts:
|
|
- PostgreSQL database
|
|
- Redis
|
|
- Minio (S3-compatible storage)
|
|
- Plunk application (all services in one container with nginx)
|
|
- API server
|
|
- Worker process
|
|
- Web dashboard
|
|
- Landing page
|
|
- Documentation
|
|
|
|
### 5. Access Services
|
|
|
|
The services are available at the configured domains:
|
|
- **Dashboard**: `http://app.localhost` (or your configured domain)
|
|
- **API**: `http://api.localhost`
|
|
- **Landing**: `http://www.localhost`
|
|
- **Docs**: `http://docs.localhost`
|
|
- **Minio Console**: `http://localhost:9001`
|
|
|
|
Create your first account and start sending emails!
|
|
|
|
## Docker Compose Configuration
|
|
|
|
The `docker-compose.yml` file uses the pre-built Plunk image from GitHub Container Registry:
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: plunk-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_DB: plunk
|
|
POSTGRES_USER: plunk
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme123}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
networks:
|
|
- plunk
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: plunk-redis
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes
|
|
volumes:
|
|
- redis_data:/data
|
|
networks:
|
|
- plunk
|
|
|
|
minio:
|
|
image: minio/minio:latest
|
|
container_name: plunk-minio
|
|
restart: unless-stopped
|
|
command: server /data --console-address ":9001"
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-plunk}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-plunkminiopass}
|
|
volumes:
|
|
- minio_data:/data
|
|
ports:
|
|
- "9000:9000" # API
|
|
- "9001:9001" # Console
|
|
networks:
|
|
- plunk
|
|
|
|
plunk:
|
|
image: ghcr.io/useplunk/plunk:latest
|
|
container_name: plunk
|
|
restart: unless-stopped
|
|
environment:
|
|
SERVICE: all # Runs all services (API, Worker, Web, Landing, Wiki)
|
|
DATABASE_URL: postgresql://plunk:${DB_PASSWORD}@postgres:5432/plunk
|
|
REDIS_URL: redis://redis:6379
|
|
JWT_SECRET: ${JWT_SECRET}
|
|
# Domain configuration for subdomain routing
|
|
API_DOMAIN: ${API_DOMAIN:-api.localhost}
|
|
DASHBOARD_DOMAIN: ${DASHBOARD_DOMAIN:-app.localhost}
|
|
LANDING_DOMAIN: ${LANDING_DOMAIN:-www.localhost}
|
|
WIKI_DOMAIN: ${WIKI_DOMAIN:-docs.localhost}
|
|
USE_HTTPS: ${USE_HTTPS:-false}
|
|
# AWS SES
|
|
AWS_SES_REGION: ${AWS_SES_REGION}
|
|
AWS_SES_ACCESS_KEY_ID: ${AWS_SES_ACCESS_KEY_ID}
|
|
AWS_SES_SECRET_ACCESS_KEY: ${AWS_SES_SECRET_ACCESS_KEY}
|
|
# S3/Minio storage
|
|
S3_ENDPOINT: ${S3_ENDPOINT:-http://minio:9000}
|
|
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-plunk}
|
|
S3_ACCESS_KEY_SECRET: ${S3_ACCESS_KEY_SECRET:-plunkminiopass}
|
|
ports:
|
|
- "465:465" # SMTP (implicit TLS)
|
|
- "587:587" # SMTP (STARTTLS)
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
- minio
|
|
networks:
|
|
- plunk
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
minio_data:
|
|
plunk_data:
|
|
|
|
networks:
|
|
plunk:
|
|
driver: bridge
|
|
```
|
|
|
|
**Note**: The Plunk image contains all applications (API, Worker, Web, Landing, Wiki) and uses nginx for subdomain-based routing.
|
|
|
|
## Production Deployment
|
|
|
|
### Using Pre-built Image
|
|
|
|
The easiest way to deploy is using the pre-built image from GitHub Container Registry:
|
|
|
|
```bash
|
|
docker pull ghcr.io/useplunk/plunk:latest
|
|
docker compose up -d
|
|
```
|
|
|
|
### Building Your Own Image
|
|
|
|
If you want to build from source:
|
|
|
|
```bash
|
|
docker build -t plunk:custom .
|
|
```
|
|
|
|
Then update `docker-compose.yml` to use your custom image:
|
|
```yaml
|
|
plunk:
|
|
image: plunk:custom
|
|
# ... rest of configuration
|
|
```
|
|
|
|
### Security Hardening
|
|
|
|
1. **Use strong passwords**
|
|
```bash
|
|
DB_PASSWORD=$(openssl rand -base64 32)
|
|
JWT_SECRET=$(openssl rand -base64 32)
|
|
```
|
|
|
|
2. **Use HTTPS**
|
|
- Set `USE_HTTPS=true` in your `.env`
|
|
- Set up reverse proxy (Traefik, Caddy, or nginx)
|
|
- Configure SSL certificates (Let's Encrypt)
|
|
|
|
3. **Configure domains**
|
|
```bash
|
|
API_DOMAIN=api.yourdomain.com
|
|
DASHBOARD_DOMAIN=app.yourdomain.com
|
|
LANDING_DOMAIN=www.yourdomain.com
|
|
WIKI_DOMAIN=docs.yourdomain.com
|
|
USE_HTTPS=true
|
|
```
|
|
|
|
4. **Restrict network access**
|
|
- Don't expose database and Redis ports publicly
|
|
- Use internal Docker networks
|
|
- Only expose port 80/443 (via reverse proxy) and SMTP ports
|
|
|
|
5. **Regular backups**
|
|
- Database backups (automated via cron)
|
|
- Minio data backups
|
|
|
|
### Scaling
|
|
|
|
The Plunk image runs all services in a single container by default. For higher scale:
|
|
|
|
#### Separate Services
|
|
|
|
You can run services separately by setting the `SERVICE` environment variable:
|
|
|
|
```yaml
|
|
# API only
|
|
plunk-api:
|
|
image: ghcr.io/useplunk/plunk:latest
|
|
environment:
|
|
SERVICE: api
|
|
# ... configuration
|
|
|
|
# Worker only
|
|
plunk-worker:
|
|
image: ghcr.io/useplunk/plunk:latest
|
|
environment:
|
|
SERVICE: worker
|
|
# ... configuration
|
|
|
|
# Web only
|
|
plunk-web:
|
|
image: ghcr.io/useplunk/plunk:latest
|
|
environment:
|
|
SERVICE: web
|
|
# ... configuration
|
|
```
|
|
|
|
#### Scale Workers
|
|
|
|
For higher email throughput, run multiple worker containers:
|
|
|
|
```bash
|
|
docker compose up -d --scale plunk-worker=3
|
|
```
|
|
|
|
#### External Services
|
|
|
|
For production at scale, use managed services:
|
|
- Managed PostgreSQL (AWS RDS, DigitalOcean, Supabase)
|
|
- Managed Redis (AWS ElastiCache, Redis Cloud, Upstash)
|
|
- AWS S3 (instead of Minio)
|
|
|
|
## Maintenance
|
|
|
|
### View Logs
|
|
|
|
```bash
|
|
# All services
|
|
docker compose logs -f
|
|
|
|
# Specific service
|
|
docker compose logs -f plunk
|
|
docker compose logs -f postgres
|
|
```
|
|
|
|
### Restart Services
|
|
|
|
```bash
|
|
docker compose restart plunk
|
|
```
|
|
|
|
### Update Plunk
|
|
|
|
Pull the latest image and restart:
|
|
|
|
```bash
|
|
docker compose pull plunk
|
|
docker compose up -d plunk
|
|
```
|
|
|
|
If you built from source:
|
|
```bash
|
|
git pull
|
|
docker build -t plunk:custom .
|
|
docker compose up -d
|
|
```
|
|
|
|
### Backup Database
|
|
|
|
```bash
|
|
docker compose exec postgres pg_dump -U plunk plunk > backup-$(date +%Y%m%d).sql
|
|
```
|
|
|
|
### Restore Database
|
|
|
|
```bash
|
|
docker compose exec -T postgres psql -U plunk plunk < backup.sql
|
|
```
|
|
|
|
### Backup Minio Data
|
|
|
|
```bash
|
|
docker compose exec minio mc alias set local http://localhost:9000 plunk plunkminiopass
|
|
docker compose exec minio mc mirror local/uploads /backups/minio
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Services won't start
|
|
|
|
Check logs:
|
|
```bash
|
|
docker compose logs plunk
|
|
```
|
|
|
|
### Database connection errors
|
|
|
|
Ensure DATABASE_URL is correct and database is running:
|
|
```bash
|
|
docker compose ps postgres
|
|
docker compose exec postgres psql -U plunk -d plunk -c "SELECT 1;"
|
|
```
|
|
|
|
### Worker not processing jobs
|
|
|
|
Check Plunk container logs for worker output:
|
|
```bash
|
|
docker compose logs plunk | grep worker
|
|
```
|
|
|
|
Verify Redis connection:
|
|
```bash
|
|
docker compose exec redis redis-cli PING
|
|
```
|
|
|
|
### Cannot access services
|
|
|
|
Check that your domains resolve correctly:
|
|
```bash
|
|
# For local development with *.localhost domains, these should work automatically
|
|
# For production domains, ensure DNS is configured correctly
|
|
curl http://api.localhost
|
|
curl http://app.localhost
|
|
```
|
|
|
|
### Minio not accessible
|
|
|
|
Check Minio is running:
|
|
```bash
|
|
docker compose ps minio
|
|
docker compose logs minio
|
|
```
|
|
|
|
Access Minio console at `http://localhost:9001` with credentials from `.env`.
|
|
|
|
## Next Steps
|
|
|
|
- [Configure environment variables](/self-hosting/environment-variables)
|
|
- [Set up email delivery](/self-hosting/email-setup)
|
|
- [Database setup and migrations](/self-hosting/database-setup)
|