Deploying
A "deploy" takes your project source, builds it into a container image on the platform, and rolls that image out to a slot. You never build locally and you never write a Dockerfile. There are three ways to start a deploy: the CLI, GitHub Actions, and the dashboard upload.
Via the CLI
velixir deploy
This:
- Packages the current directory's source into
.velixir/source.tar.gz. Packing happens in-process, so notarbinary and no build tools are needed on your machine. - Detects your language (informational) and asks the platform for a presigned upload URL, then PUTs the archive straight to object storage.
- Creates a release and finalises it.
- The platform builds the image, enqueues a deployment, and the CLI polls until it lands or fails.
The server-side build is where your dependencies are resolved and your image is assembled, so the first deploy of a project takes a little longer than the ones after it. If the build fails, the failure reason streams back to your terminal.
Deploy to a named slot with velixir deploy --slot staging, or package a different directory with velixir deploy --source-dir ./service.
Via the dashboard
From an app's Overview tab, click Upload source. Pick a .tar.gz or .zip of your project source: your code plus its manifest, for example package.json, requirements.txt, go.mod, pom.xml, or a .csproj. We sign a one-time URL pointing at object storage; your browser uploads directly to that URL (no proxy hop, no Cloudflare body-size cap), and the build starts as soon as the upload lands.
Via GitHub Actions
Add the Velixir Action to your workflow. On every push, the Action runs velixir deploy from your checked-out repo: it packages your source and hands it to Velixir to build and roll out. There is no App to install, no webhooks, and no build step in your workflow. Your CI simply triggers the same source upload the CLI does.
- No App to install. Nothing to authorise on GitHub and no webhook secrets to paste. A single repo secret,
VELIXIR_API_KEY, is all the platform needs, so the Action works the moment the workflow file lands. - Your CI stays simple. The Velixir Action is the only platform-specific step. Nothing in your workflow needs the .NET SDK, Node, or any other toolchain, because the build happens on the platform, not on the runner.
1. Add an API key as a repo secret
Generate a Write-scoped key in the dashboard under API keys, then add it on GitHub under Settings → Secrets and variables → Actions as VELIXIR_API_KEY. That secret is the only thing you add.
2. Point the workflow at your app
Run velixir init --app <id> once in the project root and commit the .velixir.json it writes (it holds only your app ID and slug, no secrets). The Action reads it to know which app to deploy, or pass --app <id> directly in the workflow step.
3. Add the deploy workflow to your repo
Drop this in .github/workflows/velixir.yml:
name: Deploy to Velixir
on:
push:
branches: [main] # change to your deploy branch
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Velixir
uses: velixir/velixir/actions/deploy@v1
env:
VELIXIR_API_KEY: ${{ secrets.VELIXIR_API_KEY }}
The Action runs velixir deploy for you: no setup-dotnet, no dotnet publish, no upload-artifact.
4. Push and watch the deploy
Push to the configured branch. GitHub Actions runs your workflow, the Velixir Action uploads your source, and the platform builds it and deploys it. Watch the Overview tab: a new release appears, then a deployment, then the live badge moves to it.
Common gotchas
- Missing API key. The Action needs a
VELIXIR_API_KEYrepo secret. Generate a Write-scoped key in the dashboard under API keys, then add it on GitHub under Settings → Secrets and variables → Actions. Without it the deploy step fails fast. - No app linked.
velixir deployneeds to know which app to target. Commit the.velixir.jsonthatvelixir initcreated, or pass--app <id>in the workflow step. - Branch mismatch. The workflow's
on: push: branches:filter decides which pushes deploy. Widen or narrow it to match your deploy branch. - Build failed. A failed build shows up on the app's Overview and in the workflow logs. Fix your source and push again.
Slots
Every app has at least one slot (production). You can deploy to a different slot to stage a release without touching live traffic:
velixir deploy --slot staging
From the dashboard's Slots tab you can then Promote that slot to live - a near-instant swap, the staged pods become production and the previously-live pods stay warm so you can flip back if anything's wrong.
Rollback
Every previous deploy is available from the Releases table on the Overview tab. Hit Redeploy on any earlier release to bring it back; we roll that release back out and the edge cuts traffic over once it's healthy.
After a deploy
- Set environment variables on the Environment tab - they're injected on the next deploy.
- The Logs tab tails container output live.
- The Metrics strip on the Overview tab updates every 10 seconds with replica count, CPU, memory, and HTTP traffic.