Skip to content
Trailer.devDocumentation

Installation Guide

Trailer.dev ships as as pre-built binaries.

  • There are binaries available for Linux, Windows and macOS (Darwin) for the server component.
  • There are binaries available for Linux and Windows for the agent component.
  • There are binaries available for Linux and Windows for the standalone mode.

Trailer.dev binaries are pre-built for arm64 and amd64 architectures.

All pre-built binaries are signed by our minisign key. The public part can be found in our Community repository.

Trailer.dev also ships as an OCI image.

  • There images based on an Alpine base image for our standalone, agent and server components.

All official OCI images are signed by cosign and can be verified with our public cosign key found in our Community repository.

Trailer runs in one of three modes:

  • Standalone: server and Docker agent in one process. Easiest single-host setup.
  • Server: the API, database, and web UI only. Pair it with one or more remote agents.
  • Agent: connects to a server and reconciles workspaces against a container runtime.

The standalone and agent deployments require a Docker unix socket. See the Architecture Overview for how the pieces interact.

The published images are standalone, server, and agent.

  1. Pull the standalone image:

    Terminal window
    docker pull ghcr.io/trailer-dev/standalone:latest
  2. Run it. The agent talks to the host Docker daemon, so mount the socket. Mount a volume for the database so data survives restarts:

    Terminal window
    docker run -d \
    --name trailer \
    -p 8090:8090 \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v trailer_data:/trailer_data \
    ghcr.io/trailer-dev/standalone:latest

The web interface listens on port 8090 by default. Both the host and the port (as well as the app’s public URL) can be configured. Check the configuration reference for supported configuration keys and their default values.

For a persistent setup it is often easier to describe the deployment in a docker-compose.yml file. Pick the tab that matches your deployment mode:

An agent connects to a remote server and manages workspace containers on its host. Point -S at the server URL you control, and give the agent its own name with -D.

services:
trailer:
image: ghcr.io/trailer-dev/agent:latest
container_name: "trailer"
restart: unless-stopped
command: -S "https://your-domain.example" -D your-agent-name
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/traefik/config:/traefik
- ./config.yml:/.config/trailer/config.yml
- /etc/machine-id:/etc/machine-id

Start the stack with:

Terminal window
docker compose up -d

command: passes startup flags to the process. -S sets the server address. On a server or standalone process it is the address to bind to: http://0.0.0.0:8090 exposes the web interface on the host’s network interfaces (not only from inside the container) on port 8090. On an agent it is instead the URL of the server to connect to, a domain you control. The agent and standalone modes also take -D to name the agent as it appears in the instance.

  • /trailer_data (server and standalone): the persistent data directory. It holds the platform’s database, uploaded files, and other state. Keep this on durable storage so nothing is lost when the container is recreated. Replace /path/to/trailer_data with a real path on your host.
  • /var/run/docker.sock (agent and standalone): the host’s Docker socket. The built-in agent needs it to create and manage workspace containers on the host.
  • config.yml (all modes): the static process configuration file. Mounting your own config.yml lets you set options such as the public URL and directories. See the Configuration Reference for the available keys.
  • machine-id (agent and standalone): a small file that gives the agent a stable identity. It is the standard /etc/machine-id file used by Linux systems. On a fresh container this identity is generated randomly, so recreating the container would otherwise register a brand-new host and leave the previous one behind. Mounting a persistent machine-id file keeps the identity stable, so after a recreation the agent re-registers as the same host instead of appearing as a new one.
  • /traefik (agent and standalone): optional. Only include this mount if you run a separate, external Traefik instance and want the platform to share routing configuration with it. If you do not, omit this line entirely.

By default the container runs as root. If you prefer, you can run it as your own user instead. Start the container with your host user id and group id, and add the host’s docker group so the process can still reach the Docker socket.

Runtime:

Terminal window
docker run -it --rm \
-u $(id -u):$(id -g) \
--group-add $(getent group docker | cut -d ':' -f 3) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ./config:/.config \
-v ./cache:/.cache \
-v ./trailer_data:/trailer_data \
ghcr.io/trailer-dev/standalone:latest

Compose:

# Export the docker group id first:
# export DOCKER_GROUP_ID=$(getent group docker | cut -d ':' -f 3)
services:
trailer:
image: ghcr.io/trailer-dev/standalone:latest
user: "${UID}:${GID}"
group_add:
- ${DOCKER_GROUP_ID}
volumes:
- ./trailer_data:/trailer_data
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/.config
- ./cache:/.cache

What each part does:

  • -u $(id -u):$(id -g) (or user: in Compose) runs the container as your own user id and group id instead of root.
  • The container still needs the Docker socket to manage workspace containers. The socket is owned by the host’s docker group, so add that group to the container with --group-add (runtime) or group_add: (Compose). getent group docker | cut -d ':' -f 3 reads the numeric id of that group on your host.
  • The mounted config, cache, and data directories must be writable by that user id on the host. Create them ahead of time and make sure your user owns them.

Each release publishes archives for the standalone, server, and agent builds (Linux, macOS, and Windows where applicable; amd64 and arm64).

  1. Download the archive for your platform from the GitHub releases page. Archives are named like trailer-standalone-linux_amd64, trailer-server-..., and trailer-agent-.... The binary inside is named trailer.

  2. Move it onto your PATH:

    Terminal window
    sudo mv trailer /usr/local/bin/
  3. Run it:

    Terminal window
    trailer

If you installed the binary (see above), you can run Trailer as a background service managed by systemd. Create a unit file at /etc/systemd/system/trailer.service. Pick the tab that matches your deployment mode:

An agent connects to a remote server. Set -S to a server URL you control, and give the agent its own name with -D.

/etc/systemd/system/trailer.service
[Unit]
Description=Trailer Agent
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/trailer -C /home/youruser/.config/trailer.dev/config.yml -D your-agent-name -S https://your-domain.example
WorkingDirectory=/tmp
Restart=on-failure
RestartSec=5
User=youruser
Group=youruser
[Install]
WantedBy=multi-user.target

Adjust the example values for your setup:

  • -C is the path to the configuration file.
  • -S is the server URL. For an agent it is the address of the server to connect to, such as https://your-domain.example (use a domain you control). For a server or standalone process it is the address to bind to, such as http://0.0.0.0:8090.
  • -D (agent and standalone modes) is the agent’s name as it appears in the connected instance. Choose your own name here.
  • User and Group should be your own system user and group.
  • Replace /home/youruser/... with the real path to your configuration file.

Then reload systemd, enable the service, and start it:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now trailer

Runtime config is read from ~/.config/trailer.dev/config.yml (XDG config home). The file is created with defaults on first run if it does not exist. Every value can be overridden by a CLI flag or environment variable.

Common options (see trailer --help):

  • --server-url (default http://localhost:8090): address the server listens on, and the address the agent connects to.
  • --deployment-name: name shown for this agent in the connected instance (defaults to the hostname).
  • --data-directory (default trailer_data): directory for the database.
  • --build-directory (default /tmp): where the agent builds images.

For the complete list, see the Configuration Reference.

  1. Check the container is running:

    Terminal window
    docker ps | grep trailer
  2. Inspect the logs:

    Terminal window
    docker logs trailer
  3. Open http://localhost:8090 in a browser. A fresh instance redirects you to the first user setup page.