# Deployment Guide This project uses Forgejo Actions for CI/CD, building a Docker image and deploying to a VPN-reachable VPS over SSH. ## Overview Deployment workflow: 1. **CI** (`.forgejo/workflows/ci.yaml`): Lint, test, type-check on every push 2. **Deploy** (`.forgejo/workflows/deploy.yaml`): Build, scan, and deploy on main branch --- ## 1. Prerequisites ### VPS Requirements - 2 vCPU, 2 GB RAM, 20 GB SSD - Docker Engine + Compose plugin - SSH access via VPN - Python 3.11+ (for healthcheck script) ### Forgejo Instance Setup 1. Enable Actions in Forgejo admin settings 2. Register a runner (or use Forgejo's built-in runner) ### Runner Setup Forgejo supports both built-in runners and self-hosted Docker runners. For Docker-in-Docker builds, ensure the runner has: - Docker installed and accessible - `docker` and `docker compose` commands available Example runner registration: ```bash # On your Forgejo server forgejo actions generate-runner-token > token.txt forgejo-runner register --instance-addr http://localhost:3000 --token $(cat token.txt) forgejo-runner daemon ``` --- ## 2. Required Secrets Configure in **Settings → Secrets and variables → Actions**: | Secret | Description | |--------|-------------| | `DEPLOY_SSH_PRIVATE_KEY` | SSH key for VPS access | | `DEPLOY_HOST` | VPS IP/hostname (VPN-reachable) | | `DEPLOY_USER` | Deploy user (default: `deploy`) | | `DEPLOY_PORT` | SSH port (default: 22) | | `DEPLOY_PATH` | Deploy path (default: `/opt/vault-dash`) | | `NICEGUI_STORAGE_SECRET` | Session secret | | `REGISTRY_PASSWORD` | Container registry token (if needed) | ### Optional Variables | Variable | Description | |----------|-------------| | `REGISTRY` | Container registry URL | | `EXTERNAL_HEALTHCHECK_URL` | Public health check URL | --- ## 3. One-Time VPS Setup ```bash # Create deploy user sudo useradd -m -s /bin/bash deploy sudo usermod -aG docker deploy # Set up deployment directory sudo mkdir -p /opt/vault-dash sudo chown deploy:deploy /opt/vault-dash # Install Docker (Debian/Ubuntu) sudo apt-get update sudo apt-get install -y docker.io docker-compose-plugin # Add SSH key for deploy user sudo -u deploy mkdir -p /home/deploy/.ssh # Add public key to /home/deploy/.ssh/authorized_keys ``` --- ## 4. Local Development ```bash # Create virtual environment python -m venv .venv source .venv/bin/activate # Install dependencies pip install -r requirements.txt pip install -r requirements-dev.txt # Run tests pytest # Start development server uvicorn app.main:app --reload --port 8000 ``` ### Docker Development ```bash # Build and run docker-compose up --build # Access at http://localhost:8000 ``` --- ## 5. Manual Deployment ```bash # Set environment variables export DEPLOY_HOST="10.100.0.10" export DEPLOY_USER="deploy" export DEPLOY_SSH_PRIVATE_KEY="$(cat ~/.ssh/deploy_key)" export APP_IMAGE="registry.example.com/vault-dash:latest" # Run deploy script bash scripts/deploy.sh ``` --- ## 6. VPN-Only Access The application binds to `127.0.0.1:8000` by default. Access via: 1. **VPN directly**: Connect VPN, access `http://VPS_IP:8000` 2. **Reverse proxy**: Use Caddy/Nginx on VPS for HTTPS ### Caddy Example ``` # Caddyfile vault.uncloud.vpn { reverse_proxy 127.0.0.1:8000 } ``` --- ## 7. Future: OAuth Integration When ready to expose publicly: 1. Set up OAuth provider (Authentik, Keycloak, etc.) 2. Configure `CORS_ORIGINS` for public URL 3. Add OAuth middleware to FastAPI 4. Enable HTTPS via Let's Encrypt --- ## 8. Troubleshooting ### Runner can't build Docker images Ensure runner has Docker access: ```bash docker run --rm hello-world ``` ### SSH connection fails ```bash ssh -i ~/.ssh/deploy_key deploy@YOUR_VPS ``` Check firewall allows VPN traffic on port 22. ### Health check fails ```bash curl http://127.0.0.1:8000/health docker compose -f /opt/vault-dash/docker-compose.deploy.yml logs ``` ### Rollback ```bash cd /opt/vault-dash PREVIOUS=$(cat .last_successful_image) sed -i "s|^APP_IMAGE=.*|APP_IMAGE=$PREVIOUS|" .env docker compose -f docker-compose.deploy.yml up -d ```