Docs

Coolify

Deploy a Proa app to Coolify on your own VPS.

Open Markdown

A Proa app runs on Coolify as an ordinary Dockerized Rust HTTP server, and Coolify handles TLS, routing, rollbacks, and preview URLs. This page covers scaffolding the project, building the image, setting runtime variables, and previewing pull requests.

Scaffolding for Coolify

Generate a site with the Coolify deployment preset:

Terminal
proa new site my-site --template marketing --deploy coolify --tailwind --yes
cd my-site

The preset writes:

Dockerfile
.dockerignore
coolify.env.example
COOLIFY.md
README.md
src/main.rs
public/

The generated server reads PROA_HOST, PORT, and RUST_LOG, and serves public/ relative to its working directory. The Dockerfile installs a pinned, checksum-verified Proa CLI, builds with proa build --locked --artifact-out, sets PROA_HOST=0.0.0.0, exposes port 3000, and copies public/ beside the binary. Public Proa dependencies resolve from crates.io without credentials.

Coolify needs matching application settings before it can build that image.

Setting up the application

  1. Push the generated project to GitHub.
  2. In Coolify, create an Application from the repository.
  3. Choose the Dockerfile build pack or Dockerfile deployment type.
  4. Set the exposed port to 3000.
  5. Add runtime variables from coolify.env.example.
  6. Set the health check path to /healthz for liveness. The generated /readyz also probes the database, so use it as the readiness check when one is configured.
  7. Deploy.

Building the image

Build the generated Dockerfile locally before deploying:

Terminal
docker build -t my-site .

proa build runs the asset build and the linked RSJS pipeline; a plain cargo build --release would skip the assets and fail at link time on any crate with islands.

For a prebuilt-image deployment, use a GitHub Actions image pipeline:

  1. Build the image in GitHub Actions.
  2. Push the image to GHCR or another Docker registry.
  3. Point Coolify at the prebuilt image.

This is the cleanest production shape because the VPS only needs permission to pull the final image.

Either path produces the same container, and that container reads its configuration from runtime variables.

Setting runtime variables

Use these runtime variables in Coolify:

coolify.env.example
PORT=3000
PROA_HOST=0.0.0.0

Add RUST_LOG=info if you want the log filter set from the environment; the generated file lists only the two the server needs.

Preview deployments read their own copy of these variables, so scope the sensitive ones before you turn previews on.

Previewing pull requests

Coolify supports pull request preview deployments for GitHub repositories. Previews can:

Use the GitHub App setup when possible. Automated comments require the GitHub App, and Coolify offers automated preview deployments only for GitHub App based repositories.

For preview domains:

  1. Add a wildcard DNS record pointing to the Coolify server, such as *.preview.example.com.
  2. In Coolify, enable Preview Deployments for the application.
  3. Use a URL template such as {{pr_id}}.preview.example.com.
  4. Keep production secrets in production-only variables.
  5. Use preview-scoped variables for disposable databases, API sandboxes, and limited tokens.

Coolify's docs describe the full setup in GitHub Preview Deploy and the general Applications settings page.

Every environment, preview or production, needs a route Coolify can poll for liveness.

Checking health

Generated Axum sites include a cheap liveness route:

Terminal
curl -fsS https://example.com/healthz

Use /healthz for Coolify's container health check. If the app needs database readiness, add a separate /readyz route and keep /healthz cheap.

Where that container gets built, on the VPS or in a pipeline, is the remaining decision.

When to use prebuilt images?

Use a prebuilt image pipeline when:

Use Coolify source builds when:

Either way, run the image locally once before you point Coolify at it.

Verifying before you deploy

Before you deploy:

Next steps

Search

Type at least 2 characters