Install Shipwick on a server
This page is for whoever administers the server. It covers the installer, what it puts on the machine, the API token, DNS and firewall, and the ways to install without it.
Before you begin
You need:
- A Linux server, and root on it.
- Docker, installed and running, with the Compose plugin. The installer does not install Docker; that decision belongs to the server's owner. If Docker is missing, the installer stops and points you to
curl -fsSL https://get.docker.com | sh. curlorwget.- Ports 80 and 443 free on the server and reachable from the internet. Automatic HTTPS depends on them.
- Optionally, two DNS names that point at the server: one for the API, one for the dashboard. Every application you give a
domainlater needs a DNS record too.
Run the installer
On the server, as root:
curl -fsSL https://get.shipwick.com | shThe installer asks two questions. Both are optional; press Enter to skip either.
| Question | Stored as | Effect |
|---|---|---|
| Hostname for the API, used by the shipwick CLI | SHIPWICK_AGENT_DOMAIN | The agent's API is served over HTTPS at this hostname, through Caddy |
| Hostname for the dashboard | SHIPWICK_DASHBOARD_DOMAIN | The dashboard is served over HTTPS at this hostname, through Caddy |
Give bare hostnames such as agent.example.com: no https://, no port, no path. The two must be different. Hostnames are validated before anything is written.
Without a terminal, the installer asks nothing and takes the hostnames from the environment:
curl -fsSL https://get.shipwick.com | SHIPWICK_AGENT_DOMAIN=agent.example.com SHIPWICK_DASHBOARD_DOMAIN=dashboard.example.com shThe output looks like this:
Shipwick installer (shipwick/shipwick@latest)
✓ Docker 29.8.0 with Compose 5.5.1
✓ Installed /opt/shipwick/compose.yml
✓ Wrote /opt/shipwick/.env
✓ Started the Shipwick services
✓ The agent is healthy
✓ Installed the shipwick CLI to /usr/local/bin/shipwick
Shipwick is running.
API token (also in /opt/shipwick/.env — it is root on this server, treat it so):
<64 hexadecimal characters>
From your laptop or CI: shipwick login --url https://agent.example.com
Dashboard: https://dashboard.example.com
Open ports 80 and 443 (and 443/udp) — and nothing else — in your firewall.
Upgrade later by running this installer again.What the installer does
- Checks for Linux, root, a running Docker and the Compose plugin.
- Writes
/opt/shipwick/compose.yml. This is the release'scompose.production.yml, in which both Shipwick images are pinned to the release's version. The file is verified against the release'schecksums.txtbefore it replaces anything. - On the first run only, writes
/opt/shipwick/.envwith a freshly generated API token and the two hostnames. The file has mode0600and the directory0700. - Pulls the images, starts the services, and waits for the agent to report healthy.
- Installs
shipwickto/usr/local/bin, verified the same way. A checksum mismatch installs nothing and leaves a running installation as it was. - Prints the token and the next steps.
Three containers run afterwards, defined in /opt/shipwick/compose.yml:
| Service | What it is |
|---|---|
agent | The Shipwick agent. It has the Docker socket mounted and publishes no port: the only ways in are Caddy and the server itself. |
caddy | The reverse proxy. It publishes ports 80 and 443 (TCP) and 443 (UDP), and obtains and renews certificates on its own. |
dashboard | The web dashboard. It is reached only through Caddy, at the dashboard hostname, and has no credentials of its own. |
State lives in Docker volumes: the agent's SQLite database in agent-data, certificates in caddy-data. Back up caddy-data and do not delete it casually.
The installer accepts these environment variables:
| Variable | Default | |
|---|---|---|
SHIPWICK_VERSION | latest | Release to install |
SHIPWICK_AGENT_DOMAIN | — | Hostname for the API; asked for when run in a terminal |
SHIPWICK_DASHBOARD_DOMAIN | — | Hostname for the dashboard; likewise |
SHIPWICK_INSTALL_DIR | /opt/shipwick | Where compose.yml and .env are written |
SHIPWICK_BIN_DIR | /usr/local/bin | Where shipwick is installed |
The API token
The installer generates the token and prints it once, in the run that created it. It is also in /opt/shipwick/.env.
The token is root on the server
The agent controls the Docker daemon, and whoever controls the Docker daemon controls the host. Treat the API token like root SSH access to the server: keep it in a password manager or a CI secret, and keep /opt/shipwick/.env private.
The agent itself keeps only the SHA-256 of the token. Read Security for the full picture.
DNS and firewall
Point DNS at the server for the API hostname, the dashboard hostname, and the domain of every application you deploy. Caddy obtains a certificate for a hostname once its DNS record resolves to the server and ports 80 and 443 are reachable.
In your firewall, open ports 80 and 443 (and 443/udp, for HTTP/3), and nothing else. The agent's own port, 9000, speaks plain HTTP and must never be exposed to the internet.
If you skipped the API hostname, the API is not exposed at all. See Reach the API without a hostname.
Install a specific version
Everything the installer fetches comes from one release — never from a branch — and each file is verified against that release's checksums. By default that is the latest release. To choose one:
curl -fsSL https://get.shipwick.com | SHIPWICK_VERSION=v0.1.0 shBecause the images are pinned in the compose file, a server runs the version it installed until you run the installer again. That is also how you upgrade.
Other ways to install
The compose file, by hand
The installer's setup is one file, configs/compose.production.yml, plus a .env next to it:
SHIPWICK_AGENT_TOKEN=<output of: openssl rand -hex 32>
SHIPWICK_AGENT_DOMAIN=agent.example.com
SHIPWICK_DASHBOARD_DOMAIN=dashboard.example.comdocker compose -f compose.production.yml up -dGenerate the token yourself, as shown. The token must be at least 16 characters. If you let the agent generate one, it prints it to its log, and under Docker that log stays readable through docker logs for as long as the container exists.
The compose file attached to a release pins both images to that release. The copy in the repository refers to latest.
From source
Build the images on the server from a checkout of the repository, then run the installer from that checkout. It uses the compose file next to it instead of downloading one.
docker build -t ghcr.io/shipwick/agent .
docker build -t ghcr.io/shipwick/dashboard dashboard/
sh scripts/install.shBuild the CLI with make build.
A plain binary, next to a Caddy on the host
The agent also runs as a plain binary on Linux, built with make build, next to a Caddy installed on the host. Point the agent at Caddy's admin endpoint:
SHIPWICK_CADDY_ADMIN=http://127.0.0.1:2019The agent listens on 127.0.0.1:9000 by default and keeps its data in /var/lib/shipwick. All variables are listed in Agent configuration.
What's next
- Install the CLI on your laptop.
- Deploy your first application.
- Open the dashboard.