Sheltie is ScottyLabs' self-hosted deployment platform, a Railway replacement running Coolify on our own server. You can deploy apps from Git, spin up databases such as PostgreSQL, and let your AI agents do the same through an authenticated MCP server, CLI, or REST API.
| Dashboard | https://sheltie.scottylabs.org |
| This guide | https://docs.sheltie.scottylabs.org |
| MCP endpoint | https://sheltie.scottylabs.org/mcp |
| REST API | https://sheltie.scottylabs.org/api/v1 |
| App domains | <name>.sheltie.scottylabs.org, HTTPS included |
Everything runs on one small server (1 vCPU, 1.8 GB RAM). Be a good neighbor: give every app a memory limit, delete what you stop using, and keep heavy builds elsewhere.
Quick start
From invite to a live app in about five minutes:
- Accept your invite. Open the link an admin sent you, click accept, and choose a password. Then turn on two-factor authentication under Profile.
- Make a project. Projects → + Add, named after your product (for example
cmucourses). - Add your app. In the project's
productionenvironment click + New Resource:- repo in the
scottylabs-labradororg → Git Repository (with GitHub App), choose sheltie-scottylabs, pick the repo; - any public repo → Public Git Repository, paste the URL.
- repo in the
- Set the basics under Configuration → General: the Ports exposes field is the port your app listens on, and Domains can be any free
https://<name>.sheltie.scottylabs.org. Then Resource Limits → Memory limit:128mto256mcovers most apps. - Deploy. Logs stream live; your app is at its domain within a minute. With the GitHub App, every push to the branch redeploys.
Want a working example to copy? katmai-sortie is a static site behind nginx with a health check, and this guide's repo builds Markdown into a page and deploys itself on every push.
1. Getting access
Public sign-up is off; an admin invites you.
- An admin sends you an invite link. It works once and expires after 3 days. Ask for a new one if it has expired.
- Open it and accept. Coolify signs you in and makes you choose a password before anything else.
- Go to Profile (top-right avatar, or
/profile) and enable Two-factor authentication. The login page is on the public internet.
You land in Root Team, which is where the server lives. Coolify also gives every account a personal team called "yourname's Team". It has no server, so nothing can be deployed there. If you ever see an empty dashboard or a "connect a server" wizard, switch back to Root Team with the team switcher in the sidebar.
Forgot your password? Email is not set up on this instance, so the "Forgot password" link cannot reach you. Ask an admin: they can issue a one-time password, and you will be asked to choose a new one when you sign in.
2. Teams and roles
Our single server belongs to Root Team, so everyone works inside it. Keep your work organized with a Project per product rather than a team per product.
| Role | Can do |
|---|---|
| Member | View projects, apps, databases, and logs. Cannot create, change, deploy, or delete. For people who only need to watch. |
| Admin | Create and deploy projects, apps, and databases; edit environment variables; invite people. The role for anyone who ships. |
| Owner | Everything, including deleting the team. Only the instance maintainer. |
Admins of Root Team are effectively admins of the whole instance: there is no per-project permission wall, and anyone with Admin can change or delete anyone's resources. Treat Admin as "trusted to be careful".
Changing someone's role, or removing them from the team, revokes all of their API tokens for the team, so their agents lose access at the same time.
3. Inviting people (admins)
- Open Team in the sidebar (
/team) → Members. - Under Invite a member, enter their email and choose Admin (can ship) or Member (read-only).
- Click Generate link and send them the link yourself, ideally in a direct message. Send email does not work here because email is not configured.
- Pending links are listed on the same page until they are used or expire (3 days).
New emails get a fresh account that must set a password on first use; existing accounts are simply added to the team. To change a role use the dropdown next to the person; to remove them use Remove.
4. Deploying an app
Pick a source
| Your code is… | Choose | Push-to-deploy |
|---|---|---|
In the scottylabs-labrador org (private or public) |
Git Repository (with GitHub App) → sheltie-scottylabs |
Automatic |
| Any other public GitHub repo | Public Git Repository | Add a webhook (below) |
| A private repo elsewhere (e.g. your personal account) | Private Git Repository (with Deploy Key) | Add a webhook (below) |
| Already a container image | Docker Image | Redeploy from the UI or API |
| Several services | Docker Compose | Depends on the source |
If your repo isn't in the org, consider transferring it there; the GitHub App path is by far the easiest.
Deploy key, for a private repo outside the org: create an SSH key in Keys & Tokens → Private Keys (Coolify can generate one), add its public half to the repo under GitHub → Settings → Deploy keys (read-only), then choose that key when you add the resource.
Webhook, for push-to-deploy without the GitHub App: in the app open Webhooks, set a secret in the GitHub section, and add its Webhook URL in GitHub → Settings → Webhooks with content type application/json, the same secret, and just the push event.
Build
- Dockerfile (recommended): put a
Dockerfilein the repo and choose the Dockerfile build pack. Predictable and cache-friendly. - Nixpacks: auto-detects common stacks (Node, Python, Go, static sites…). Fine for simple apps.
- Monorepo? Set Base Directory to the app's folder, and Watch paths (for example
web/**) so unrelated pushes don't redeploy it.
Keep builds light. The server has one CPU; a 10-minute Next.js build slows everyone down. Building an image in GitHub Actions and deploying it as a Docker Image is a good option for heavy projects.
Configure
- Ports exposes: the port your app listens on inside the container (
3000,8080,80…). - Listen on all interfaces. Bind to
0.0.0.0, or better::(IPv4 and IPv6), not127.0.0.1. Health checks callhttp://localhost:<port>, which can resolve to IPv6. - Healthcheck: point it at a cheap endpoint such as
/healthzthat returns 200. - Resource Limits → Memory limit: always set one.
64mfor a static site,128mto256mfor most apps, more only if you have measured it. - Persistent Storage: anything written inside a container disappears on redeploy. Mount a volume (for example at
/data) for files you need to keep, or use a database. - Domains: any
https://<name>.sheltie.scottylabs.orgworks with no DNS setup. For your own domain, point an A record at the server and add it here.
Environment variables and secrets
Add them under Environment Variables. Each variable has a Build time and a Runtime setting. For secrets (API keys, database passwords, tokens) choose Not available during build so they are not baked into the image or printed in build logs. Only things your build genuinely needs, like public URLs for a frontend bundle, should be available during build.
Databases
+ New Resource → Databases gives you PostgreSQL, MySQL, MariaDB, MongoDB, Redis and others.
- Databases are private to the server by default. Apps reach them through the internal URL on the database page.
- Turn on Public access only if you really need outside access, and use a strong password.
- Set a memory limit (
256mis plenty for a small Postgres). - Schedule backups on the database's Backups tab. They are stored on the same server, so also keep your own exports of anything you can't lose.
Clean up
When you are done with something, delete it and leave "delete volumes" checked. Orphaned volumes are how the disk quietly fills up.
5. API tokens (for MCP, CLI, and the API)
Tokens are personal, tied to the team you are in when you create them, and shown only once.
- Check that the team switcher shows Root Team, then open Keys & Tokens → API tokens (
/security/api-tokens). A token made in your personal team sees nothing. - Name it after where it will live, for example
claude-code-laptop. - Pick the fewest permissions that work:
| Permission | Allows |
|---|---|
read |
List and inspect resources. Secrets are redacted. |
read:sensitive |
Also see env values, passwords, logs, private keys. Admin only. |
deploy |
Trigger deploys, restarts, stops. Admin only. |
write |
Create, update, delete resources. Admin only. |
root |
Skip permission checks (still limited to the team). Admin only. |
- Click Create and copy the token right away.
A token reaches every project in Root Team, not just yours, so keep agents on read + deploy and tell them which project they work on. Add write only if the agent must create apps or edit configuration. Treat tokens like passwords: never commit them, and revoke them on the same page when you are done.
6. MCP: let your AI agent operate Sheltie
Coolify serves MCP over Streamable HTTP with the same team scope and permissions as your token, redacting secrets unless the token has read:sensitive.
Claude Code
claude mcp add --transport http sheltie https://sheltie.scottylabs.org/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
Ask it to run get_current_team or get_infrastructure_overview to confirm it sees Root Team.
Cursor, Windsurf, and other MCP clients (~/.cursor/mcp.json or the project's .cursor/mcp.json for Cursor):
{
"mcpServers": {
"sheltie": {
"url": "https://sheltie.scottylabs.org/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}
A read token exposes inspection tools such as list_applications, get_application, list_databases, list_deployments, and get_logs. Deploy and lifecycle tools appear with deploy; create and update tools need write.
7. CLI
brew install coollabsio/coolify-cli/coolify-cli
# or: curl -fsSL https://raw.githubusercontent.com/coollabsio/coolify-cli/main/scripts/install.sh | bash
coolify context add sheltie https://sheltie.scottylabs.org YOUR_TOKEN
coolify context use sheltie
coolify context verify
coolify project list
coolify app list
coolify deploy # deploy by uuid or the app linked to this directory
The CLI keeps your token in ~/.config/coolify/config.json; keep that file private.
8. REST API
Same token, as a Bearer header:
curl -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" \
https://sheltie.scottylabs.org/api/v1/applications
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"uuid": "APP_UUID"}' https://sheltie.scottylabs.org/api/v1/deploy
Reference: https://coolify.io/docs/api/overview. Bad or revoked tokens get 401; a request beyond the token's permissions gets 403 naming the missing permission.
9. Troubleshooting
| Symptom | Cause / fix |
|---|---|
| "Invitation has expired or been revoked" | The link is older than 3 days or was already used. Ask an admin for a new one. |
| Forgot password | Ask an admin for a one-time password (no email on this instance). |
| Empty dashboard or a "connect a server" wizard | You are in your personal team. Switch to Root Team. |
| Everything is greyed out or denied | You are a Member (read-only). Ask an admin for Admin. |
| "Your connection is not private" on a new domain | The certificate is still being issued. Wait 30 seconds and reload. |
Bad Gateway / no available server |
Ports exposes doesn't match the port your app listens on, or it listens on 127.0.0.1. |
| Deploy stuck on "waiting for healthcheck" | The health check path doesn't return 200, or the app doesn't listen on ::/0.0.0.0. |
| Deploy killed or the server feels slow | Out of memory. Set memory limits and delete unused resources, volumes included. |
| My token can't deploy or create | It lacks deploy/write, or you are a Member; tokens can't exceed your role. |
| Agent connects but sees no projects | The token was created in your personal team. Switch to Root Team and create a new one. |
401 Unauthenticated from API or MCP |
Token wrong or revoked (role changes and removals revoke tokens). Create a new one. |
Your kernel does not support memory swappiness in logs |
Harmless on this host. |
Stuck? Ask a Sheltie admin, and include your project and app name.
Edit this guide: scottylabs-labrador/sheltie. Pushes to main redeploy https://docs.sheltie.scottylabs.org.
Updated 2026-10-10