Teams, projects and apps
What it is
Section titled “What it is”Everything a user deploys belongs to a tree:
User ──member of──► Team (role: viewer | developer | admin | owner) └── Project └── App ── deployments, env vars, domains, cron jobs, webhook, metrics, logs- A team is the unit of access and of quota. Users join teams with a role.
- A project groups apps inside a team. It’s only a grouping and an access boundary: nothing on the host depends on it.
- An app is one deployable service: one Linux user, one work directory, one systemd unit (or a set of units for Celery), and an optional port.
Next to the tree sits node-wide infrastructure that no team owns: runtime toolchains (“Applications”), PostgreSQL and MongoDB instances, managed services such as Redis, object storage, mail and the firewall. Only superusers manage that.
When to use it
Section titled “When to use it”- Give each customer, client or group of people their own team, so they see only their apps and count against their own quota.
- Use projects to group related apps, such as an API, its worker and its frontend.
- Use roles to let someone deploy without being able to delete apps or manage members.
When not to use it
Section titled “When not to use it”Projects aren’t an isolation boundary on the host. Apps in different projects of the same team are isolated from each other by the same Linux-level sandbox as apps in different teams, but team members can see all of them. If two groups of people must not see each other’s apps, put them in different teams.
How it works
Section titled “How it works”Accounts
Section titled “Accounts”There is no public sign-up. A superuser creates accounts with
POST /auth/users. Each new account also gets a personal team it owns. The
installer seeds the first superuser from SUPERUSER_EMAIL and
SUPERUSER_PASSWORD in /etc/gisila/.env, and that superuser starts with an
“Administrators” team.
Any signed-in user can create more teams (POST /teams/) and becomes their
owner. To add someone to a team, an admin invites an existing account by
email (POST /teams/{id}/invitations, default role developer).
Team roles
Section titled “Team roles”Roles are ordered. Each role can do everything the roles below it can.
| Role | Can |
|---|---|
viewer |
Read the team’s projects and apps: status, deployments, build logs, env var names (secret values hidden), domains, metrics, runtime logs, cron jobs, webhook status, quota. |
developer |
Create projects and apps, deploy, upload artifacts, roll back, start and restart, edit app settings and env vars, add and remove domains, issue certificates, manage cron jobs and see their output, run console commands, toggle a tcp app’s public reachability, unlink storage buckets. |
admin |
Stop apps, delete apps and projects, invite members, manage the push-to-deploy webhook and its commit-status token, move an app to a project in another team (needs admin on both teams). |
owner |
Delete the team, along with every project and app in it. |
A user who isn’t a member gets the same 403 as an under-privileged member,
so membership isn’t leaked.
Superusers
Section titled “Superusers”A superuser (is_superuser: true on the user) bypasses team roles on app and project
routes. Superusers are the only ones who can:
- Create, edit and delete user accounts, and reset another user’s 2FA.
- Set team quotas.
- Install runtimes and versions, managed services, database instances, storage providers and the mail stack.
- Create databases, buckets and mailboxes, and link a bucket to an app.
- Change the firewall and the panel-wide SMTP settings.
- Create alert rules for anything other than an app.
Quotas
Section titled “Quotas”A team can have a quota of maxApps, maxMemoryMb and maxCpuPercent, which
a superuser sets with PUT /teams/{id}/quota. Leave a field out for no limit.
The quota is checked when an app is created, when its memory or CPU limit is
raised, and when it’s moved into the team. Team owners can’t raise their own
quota.
Per-app limits
Section titled “Per-app limits”Each app has memoryMbLimit (default 256, minimum 32, at most the host’s
RAM), cpuQuotaPercent (default 50, percent of one core, at most cores × 100)
and tasksLimit (default 100, 16 to 16384). They become the systemd
MemoryMax=, CPUQuota= and TasksMax= settings. GET /apps/limits returns
the host’s ceilings.
Example
Section titled “Example”Create a team, a project and an app with the API:
H='Authorization: Bearer gsl_xxxxxxxxxxxxxxxx'J='Content-Type: application/json'
curl -sX POST https://panel.example.com/teams/ -H "$H" -H "$J" \ -d '{"name": "Acme"}'# → {"id": 7, "name": "Acme", "slug": "acme", ...}
curl -sX POST https://panel.example.com/projects/ -H "$H" -H "$J" \ -d '{"teamId": 7, "name": "Billing"}'# → {"id": 12, ...}
curl -sX POST https://panel.example.com/teams/7/invitations -H "$H" -H "$J" \ -d '{"email": "dev@example.com", "role": "developer"}'