seminar recap

Shipping a tiny server with systemd, then automating it away

A few of the closing steps got rushed for time, so here's the full sequence again — from a manual curl → chmod → systemd setup to the one-line install script that replaces all of it.

what we did by hand

The manual setup

Before writing any automation, this is the sequence we ran ourselves to get the server running as a proper background service.

  1. Download the binary — fetched it directly with curl.
  2. Make it executable — so the shell is allowed to run it as a program.
  3. Write a systemd service file — so the server auto-starts on boot and auto-restarts after a crash or reboot.
  4. Reload the systemd daemon — so systemd picks up the new unit file.
  5. Enable and start the service — enable registers it for boot, start runs it now.

Doing this manually is fine for a single machine, but becomes tedious when deploying to hundreds of systems — which is exactly the problem a shell script solves.

install.sh

Automating it with a bash script

Bash is the default scripting language of the shell on most Linux distributions, which makes it the natural choice for a portable install script. The one written here does a bit more than we covered in class — here's the full thing.

infra/install.sh
#!/bin/bash
set -e
USER_NAME="cowserver"
BINARY_URL="https://github.com/Leon-raj/cowsay-server/releases/download/v0.1/cowserve"
SERVICE_URL="https://github.com/Leon-raj/cowsay-server/releases/download/v0.1/cows.service"
echo "==> Creating system user..."
if ! id -u "$USER_NAME" >/dev/null 2>&1; then
sudo useradd --system --no-create-home \
--shell /usr/sbin/nologin "$USER_NAME"
fi
echo "==> Downloading cowserver..."
sudo curl -fsSL "$BINARY_URL" -o /usr/local/bin/cowserver
sudo chmod 755 /usr/local/bin/cowserver
sudo chown root:root /usr/local/bin/cowserver
echo "==> Downloading systemd service..."
sudo curl -fsSL "$SERVICE_URL" -o /etc/systemd/system/cows.service
sudo chmod 644 /etc/systemd/system/cows.service
sudo chown root:root /etc/systemd/system/cows.service
echo "==> Reloading systemd..."
sudo systemctl daemon-reload
echo "==> Enabling service..."
sudo systemctl enable cows
echo "==> Starting service..."
sudo systemctl restart cows
systemctl --no-pager --full status cows

Three things it adds beyond what we discussed live:

  1. It creates a dedicated system user (cowserver) to run the service as. This is best practice — if the service is ever compromised, the attacker is confined to that low-privilege user instead of the whole system.
  2. It sets permissions numerically (755 for the binary, 644 for the service file). I'll get into what those numbers mean in the next class if I get a chance.
  3. It then runs the same systemctl commands we already covered — daemon-reload, enable, and restart — just scripted instead of typed by hand.
try it yourself

Reset, then reinstall

First, tear down the service we installed manually earlier in class:

bash
$ sudo systemctl stop cows
$ sudo systemctl disable cows
$ sudo rm /etc/systemd/system/cows.service

Confirm it's really gone:

bash
$ sudo systemctl status cows

Now run the install script directly from the internet:

bash
$ curl -L https://tinyurl.com/cowserve | bash

curl downloads the script, and the pipe (|) hands its output straight to bash, which executes it as it streams in.

Worth knowing: piping a remote script straight into bash is convenient for a classroom demo, but it means you're trusting the source completely — there's no chance to read the script first. Fine here; worth a second thought in the wild.

Once it's running, find your machine's IP and check the server in a browser:

bash
$ hostname -I

Visit YOUR-IP:8080/say in a browser.

watching it work

Live logs with journalctl

One of the biggest advantages of using systemd is centralized logging:

bash
$ journalctl -f -u cows

journalctl reads logs from every service on the system; -u narrows it to one unit, and -f ("follow") streams new lines live instead of just showing history. Refresh the page in your browser and watch new lines appear.

go further

Source & next steps

The best way to learn Linux is still to keep tinkering with it.