Skip to content

Latest commit

 

History

History
312 lines (222 loc) · 6.03 KB

File metadata and controls

312 lines (222 loc) · 6.03 KB

Docker Deployment on Iranian Host

🐳 What You Got

  • 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 + SSL
  • deploy-docker.sh - One-command deployment

Step 1: Local Testing (Optional but Recommended)

Build and run locally to verify everything works:

# 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/api

Stop: docker-compose down


Step 2: Prepare Server

SSH into your server:

ssh user@your-server-ip

Install Docker & Docker Compose:

# 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 --version

Step 3: Upload Project

Option A: Git (Recommended)

cd /opt
git clone https://github.com/your-username/bodybuilding.git
cd bodybuilding

Option B: Direct Upload

scp -r /path/to/bodybuilding user@host:/opt/
ssh user@host "cd /opt/bodybuilding"

Step 4: Configure for Production

On the server:

cd /opt/bodybuilding

# Copy example env
cp .env.docker .env.prod

# Edit with your values
nano .env.prod

Update 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.ir

Generate JWT_SECRET locally:

node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"

Step 5: Setup SSL Certificate

Using Let's Encrypt (Free):

# 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/*.pem

Step 6: Make Deploy Script Executable

cd /opt/bodybuilding
chmod +x deploy-docker.sh

Step 7: Deploy! 🚀

cd /opt/bodybuilding
./deploy-docker.sh

What it does:

  1. ✅ Checks .env.prod exists
  2. ✅ Builds Docker images
  3. ✅ Starts MongoDB, Node.js app, Nginx
  4. ✅ Shows status

Step 8: Verify Deployment

# 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/api

Expected: Should return 404 (normal, means server is running)


Daily Commands

# 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)

Update/Redeploy

After pushing new code:

cd /opt/bodybuilding

# Pull latest
git pull origin main

# Rebuild and deploy
./deploy-docker.sh

That's it! Docker handles everything.


Troubleshooting

Services won't start

docker-compose -f docker-compose.prod.yml logs

Look for errors in output.

Port 80/443 already in use

# 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 installed

CORS errors

Edit .env.prod:

DOMAIN=yourdomain.ir

Then redeploy: ./deploy-docker.sh

Out of disk space

docker system prune -a  # Removes unused images

MongoDB connection errors

# Check MongoDB logs
docker-compose -f docker-compose.prod.yml logs mongodb

# Restart MongoDB
docker-compose -f docker-compose.prod.yml restart mongodb

Production Checklist

  • Docker & Docker Compose installed on server
  • Project cloned to /opt/bodybuilding
  • .env.prod created and filled with values
  • SSL certificates in ./ssl/ directory
  • yourdomain.ir DNS pointing to server IP
  • Ran ./deploy-docker.sh successfully
  • All containers showing Up in docker-compose ps
  • https://yourdomain.ir loads without errors
  • API at https://yourdomain.ir/api returns 404

Backups

Automatic daily backup (add to crontab)

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)

Manual backup

docker-compose -f docker-compose.prod.yml exec mongodb mongodump -u admin -p password --db bodybuilding --out ./backups

Performance Monitoring

# Real-time container stats
docker stats

# View disk usage
docker system df

# Prune unused data (safe)
docker system prune

Costs

  • 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 🎉


Need Help?

📧 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.prod has correct MONGO_ROOT_PASSWORD