Comprehensive deployment configuration and automation for the Bitwise learning platform on AWS EC2.
This repository contains Docker Compose configurations, deployment scripts, and CI/CD workflows for deploying the Bitwise application stack on AWS EC2. The deployment uses Traefik as a reverse proxy with automatic SSL certificate management via Let's Encrypt.
The deployment consists of three main services:
- Traefik - Reverse proxy and SSL termination
- Backend - NestJS API server (Node.js)
- Frontend - React application (served via Nginx)
- AWS EC2 instance (Ubuntu 22.04 LTS recommended)
- Minimum t2.medium instance (2 vCPU, 4GB RAM)
- At least 20GB of storage
- Elastic IP address assigned to the instance
- Domain name pointed to the Elastic IP (for SSL)
Your EC2 security group must allow the following inbound traffic:
| Port | Protocol | Source | Purpose |
|---|---|---|---|
| 22 | TCP | Your IP | SSH access |
| 80 | TCP | 0.0.0.0/0 | HTTP (redirects to HTTPS) |
| 443 | TCP | 0.0.0.0/0 | HTTPS |
| 8080 | TCP | Your IP | Traefik dashboard (optional) |
- Docker Engine (v24.0 or higher)
- Docker Compose V2 plugin
- Git
- SSH access with key-based authentication
For automated deployments via GitHub Actions, configure these repository secrets:
| Secret Name | Description | Example |
|---|---|---|
EC2_HOST |
EC2 instance public IP or domain | 47.129.118.12 |
EC2_USER |
SSH username | ubuntu |
EC2_SSH_KEY |
Private SSH key content | Contents of .pem file |
The project follows a multi-repository structure. On your EC2 server, the directory layout should be:
~/bitwise/
├── bitwise-deploy/
│ └── deploy/
│ └── aws/
│ ├── docker-compose.yml # Main deployment config
│ ├── deploy.sh # Deployment automation script
│ ├── letsencrypt/ # SSL certificates (auto-created)
│ ├── README.md # AWS-specific documentation
│ ├── SECRETS_MANAGEMENT.md # Environment variables guide
│ └── TROUBLESHOOTING.md # Common issues and solutions
├── bitwise-server/
│ ├── .env # Backend environment variables
│ ├── Dockerfile
│ └── src/
└── bitwise-ui/
├── .env # Frontend environment variables (if needed)
├── Dockerfile
└── src/
SSH into your EC2 instance:
ssh -i "path/to/your-key.pem" ubuntu@<your-ec2-ip># Update package index
sudo apt-get update
# Install Docker
sudo apt-get install -y docker.io
# Install Docker Compose plugin
sudo apt-get install -y docker-compose-plugin
# Add user to docker group (to run without sudo)
sudo usermod -aG docker $USER
# Logout and login again for group changes to take effect
exitVerify installation:
docker --version
docker compose version # Note: space, not hyphen# Create project directory
mkdir -p ~/bitwise
cd ~/bitwise
# Clone all three repositories
git clone https://github.com/One-Team-One-Goal/bitwise-deploy.git
git clone https://github.com/One-Team-One-Goal/bitwise-server.git
git clone https://github.com/One-Team-One-Goal/bitwise-ui.gitBackend Environment (.env):
cd ~/bitwise/bitwise-server
nano .envAdd the following variables:
# Node Environment
NODE_ENV=production
PORT=3000
HOST=0.0.0.0
# Database Configuration
DATABASE_URL="postgresql://username:password@host:5432/database"
DIRECT_URL="postgresql://username:password@host:5432/database"
# Authentication
JWT_SECRET="your-secure-random-string-here"
# AI Services
GOOGLE_AI_API_KEY="your-google-ai-key"
GROQ_API_KEY="your-groq-api-key"
# Supabase
SUPABASE_URL="your-supabase-url"
SUPABASE_KEY="your-supabase-key"
# CORS
FRONTEND_URL="https://bitwise.live"Frontend Environment (.env):
cd ~/bitwise/bitwise-ui
nano .envAdd:
VITE_API_URL="https://bitwise.live/api"
VITE_SUPABASE_URL="your-supabase-url"
VITE_SUPABASE_ANON_KEY="your-supabase-anon-key"cd ~/bitwise/bitwise-deploy/deploy/aws
chmod +x deploy.shcd ~/bitwise/bitwise-deploy/deploy/aws
./deploy.shThis script will:
- Create necessary directories
- Set up SSL certificate storage
- Pull latest code from all repositories
- Build Docker images
- Start all containers
- Configure SSL certificates automatically
Check container status:
cd ~/bitwise/bitwise-deploy/deploy/aws
docker compose psAll three services should show "Up" status.
View logs:
# All services
docker compose logs -f
# Specific service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f traefikAccess your application:
- Frontend:
https://bitwise.liveorhttps://www.bitwise.live - Backend API:
https://bitwise.live/api - Traefik Dashboard:
http://<your-ec2-ip>:8080(if enabled)
When you push to the main branch of either bitwise-ui or bitwise-server, GitHub Actions will:
- Connect to your EC2 instance via SSH
- Navigate to the deployment directory
- Execute the
deploy.shscript - Pull latest changes from all repositories
- Rebuild and restart containers with zero downtime
1. SSH Connection Failed
Error: Permission denied (publickey) or Connection timeout
Solution:
- Verify
EC2_HOSTsecret contains the correct IP/domain - Ensure
EC2_SSH_KEYcontains the complete private key (including-----BEGIN RSA PRIVATE KEY-----and-----END RSA PRIVATE KEY-----) - Check EC2 security group allows SSH (port 22) from GitHub Actions IP ranges
- Verify the SSH key matches the one configured in EC2
2. Deploy Script Not Found
Error: No such file or directory: deploy.sh
Solution:
# SSH to server and verify structure
cd ~/bitwise/bitwise-deploy/deploy/aws
ls -la deploy.sh
# If missing, pull the latest deployment repo
cd ~/bitwise/bitwise-deploy
git pull origin main3. Permission Denied Running Script
Error: Permission denied: ./deploy.sh
Solution:
cd ~/bitwise/bitwise-deploy/deploy/aws
chmod +x deploy.sh4. Docker Compose Command Not Found
Error: docker-compose: command not found or KeyError: 'ContainerConfig'
Solution:
# Install Docker Compose V2
sudo apt-get update
sudo apt-get install -y docker-compose-plugin
# Verify installation
docker compose versionThe deploy.sh script automatically handles both docker compose (V2) and docker-compose (V1).
5. Git Pull Fails
Error: Could not resolve host: github.com or Authentication failed
Solution:
# Ensure EC2 can access GitHub
ssh -i "your-key.pem" ubuntu@<ec2-ip>
ping github.com
# If using private repositories, set up SSH keys or deploy tokensIf GitHub Actions fails and you need to deploy manually:
# SSH to server
ssh -i "your-key.pem" ubuntu@<ec2-ip>
# Run deployment
cd ~/bitwise/bitwise-deploy/deploy/aws
./deploy.shSimply push to the main branch:
git push origin mainGitHub Actions will automatically deploy the changes.
SSH to server and run:
cd ~/bitwise/bitwise-deploy/deploy/aws
./deploy.shcd ~/bitwise/bitwise-deploy/deploy/aws
# Update and rebuild specific service
docker compose up -d --build --no-deps backend
# or
docker compose up -d --build --no-deps frontendcd ~/bitwise/bitwise-deploy/deploy/aws
# Real-time logs for all services
docker compose logs -f
# Last 100 lines of backend logs
docker compose logs --tail=100 backend
# Logs since last hour
docker compose logs --since 1h frontendcd ~/bitwise/bitwise-deploy/deploy/aws
# Restart all services
docker compose restart
# Restart specific service
docker compose restart backendcd ~/bitwise/bitwise-deploy/deploy/aws
# Stop all services
docker compose down
# Stop and remove volumes (careful!)
docker compose down -v# Remove unused images
docker image prune -f
# Remove all unused resources
docker system prune -afTraefik automatically renews Let's Encrypt certificates. To verify:
cd ~/bitwise/bitwise-deploy/deploy/aws
ls -la letsencrypt/acme.json- Environment Variables: Never commit
.envfiles to Git - SSH Keys: Use strong SSH keys and restrict access by IP when possible
- Secrets Rotation: Regularly rotate JWT secrets, API keys, and database passwords
- Updates: Keep Docker, Docker Compose, and the OS updated
- Monitoring: Set up CloudWatch or equivalent for monitoring
- Backups: Regularly backup your database and environment files
# SSH to EC2
ssh -i "your-key.pem" ubuntu@<ec2-ip>
# Check running containers
cd ~/bitwise/bitwise-deploy/deploy/aws
docker compose ps
# View all logs
docker compose logs -f
# View specific service logs
docker compose logs -f backend
docker compose logs -f frontend
# Restart services
docker compose restart
# Deploy/Update
./deploy.sh
# Check disk space
df -h
# Clean up Docker resources
docker image prune -af
docker system prune -afBackend (.env in bitwise-server/):
FRONTEND_URL- Must behttps://bitwise.live(or your domain)CORS_ALLOWED_ORIGINS- Include both www and non-www domainsDATABASE_URL- Supabase connection with poolingGROQ_API_KEY- AI service key
Frontend (.env in bitwise-ui/):
VITE_API_BASE_URL- Must behttps://bitwise.live/api(through Traefik)VITE_SUPABASE_URL- Supabase project URLVITE_SUPABASE_ANON_KEY- Supabase anonymous key
- ✅ Containers running:
docker compose ps - ✅ Check logs:
docker compose logs backend --tail=50 - ✅ Test backend:
curl http://localhost/api - ✅ Verify SSL:
https://bitwise.live - ✅ Disk space:
df -h(should be < 80%) - ✅ GitHub secrets configured in repository settings
- AWS Deployment Guide - AWS-specific configuration
- Secrets Management - Managing sensitive data
- Troubleshooting Guide - Common issues and solutions
For deployment issues:
- Check the Troubleshooting Guide
- Review application logs
- Verify GitHub Actions workflow runs
- Check EC2 instance health and resource usage
This project is private and unlicensed.