Files
jd-book-uploader-backend/.gitea/workflows

Gitea Workflows

This directory contains Gitea Actions workflows for CI/CD Pipelines.

Workflows

build.yml - Build Application Image

Builds the application image using Cloud Native Buildpacks.

Triggers:

  • Push to main, production, or develop branches
  • Pull requests to main or production
  • Manual workflow dispatch

Outputs:

  • Docker image (tagged and optionally pushed to registry)
  • Image artifact (if no registry configured)

deploy.yml - Deploy to Production

Deploys the built image to production server.

Triggers:

  • After successful build.yml workflow completion
  • Manual workflow dispatch (with image tag input)

Process:

  • Downloads image artifact or pulls from registry
  • Transfers deployment files to production server
  • Mounts Firebase credentials securely
  • Starts container and verifies health

test.yml - Run Tests

Runs Go tests and linting.

Triggers:

  • Push to main or develop branches
  • Pull requests to main or develop

Jobs:

  • test - Runs Go tests with coverage
  • lint - Runs golangci-lint

Triggers

  • Push to main or production branches (when backend/** files change)
  • Manual workflow dispatch with environment selection

Workflow Flow

Push to main/production
    ↓
[build.yml] → Builds image → Pushes to registry (optional)
    ↓
[deploy.yml] → Deploys to production → Verifies health

Manual Deployment:

  1. Run build.yml manually (or wait for push)
  2. Run deploy.yml manually with image tag

Required Secrets

Configure these secrets in Gitea repository settings:

Build Secrets:

  • FRONTEND_URL - Frontend application URL
  • DB_HOST - Database host
  • DB_PORT - Database port
  • DB_USER - Database username
  • DB_PASSWORD - Database password
  • DB_NAME - Database name
  • FIREBASE_PROJECT_ID - Firebase project ID
  • FIREBASE_STORAGE_BUCKET - Firebase storage bucket name

Deployment Secrets:

  • DEPLOY_HOST - Production server hostname/IP
  • DEPLOY_USER - SSH user for deployment
  • DEPLOY_PATH - Deployment directory on server
  • SSH_PRIVATE_KEY - SSH private key for server access
  • SSH_KNOWN_HOSTS - SSH known hosts entry
  • FIREBASE_CREDENTIALS_FILE_PATH - Path to Firebase credentials file on server
  • PORT - Application port (default: 8080)

Optional Secrets:

  • REGISTRY_URL - Container registry URL (if using registry)
  • REGISTRY_USERNAME - Registry username
  • REGISTRY_PASSWORD - Registry password
  • NOTIFICATION_WEBHOOK - Webhook URL for deployment notifications

Security Considerations

  1. Firebase Credentials:

    • Credentials are NOT included in the build
    • Credentials are mounted at runtime on the production server
    • File must exist on production server at path specified in FIREBASE_CREDENTIALS_FILE_PATH
    • Mounted with read-only and SELinux shared context (:ro,z)
  2. Database Credentials:

    • Stored as Gitea secrets
    • Passed as environment variables at runtime
    • Never committed to repository
  3. SSH Access:

    • Uses SSH key authentication
    • Private key stored as Gitea secret
    • Known hosts verified

Deployment Process

  1. Build Phase:

    • Checks out code
    • Sets up Docker and Pack CLI
    • Configures Docker socket (handles rootless Docker)
    • Builds image using Pack with --docker-host flag
    • Tags and optionally pushes to registry
  2. Deploy Phase:

    • Transfers deployment files to production server
    • Transfers image (if not using registry)
    • Creates .env.production on server
    • Runs deployment script that:
      • Stops existing container
      • Mounts Firebase credentials (read-only)
      • Starts new container
    • Verifies deployment with health check
    • Rolls back on failure

Manual Deployment

To trigger manual deployment:

  1. Go to Gitea repository → Actions → Workflows
  2. Select "Production Deployment"
  3. Click "Run workflow"
  4. Select environment (production/staging)
  5. Click "Run workflow"

Troubleshooting

Build fails with Docker permission error:

  • Ensure Docker socket is accessible
  • Check PACK_DOCKER_HOST is set correctly
  • Verify --docker-host flag is being passed to pack

Deployment fails with Firebase credentials error:

  • Verify credentials file exists on server at specified path
  • Check file permissions: chmod 644 firebase-credentials.json
  • Ensure SELinux allows access (use :z flag in mount)

SSH connection fails:

  • Verify SSH key is correct
  • Check known hosts entry
  • Ensure user has access to deployment directory

Health check fails:

  • Check container logs: podman logs jd-book-uploader
  • Verify port is accessible
  • Check firewall rules
  • ../../deployment/docs/pack-docker-permissions-fix.md - Pack Docker permissions fix
  • ../../deployment/docs/secrets-management.md - Secrets management guide