Part 4 of 5

    Gitea + Dokploy & Coolify: Auto-Deploy on Every Push

    Connect your Gitea CI/CD pipeline to a PaaS deployment platform for automatic redeployments on push.

    Architecture: Code push to Gitea → Gitea Actions pipeline runs → Docker image pushed to Gitea registry → Webhook fires to Dokploy or Coolify → New container deployed automatically. This entire pipeline runs on one or two RamNode VPS instances with no third-party services required.

    Choosing Between Dokploy and Coolify

    FeatureDokployCoolify
    MaturityNewer (2024)More established (2022)
    UI styleClean, minimalFeature-rich
    Multi-serverYes (agents)Yes (SSH-based)
    Build methodDockerfile, Nixpacks, BuildpacksDockerfile, Nixpacks, static
    Native Gitea supportVia webhooksVia webhooks + OAuth
    Database managementBuilt-in UIBuilt-in UI
    Traefik integrationBuilt-inBuilt-in
    Best forClean installs, simpler appsLarger teams, more services

    Option A: Gitea + Dokploy

    1

    Installing Dokploy

    Dokploy can be installed on the same VPS as Gitea or on a separate RamNode instance. Using a separate VPS is recommended for production:

    Install Dokploy
    # On your deployment VPS (can be same or different from Gitea VPS)
    curl -sSL https://dokploy.com/install.sh | sh
    
    # Dokploy installs Docker, sets up Traefik, and starts itself
    # Access the UI at: http://YOUR_VPS_IP:3000
    
    # The installer will prompt you to create an admin account on first visit

    Note: Dokploy installs Traefik automatically to handle reverse proxy and SSL for all deployed apps. You do not need to configure Nginx separately for apps managed by Dokploy.

    2

    Connecting Gitea as a Source Provider

    Dokploy supports Gitea as a git source via OAuth:

    • 1. In Gitea: User Settings → Applications → OAuth2 Applications
    • 2. Application Name: Dokploy
    • 3. Redirect URI: https://your-dokploy-domain.com/api/auth/gitea/callback
    • 4. Save the Client ID and Client Secret
    • 5. In Dokploy: Settings → Git Providers → Add Gitea → Enter URL, Client ID, Secret

    Creating an Application

    • 1. In Dokploy dashboard: Projects → New Project → Add Application
    • 2. Select Gitea as the source provider
    • 3. Choose your organization and repository
    • 4. Select the branch to deploy (main or production)
    • 5. Set the build method: Dockerfile (recommended) or Nixpacks
    • 6. Configure environment variables, port, and domain
    3

    Auto-Deploy via Webhook

    Dokploy can auto-configure a Gitea webhook. To configure manually:

    Dokploy webhook configuration
    # Dokploy webhook URL format:
    https://your-dokploy-domain.com/api/deploy/webhook/APPLICATION_ID
    
    # In Gitea (Repository > Settings > Webhooks > Add Webhook > Gitea)
    # Target URL: (paste Dokploy URL)
    # Secret: (copy from Dokploy application settings)
    # Trigger on: Push Events
    # Branch filter: main
    
    # Test the webhook with the 'Test Delivery' button in Gitea

    Deploying from Gitea Container Registry

    For the full pipeline (Gitea Actions builds image → pushes to Gitea registry → Dokploy deploys):

    Deploy from pre-built image
    # In Dokploy application: Source > Image
    # Registry URL: git.yourdomain.com
    # Image: your-org/myapp
    # Tag: latest (or use a specific SHA tag from CI)
    
    # Add registry credentials:
    # Registry Username: your_gitea_user
    # Registry Password: YOUR_GITEA_PAT
    
    # Then configure a deploy webhook to be called from your CI pipeline:
    
    # In .gitea/workflows/deploy.yml:
    - name: Trigger Dokploy deploy
      run: |
        curl -X POST \
          -H 'Content-Type: application/json' \
          -H 'x-webhook-token: ${{ secrets.DOKPLOY_WEBHOOK_SECRET }}' \
          https://your-dokploy-domain.com/api/deploy/webhook/YOUR_APP_ID

    Option B: Gitea + Coolify

    4

    Installing Coolify

    Install Coolify
    # Install Coolify
    curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
    
    # Access UI at: http://YOUR_VPS_IP:8000
    # Complete the setup wizard to create your admin account
    5

    Adding Gitea as a Source in Coolify

    Coolify calls git sources 'Private Git Sources'. Gitea is fully supported:

    • 1. In Coolify: Settings → Private Git Sources → Add
    • 2. Type: Gitea
    • 3. Gitea App URL: https://git.yourdomain.com
    • 4. Create a Gitea OAuth app with redirect URI: https://your-coolify-domain.com/api/v1/auth/source/gitea
    • 5. Enter Client ID and Client Secret in Coolify
    • 6. Click Connect and authorize the OAuth flow

    Creating a Service

    • 1. Create a Project and Environment
    • 2. Add a New Resource → Application
    • 3. Source: Gitea (select your private git source)
    • 4. Select the repository and branch
    • 5. Build Pack: Dockerfile (or Nixpacks for auto-detection)
    • 6. Set the port your app listens on
    • 7. Configure a custom domain if needed

    Coolify Webhook Integration

    Coolify webhook trigger
    # Find the webhook URL in Coolify:
    # Service > Configuration > Deploy Webhook URL
    
    # Add to Gitea repository secrets as COOLIFY_WEBHOOK_URL
    
    # In your Gitea Actions workflow:
    - name: Trigger Coolify deploy
      if: github.ref == 'refs/heads/main'
      run: |
        curl --request GET \
          --url '${{ secrets.COOLIFY_WEBHOOK_URL }}' \
          --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}'

    Full End-to-End Pipeline

    Complete CI/CD Workflow

    This workflow builds, tests, packages, and deploys your application on every push to main:

    .gitea/workflows/deploy.yml
    name: Build, Publish, and Deploy
    
    on:
      push:
        branches: [main]
    
    env:
      REGISTRY: git.yourdomain.com
      IMAGE_NAME: your-org/myapp
    
    jobs:
      build-and-push:
        runs-on: ubuntu-22.04
        outputs:
          image-tag: ${{ steps.meta.outputs.tags }}
        steps:
          - uses: actions/checkout@v4
    
          - name: Set image tag
            id: meta
            run: |
              SHA_SHORT=${GITEA_SHA:0:8}
              echo "tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$SHA_SHORT" >> $GITHUB_OUTPUT
    
          - name: Login to Gitea Registry
            run: |
              echo ${{ secrets.GITEA_DEPLOY_TOKEN }} | \
                docker login ${{ env.REGISTRY }} -u ${{ gitea.actor }} --password-stdin
    
          - name: Build and push
            run: |
              docker build -t ${{ steps.meta.outputs.tags }} .
              docker push ${{ steps.meta.outputs.tags }}
              docker tag ${{ steps.meta.outputs.tags }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
              docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
    
      deploy:
        needs: build-and-push
        runs-on: ubuntu-22.04
        steps:
          - name: Trigger deploy webhook
            run: |
              curl -X POST \
                -H 'Content-Type: application/json' \
                -H 'x-webhook-token: ${{ secrets.DEPLOY_WEBHOOK_SECRET }}' \
                ${{ secrets.DEPLOY_WEBHOOK_URL }}

    Zero-Downtime Deployments

    Both Dokploy and Coolify use Traefik for routing, which supports zero-downtime deployments through rolling updates:

    Dockerfile health check
    # In your Dockerfile, add a HEALTHCHECK instruction:
    HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
      CMD curl -f http://localhost:3000/health || exit 1
    
    # In Dokploy application settings > Advanced:
    # Health Check Path: /health
    # Health Check Interval: 30s
    
    # Traefik waits for the health check to pass before routing traffic
    # to the new container, providing zero-downtime deployments

    Rollback Strategies

    Both platforms keep a deployment history with the ability to roll back to any previous image tag:

    Rollback via API
    # Manual rollback via Dokploy UI:
    # Applications > Your App > Deployments > Select previous > Redeploy
    
    # Or via API:
    curl -X POST \
      -H 'Authorization: Bearer YOUR_DOKPLOY_TOKEN' \
      https://your-dokploy-domain.com/api/deployments/DEPLOYMENT_ID/redeploy
    
    # Tag Docker images with both SHA and version to make rollbacks predictable:
    docker tag myapp:latest myapp:v1.2.3
    docker push git.yourdomain.com/your-org/myapp:v1.2.3

    Environment-Specific Deployments

    Configure separate pipelines for staging (auto-deploy on every push) and production (manual approval required):

    Staging + Production workflows
    # .gitea/workflows/staging.yml
    on:
      push:
        branches: [develop]
    # (same build steps, trigger staging webhook)
    
    # .gitea/workflows/production.yml
    on:
      push:
        branches: [main]
    # (same build steps, require manual approval then trigger prod webhook)
    
    jobs:
      deploy-production:
        environment:
          name: production
          url: https://app.yourdomain.com
        # In Gitea: Create an 'environment' with required reviewers
        # The workflow pauses here until approved
        runs-on: ubuntu-22.04
        steps:
          - name: Deploy to production
            run: curl -X POST ${{ secrets.PROD_WEBHOOK_URL }}

    Note: Gitea supports environment protection rules (required reviewers, deployment freeze windows) under repository Settings → Environments. This is the Gitea equivalent of GitHub's protected environments.

    What's Next

    Part 5 covers team workflows, branch protection rules, PR review processes, and production hardening to complete your self-hosted DevOps stack.