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.
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 }}
username: ubuntu
key: ${{ secrets.GH_DEPLOY_KEY }}
script: |
cd /srv/myapp
git pull origin main
npm install --production
systemctl restart myapp
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 that fires if your service becomes unreachable. You'll get notified on Slack or email within 60 seconds of a failed deployment.
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