Docker Deployment
One-click deployment with Docker Compose.
Overview
Deploy Drip server with Docker Compose for easy management and automatic TLS via Caddy. This is the recommended approach for containerized deployments.
Prerequisites
- Docker and Docker Compose installed
- Domain with DNS pointing to your server
- Cloudflare account (for DNS challenge)
Step 1: Create Project Directory
bash
mkdir drip && cd dripStep 2: Create Configuration Files
docker-compose.yml
yaml
services:
caddy:
image: slothcroissant/caddy-cloudflaredns:latest
container_name: drip-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
environment:
DOMAIN: ${DOMAIN}
ACME_EMAIL: ${ACME_EMAIL:-}
CF_API_TOKEN: ${CF_API_TOKEN}
extra_hosts:
- "host.docker.internal:host-gateway"
mem_limit: 256m
mem_reservation: 64m
drip-server:
image: driptunnel/drip-server:${VERSION:-latest}
container_name: drip-server
restart: unless-stopped
network_mode: host
volumes:
- ./config.yaml:/app/config.yaml:ro
environment:
GOMEMLIMIT: 256MiB
mem_limit: 512m
mem_reservation: 128m
volumes:
caddy-data:Caddyfile
caddyfile
{
email {$ACME_EMAIL}
}
{$DOMAIN}, *.{$DOMAIN} {
tls {
dns cloudflare {$CF_API_TOKEN}
protocols tls1.3 tls1.3
}
reverse_proxy host.docker.internal:8443 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
}
}config.yaml
yaml
# Drip Server Configuration (Caddy reverse proxy mode)
# Use with: docker-compose.yml
#
# Architecture:
# Client --[HTTPS/WSS]--> Caddy:443 --[HTTP/WS]--> drip-server:8443
# Client --[TCP tunnel]--> drip-server:20000-20100 (direct, no proxy)
# Server port - Caddy will proxy to this port (internal only)
port: 8443
# Domain for client connections (required)
domain: tunnel.example.com
# Domain for tunnel URLs (optional, defaults to domain)
# tunnel_domain: example.com
# Authentication token (required for production)
# Generate with: openssl rand -hex 32
token: YOUR_SECRET_TOKEN
# TLS disabled - Caddy handles TLS termination
tls_enabled: false
# Public port for URLs - set to 443 since Caddy serves on 443
public_port: 443
# TCP tunnel port range (exposed directly to clients, not through Caddy)
tcp_port_min: 20000
tcp_port_max: 20100
# Monitoring - Use separate token
# Generate with: openssl rand -hex 32
metrics_token: YOUR_METRICS_TOKEN
# Optional settings
# debug: false # Enable debug logging
# pprof_port: 6060 # Enable pprof profiling
# transports: # Allowed transports (default: tcp,wss)
# - tcp
# - wss
# tunnel_types: # Allowed tunnel types (default: http,https,tcp)
# - http
# - https
# - tcp.env (Secure Environment File)
bash
# Domain configuration
DOMAIN=tunnel.example.com
ACME_EMAIL=your-email@example.com
# Cloudflare API token for DNS challenge
# Get from: Cloudflare Dashboard → My Profile → API Tokens
CF_API_TOKEN=your-cloudflare-api-token
# Drip server version (use specific version in production)
VERSION=latestStep 3: Get Cloudflare API Token
- Go to Cloudflare Dashboard → My Profile → API Tokens
- Create Token → Edit zone DNS template
- Set permissions: Zone - DNS - Edit
- Include specific zone: your domain
- Copy the token to
.envfile
Step 4: Start Services
bash
docker-compose up -dManagement Commands
bash
# View logs
docker-compose logs -f
# View Caddy logs only
docker-compose logs -f caddy
# View Drip server logs only
docker-compose logs -f drip-server
# Restart services
docker-compose restart
# Stop services
docker-compose down
# Update to latest version
docker-compose pull && docker-compose up -dVerify Setup
bash
# Check container status
docker-compose ps
# Test health endpoint
curl https://tunnel.example.com/health
# Check server stats (if metrics_token configured)
curl -H "Authorization: Bearer YOUR_METRICS_TOKEN" \
https://tunnel.example.com/statsFirewall Configuration
Make sure to open the required ports:
bash
# HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# TCP tunnel port range
sudo ufw allow 20000:20100/tcp
# Verify rules
sudo ufw statusSecurity Checklist
Before going to production:
- [ ] Generated secure random token (32+ chars) with
openssl rand -hex 32 - [ ] Replaced placeholder token in config.yaml
- [ ] Set file permissions to 600 for config.yaml and .env
- [ ] Using specific image version (not
latest) - [ ] Configured separate metrics_token
- [ ] Firewall configured to only allow necessary ports
- [ ] DNS records pointing to server IP
- [ ] Tested health endpoint returns 200
Troubleshooting
Certificate Issues
bash
# Check Caddy logs for certificate errors
docker-compose logs caddy | grep -i cert
# Verify DNS is pointing to your server
dig tunnel.example.com
# Check Cloudflare API token permissions
docker-compose logs caddy | grep -i cloudflareConnection Issues
bash
# Check if containers are running
docker-compose ps
# Check drip-server logs
docker-compose logs drip-server
# Test internal connectivity
docker-compose exec caddy wget -qO- http://host.docker.internal:8443/healthAuthentication Errors
bash
# Verify token in config
docker-compose exec drip-server cat /app/config.yaml | grep token
# Check for whitespace issues in token