First deploy of a Gisila app
In this guide you deploy a Gisila API from a git repository. At the end it runs as a sandboxed systemd service, passes the panel’s health check, and answers on your own domain over HTTPS.
Prerequisites
Section titled “Prerequisites”- A panel you can sign in to with at least the
developerrole in a team (Install on a VPS). - The Dart runtime installed on the Applications page (a superuser does this once per server).
- A Gisila app in a git repository with a
bin/server.dartentry point. The server must be reachable from the panel: public overhttps://, or private with an SSH deploy key (see Deploy from git, a binary or a ZIP).
1. Make the app read PORT and expose a health check
Section titled “1. Make the app read PORT and expose a health check”The panel tells your process which port to listen on through the PORT env
var. A health check path lets the panel confirm after each deploy that the
app actually routes requests, not only that the process started.
import 'dart:io';
import 'package:gisila/gisila.dart';
Future<void> main() async { final port = int.parse(Platform.environment['PORT'] ?? '8080');
final app = GisilaApp( config: AppConfig( // Answers {"status":"ok"} with no auth, ahead of other middleware. healthCheckPath: '/healthz', ), ); // ...register services and controllers...
// stopOnSignals: drain requests on the SIGTERM systemd sends on restart. await app.start(host: '127.0.0.1', port: port, stopOnSignals: true);}Commit and push.
2. Create a project and an app
Section titled “2. Create a project and an app”In the UI, open a team, create a project, then New app. Or use the API (see Use the API with tokens):
H='Authorization: Bearer gsl_xxxxxxxxxxxxxxxx'J='Content-Type: application/json'PANEL=https://panel.example.com
curl -sX POST $PANEL/projects/ -H "$H" -H "$J" \ -d '{"teamId": 7, "name": "Billing"}'
curl -sX POST $PANEL/apps/ -H "$H" -H "$J" -d '{ "projectId": 12, "name": "billing-api", "runtime": "dart", "sourceType": "git", "gitUrl": "https://github.com/acme/billing-api.git", "gitBranch": "main", "internalPort": 4001, "healthCheckPath": "/healthz", "memoryMbLimit": 256, "cpuQuotaPercent": 50}'runtime picks the installed Application by key. You can pass its numeric
applicationId instead. With no buildCommand, the Dart runtime runs
dart pub get && dart compile exe bin/server.dart -o build/app, and the
binary becomes <workDir>/current/app. Pin a toolchain with dartVersion if
you have several installed.
internalPort must be between 1024 and 65535 and not used by another app.
3. Set env vars
Section titled “3. Set env vars”Add configuration before the first deploy, since env vars are read at build and at start:
curl -sX POST $PANEL/apps/42/envs -H "$H" -H "$J" \ -d '{"name": "DATABASE_URL", "value": "postgresql://…", "isSecret": true}'See Env vars and secrets.
4. Deploy
Section titled “4. Deploy”Click Deploy, or:
curl -sX POST $PANEL/apps/42/deployments/ -H "$H" -H "$J" \ -d '{"sourceType": "git"}'# → {"id": 101, "status": "queued", ...}The Build logs tab streams the clone, the compile, unit generation, the restart, and finally the health check:
Verifying the service is up…Deployment succeeded. gisila-app_ab12cd.service is active, 127.0.0.1:4001 isaccepting connections, /healthz answered, and stayed that way for 5s after therestart.5. Attach your domain
Section titled “5. Attach your domain”Point an A record for api.example.com at the server, then add the domain
and issue a certificate from the Domains tab, or:
curl -sX POST $PANEL/apps/42/domains/ -H "$H" -H "$J" \ -d '{"hostname": "api.example.com", "isPrimary": true}'curl -sX POST $PANEL/apps/42/domains/<domainId>/ssl -H "$H"Verify it works
Section titled “Verify it works”curl -s https://api.example.com/healthz# {"status":"ok"}
curl -s "$PANEL/apps/42" -H "$H" | jq .status# "running"If the deploy fails, the end of the build log shows why (nothing listening on
the port, /healthz failing, or the unit crash-looping) followed by the last
journal lines of the unit.