Deploying with Coolify
How to deploy ZapTicket services on Coolify — base directories, Dockerfiles, Railpack, health checks, and port configuration.
Overview
Coolify is a self-hosted PaaS (like Heroku/Vercel on your own server). ZapTicket is designed to deploy cleanly on Coolify with minimal configuration. Each service in the monorepo is deployed as a separate Coolify application pointing to different base directories.
Service Configuration
┌────────────────────────────────────────────────────────────────┐
│ Service │ Base Directory │ Build Method │ Port │ Domain │
├─────────────┼────────────────┼──────────────┼──────┼───────────┤
│ Backend │ /backend │ Dockerfile │ 5000 │ api.* │
│ Dashboard │ /dashboard │ Railpack │ 3000 │ app.* │
│ Widget │ /widget │ Railpack │ 3000 │ widget.* │
│ Marketing │ /marketing │ Railpack │ 3000 │ www.* │
│ Docs │ /docs-site │ Railpack │ 3000 │ docs.* │
└────────────────────────────────────────────────────────────────┘Backend (Dockerfile)
The .NET backend uses a standard multi-stage Dockerfile. In Coolify, set the build method to "Dockerfile" and point to the /backend base directory.
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app .
EXPOSE 5000
ENV ASPNETCORE_URLS=http://+:5000
ENTRYPOINT ["dotnet", "ZapTicket.Api.dll"]Coolify Settings for Backend
Base Directory: /backend
Build Pack: Dockerfile
Dockerfile Path: Dockerfile (relative to base directory)
Port: 5000
Health Check Path: /healthz
Health Check Port: 5000Frontend Apps (Railpack)
The Next.js apps (dashboard, widget, marketing, docs) use Railpack — Coolify's auto-detection build system similar to Nixpacks. It detects the Next.js project and builds it automatically without needing a Dockerfile.
Coolify Settings for Dashboard
Base Directory: /dashboard
Build Pack: Railpack
Port: 3000
Health Check Path: /healthz
Health Check Port: 3000/healthz endpoint that returns 200 OK. This is used by Coolify's health check to determine when the container is ready to receive traffic.Coolify Settings for Widget
Base Directory: /widget
Build Pack: Railpack
Port: 3000
Health Check Path: /healthz
Health Check Port: 3000Port Configuration
Coolify maps container ports to external traffic via its built-in reverse proxy (Traefik or Caddy). All Next.js services listen on port 3000 internally:
PORT=3000PORT variable for Next.js apps. Railpack configures the container to listen on the port specified by this variable, and Coolify expects it to match the port configured in the UI.Health Checks
Every service exposes a /healthz endpoint for Coolify's health monitoring:
Backend: GET http://localhost:5000/healthz → 200 "Healthy"
Dashboard: GET http://localhost:3000/healthz → 200 "OK"
Widget: GET http://localhost:3000/healthz → 200 "OK"
Marketing: GET http://localhost:3000/healthz → 200 "OK"
Docs: GET http://localhost:3000/healthz → 200 "OK"The backend health check verifies database connectivity. Frontend health checks simply return 200 to confirm the Next.js server is ready.
Environment Variables
Set environment variables in Coolify's UI for each service. See the full list in Environment Variables.
Key variables for Coolify deployment:
ConnectionStrings__DefaultConnection=Host=...;Database=zapticket;Username=...;Password=...
JWT_SECRET=your-production-secret-min-32-characters
ASPNETCORE_ENVIRONMENT=Production
RUN_MIGRATIONS_ON_STARTUP=trueNEXT_PUBLIC_API_URL=https://api.yourdomain.com
NEXT_PUBLIC_SIGNALR_URL=https://api.yourdomain.com/hubs/chat
PORT=3000Database
You can either use Coolify's built-in PostgreSQL service or an external managed database. For production, a managed PostgreSQL (Neon, Supabase, or cloud-provider managed) is recommended for automatic backups and high availability.
Deployment Checklist
- Create PostgreSQL database (managed or Coolify-hosted)
- Create backend app → set base directory, Dockerfile, env vars
- Deploy backend → verify
/healthzreturns 200 - Create dashboard app → set base directory, Railpack, env vars
- Create widget app → set base directory, Railpack, env vars
- Configure domains and SSL (auto-provisioned by Coolify)
- Test end-to-end: register → create workspace → embed widget → chat