Skip to main content

How Vessl Works

When you push to GitHub and your app shows up in the browser a minute later, there's a lot happening behind the scenes. This page walks through the full flow so you know what to expect — and where to look when something goes wrong.

The three pieces

Vessl is made up of three parts working together:

  • Control plane — the brain. It receives webhooks from GitHub, orchestrates builds, manages add-ons, and stores all your app configuration.
  • Your server — the VPS you bring. This is where your app containers actually run.
  • Traefik gateway — a reverse proxy running on your server that handles HTTPS termination and routes traffic to the right container.

They communicate over SSH. Vessl doesn't need your server to be publicly accessible beyond the ports you allow.

The deploy flow

1. Push to GitHub

When you push to a watched branch, GitHub sends a webhook to Vessl. Vessl queues a build immediately — you don't need to trigger anything manually.

2. Build the image

Vessl clones your repo and builds a Docker image:

  • No Dockerfile → Vessl uses Nixpacks, which auto-detects your stack (Laravel, Next.js, Django, Rails, Go, static sites, and more) and produces an optimized image.
  • With a Dockerfile → Vessl uses it directly, respecting your CMD and build args.

The resulting image is pushed to an internal registry.

3. Canary health check

Before replacing your running app, Vessl starts the new image as a canary — a temporary container that doesn't yet receive public traffic. It waits for the container to pass a health check (your configured endpoint returning 200) within a set timeout.

If the canary fails, Vessl stops the deploy. Your existing container keeps serving traffic — no downtime, no broken app in production.

4. Swap

Once the canary is healthy, Vessl:

  1. Stops the old container.
  2. Promotes the new container to production.
  3. Updates Traefik routing so traffic flows to the new container.

The swap is fast — users mid-session typically won't notice.

5. Post-deploy commands

If you've configured a post-deploy command (like php artisan migrate), Vessl runs it inside the new container after it's live, before marking the deploy as complete.


Add-ons

When you add a database or cache (PostgreSQL, MySQL, Redis), Vessl runs it as a container on the same server, in the same Docker network as your app. The connection between your app and its database never leaves the server — it's a private network link.

Connection credentials are injected automatically as environment variables into your app's container at deploy time.

Routing & HTTPS

Traefik on your server handles all routing:

  • Every app gets a *.shipto.id subdomain automatically.
  • Add a custom domain and Vessl provisions a Let's Encrypt certificate via HTTP-01 challenge — usually done within 1–3 minutes.
  • All traffic is redirected to HTTPS.
Your server, your containers

Traefik and your app containers run on the VPS you own. If Vessl's control plane were ever unreachable, your already-deployed apps would keep running and serving traffic — because the containers live on your server, not Vessl's infrastructure.