This document describes the deployment process for the Telegram Clone application. The deployment is split into manual setup (infrastructure) and automated deployment (application code).
- VPS Server: Hosts the entire application
- Components:
- PostgreSQL Database: Manually configured
- Nginx: Manually configured as reverse proxy and static file server
- Server Application: Automated deployment via GitHub Actions
- Web Application: Automated deployment via GitHub Actions
- Ubuntu/Debian-based VPS
- SSH access with deploy user
- Domain pointing to VPS IP
- Install PostgreSQL on the VPS
- Create database:
telegram_clone - Create database user with appropriate permissions
- Configure connection settings
- Install Nginx
- Configure as reverse proxy for the server application
- Serve static files for the web application
- Set up SSL/TLS certificates (Let's Encrypt recommended)
- Configure web root at
/var/www/telechat/web/
- Install Node.js (v14+)
- Install pnpm package manager
- Install PM2 for process management
- Install Git for code deployment
/home/deploy/telechat/ # Application code repository
/var/www/telechat/web/ # Web application static files
- Create
deployuser with SSH access - Configure SSH key authentication
- Grant necessary permissions for deployment operations
The deployment workflow (.github/workflows/deploy.yml) triggers on:
- Push to
masterbranch - Changes to specific paths:
server/**(server code)web/**(web code)shared/**(shared utilities)deploy-*.sh(deployment scripts).github/workflows/deploy.yml(workflow itself)
- Uses
dorny/paths-filterto detect which components changed - Runs separate jobs for server and web deployments
- Only deploys changed components
Triggers when: Server, shared, or deployment script changes
Automated steps:
- SSH into VPS
- Navigate to
/home/deploy/telechat - Pull latest code from
masterbranch - Install dependencies with
pnpm install --frozen-lockfile - Build server application:
pnpm --filter server build - Run database migrations:
pnpm --filter server prisma migrate deploy - Restart server with PM2:
pm2 restart telegram-server - Save PM2 state
Triggers when: Web, shared, or deployment script changes
Automated steps:
- SSH into VPS
- Navigate to
/home/deploy/telechat - Pull latest code from
masterbranch - Install dependencies with
pnpm install --frozen-lockfile - Build web application with environment variables
- Remove old static files from
/var/www/telechat/web/ - Copy new build to web root
Configure these in your GitHub repository settings under Secrets and Variables > Actions:
VPS_HOST: VPS server IP address or hostnameVPS_USERNAME: SSH username (typicallydeploy)VPS_SSH_KEY: Private SSH key for authenticationVITE_API_URL: API endpoint URL for web applicationVITE_WS_URL: WebSocket endpoint URL for web applicationVITE_PORT: Port for the web application
The workflow uses the PROD environment, which should be configured in GitHub with the above secrets.
- Located at project root
- Handles server-side deployment
- Includes database migration
- Manages PM2 process restart
- Located at project root
- Handles web application build and deployment
- Takes environment variables as arguments
- Copies built files to Nginx web root
# Update system
sudo apt update && sudo apt upgrade -y
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install pnpm
npm install -g pnpm
# Install PM2
npm install -g pm2
# Install PostgreSQL
sudo apt install postgresql postgresql-contrib
# Install Nginx
sudo apt install nginx
# Install Git
sudo apt install git# Switch to postgres user
sudo -u postgres psql
# Create database and user
CREATE DATABASE telegram_clone;
CREATE USER deploy_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE telegram_clone TO deploy_user;
\q# Create deploy user
sudo adduser deploy
sudo usermod -aG sudo deploy
# Create application directory
sudo mkdir -p /home/deploy/telechat
sudo chown deploy:deploy /home/deploy/telechat
# Create web directory
sudo mkdir -p /var/www/telechat/web
sudo chown deploy:deploy /var/www/telechat/web# Generate SSH key pair locally
ssh-keygen -t rsa -b 4096 -C "deploy@telegram-clone"
# Copy public key to VPS
ssh-copy-id deploy@your-vps-ip
# Add private key to GitHub Secrets as VPS_SSH_KEYCreate /etc/nginx/sites-available/telechat:
server {
listen 80;
server_name your-domain.com;
# Web application static files
location / {
root /var/www/telechat/web;
try_files $uri $uri/ /index.html;
}
# API proxy
location /api {
proxy_pass http://localhost:5000;
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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# WebSocket proxy
location /socket.io {
proxy_pass http://localhost:5000;
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable the site:
sudo ln -s /etc/nginx/sites-available/telechat /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx# Clone repository
cd /home/deploy
git clone https://github.com/your-username/telegram-clone.git telechat
cd telechat
# Install dependencies
pnpm install
# Build server
pnpm --filter server build
# Set up database
pnpm --filter server prisma migrate deploy
# Start server with PM2
pm2 start pnpm --name "telegram-server" -- --filter server start
pm2 save
pm2 startup- Add the required secrets to GitHub repository
- Ensure the
deploy.ymlworkflow file is present - Push changes to
masterbranch to trigger first automated deployment
# Check status
pm2 status
# View logs
pm2 logs telegram-server
# Restart service
pm2 restart telegram-server
# Monitor
pm2 monit# Backup database
pg_dump -U deploy_user telegram_clone > backup.sql
# Restore database
psql -U deploy_user telegram_clone < backup.sql# Check status
sudo systemctl status nginx
# Test configuration
sudo nginx -t
# Reload configuration
sudo systemctl reload nginx- PM2 process not starting: Check server logs and ensure database is accessible
- Web deployment fails: Verify Nginx permissions and web root directory
- Database connection issues: Check PostgreSQL service status and connection string
- SSH deployment fails: Verify SSH key and VPS connectivity
- Server logs:
pm2 logs telegram-server - Nginx logs:
/var/log/nginx/access.logand/var/log/nginx/error.log - PostgreSQL logs:
/var/log/postgresql/
- Use SSH key authentication (no passwords)
- Configure firewall to only allow necessary ports
- Regular security updates
- Database user with minimal required permissions
- SSL/TLS certificates for HTTPS
- Environment variables for sensitive data