This guide provides step-by-step instructions for deploying ResShare in a development environment on AWS EC2 (backend) and Vercel (frontend).
- Prerequisites
- Backend Deployment on EC2
- Frontend Deployment on Vercel
- Configuration
- Post-Deployment Setup
- Troubleshooting
- Maintenance
- Google Gemini API Key: For RAG chat functionality
- Get it from: https://aistudio.google.com/prompts/new_chat
- Flask Secret Key: For session management (generate a secure random string)
- ResilientDB KV Service URL
- Minimum: t3.medium (2 vCPU, 4 GB RAM)
- Recommended: t3.large (2 vCPU, 8 GB RAM) or better
- Storage: 20 GB minimum (gp3 SSD)
- OS: Ubuntu 22.04 LTS
-
Login to AWS Console → Navigate to EC2
-
Click "Launch Instance" and configure:
- Name:
resshare-backend - AMI: Ubuntu Server 22.04 LTS (HVM), SSD Volume Type
- Instance Type: t3.medium or t3.large
- Key Pair: Select or create a new key pair (save the
.pemfile securely) - Network Settings:
- Create security group with the following rules:
Type Protocol Port Range Source Description SSH TCP 22 Your IP SSH access Custom TCP TCP 5000 0.0.0.0/0 Flask application Custom TCP TCP 8080 0.0.0.0/0 IPFS Gateway Custom TCP TCP 9094 0.0.0.0/0 IPFS Cluster API Custom TCP TCP 80 0.0.0.0/0 HTTP (for Nginx) Custom TCP TCP 443 0.0.0.0/0 HTTPS (for Nginx) - Storage: 20 GB gp3 (minimum)
- Name:
-
Launch the instance
-
Note the Public IP address of your instance
# On your local machine
ssh -i your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP-
Update the system:
sudo apt-get update && sudo apt-get upgrade -y -
Install Docker:
sudo apt-get install -y ca-certificates curl gnupg lsb-release 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 sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
Start Docker and enable on boot:
sudo systemctl start docker sudo systemctl enable docker sudo usermod -aG docker ubuntu -
Logout and reconnect for group changes to take effect:
exit ssh -i your-key.pem ubuntu@your-ec2-public-ip -
Verify Docker installation:
docker --version docker compose version
# On EC2 instance
cd ~
git clone https://github.com/devangb3/ResShareDeployable.git
cd ResShareDeployable
### Step 5: Configure Environment Variables
```bash
# Create .env file
cd ~/ResShareDeployable
cp env.example .env
nano .env
Edit .env with your actual values:
# Google API Key for Gemini (required for RAG chat functionality)
GOOGLE_API_KEY=your-actual-gemini-api-key-here
# Flask Configuration
FLASK_ENV=production
# CORS Origins (comma-separated, for production frontends)
# Add your Vercel domain here
CORS_ORIGINS=https://res-share-deployable.vercel.app/
# Flask Secret Key (generate a secure random string)
FLASK_SECRET_KEY=your-secure-random-secret-key-here
# Storage Type: 'memory' or 'resilientdb'
STORAGE_TYPE=memory
# KV Service URL (if using resilientdb)
KV_SERVICE_URL=https://crow.resilientdb.comGenerate a secure Flask secret key:
python3 -c "import secrets; print(secrets.token_hex(32))"# Build the Docker image (this will take 10-20 minutes on first build)
cd ~/ResShareDeployable
docker build -t resshare-backend:latest .
# Run with Docker Compose
docker compose up -d
# Check logs
docker compose logs -fWait for services to start (about 60-90 seconds). You should see:
- IPFS daemon started
- IPFS Cluster service started
- Flask application started
# Check if container is running
docker ps
# Test health endpoint from EC2
curl http://localhost:5000/
# Test from your local machine
curl http://YOUR_EC2_PUBLIC_IP:5000/Expected response:
{"message": "OK"}Ngrok provides a secure tunnel to your local/EC2 backend, useful for development, testing, or when you don't want to expose EC2 directly to the internet.
Install ngrok on EC2:
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com bookworm main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update \
&& sudo apt install ngrokGet ngrok authtoken (if not already configured):
- Sign up at ngrok.com (free account available)
- Get your authtoken from the dashboard
- Configure it:
ngrok config add-authtoken YOUR_NGROK_AUTHTOKEN
Start ngrok tunnel:
# Tunnel to Flask backend (port 5000)
ngrok http 5000curl http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'
**Note the ngrok URL** (e.g., `https://abc123.ngrok-free.app`)
**Update backend CORS to include ngrok URL:**
```bash
cd ~/ResShareDeployable
nano .env
Add ngrok URL to CORS_ORIGINS:
CORS_ORIGINS=https://res-share-deployable.vercel.app/,https://abc123.ngrok-free.appRestart backend:
docker compose restartUse ngrok URL for frontend:
- Update
REACT_APP_API_BASE_URLin Vercel to use the ngrok URL
-
Update API Configuration
Edit
frontend/src/utils/api.jsor create a.envfile in thefrontenddirectory:cd frontend nano .env.productionAdd:
REACT_APP_API_BASE_URL=https://your-ec2-public-ip:5000Or if using a domain with HTTPS:
REACT_APP_API_BASE_URL=https://your-domain.comOr if using ngrok tunnel:
REACT_APP_API_BASE_URL=https://your-ngrok-url.ngrok-free.app -
Update CORS in Backend
Make sure your EC2 backend's
.envincludes your Vercel domain:CORS_ORIGINS=https://your-app.vercel.app
Then restart the backend:
docker compose restart
** Using Vercel Dashboard**
Add Environment Variables:
- Click "Environment Variables"
- Add:
REACT_APP_API_BASE_URL = https://your-domain.com
- Click "Deploy"
After Vercel deployment, you'll get a URL like https://res-share-deployable.vercel.app/.
-
Update EC2 backend
.env:ssh -i your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP cd ~/ResShareDeployable nano .env
Update:
CORS_ORIGINS=https://res-share-deployable.vercel.app/
-
Restart backend:
docker compose down docker compose up -d
- Visit your Vercel URL:
https://res-share-deployable.vercel.app/ - Test login/signup functionality
- Check browser console for any CORS errors
| Variable | Description | Required | Example |
|---|---|---|---|
| GOOGLE_API_KEY | Google Gemini API key for RAG chat | Yes | AIzaSy... |
| FLASK_ENV | Flask environment | No | production |
| FLASK_SECRET_KEY | Secret key for session management | Yes | abc123... (32+ chars) |
| CORS_ORIGINS | Allowed frontend origins (comma-sep) | Yes | https://app.vercel.app |
| STORAGE_TYPE | Storage backend type | No | memory or resilientdb |
| KV_SERVICE_URL | ResilientDB KV service URL | No | https://crow.resilientdb.com |
| Variable | Description | Required | Example |
|---|---|---|---|
| REACT_APP_API_BASE_URL | Backend API URL | Yes | https://your-ec2-ip:5000 |
The backend uses IPFS Cluster for file storage. Configuration files are in:
backend/config/ipfs.config- IPFS Cluster and Gateway URLsbackend/config/kv_service.config- KV Service configuration
These are automatically configured in the Docker container.
# Check logs
docker compose logs
# Common issues:
# - IPFS not starting: Wait 60-90 seconds
# - Port 5000 in use: Change port in docker-compose.yml
# - Out of memory: Increase EC2 instance size# Enter container
docker exec -it resshare-backend bash
# Check IPFS status
ipfs id
ipfs-cluster-service --version
# Check IPFS logs
cat /app/ipfs.log
cat /app/ipfs-cluster.log-
Check security group: Ensure port 5000 is open
-
Check if Flask is listening on all interfaces:
docker exec -it resshare-backend bash netstat -tuln | grep 5000
Should show
0.0.0.0:5000, not127.0.0.1:5000 -
Test from EC2 first:
curl http://localhost:5000/
-
Then test externally:
curl http://YOUR_EC2_PUBLIC_IP:5000/
-
Check backend
.envhas correct Vercel URL:CORS_ORIGINS=https://your-app.vercel.app
-
Restart backend:
docker compose restart
-
Check browser console for specific CORS error messages
Ngrok tunnel not working:
# Check if ngrok is running
ps aux | grep ngrok
# Check ngrok status
curl http://localhost:4040/api/tunnels
# View ngrok logs
tail -f /tmp/ngrok.log
# Restart ngrok
pkill ngrok
ngrok http 5000Ngrok URL changed:
- Free ngrok URLs change on each restart
- Update
CORS_ORIGINSin backend.envwith new URL - Update
REACT_APP_API_BASE_URLin Vercel - Restart backend:
docker compose restart
Ngrok connection refused:
- Ensure Flask backend is running:
docker compose ps - Verify port 5000 is accessible:
curl http://localhost:5000/ - Check ngrok is pointing to correct port:
ngrok http 5000
Get current ngrok URL programmatically:
# Get ngrok URL
curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'
# Or without jq
curl -s http://localhost:4040/api/tunnels | grep -o '"public_url":"[^"]*"' | head -1- Check
REACT_APP_API_BASE_URLin Vercel environment variables - Verify backend is accessible from browser
- Check CORS configuration in backend
- Check build logs in Vercel dashboard
- Verify
package.jsonhas correct build scripts - Ensure all dependencies are in
package.json(not just devDependencies)
# Stop and remove everything
docker compose down -v
# Remove image
docker rmi resshare-backend:latest
# Rebuild and restart
docker build -t resshare-backend:latest .
docker compose up -d# Stop container
docker compose down
# Remove IPFS volumes
docker volume rm resshare_ipfs resshare_ipfs_cluster
# Restart
docker compose up -dBackend (EC2):
ssh -i your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP
cd ~/ResShareDeployable
git pull origin main
docker compose down
docker build -t resshare-backend:latest .
docker compose up -dFrontend (Vercel):
- Push changes to GitHub
- Vercel will automatically redeploy
- Or manually trigger redeploy in Vercel dashboard
Backup Docker volumes:
# Backup all volumes
docker run --rm \
-v resshare_ipfs:/ipfs \
-v resshare_ipfs_cluster:/cluster \
-v resshare_vector_db:/vector_db \
-v $(pwd):/backup \
ubuntu tar czf /backup/resshare_backup_$(date +%Y%m%d).tar.gz -C / ipfs cluster vector_db
# Download backup
scp -i your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP:~/ResShareDeployable/resshare_backup_*.tar.gz ./Restore from backup:
# Upload backup to EC2
scp -i your-key.pem resshare_backup_YYYYMMDD.tar.gz ubuntu@YOUR_EC2_PUBLIC_IP:~/
# On EC2, restore
docker compose down
docker run --rm \
-v resshare_ipfs:/ipfs \
-v resshare_ipfs_cluster:/cluster \
-v resshare_vector_db:/vector_db \
-v $(pwd):/backup \
ubuntu tar xzf /backup/resshare_backup_YYYYMMDD.tar.gz -C /
docker compose up -dBackend logs:
# All logs
docker compose logs
# Follow logs
docker compose logs -f
# Last 100 lines
docker compose logs --tail=100
# Specific service logs
docker compose logs resshare-backendFrontend logs:
- Check Vercel dashboard → Your Project → Deployments → View Function Logs
EC2 Resource Usage:
# CPU and memory
htop
# Disk usage
df -h
# Docker disk usage
docker system dfVercel Usage:
- Check Vercel dashboard → Your Project → Analytics
- Use HTTPS: Set up SSL/TLS with Let's Encrypt
- Rotate Secrets: Regularly update
FLASK_SECRET_KEY - Limit Security Group: Restrict SSH access to your IP only
- Keep Updated: Regularly update Docker images and dependencies
- Monitor Logs: Set up log monitoring and alerts
- Backup Regularly: Automate backups of Docker volumes
- t3.medium: ~$30/month (on-demand)
- t3.large: ~$60/month (on-demand)
- Storage (20 GB): ~$2/month
- Data Transfer: Varies by usage
Tips to reduce costs:
- Use Reserved Instances (1-3 year commitment)
- Use Spot Instances for development
- Set up auto-scaling if needed
-
Free Tier:
- 100 GB bandwidth/month
- Unlimited deployments
- Perfect for small to medium applications
-
Pro Tier ($20/month):
- 1 TB bandwidth/month
- Advanced features
For issues and questions:
- Check logs:
docker compose logs - GitHub Issues: [Your repository URL]
- Documentation: See
docs/directory
# Start
docker compose up -d
# Stop
docker compose down
# Restart
docker compose restart
# View logs
docker compose logs -f
# Rebuild
docker build -t resshare-backend:latest .
docker compose up -d
# Check status
docker ps
curl http://localhost:5000/# Install ngrok
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com bookworm main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update \
&& sudo apt install ngrok
# Configure authtoken
ngrok config add-authtoken YOUR_NGROK_AUTHTOKEN
# Start tunnel
ngrok http 5000
# Start in background
nohup ngrok http 5000 > /tmp/ngrok.log 2>&1 &
# Get current URL
curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'
# Check status
curl http://localhost:4040/api/tunnels
# Stop ngrok
pkill ngrok# Deploy
vercel --prod
# View logs
vercel logs
# List deployments
vercel ls