Musselman Development

Further Simplifying Blog and Service Deployment

3 mins ยท

This article is a follow-up to my previous posts (see blog post automation and switching to a simpler web server), I wanted to make setting up all my services easier. One of the problems I have been thoroughly tackling is the amount of steps it takes to set up a service. Even though the steps to set up a service were vastly decreased when I switched to Caddy, there was still room for simplification and automation. Most of what I was left doing could easily be transformed into a series of templates as there were only small changes between each item. Below are the changes I made to enable this and the current iteration of the script I use to deploy a new service.

Necessary Changes

As I wanted to minimize the hustle of setting up the new sites I decided that entering my passwords as little as possible was a necessity. Due to the nature of the /etc/ directory that was not possible as all files there need elevated privileges in order to be edited and saved. Thankfully both rathole and Caddy allow for specifying custom configuration locations.

I had arbitrarily set rathole’s configuration to be at /etc/rathole early on in my homelabing journey, and decided to move that one first. Its new location is at a top level directory (/rathole/). This new location allowed me to set the permissions (using the chmod/chown commands) of the files. This way I could add the user I was ssh-ing into to a group that had permissions for the files and directory. I attempted to do the same for Caddy but was running into a permissions’ error for the Caddy system user. In the end I resorted to using a link to edit the file which worked by setting the permissions on the file itself. With that I can now access both files without using sudo, in an easily accessible1 directory.

Another issue I needed to solve was entering my credentials to ssh into a server. This was easily solved decades ago, and was easily solved by creating a key pair and moving them appropriately to where they needed to be.

Setting up the script

#!/bin/bash

# Ask for user input for the subdomain you want the service to 
# be accessed at, and the port that the service is running on.
read -p "Enter the subdomain: " SUB_DOMAIN
read -p "Enter the exit port: " PORT

# Generate random secure key locally for a  secure connection
# between the homelab/server and the gateway/vps
KEY=$(openssl rand -base64 32)

# Add configuration to the local file (on the homelab), 
echo "[client.services.$SUB_DOMAIN]" >> /rathole/client.toml
echo "token = \"$KEY\"" >> /rathole/client.toml
echo "local_addr = \"127.0.0.1:$PORT\"" >> /rathole/client.toml

# SSH into the remote system and append configuration 
# to a specific file and add the domain and port to 
# the web server configuration (CaddyFile)
ssh gateway "echo '[server.services.$SUB_DOMAIN]' >> /rathole/server.toml
echo 'token = \"$KEY\"' >> /rathole/server.toml
echo 'bind_addr = \"0.0.0.0:$PORT\"' >> /rathole/server.toml
echo '$SUB_DOMAIN.privacyquest.net {
    reverse_proxy localhost:$PORT
}' >> /caddy/Caddyfile

# restart the caddy service
sudo -S systemctl restart caddy"

The new setup process

With the abstractions above now all that is required to set up a new public facing service is:

  1. Set up the service in a production manner locally on the homelab.
  2. Run service_setup and give it the desired subdomain and the services port number.
  3. Type in my password to restart the Caddy web server.

  1. To the specific user I was using for the service management. ↩︎

Tags: Permissions KISS CI/CD Blogging SSH