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:
- Push code to GitHub
- GitHub Actions runs your test suite
- On success, Actions SSHes into your VeloxaHost instance using a deploy key
- 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