Dockerfile- Builds your app (client + server in one image)docker-compose.yml- Local development (client, server, MongoDB)docker-compose.prod.yml- Production (app, MongoDB, Nginx)nginx.conf- Reverse proxy + SSLdeploy-docker.sh- One-command deployment
# Install Docker Desktop from docker.com
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Open http://localhost:5173 (client)
# API at http://localhost:3000/apiStop: docker-compose down
SSH into your server:
ssh user@your-server-ip# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker
# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Verify
docker --version
docker-compose --versioncd /opt
git clone https://github.com/your-username/bodybuilding.git
cd bodybuildingscp -r /path/to/bodybuilding user@host:/opt/
ssh user@host "cd /opt/bodybuilding"On the server:
cd /opt/bodybuilding
# Copy example env
cp .env.docker .env.prod
# Edit with your values
nano .env.prodUpdate these in .env.prod:
MONGO_ROOT_PASSWORD=your-secure-password-here
JWT_SECRET=<run: node -e "console.log(require('crypto').randomBytes(48).toString('hex'))">
DOMAIN=yourdomain.irGenerate JWT_SECRET locally:
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"# Install Certbot
sudo apt install -y certbot
# Generate certificate
sudo certbot certonly --standalone -d yourdomain.ir -d www.yourdomain.ir
# Copy to project
sudo cp /etc/letsencrypt/live/yourdomain.ir/fullchain.pem ./ssl/cert.pem
sudo cp /etc/letsencrypt/live/yourdomain.ir/privkey.pem ./ssl/key.pem
sudo chown $USER:$USER ./ssl/*.pemcd /opt/bodybuilding
chmod +x deploy-docker.shcd /opt/bodybuilding
./deploy-docker.shWhat it does:
- ✅ Checks
.env.prodexists - ✅ Builds Docker images
- ✅ Starts MongoDB, Node.js app, Nginx
- ✅ Shows status
# Check all services running
docker-compose -f docker-compose.prod.yml ps
# View logs
docker-compose -f docker-compose.prod.yml logs -f
# Test API
curl https://yourdomain.ir/apiExpected: Should return 404 (normal, means server is running)
# View logs (real-time)
docker-compose -f docker-compose.prod.yml logs -f
# Stop all services
docker-compose -f docker-compose.prod.yml down
# Start again
docker-compose -f docker-compose.prod.yml up -d
# Restart one service
docker-compose -f docker-compose.prod.yml restart app
# View resource usage
docker stats
# Backup database
docker-compose -f docker-compose.prod.yml exec mongodb mongodump -u admin -p $MONGO_ROOT_PASSWORD --db bodybuilding --out /backups/bodybuilding-$(date +%Y%m%d)After pushing new code:
cd /opt/bodybuilding
# Pull latest
git pull origin main
# Rebuild and deploy
./deploy-docker.shThat's it! Docker handles everything.
docker-compose -f docker-compose.prod.yml logsLook for errors in output.
# Check what's using them
sudo lsof -i :80
sudo lsof -i :443
# Stop conflicting service
sudo systemctl stop nginx # if Nginx installed
sudo systemctl stop apache2 # if Apache installedEdit .env.prod:
DOMAIN=yourdomain.ir
Then redeploy: ./deploy-docker.sh
docker system prune -a # Removes unused images# Check MongoDB logs
docker-compose -f docker-compose.prod.yml logs mongodb
# Restart MongoDB
docker-compose -f docker-compose.prod.yml restart mongodb- Docker & Docker Compose installed on server
- Project cloned to
/opt/bodybuilding -
.env.prodcreated and filled with values - SSL certificates in
./ssl/directory -
yourdomain.irDNS pointing to server IP - Ran
./deploy-docker.shsuccessfully - All containers showing
Upindocker-compose ps -
https://yourdomain.irloads without errors - API at
https://yourdomain.ir/apireturns 404
crontab -e
# Add:
0 2 * * * cd /opt/bodybuilding && docker-compose -f docker-compose.prod.yml exec -T mongodb mongodump -u admin -p $MONGO_ROOT_PASSWORD --db bodybuilding --out /backups/bodybuilding-$(date +\%Y\%m\%d)docker-compose -f docker-compose.prod.yml exec mongodb mongodump -u admin -p password --db bodybuilding --out ./backups# Real-time container stats
docker stats
# View disk usage
docker system df
# Prune unused data (safe)
docker system prune- Server: 50,000-200,000 ریال/month
- Domain .ir: 100,000 ریال/year
- SSL: FREE (Let's Encrypt)
- No MongoDB hosting cost (runs on your server)
Total: ~100K-200K ریال/month 🎉
📧 Email: icwt.life@gmail.com
Common issues:
- Can't SSH to server → check server firewall allows port 22
- Certificate error → double-check SSL cert paths in
.env.prod - Services won't start → check disk space (
df -h) - Database errors → check
.env.prodhas correctMONGO_ROOT_PASSWORD