Automate your code deployments with Carpathian Cloud. Easily push code to your development and production spark servers.
Deploy code to your Carpathian server automatically when you push to GitHub. Uses GitHub Actions to trigger deployments via the Carpathian API.
What You Need
- A running Carpathian Spark Server
- A GitHub repository with your code
- An API key with Deployment scope
How It Works
When you push to a configured branch, GitHub Actions sends a request to the Carpathian API. Carpathian then SSHs into your server and runs your configured commands in order:
- Before Deploy hook (optional) — e.g. enable maintenance mode
- Git pull — fetches and checks out the latest code
- Command groups — each group runs its build and restart commands in order
- After Deploy hook (optional) — e.g. disable maintenance mode
Step 1: Configure Deployment
- Go to Cloud Servers in the dashboard
- Click Actions on your server card
- Select Configure Deployment
- Fill in the settings:
Repository Settings
- Repository URL (optional) — your GitHub repo URL. If blank, uses the URL from the GitHub webhook.
- Branch (required) — the branch to deploy from (e.g.
main)
Lifecycle Hooks
These run once per deployment, wrapping all command groups.
- Before Deploy — runs first, before git pull. Use for things like enabling maintenance mode (
php artisan down) or stopping workers (systemctl stop worker). - After Deploy — runs last, after all command groups finish. Use for disabling maintenance mode (
php artisan up) or restarting workers.
Command Groups
Command groups are the core of the deployment. Each group represents one application stack (backend or frontend) with its own directory, build, and restart commands.
Click Add Backend or Add Frontend to create a group. Each group has:
- Type — Backend or Frontend. This filters the framework templates shown.
- Framework — pre-configured templates (Django, Flask, Next.js, React, etc.) that auto-fill build and restart commands. Select "Custom" for manual configuration.
- Label (optional) — a display name for the group (e.g. "API Server", "Admin Panel")
- Deploy Directory — absolute path where the code lives on your server (e.g.
/var/www/app) - Build Command — install dependencies and build (e.g.
npm install && npm run build) - Restart Command — restart the application process (e.g.
pm2 restart app)
Groups execute top-to-bottom. For a typical dual-stack setup:
1. Before Deploy → php artisan down
2. Git pull → git fetch && checkout && pull
3. Backend group → cd /var/www/api && pip install && systemctl restart gunicorn
4. Frontend group → cd /var/www/frontend && npm install && npm run build && pm2 restart frontend
5. After Deploy → php artisan up
Running frontend and backend on the same server is less secure than separating them. A compromise in one layer could affect the other. For production workloads, deploy frontend and backend on separate servers.
- Toggle Enable Deployment to ON
- Click Save Configuration
Step 2: Generate an API Key
- On the Cloud Servers page, click Actions on your server card
- Select Manage API Keys
- Click Generate New API Key
- Set the permission scope to Deployment
- Copy the key immediately — it is only shown once
The key format is cpk_.... You can also manage keys from API Keys in the dashboard sidebar.
Step 3: Add the Key to GitHub Secrets
- Go to your GitHub repository
- Click Settings > Secrets and variables > Actions
- Click New repository secret
- Name:
CARPATHIAN_API_KEY - Value: your
cpk_...key - Click Add secret
Step 4: Create the Workflow
Create .github/workflows/deploy.yml in your repository:
name: Deploy to Carpathian
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Trigger Carpathian Deployment
env:
CARPATHIAN_API_KEY: ${{ secrets.CARPATHIAN_API_KEY }}
run: |
curl -X POST https://api.carpathian.ai/api/v1/deployment/trigger \
-H "Authorization: Bearer $CARPATHIAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"repository": "${{ github.repository }}",
"commit": "${{ github.sha }}",
"branch": "${{ github.ref_name }}",
"commit_message": "${{ github.event.head_commit.message }}",
"author_name": "${{ github.event.head_commit.author.name }}",
"author_email": "${{ github.event.head_commit.author.email }}",
"webhook_url": "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
}'
Step 5: Test
git add .github/workflows/deploy.yml
git commit -m "Add Carpathian deployment workflow"
git push origin main
Check the Deployments page in your dashboard to see the deployment status and logs.
Framework Examples
Backend
Django
Build: pip install -r requirements.txt && python manage.py migrate && python manage.py collectstatic --noinput
Restart: systemctl restart gunicorn
Flask
Build: pip install -r requirements.txt
Restart: systemctl restart gunicorn
Node.js / Express
Build: npm install
Restart: pm2 restart node-app || pm2 start server.js --name node-app
Laravel
Build: composer install --no-dev && php artisan migrate --force && php artisan config:cache && php artisan route:cache && php artisan view:cache
Restart: php artisan queue:restart && systemctl restart php-fpm
Frontend
Next.js
Build: npm install && npm run build
Restart: pm2 restart nextjs-app || pm2 start npm --name nextjs-app -- start
React (Vite/CRA)
Build: npm install && npm run build
Restart: pm2 restart react-app || pm2 start serve --name react-app -- -s build -l 3000
Vue.js
Build: npm install && npm run build
Restart: pm2 restart vue-app || pm2 start serve --name vue-app -- -s dist -l 3000
Workflow Customization
Deploy on multiple branches:
on:
push:
branches: [main, staging, production]
Deploy on pull request merge:
on:
pull_request:
types: [closed]
branches: [main]
Manual trigger:
on:
workflow_dispatch:
Multiple environments with separate API keys:
jobs:
deploy-staging:
if: github.ref == 'refs/heads/staging'
steps:
- name: Deploy to Staging
env:
CARPATHIAN_API_KEY: ${{ secrets.CARPATHIAN_STAGING_KEY }}
run: curl -X POST https://api.carpathian.ai/api/v1/deployment/trigger ...
deploy-production:
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Production
env:
CARPATHIAN_API_KEY: ${{ secrets.CARPATHIAN_PRODUCTION_KEY }}
run: curl -X POST https://api.carpathian.ai/api/v1/deployment/trigger ...
Checking Deployment Status
The easiest way to check deployment status is the Deployments page in your dashboard. The Deployment Logs tab shows all deployments with their status, commit info, and full output logs.
If you need to check status programmatically (e.g. in a CI pipeline), the trigger endpoint returns a deployment_id in its response. You can use that ID with the status and logs endpoints. These endpoints require the same API key used to trigger the deployment — you can only query deployments that belong to your server.
#Check status (deployment_id is returned by the trigger response)
curl -H "Authorization: Bearer $CARPATHIAN_API_KEY" \
https://api.carpathian.ai/api/v1/deployment/status/DEPLOYMENT_ID
#Get full logs
curl -H "Authorization: Bearer $CARPATHIAN_API_KEY" \
https://api.carpathian.ai/api/v1/deployment/logs/DEPLOYMENT_ID
Troubleshooting
"Deployment Not Configured"
You haven't set up deployment on this server yet. Go to Cloud Servers > Actions > Configure Deployment.
Deployment not triggering
- Check that the API key status is Active (not Locked or Revoked)
- Verify the key has Deployment scope
- Confirm
CARPATHIAN_API_KEYexists in GitHub Secrets with the fullcpk_...value - Check the GitHub Actions tab for workflow errors
- Verify you're using the url:
https://carpathian.aifor all API calls
"Invalid API Key"
The key may be revoked, deleted, or locked. Check status in API Keys. Generate a new key if needed.
API Key Locked
Keys auto-lock after 3 failed IP allowlist checks within 5 minutes. Go to the key details, review Security Events, then click Unlock.
Deployment triggered but nothing changed
- Check the Deployments page for logs and error messages
- Verify your deploy directory path is correct
- Confirm build and restart commands work when run manually via SSH
Security
- Use Deployment scope — avoid Full Access for CI/CD
- Never commit API keys to git — always use GitHub Secrets
- Use IP allowlists to restrict key usage to GitHub Actions IPs (
185.199.108.0/22,140.82.112.0/20,143.55.64.0/20) - Revoke keys that haven't been used in 90+ days
- Monitor key usage and security events in the dashboard
This documentation is open to the public to make the platform API available for customers. However, since Carpathian Cloud is still in beta and being actively developed, this document might be outdated or incorrect. If you find anything confusing or misleading, please send an email to info@carpathian.ai.