Skip to Content
Greyship Docs

Install Greyship (self-hosting)

Put Greyship itself on your own server with one command.

Greyship is open source (AGPL-3.0) and made to run on a server you own. One server runs everything: the API, the dashboard, the builder, the sandboxes your apps run in, and the router that gives them HTTPS.

Early software

Greyship is young. It runs real apps, but expect rough edges, and it's a single server for now (no high availability). Keep backups of anything that matters.

What you need

  • A fresh Ubuntu 22.04 / 24.04 or Debian 12 server, x86_64 or arm64, with root access.
  • 4 GB of RAM or more (2 GB runs it, but builds on the server need room). The apps you deploy share what's left.
  • Ports 80, 443 and 8000 free. That is all you need to start: no domain is required.

Run it on its own server, or free these ports first

Greyship's router takes ports 80 and 443 for itself, because every app and the dashboard are served through it. If something else on the server already uses them (nginx, Apache, Caddy, Traefik, Coolify, another panel), the installer stops and tells you which program it is. Two programs can't share a port, and Greyship also runs its own firewall rules and Docker networks, so the safest setup is a server that only runs Greyship. If you must share, stop the other program, or put it on different ports, before installing, and expect its sites to stop answering on 80 and 443.

Install

On the server, as root:

curl -fsSL https://greyship.tech/install | sudo sh

(https://greyship.tech/install redirects to the installer in the repository, deploy/install/install.sh; you can fetch that file directly from github.com/greylabss/greyship if you prefer.)

It installs Docker, gVisor, Postgres, an S3-compatible store (Garage) and Node.js, downloads the release and checks its checksums, generates every secret into /etc/greyship (readable by root only), sets Greyship up as systemd services, and turns on a firewall for SSH and the ports above.

When it finishes, the dashboard is at http://<your server's IP>:8000. Apps you deploy get free addresses like http://<name>.apps-<ip>.sslip.io. This is plain HTTP, so passwords and tokens are not encrypted yet: fine to try it out, not for real use. To make it real, add a domain (below).

To say who the owner is up front, add --email you@example.com: then only that email can create the first account.

First visit

Open the dashboard. A new Greyship has no accounts, so you see Create the owner account. Pick an email and a password. That account is the owner and an admin. It works once: after that nobody can sign themselves up.

Adding people

Open Admin → Users → Add user. Give an email, a name and a password (or press Generate), and tick Admin if they should manage the instance too. Send them the address and their password yourself; they can change it in Settings.

Per user you can also:

  • Limits: how much memory, how many CPU cores and how many builds at once their apps may use together. Leave a field empty for no limit. A deploy that would pass a limit fails with a message saying which, and the version that is live keeps running. A deploy briefly runs the old and the new version side by side, so leave some room.
  • Reset password and Make admin / Remove admin. There is always at least one admin.

To add many people at once, put their emails in a file, one per line, and run sudo greyship-admin add-users emails.txt. It asks for one password for all of them (tell them to change it in Settings) and skips anyone who already has an account.

Forgot a password?

Nobody gets an email. On the server, as root:

sudo greyship-admin password someone@example.com

It prints a new random password once and signs that account out everywhere. A saved password can't be shown (only a fingerprint of it is stored), so this sets a new one. With no email it resets the owner's. reset-password is the same command.

Add a domain (HTTPS)

You need two domains (or subdomains of two domains) you can add DNS records to: one for the dashboard, like greyship.example.com, and one for your apps, like example.net, where each web service gets <service>-<project>.example.net. Use a different registrable domain for apps than for the dashboard if you can: browsers then treat them as separate sites, so an app can't act as the dashboard.

sudo greyship-admin domain greyship.example.com example.net you@example.com

It switches the dashboard, the API, uploads and your apps to those domains with HTTPS and prints the DNS records to add:

RecordNameFor
Agreyship.example.comthe dashboard
A*.greyship.example.coms3.… (uploads) and api.…
A*.example.netyour apps

Certificates come from Let's Encrypt, automatically, the first time each name is visited, once DNS answers. Sign in again afterwards (sessions don't carry over). You can also give the installer the domains from the start: ... | sudo sh -s -- --domain greyship.example.com --apps-domain example.net --email you@example.com.

Use it

On your computer:

