Complete guide for deploying HushNet Backend with Docker.
- Overview
- Prerequisites
- Quick Start
- Docker Compose Setup
- Environment Variables
- Building Images
- Running Services
- Database Management
- Monitoring & Logs
- Troubleshooting
- Production Deployment
HushNet Backend can be deployed using Docker with two services:
- PostgreSQL Database - Stores all application data
- HushNet Backend - Rust API server
The setup uses Docker Compose for orchestration with health checks and automatic restarts.
docker --version
docker compose versiongit clone https://github.com/HushNet/HushNet-Backend.git
cd HushNet-Backend# Copy example environment file
cp .env.example .env
# Edit with your settings (optional)
nano .env# Build and start all services
docker compose up -d
# View logs
docker compose logs -f# Check service health
docker compose ps
# Test API
curl http://localhost:8080/Expected response:
{
"message": "Hello from HushNet Backend",
"version": "0.1.0",
"status": "healthy"
}┌─────────────────────────────────────────┐
│ Docker Network (hushnet) │
│ │
│ ┌──────────────┐ ┌──────────────┐│
│ │ PostgreSQL │◄─────┤ Backend ││
│ │ :5432 │ │ :8080 ││
│ └──────┬───────┘ └──────┬───────┘│
│ │ │ │
└─────────┼─────────────────────┼─────────┘
│ │
│ │
┌─────▼─────┐ ┌────▼─────┐
│ Volume │ │ Host │
│postgres_ │ │:8080 │
│ data │ │ │
└───────────┘ └──────────┘
| Service | Image | Port | Description |
|---|---|---|---|
postgres |
postgres:16-alpine | 5432 | PostgreSQL database |
backend |
Built from Dockerfile | 8080 | HushNet API server |
# Database Configuration
POSTGRES_USER=postgres # PostgreSQL username
POSTGRES_PASSWORD=dev # PostgreSQL password (CHANGE IN PRODUCTION!)
POSTGRES_DB=e2ee # Database name
POSTGRES_PORT=5432 # Host port for PostgreSQL
# Backend Configuration
BACKEND_PORT=8080 # Host port for backend
SERVER_HOST=0.0.0.0 # Backend bind address
SERVER_PORT=8080 # Backend internal port
# Database URL (used by backend)
DATABASE_URL=postgresql://postgres:dev@postgres:5432/e2ee
# Logging Level
RUST_LOG=info # Options: error, warn, info, debug, trace# Generate secure password
POSTGRES_PASSWORD=$(openssl rand -base64 32)# Build with default tag
docker compose build backend
# Build with custom tag
docker build -t hushnet-backend:latest .
# Build with specific target
docker build --target builder -t hushnet-builder .The Dockerfile uses a multi-stage build:
-
Builder Stage (
rust:1.75-slim)- Compiles Rust code
- Produces optimized binary
- ~2GB image size
-
Runtime Stage (
debian:bookworm-slim)- Only includes binary + runtime deps
- ~150MB final image size
- Runs as non-root user
# Build with custom Rust version
docker build --build-arg RUST_VERSION=1.76 .# Start in detached mode
docker compose up -d
# Start with build
docker compose up -d --build
# Start specific service
docker compose up -d postgres# Stop all services
docker compose stop
# Stop and remove containers
docker compose down
# Stop and remove volumes (⚠️ deletes data!)
docker compose down -v# Restart all
docker compose restart
# Restart specific service
docker compose restart backend# Run multiple backend instances (requires load balancer)
docker compose up -d --scale backend=3# Via docker exec
docker compose exec postgres psql -U postgres -d e2ee
# Via psql client (if installed)
psql -h localhost -U postgres -d e2ee# Execute SQL file
docker compose exec -T postgres psql -U postgres -d e2ee < script.sql
# Run inline SQL
docker compose exec postgres psql -U postgres -d e2ee -c "SELECT COUNT(*) FROM users;"# Create backup
docker compose exec postgres pg_dump -U postgres e2ee > backup_$(date +%Y%m%d).sql
# Restore backup
docker compose exec -T postgres psql -U postgres -d e2ee < backup.sql# Apply seed.sql (runs automatically on first start)
docker compose exec postgres psql -U postgres -d e2ee -f /docker-entrypoint-initdb.d/seed.sql# All services
docker compose logs -f
# Specific service
docker compose logs -f backend
# Last 100 lines
docker compose logs --tail=100 backend
# Since specific time
docker compose logs --since 2024-01-01T10:00:00 backend# List containers
docker compose ps
# Show resource usage
docker stats
# View service health
docker compose ps --format json | jqBoth services have health checks:
# PostgreSQL health check
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Backend health check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/"]
interval: 30s
timeout: 3s
retries: 3Check health status:
docker inspect --format='{{.State.Health.Status}}' hushnet-backendError: Bind for 0.0.0.0:8080 failed: port is already allocated
Solution:
# Change port in .env
BACKEND_PORT=8081
# Or stop conflicting service
lsof -ti:8080 | xargs kill -9 # macOS/Linux
netstat -ano | findstr :8080 # WindowsError: could not connect to server: Connection refused
Solution:
# Check if PostgreSQL is healthy
docker compose ps postgres
# Wait for PostgreSQL to be ready
docker compose logs postgres
# Restart backend after PostgreSQL is ready
docker compose restart backendError: failed to solve: failed to compute cache key
Solution:
# Clear Docker cache
docker compose build --no-cache
# Remove old images
docker system prune -aError: permission denied while trying to connect to the Docker daemon socket
Solution:
# Add user to docker group (Linux)
sudo usermod -aG docker $USER
newgrp docker
# Or run with sudo
sudo docker compose up -d# Enable debug logging
RUST_LOG=debug docker compose up
# Enable trace logging (very verbose)
RUST_LOG=trace docker compose up# Open shell in backend container
docker compose exec backend bash
# Open shell in postgres container
docker compose exec postgres bash
# View environment variables
docker compose exec backend env- Change Default Passwords
# Generate secure credentials
POSTGRES_PASSWORD=$(openssl rand -base64 32)- Use Docker Secrets (Docker Swarm)
secrets:
postgres_password:
external: true
services:
postgres:
secrets:
- postgres_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password- Limit Container Resources
services:
backend:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256MUse Nginx or Traefik for:
- HTTPS/TLS termination
- Load balancing
- Rate limiting
Example with Nginx:
server {
listen 443 ssl http2;
server_name api.hushnet.com;
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Add monitoring stack:
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups"
# Backup database
docker compose exec -T postgres pg_dump -U postgres e2ee > "$BACKUP_DIR/db_$DATE.sql"
# Compress
gzip "$BACKUP_DIR/db_$DATE.sql"
# Delete backups older than 7 days
find "$BACKUP_DIR" -name "db_*.sql.gz" -mtime +7 -delete
echo "Backup completed: db_$DATE.sql.gz"Add to crontab:
# Run daily at 2 AM
0 2 * * * /path/to/backup.shFor production HA setup:
services:
backend:
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
max_attempts: 3
postgres:
# Use managed PostgreSQL (AWS RDS, Google Cloud SQL)
# Or setup PostgreSQL replication# Build & Start
docker compose up -d --build # Build and start services
docker compose up --force-recreate # Recreate containers
# Stop & Remove
docker compose stop # Stop services
docker compose down # Stop and remove containers
docker compose down -v # Stop and remove volumes
# Logs & Monitoring
docker compose logs -f # Follow logs
docker compose logs --tail=100 # Last 100 lines
docker compose ps # List services
docker stats # Resource usage
# Execute Commands
docker compose exec backend bash # Open shell
docker compose exec postgres psql # Open PostgreSQL
# Maintenance
docker system prune -a # Remove unused data
docker volume prune # Remove unused volumes
docker compose build --no-cache # Rebuild from scratch- Docker Documentation
- Docker Compose Documentation
- PostgreSQL Docker Image
- Best Practices for Writing Dockerfiles