Setup

This page covers everything needed to get a remote coast running: preparing the remote host, deploying coast-service, registering the remote, and running your first remote coast.

Host Requirements

Requirement Why
Docker Runs coast-service and DinD containers
GatewayPorts clientspecified in sshd_config Allows SSH reverse tunnels for shared services to bind on all interfaces, not just localhost
Passwordless sudo for SSH user The daemon uses sudo rsync and sudo chown for workspace file management (remote workspace directories may be owned by root from coast-service operations)
Bind mount for /data (not a Docker volume) The daemon rsyncs files to the host filesystem via SSH. Named Docker volumes are isolated from the host filesystem and invisible to rsync
50 GB+ disk Docker images exist on host Docker, in tarballs, and loaded into DinD containers. See disk management for details
SSH access The daemon connects to the remote via SSH for tunnels, rsync, and coast-service API access

Prepare the Remote Host

On a fresh Linux machine (EC2, GCP, bare metal):

# Install Docker and git
sudo yum install -y docker git          # Amazon Linux
# sudo apt-get install -y docker.io git # Ubuntu/Debian

# Enable Docker and add your user to the docker group
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $(whoami)

# Enable GatewayPorts for shared service tunnels
sudo sh -c 'echo "GatewayPorts clientspecified" >> /etc/ssh/sshd_config'
sudo systemctl restart sshd

# Create the data directory with correct ownership
sudo mkdir -p /data && sudo chown $(whoami):$(whoami) /data

Log out and back in for the docker group change to take effect.

Deploy coast-service

Clone the repository and build the production image:

git clone https://github.com/coast-guard/coasts.git
cd coasts && git checkout <branch>
docker build -t coast-service -f Dockerfile.coast-service .

Run it with a bind mount (not a Docker volume):

docker run -d \
  --name coast-service \
  --privileged \
  -p 31420:31420 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /data:/data \
  coast-service

Verify it is running:

curl http://localhost:31420/health
# ok

Why --privileged

coast-service manages Docker-in-Docker containers. The --privileged flag grants the container the capabilities needed to run nested Docker daemons.

Why bind mount, not Docker volume

The daemon rsyncs workspace files from your laptop to the remote host via SSH. Those files land on the host filesystem at /data/workspaces/{project}/{instance}/. If /data were a named Docker volume, the files would be isolated inside Docker's storage and invisible to coast-service running inside the container.

Use -v /data:/data (bind mount), not -v coast-data:/data (named volume).

Register the Remote

On your local machine:

coast remote add my-vm ubuntu@10.0.0.1 --key ~/.ssh/my_key

With a custom SSH port:

coast remote add my-vm ubuntu@10.0.0.1:2222 --key ~/.ssh/coast_key

Test connectivity:

coast remote test my-vm

This verifies SSH access, checks that coast-service is reachable on port 31420 over the SSH tunnel, and reports the remote's architecture and coast-service version.

Build and Run

# Build on the remote (uses the remote's native architecture)
coast build --type remote

# Run a remote coast instance
coast run dev-1 --type remote

After this, all standard commands work:

coast ps dev-1                              # service status
coast exec dev-1 -- bash                    # shell into remote DinD
coast logs dev-1                            # stream service logs
coast assign dev-1 --worktree feature/x     # switch worktree
coast checkout dev-1                        # canonical ports → dev-1
coast ports dev-1                           # show port mappings

Multiple Remotes

You can register more than one remote machine:

coast remote add dev-server ubuntu@10.0.0.1 --key ~/.ssh/key1
coast remote add gpu-box   ubuntu@10.0.0.2 --key ~/.ssh/key2
coast remote ls

When running or building, specify which remote to target:

coast build --type remote --remote gpu-box
coast run dev-1 --type remote --remote gpu-box

If only one remote is registered, it is selected automatically.

Local Dev Setup

For developing coast-service itself, use the dev container which includes DinD, sshd, and cargo-watch hot reload:

make coast-service-dev

Then register the dev container as a remote:

coast remote add dev-vm root@localhost:2222 --key $(pwd)/.dev/ssh/coast_dev_key
coast remote test dev-vm

Use absolute paths for the --key flag.