CI/CD from GitHub to VeloxaHost: Automated Deployments in 15 Minutes

GH VH

Manual deployments are error-prone and slow. With GitHub Actions and VeloxaHost deploy keys, you can have code automatically tested and deployed on every push to main — in about 15 minutes of setup.

Architecture Overview

The pipeline looks like this:

  1. Push code to GitHub
  2. GitHub Actions runs your test suite
  3. On success, Actions SSHes into your VeloxaHost instance using a deploy key
  4. It pulls the latest code and restarts your service

Step 1 — Create a Deploy Key

Generate a dedicated SSH key for your pipeline (don't reuse personal keys):

ssh-keygen -t ed25519 -f ~/.ssh/deploy_veloxahost -C "github-actions-deploy"

Add the public key to VeloxaHost under Settings → Deploy Keys. Add the private key as a GitHub Actions secret named GH_DEPLOY_KEY.

ℹ️

Deploy keys are injected into a server only when it is created. For a server that already exists, append the public key to /root/.ssh/authorized_keys on the server yourself.

Step 2 — The GitHub Actions Workflow

Create .github/workflows/deploy.yml:

name: Deploy to VeloxaHost

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: npm test   # or: pytest, cargo test, etc.

      - name: Deploy
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.INSTANCE_IP }}     # the region's shared IPv4 address
          port: ${{ secrets.INSTANCE_SSH_PORT }} # first port of your server's block
          username: root
          key: ${{ secrets.GH_DEPLOY_KEY }}
          script: |
            cd /srv/myapp
            git pull origin main
            npm install --production
            systemctl restart myapp

Your server is reached through a block of ports on the region's shared IPv4 address, shown on the server page; the first port forwards to SSH (port 22). If the server has a dedicated IPv4 address, use that address and port 22 instead.

💡

Zero-downtime tip: Use a rolling restart pattern — start the new version before stopping the old one. Tools like pm2 reload or gunicorn --graceful-timeout handle this automatically.

Step 3 — Manage Secrets Safely

Never commit secrets to your repository. Store them in GitHub Actions secrets and inject them as environment variables at deploy time:

      - name: Deploy
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          REDIS_URL: ${{ secrets.REDIS_URL }}

Step 4 — Monitor Your Deployment

Set up a VeloxaHost alert rule under Alerts that fires if your server stops running or its CPU, memory or disk usage crosses a threshold. Rules are checked every 5 minutes, so you'll get notified on Slack or email within about 5 minutes. Alert rules don't probe your service itself; for that, add an external uptime check.

What's Next?

  • Add a staging environment that deploys on every PR
  • Use VeloxaHost's Webhooks to trigger post-deploy tasks (cache warmup, notifications)
  • Implement health checks so GitHub Actions waits for your app to be healthy before marking the deployment successful