shutting down

thank you to everyone who has used and supported this project over the past few years.

i will keep a baseline *.homelab.express certificate available through march, after which the site will shut down.

if you need any of the multi-level subdomains, you can request them in the discord and i will do my best to provide a cert that will work for you.

.cer

public certificate and chain

.key

plaintext private key

automated updates

homelab.express provides a certificate updater to simplify the process of regularly pulling down our updated certificates for your docker environment.

this container was created to work with the traefik reverse proxy, but it should work for any TLS provider that supports a certificate with a separate plaintext private key.

docker-compose.yaml example

traefik-cert-updater: image: 'cinderblockgames/homelab.express-cert-updater:latest' container_name: 'traefik-cert-updater' restart: always volumes: - '/run/homelab/storage/traefik/config/certs.toml:/data/dynamic.toml' - '/run/homelab/storage/traefik/config/certs:/data/certs' network_mode: bridge
services: traefik-cert-updater: image: 'cinderblockgames/homelab.express-cert-updater:latest' volumes: - '/run/homelab/storage/traefik/config/certs.toml:/data/dynamic.toml' - '/run/homelab/storage/traefik/config/certs:/data/certs' networks: [swarm] networks: swarm: external: true

traefik.toml example

[entryPoints] [entryPoints.web] address = ":80" [entryPoints.web-secure] address = ":443" [api] dashboard = true [providers.docker] exposedByDefault = false [providers.file] watch = true directory = "/config"

config/certs.toml example

[tls] [[tls.certificates]] certFile = "/config/certs/wildcard.homelab.express.cer" keyFile = "/config/certs/wildcard.homelab.express.key" stores = ["default"] [tls.stores] [tls.stores.default] [tls.stores.default.defaultCertificate] certFile = "/config/certs/wildcard.homelab.express.cer" keyFile = "/config/certs/wildcard.homelab.express.key"

get up and running

if you just acquired a new raspberry pi or similar device and are looking to get it stood up as a personal deployment environment, consider using the setup outlined here to get it up and running in no time.

prep

follow these steps to prepare your device:

  1. update the machine's IP address with a Fixed Allocation from your DHCP provider (probably your home router)
  2. set up docker, then reboot:
    curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $(whoami) sudo reboot
  3. run the following commands, then log out and back in:
    sudo groupadd homelab sudo usermod -aG homelab $(whoami) sudo mkdir /run/homelab -m775 sudo chgrp homelab /run/homelab

run

once your device is prepped, you can use our script to set up the environment:

wget https://homelab.express/setup/arm/homelab.express-first.sh sh homelab.express-first.sh
wget https://homelab.express/setup/x86/homelab.express-first.sh sh homelab.express-first.sh

then head to /run/homelab/compose/infrastructure/ and start your infrastructure containers:

docker compose up -d

as long as you have your new lab's IP set in your hosts file, you can head to https://manage.homelab.express, set up a password, and explore portainer.

you can also head to https://{hostname}.homelab.express (replacing {hostname} with the hostname of your device) to view the traefik dashboard.

manual setup

if you prefer not to use the script, you can replicate its functionality by running the following commands:

wget https://homelab.express/setup/arm/first/compose/infrastructure/docker-compose.yaml -O /run/homelab/compose/infrastructure/docker-compose.yaml wget https://homelab.express/setup/arm/first/storage/traefik/traefik.toml -O /run/homelab/storage/traefik/traefik.toml wget https://homelab.express/setup/arm/first/storage/traefik/config/certs.toml -O /run/homelab/storage/traefik/config/certs.toml
wget https://homelab.express/setup/x86/first/compose/infrastructure/docker-compose.yaml -O /run/homelab/compose/infrastructure/docker-compose.yaml wget https://homelab.express/setup/x86/first/storage/traefik/traefik.toml -O /run/homelab/storage/traefik/traefik.toml wget https://homelab.express/setup/x86/first/storage/traefik/config/certs.toml -O /run/homelab/storage/traefik/config/certs.toml

once you've copied the files over, make sure to update /run/homelab/compose/infrastructure/docker-compose.yaml to replace ${hostname} with your machine's hostname.

adding containers

when standing up additional containers, all you need to do to have them served correctly by traefik behind our certificate is to ensure the container is on the same network as traefik and add the traefik labels:

network_mode: bridge labels: - 'traefik.enable=true' - 'traefik.http.routers.{your-container}.rule=Host(`{your-subdomain}.homelab.express`)' - 'traefik.http.routers.{your-container}.entrypoints=web-secure' - 'traefik.http.routers.{your-container}.tls' - 'traefik.http.services.{your-container}.loadbalancer.server.port={your-port}'

here is an example with the whoami container, which stands up a lightweight demo server:

