mitlist/PRODUCTION.md
mohamad cb51186830 feat: Add production deployment configuration and environment setup
- Introduced `docker-compose.prod.yml` to define services for production deployment, including PostgreSQL, FastAPI backend, frontend, and Redis.
- Created `env.production.template` to outline necessary environment variables for production, ensuring sensitive data is not committed.
- Added `PRODUCTION.md` as a deployment guide detailing the setup process using Docker Compose and Gitea Actions for CI/CD.
- Implemented Gitea workflows for build, test, and deployment processes to streamline production updates.
- Updated backend and frontend Dockerfiles for optimized production builds and configurations.
- Enhanced application settings to support environment-specific configurations, including CORS and health checks.
2025-05-28 08:23:22 +02:00

8.9 KiB

Production Deployment Guide (Gitea Actions)

This guide covers deploying the mitlist application to a production environment using Docker Compose and Gitea Actions for CI/CD.

🚀 Quick Start

  1. Clone the repository (if not already done):

    git clone <your-repo>
    cd mitlist
    
  2. Configure Gitea Secrets: In your Gitea repository settings, go to "Secrets" and add the following secrets. These will be used by the deploy-prod.yml workflow.

    • DOCKER_USERNAME: Your Docker Hub username (or username for your container registry).
    • DOCKER_PASSWORD: Your Docker Hub password (or token for your container registry).
    • SERVER_HOST: IP address or hostname of your production server.
    • SERVER_USERNAME: Username for SSH access to your production server.
    • SSH_PRIVATE_KEY: Your private SSH key for accessing the production server.
    • SERVER_PORT: (Optional) SSH port for your server (defaults to 22).
    • POSTGRES_USER: Production database username.
    • POSTGRES_PASSWORD: Production database password.
    • POSTGRES_DB: Production database name.
    • DATABASE_URL: Production database connection string.
    • SECRET_KEY: FastAPI application secret key.
    • SESSION_SECRET_KEY: FastAPI session secret key.
    • GEMINI_API_KEY: API key for Gemini.
    • REDIS_PASSWORD: Password for Redis.
    • SENTRY_DSN: (Optional) Sentry DSN for backend error tracking.
    • CORS_ORIGINS: Comma-separated list of allowed CORS origins for production (e.g., https://yourdomain.com).
    • FRONTEND_URL: The public URL of your frontend (e.g., https://yourdomain.com).
    • VITE_API_URL: The public API URL for the frontend (e.g., https://yourdomain.com/api).
    • VITE_SENTRY_DSN: (Optional) Sentry DSN for frontend error tracking.
  3. Prepare your Production Server:

    • Install Docker and Docker Compose (see Prerequisites section below).
    • Ensure your server can be accessed via SSH using the key you added to Gitea secrets.
    • Create the deployment directory on your server (e.g., /srv/mitlist).
    • Copy the docker-compose.prod.yml file to this directory on your server.
  4. Push to main branch: Once the Gitea workflows (.gitea/workflows/build-test.yml and .gitea/workflows/deploy-prod.yml) are in your repository, pushing to the main branch will automatically trigger the deployment workflow.

📋 Prerequisites (Server Setup)

System Requirements

  • OS: Ubuntu 20.04+ / CentOS 8+ / Debian 11+
  • RAM: Minimum 2GB, Recommended 4GB+
  • Storage: Minimum 20GB free space
  • CPU: 2+ cores recommended

Software Dependencies (on Production Server)

  • Docker 20.10+
  • Docker Compose 2.0+

Installation Commands

Ubuntu/Debian:

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER # Add your deployment user to docker group

# Install Docker Compose
sudo apt install docker-compose-plugin

# Reboot or log out/in to apply group changes
# sudo reboot

CentOS/RHEL:

# Update system
sudo yum update -y

# Install Docker
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER # Add your deployment user to docker group

# Reboot or log out/in to apply group changes
# sudo reboot

🔧 Configuration Overview

  • docker-compose.prod.yml: Defines the production services (database, backend, frontend, redis). This file needs to be on your production server in the deployment directory.
  • .gitea/workflows/build-test.yml: Gitea workflow that builds and runs tests on every push to main or develop, and on pull requests to these branches.
  • .gitea/workflows/deploy-prod.yml: Gitea workflow that triggers on pushes to the main branch. It builds and pushes Docker images to your container registry and then SSHes into your production server to update environment variables and restart services using docker-compose.
  • env.production.template: A template file showing the environment variables needed. These are now set directly in the Gitea deployment workflow via secrets.

🚀 Deployment Process (via Gitea Actions)

  1. Code Push: Developer pushes code to the main branch.
  2. Build & Test Workflow: (Optional, if you keep build-test.yml active on main as well) The build-test.yml workflow runs, ensuring code quality.
  3. Deploy Workflow Trigger: The deploy-prod.yml workflow is triggered.
  4. Checkout Code: The workflow checks out the latest code.
  5. Login to Registry: Logs into your specified Docker container registry.
  6. Build & Push Images: Builds the production Docker images for the backend and frontend and pushes them to the registry.
  7. SSH to Server: Connects to your production server via SSH.
  8. Set Environment Variables: Creates/updates the .env.production file on the server using the Gitea secrets.
  9. Pull New Images: Runs docker-compose pull to fetch the newly pushed images.
  10. Restart Services: Runs docker-compose up -d to restart the services with the new images and configuration.
  11. Prune Images: Cleans up old, unused Docker images on the server.

🏗️ Simplified Architecture

With the removal of nginx as a reverse proxy, the architecture is simpler:

[ User / Internet ]
      |
      v
[ Frontend Service (Port 80) ]  <-- Serves Vue.js app (e.g., via `serve`)
      |
      v (API Calls)
[ Backend Service (Internal Port 8000) ] <-- FastAPI
      |         |
      v         v
[ PostgreSQL ] [ Redis ]
(Database)   (Cache)
  • The Frontend service now directly exposes port 80 (or another port you configure) to the internet.
  • The Backend service is still internal and accessed by the frontend via its Docker network name (backend:8000).

Note on SSL/HTTPS: Since nginx is removed, SSL termination is not handled by this setup. You would typically handle SSL at a higher level, for example: * Using a cloud provider's load balancer with SSL termination. * Placing another reverse proxy (like Caddy, Traefik, or a dedicated nginx instance) in front of your Docker setup on the server, configured for SSL. * Using services like Cloudflare that can provide SSL for your domain.

📊 Monitoring & Logging

Health Checks

  • Backend: http://<your_server_ip_or_domain>/api/health (assuming your backend health endpoint is accessible if you map its port in docker-compose.prod.yml or if the frontend proxies it).
  • Frontend: The serve package used by the frontend doesn't have a dedicated health check endpoint by default. You can check if the main page loads.

Log Access

# On your production server, in the deployment directory
docker-compose -f docker-compose.prod.yml logs -f

# Specific service logs
docker-compose -f docker-compose.prod.yml logs -f backend
docker-compose -f docker-compose.prod.yml logs -f frontend

🔄 Maintenance

Database Backups

Manual backups can still be performed on the server:

# Ensure your .env.production file is sourced or vars are available
docker exec postgres_db_prod pg_dump -U $POSTGRES_USER $POSTGRES_DB > backup-$(date +%Y%m%d).sql

Consider automating this with a cron job on your server.

Updates

Updates are now handled by pushing to the main branch, which triggers the Gitea deployment workflow.

🐛 Troubleshooting

Gitea Workflow Failures

  • Check the Gitea Actions logs for the specific workflow run to identify errors.
  • Ensure all secrets are correctly configured in Gitea.
  • Verify Docker Hub/registry credentials.
  • Check SSH connectivity to your server from the Gitea runner (if using self-hosted runners, ensure network access).

Service Not Starting on Server

  • SSH into your server.
  • Navigate to your deployment directory (e.g., /srv/mitlist).
  • Check logs: docker-compose -f docker-compose.prod.yml logs <service_name>
  • Ensure .env.production has the correct values.
  • Check docker ps to see running containers.

Frontend Not Accessible

  • Verify the frontend service is running (docker ps).
  • Check frontend logs: docker-compose -f docker-compose.prod.yml logs frontend.
  • Ensure the port mapping in docker-compose.prod.yml for the frontend service (e.g., 80:3000) is correct and not blocked by a firewall on your server.

📝 Changelog

v1.1.0 (Gitea Actions Deployment)

  • Removed nginx reverse proxy and related shell scripts.
  • Frontend now served directly using serve.
  • Added Gitea Actions workflows for CI (build/test) and CD (deploy to production).
  • Updated deployment documentation to reflect Gitea Actions strategy.
  • Simplified docker-compose.prod.yml.