Docker Architecture & Deployment
System Overview
This document describes the Docker container architecture for LUStores running on a VM host, including volume mappings, networking, and data persistence strategies.
Architecture Diagram
graph TB subgraph "Host VM" subgraph "Docker Network: lustores_network<br/>172.20.0.0/16" subgraph "Web Layer" NGINX[nginx:alpine<br/>:80, :443<br/>SSL Termination] end subgraph "Application Layer" APP[LUStores App<br/>st7ma784/lustores:latest<br/>:5000] AUTH[Replit Auth<br/>st7ma784/replitauth:latest<br/>:3001] end subgraph "Data Layer" DB[(PostgreSQL 15<br/>:5432<br/>university_inventory)] REDIS[(Redis 7<br/>:6379<br/>Session Store)] end subgraph "Support Services" CERTBOT[Certbot<br/>SSL Renewal] WATCHTOWER[Watchtower<br/>Auto-updates] end end subgraph "Host Volumes" DBVOL[/db<br/>PostgreSQL Data] REDISVOL[redis_data<br/>Redis Data] LOGS[./logs<br/>Application Logs] CERTBOT_CONF[./certbot/conf<br/>SSL Certificates] CERTBOT_WWW[./certbot/www<br/>ACME Challenge] NGINX_CONF[./nginx<br/>Config Files] ENV[.env.prod<br/>Environment Config] end end subgraph "External" INTERNET((Internet<br/>Users)) DOCKERHUB((Docker Hub<br/>Image Registry)) LETSENCRYPT((Let's Encrypt<br/>Certificate Authority)) end INTERNET -->|HTTPS :443| NGINX INTERNET -->|HTTP :80| NGINX NGINX -->|proxy_pass| APP APP -->|health checks| NGINX APP --> DB APP --> REDIS APP --> AUTH CERTBOT -->|cert renewal| LETSENCRYPT CERTBOT --> CERTBOT_CONF CERTBOT --> CERTBOT_WWW NGINX --> CERTBOT_CONF NGINX --> NGINX_CONF NGINX --> LOGS DB --> DBVOL REDIS --> REDISVOL APP --> LOGS WATCHTOWER -->|monitors| APP WATCHTOWER -->|monitors| AUTH WATCHTOWER -->|pulls updates| DOCKERHUBContainer Details
nginx - Reverse Proxy & SSL Termination
Image:
nginx:alpinePorts:
80:80- HTTP (redirects to HTTPS)443:443- HTTPS
Volumes:
./nginx/nginx.conf.template:/etc/nginx/templates/default.conf.template:ro./certbot/conf:/etc/letsencrypt:ro- SSL certificates./certbot/www:/var/www/certbot:ro- ACME challenges./logs/nginx:/var/log/nginx- Access & error logs
Health Check:
nc -z 127.0.0.1 80every 30sRestart Policy:
unless-stopped
app - Main LUStores Application
Image:
st7ma784/lustores:latestInternal Port:
5000(not exposed externally)Environment:
NODE_ENV=productionDATABASE_URL- PostgreSQL connectionSESSION_SECRET,JWT_SECRET- Security keysDOMAIN,EMAIL- Deployment config
Depends On:
db(healthy),replit-auth(healthy)Volumes:
./logs:/app/logs- Application logsHealth Check:
wget --spider http://127.0.0.1:5000/healthevery 30sRestart Policy:
unless-stoppedLabels:
com.centurylinklabs.watchtower.enable=true- Auto-update enabled
db - PostgreSQL Database
Warning
The database volume is mounted at /db on the host - this is CRITICAL for backups!
Image:
postgres:15-alpinePort:
5432:5432Database:
university_inventoryVolumes:
/db:/var/lib/postgresql/data- CRITICAL: Host volume at/db./init.sql:/docker-entrypoint-initdb.d/init.sql- Schema initialization
Environment:
POSTGRES_DB=university_inventoryPOSTGRES_USER=postgresPOSTGRES_PASSWORD=${DB_PASSWORD}PGDATA=/var/lib/postgresql/data/pgdata
Health Check:
pg_isready -U postgres -d university_inventoryevery 10sRestart Policy:
unless-stopped
redis - Session Store & Cache
Image:
redis:7-alpinePort:
6379:6379Volumes:
redis_data:/data- Named Docker volumeCommand:
redis-server --appendonly yes- AOF persistence enabledRestart Policy:
unless-stopped
replit-auth - Authentication Service
Image:
st7ma784/replitauth:latestPort:
3001:3001Environment:
PORT=3001JWT_SECRET=${JWT_SECRET}ALLOWED_ORIGINS=https://${DOMAIN}
Health Check:
wget --spider http://127.0.0.1:3001/healthevery 30sRestart Policy:
unless-stoppedLabels: Watchtower enabled with graceful shutdown (
SIGTERM)
certbot - SSL Certificate Management
Image:
certbot/certbotVolumes:
./certbot/conf:/etc/letsencrypt- Certificate storage./certbot/www:/var/www/certbot- ACME challenge directory./logs/certbot:/var/log/certbot- Renewal logs
Environment:
DOMAIN=${DOMAIN}- Your domain nameEMAIL=${EMAIL}- Admin email for notificationsCERTBOT_STAGING- Use staging server for testing
Function: Automatically renews certificates every 12 hours
Restart Policy:
unless-stopped
watchtower - Automatic Container Updates
Image:
containrrr/watchtower:latestVolumes:
/var/run/docker.sock:/var/run/docker.sock- Docker API accessEnvironment:
WATCHTOWER_CLEANUP=true- Remove old imagesWATCHTOWER_SCHEDULE=0 */15 * * * *- Check every 15 minutesWATCHTOWER_LABEL_ENABLE=true- Only update labeled containersWATCHTOWER_NOTIFICATION_WEBHOOK_URL- Notifications to app
Restart Policy:
unless-stoppedLabels:
watchtower.enable=false- Don’t update itself
Network Configuration
Network: lustores_network
Driver:
bridgeSubnet:
172.20.0.0/16Purpose: Isolated internal communication between containers
Service Discovery
Docker DNS automatically resolves container names:
http://app:5000- Applicationhttp://replit-auth:3001- Auth servicepostgresql://postgres:${DB_PASSWORD}@db:5432/university_inventory- Database
Volume Strategy
Critical Data Volumes (MUST BACKUP)
PostgreSQL Database - /db (Host Volume)
Danger
This is the MOST important data to backup!
Location:
/dbon host VMContains: All application data, users, inventory, orders, sales
Backup Strategy: See Backup & Restore Procedures
Redis Data - redis_data (Docker Volume)
Type: Named Docker volume
Contains: Session data, cache
Backup Priority: Medium (transient data)
Location: Managed by Docker (typically
/var/lib/docker/volumes/)
Configuration Files (MUST BACKUP)
SSL Certificates - ./certbot/conf
Contains: Let’s Encrypt certificates and keys
Backup Priority: High
Renewal: Automatic via certbot, but backup recommended
Environment Configuration - .env.prod
Danger
Store encrypted backup in secure location!
Contains: All secrets, passwords, configuration
Backup Priority: CRITICAL
Security: Never commit to git, store encrypted
Nginx Configuration - ./nginx/
Contains: Web server configuration
Backup Priority: Medium (can be recreated, but contains custom settings)
Port Mapping
Service |
Internal |
External |
Protocol |
Purpose |
|---|---|---|---|---|
nginx |
80 |
80 |
HTTP |
Redirect to HTTPS |
nginx |
443 |
443 |
HTTPS |
Main access point |
app |
5000 |
(none) |
HTTP |
Internal only (via nginx) |
replit-auth |
3001 |
3001 |
HTTP |
Auth service |
db |
5432 |
5432 |
PostgreSQL |
Database (exposed for admin) |
redis |
6379 |
6379 |
Redis |
Cache (exposed for admin) |
Note
In production, consider closing external access to db:5432 and redis:6379 by removing port mappings from docker-compose.prod.yml
Data Flow
sequenceDiagram participant User participant nginx participant app participant auth as replit-auth participant db as PostgreSQL participant redis as Redis User->>nginx: HTTPS Request :443 nginx->>nginx: Terminate SSL nginx->>app: HTTP Request :5000 app->>auth: Validate Token :3001 auth-->>app: Token Valid app->>db: Query Data :5432 db-->>app: Return Results app->>redis: Cache Session :6379 redis-->>app: Session Stored app-->>nginx: HTTP Response nginx-->>User: HTTPS ResponseHealth Monitoring
All critical services have health checks:
Service |
Check Command |
Interval |
Timeout |
Retries |
Start Period |
|---|---|---|---|---|---|
nginx |
|
30s |
10s |
3 |
30s |
app |
|
30s |
10s |
5 |
60s |
db |
|
10s |
5s |
5 |
30s |
replit-auth |
|
30s |
10s |
3 |
30s |
Monitoring Commands
Check health status:
docker compose -f docker-compose.prod.yml ps
View health logs:
docker compose -f docker-compose.prod.yml logs -f app
Automatic Updates (Watchtower)
Watchtower monitors Docker Hub for new images and automatically updates:
app (
st7ma784/lustores:latest)replit-auth (
st7ma784/replitauth:latest)
Update Process
Watchtower checks Docker Hub every 15 minutes
If new image found, pulls the update
Stops old container gracefully
Starts new container
Removes old image
Sends webhook notification to app
Manual Override
Disable watchtower temporarily:
docker compose -f docker-compose.prod.yml stop watchtower
Update specific service manually:
docker compose -f docker-compose.prod.yml pull app
docker compose -f docker-compose.prod.yml up -d app
Security Considerations
SSL/TLS: All external traffic encrypted via Let’s Encrypt certificates
Internal Network: Containers communicate via isolated Docker network
Secrets: Managed via
.env.prodfile (not committed to git)Updates: Automatic security updates via Watchtower
Health Checks: Automatic restart on failures
Firewall: Only ports 80 and 443 should be publicly accessible
Troubleshooting
See Quick Reference Handbook (Quick Reference Handbook) for common issues and solutions.
Quick diagnostic commands:
# Check all container status
docker compose -f docker-compose.prod.yml ps
# View logs for specific service
docker compose -f docker-compose.prod.yml logs -f app
# Restart specific service
docker compose -f docker-compose.prod.yml restart app
# Check disk space
df -h /db
# Check Docker volumes
docker volume ls
docker volume inspect lustores_redis_data