version: '3.8' services: whoami: image: 'containous/whoami' container_name: whoami restart: always network_mode: bridge labels: - 'traefik.enable=true' - 'traefik.http.routers.whoami.rule=Host(`whoami.homelab.express`)' - 'traefik.http.routers.whoami.entrypoints=web-secure' - 'traefik.http.routers.whoami.tls' - 'traefik.http.services.whoami.loadbalancer.server.port=80'

adding devices

adding additional devices is the same as setting up the first one, except the script to set up the environment is slightly different:

wget https://homelab.express/setup/arm/homelab.express-add-on.sh sh homelab.express-add-on.sh
wget https://homelab.express/setup/x86/homelab.express-add-on.sh sh homelab.express-add-on.sh

manually adding devices

if you prefer not to use the script, the only difference between the first script and the add-on script is that we use portainer agent instead of portainer in /run/homelab/compose/infrastructure/docker-compose.yaml:

portainer-agent: image: 'portainer/agent' container_name: 'portainer-agent' restart: always ports: - '9001:9001' volumes: - '/var/run/docker.sock:/var/run/docker.sock' - '/var/lib/docker/volumes:/var/lib/docker/volumes' network_mode: bridge

prep

follow these steps to prepare your device:

  1. update the machine's IP address with a Fixed Allocation from your DHCP provider (probably your home router)
  2. set up docker, then reboot:
    curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $(whoami) sudo reboot
  3. run the following commands, then log out and back in:
    sudo groupadd homelab sudo usermod -aG homelab $(whoami) sudo mkdir /run/homelab -m775 sudo chgrp homelab /run/homelab docker swarm init docker network create --opt encrypted --driver overlay swarm

if your device has multiple IP addresses assigned to it, you will need to specify the static IP address you set in the first step by including the --advertise-addr option in the docker swarm init command.

run

once your device is prepped, you can use our script to set up the environment:

wget https://homelab.express/setup/arm/homelab.express-swarm.sh sh homelab.express-swarm.sh
wget https://homelab.express/setup/x86/homelab.express-swarm.sh sh homelab.express-swarm.sh

then head to /run/homelab/compose/infrastructure/ and start your infrastructure services:

docker stack deploy -c docker-compose.yaml infrastructure

as long as you have your new lab's IP set in your hosts file, you can head to https://manage.homelab.express, set up a password, and explore portainer.

you can also head to https://monitor.homelab.express to view the traefik dashboard.

manual setup

if you prefer not to use the script, you can replicate its functionality by running the following commands:

wget https://homelab.express/setup/arm/swarm/compose/infrastructure/docker-compose.yaml -O /run/homelab/compose/infrastructure/docker-compose.yaml wget https://homelab.express/setup/arm/swarm/storage/traefik/traefik.toml -O /run/homelab/storage/traefik/traefik.toml wget https://homelab.express/setup/arm/swarm/storage/traefik/config/certs.toml -O /run/homelab/storage/traefik/config/certs.toml
wget https://homelab.express/setup/x86/swarm/compose/infrastructure/docker-compose.yaml -O /run/homelab/compose/infrastructure/docker-compose.yaml wget https://homelab.express/setup/x86/swarm/storage/traefik/traefik.toml -O /run/homelab/storage/traefik/traefik.toml wget https://homelab.express/setup/x86/swarm/storage/traefik/config/certs.toml -O /run/homelab/storage/traefik/config/certs.toml

adding services

when standing up additional services, all you need to do to have them served correctly by traefik behind our certificate is to ensure the service is on the same network as traefik and add the traefik labels:

networks: [swarm] deploy: mode: replicated replicas: 1 labels: - 'traefik.enable=true' - 'traefik.http.routers.{your-container}.rule=Host(`{your-subdomain}.homelab.express`)' - 'traefik.http.routers.{your-container}.entrypoints=web-secure' - 'traefik.http.routers.{your-container}.tls' - 'traefik.http.services.{your-container}.loadbalancer.server.port={your-port}' networks: swarm: external: true

here is an example with the whoami container, which stands up a lightweight demo server:

version: '3.8' services: whoami: image: 'containous/whoami' networks: [swarm] deploy: mode: replicated replicas: 1 labels: - 'traefik.enable=true' - 'traefik.http.routers.whoami.rule=Host(`whoami.homelab.express`)' - 'traefik.http.routers.whoami.entrypoints=web-secure' - 'traefik.http.routers.whoami.tls' - 'traefik.http.services.whoami.loadbalancer.server.port=80' networks: swarm: external: true

adding nodes

adding additional nodes to the swarm comes with a challenge: namely, how to managed shared data. you have a few options for how to go about this: you can create global volumes, have copies of the relevant data on every node, or use placement constraints to keep services that rely on certain data deployed only to the nodes that contain that data.

once you've solved the data problem, you can add a node to your swarm by getting a join token from a manager node already in the swarm:

docker swarm join-token worker
docker swarm join-token manager

run the returned join command on the node you want to join to the swarm. you can continue managing the swarm and its services from a manager node or from within portainer.