curl -fsSL https://greyship.tech/cli/install | sh
grey login https://greyship.example.com
cd my-go-project
grey deploy

grey remembers the server, so every later command talks to it. grey whoami shows which one. To use another Greyship again, run grey login <its address>.

Connecting GitHub

Everyone connects their own GitHub, with their own GitHub App, so nobody needs the server's admin for it. In the dashboard, open New project (or Settings → GitHub) and press Create GitHub App. You can name it and give an organisation to own it. You confirm on GitHub and come straight back; Greyship stores the app's keys encrypted. Then install the app on the repositories you want from New project → Import from GitHub.

GitHub can only tell Greyship about pushes if the dashboard's address is reachable from the internet. On a private or localhost address the page warns you: importing and Deploy latest still work, but pushes won't deploy by themselves. Add a domain (above) for push-to-deploy.

Turning on email

Email is optional and only sends deploy notifications (a deploy succeeded or failed, a project was created). Signing in never needs it. You turn it on in the dashboard, no config file needed:

  1. Create a Resend account, add your domain there and verify it.
  2. Create an API key in Resend.
  3. In Greyship open Admin → Email, paste the key, enter the domain (for example mail.example.com), tick Send email, and press Save.
  4. Press Send test email. It goes to your own address and shows Resend's error if something is wrong (usually an unverified domain).

The key is stored encrypted and is never shown again. Mail comes from notifications@ your domain. Without email, deploy notifications still appear in the bell and as browser notifications.

Keeping it running

greyship-admin status          # is every service up
greyship-admin logs api        # follow a service's log (api, builder, scheduler, agent, router, dashboard)
greyship-admin upgrade         # install the latest release (keeps your settings and data)
greyship-admin password <email>   # a forgotten password

Settings live in /etc/greyship/greyship.env; restart with systemctl restart greyship-api greyship-builder greyship-scheduler greyship-agent greyship-router.

Upgrading

greyship-admin upgrade

keeps your settings and data, and writes a backup to /var/backups/greyship first (the newest 5 are kept). To update the CLI on your computer, run grey upgrade. Reinstalling by running the install command again does the same thing: it never wipes an existing install.

Backups and moving to a new server

sudo greyship-admin backup            # one file in /var/backups/greyship (or give a folder)

The file holds your accounts, projects, deployments and env vars and your secrets, the master key included: keep it private and copy it off the server. To move, or to start over on a clean machine:

# on the new server: install Greyship (same version or newer), then
sudo greyship-admin restore greyship-v0.1.2-20261107-013345.tar.gz

A restore replaces what is on that server with the backup, so it asks you to type yes. Built binaries and uploaded sources are not in the file (redeploy a project to run it again), and neither are domain settings (run greyship-admin domain again).

The older way, by hand:

Back up these two things:

  • /etc/greyship. It holds the master key that unlocks every stored env var. Lose it and the stored values can't be read.

  • The database:

    docker compose -p greyship -f /usr/local/lib/greyship/compose.yml exec -T postgres \
      pg_dump -U greyship -Fc greyship > greyship-$(date +%F).dump

Built binaries and uploaded sources live in the greyship-garage Docker volume. They're needed for rollbacks, not for redeploying: any project can be deployed again from its source.

Good to know

  • No plans, no billing. Everyone on the instance can build and run as much as the server allows, unless you limit them.
  • Builds run on your server inside gVisor. (Greyship can also build on Fly.io machines; that is an advanced setting.)
  • GitHub is connected by each person with one click (see below). Importing a public repository by link works without it.

Uninstall

systemctl disable --now greyship-dashboard greyship-router greyship-agent greyship-scheduler greyship-builder greyship-api greyship-infra greyship-firewall
docker compose -p greyship -f /usr/local/lib/greyship/compose.yml down -v   # deletes the database and stored binaries
rm -rf /usr/local/lib/greyship /etc/greyship /etc/systemd/system/greyship-*.service /usr/local/bin/greyship-admin

Security notes

  • Every app runs in a gVisor sandbox with its own network: it can reach the internet, but not other apps, the server, or Greyship's own services.
  • The server runs other people's code, so keep it patched, keep SSH locked down (keys, no passwords), and don't turn off AppArmor.
  • Found a vulnerability? Report it privately through the repository's Security tab.

On this page