Rove

Menu

Rove is a tool for self-hosting on Linux. It ships as a single binary which provisions machines and deploys containers directly to them via SSH.

rove machine add <name> <user> <ip> ~/.ssh/id_ed25519

Connected to remote address '<user>@<ip>'.

Rove will make the following changes to remote machine:

 ~ Enable firewall
 ~ Install docker
 ~ Enable swarm

Do you want Rove to run this deployment?
  Type 'yes' to approve, or anything else to deny.
  Enter a value: yes

sudo ufw logging on Logging enabled

sudo ufw allow 22/tcp Rules updated
Rules updated (v6)

sudo ufw enable Firewall is active and enabled on system startup

~ Enabled firewall
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ca-certificates curl >/dev/null
+ sh -c install -m 0755 -d /etc/apt/keyrings
+ sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" -o /etc/apt/keyrings/docker.asc
+ sh -c chmod a+r /etc/apt/keyrings/docker.asc
+ sh -c echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null
+ sh -c docker version
~ Installed docker
~ Enabled swarm

Setup '<name>' and set as default machine.
Next

Under the hood, Rove just setup a standard docker installation with a firewall. No proprietary or closed-source technology is ever deployed to the server. Rove does not collect telemetry. All client configuration is saved locally in a .rove file, which does not need to be synced to deploy from other workstations, CI, etc.

Next, let's deploy a python container to host a simple file server. We'll use a service for this, because we want it to run indefinitely.

Next
rove service run files --publish 80:80 python:3.12 \
  python3 -m http.server 80

Rove will create files:

 + service files:
 +   command  = ["python3","-m","http.server","80"]
 +   image    = "python:3.12"
 +   publish  = ["80:80"]
 +   replicas = "1"

Do you want Rove to run this deployment?
  Type 'yes' to approve, or anything else to deny.
  Enter a value: yes

Deploying...

Rove deployed 'files'.
Next

By default, containers are not exposed to each other on the docker network. Let's create a docker network, so that other containers may connect to our files service.

rove network add fileshare

Rove will create the 'fileshare' network.

Do you want Rove to run this deployment?
  Type 'yes' to approve, or anything else to deny.
  Enter a value: yes

Created 'fileshare' network.
Next

Rove diffs the options you provide against what is actually running, so you can see exactly how changes will impact services before updating.

rove service run files --publish 80:80 \
  --network fileshare \
  python:3.12 python3 -m http.server 80

Rove will update files:

 ~ service files:
     command  = ["python3","-m","http.server","80"]
     image    = "python:3.12"
 +   network  = ["fileshare"]
     publish  = ["80:80"]
     replicas = "1"

Do you want Rove to run this deployment?
  Type 'yes' to approve, or anything else to deny.
  Enter a value: yes

Deploying...

Rove deployed 'files'.
Next

Let's ping the server and then read the logs.

curl -v <ip>
rove logs files --follow
10.0.0.2 - - [30/Jun/2024 02:13:22] "GET / HTTP/1.1" 200 -
^C
Next

Run one-off tasks. Connect to other services on the network with DNS.

rove task run --network fileshare alpine/curl curl files

Rove will deploy:

 + task:
 +   command  = ["curl","files"]
 +   image    = "alpine/curl"
 +   network  = ["fileshare"]
 +   replicas = "1"

Do you want Rove to run this deployment?
  Type 'yes' to approve, or anything else to deny.
  Enter a value: yes

Deploying...

Rove deployed task: <id>