VPS Docker Setup (Ubuntu + FastPanel)
Overview
| Created | Updated | Status |
|---|---|---|
| 2026-01-28 | 2026-01-31 | ✅ Accepted |
Context
Deploy Docker containers on Ubuntu VPS with FastPanel. FastPanel manages WordPress and provides Nginx reverse proxy with SSL.
Decision: Use FastPanel's Nginx as reverse proxy. Docker containers bind to localhost, FastPanel handles SSL via Let's Encrypt.
Architecture
FastPanel Nginx (:80/:443)
├─ blog.quangnguyen.dev → WordPress (FastPanel)
├─ app.quangnguyen.dev → Docker: web (localhost:7979)
└─ api.quangnguyen.dev → Docker: api (localhost:3001)
Docker: web ↔ api ↔ postgres (internal network)
Setup Steps
1. Install Docker
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker GPG key + repo
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker && sudo systemctl start docker
sudo usermod -aG docker $USER # Logout/login after
2. Configure DNS
Add A records: app → VPS_IP, api → VPS_IP
nslookup app.quangnguyen.dev # Verify
3. Clone & Configure
cd /var/www/app_quangnguyen_dev/data/www/app.quangnguyen.dev
git clone https://github.com/QuangNguyen1607/web-app-business.git .
cp .env.prod.example .env.prod && nano .env.prod
chmod 600 .env.prod
4. FastPanel Reverse Proxy
Create proxies in FastPanel UI:
| Domain | Target | SSL |
|---|---|---|
| app.quangnguyen.dev | http://127.0.0.1:7979 | Let's Encrypt |
| api.quangnguyen.dev | http://127.0.0.1:3001 | Let's Encrypt |
5. Deploy
docker compose -f docker-compose.prod.yml up -d --build
6. Verify
docker ps
curl http://127.0.0.1:7979
curl https://app.quangnguyen.dev
Maintenance
# Logs
docker compose -f docker-compose.prod.yml logs -f
# Update
git pull origin dev && docker compose -f docker-compose.prod.yml up -d --build
# Backup DB
docker exec flowershop-postgres pg_dump -U flowershop flowershop > backup.sql
# Cleanup
docker image prune -f
Alternatives Considered
| Option | Rejected Because |
|---|---|
| Caddy proxy | Redundant with FastPanel Nginx |
| Docker Hub | VPS-direct builds faster, no registry costs |
| Kubernetes | Overkill for single-server |
Consequences
Positive: Single Nginx layer, automatic SSL renewal, no conflicts with WordPress Negative: Dependent on FastPanel UI for proxy config