thequad/README.md
2026-01-30 06:50:32 +00:00

190 lines
6.9 KiB
Markdown

# The Quad
This is my current setup for managing a good portion of my cloud infrastructure.
I tried to do this with ansible in the past bug I couldn't be bothered finishing
it all. This, I like better. It's more accessible and straightforward.
More info on [podman
quadlets](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
## Basics
This repo contains all container definitions that I use. More can be added and
then just need to be symlinked to the user `systemd` directory followed by
running `systemctl --user daemon-reload`, at which point the container should be
picked up and started.
```
cd .config/containers/systemd/
ln -s ~/repos/thequad/openhab/openhab.container .
systemctl --user daemon-reload
```
## Backups
I haven't set this up yet but I'm going to use `restic` to back up the data
directories to both my NAS and to Backblaze B2.
> More to come here...
## Notes
I've decided to store all of the container data in `/mnt/data/containers/` in a directory with
the containers name. This seemed most straightforward to me.
`plucky-pinning.sh` provides a way to automatically pin podman to the version
released in Ubuntu 25.05 (Plucky). The reason this is useful is that the podman
v4 -> v5 transition introduces a lot of nice to haves (such as Pods) because
podman quadlets are still in active development.
### Root containers
`./drone-agent.container` is not rootless as it needs access to the
podman/docker socket to run containers for actions/pipelines.
```
sudo ln -s ~/repos/thequad/drone/* /etc/containers/systemd/
```
### Rootless containers
If you need the socket in a rootless container, see
[here](https://github.com/gethomepage/homepage/discussions/4013#discussioncomment-12135538)
If you have issues binding ports; podman cannot create rootless containers that
bind to ports <= 1024 (see
[here](https://github.com/containers/podman/blob/main/rootless.md)), you can run
the following to update the systems settings to allow down to whaever you want
(80 here):
```
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
```
__NOTE__ this is changing your host's settings, not podman's, BE CAREFUL!
### Homepage
This requires some additional configuration, namely updating the file in the
containers data directory referenced
[here](https://gethomepage.dev/configs/docker/#using-socket-directly) and
setting up the podman socket for rootless access, see above.
### ARR Suite
Currnt thoughts for getting media automations set up are:
Using: sonarr, radarr, prowlerr, profilerr, qbittorrent, and gluetun (connected
to protonvpn via a wireguard config)
Things to work out:
- networking, I'll want to connect be able to connect locally, can I do this
with the vpn handling container network traffic? how should I set up the pod,
will it even need a network file, or will the gluetun container be the
network?
Some references:
- [podman protonvpn and gluetun](https://beerstra.org/2024/07/12/vpn-enabled-podman-containers/)
- [docs](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/protonvpn.md)
UPDATES:
I've set up usenet, I have sabnzbd for downloading and have switched off
qbittorrent, gluetun, and flaresolver.
### Unifi Network Application
Although easiest to migrate with a config export and import, I did need to
factory reset the devices, ssh into them with
`ssh ubnt@<device id>`
and the password of `ubnt`
and run
```
set-inform http://192.168.2.61:8080/inform
```
To resolve an issue where the devices were stuck in an infinite 'adopting'
state.
### Photoprism
UUUUUUUUHHHG, have to use CLI to add users, ffs.
```
photoprism users add -p your_password -r guest your_username
```
It does look like PP is the best option for self hosted though.
[Managing users reference
guide/docs](https://docs.photoprism.app/user-guide/users/cli/#managing-user-accounts)
I'm going to look into immich which also looks quite nice
### Authelia
I have set this up to provide auth if an when I need it, it's pretty simple to
integrate into caddy, look at the drone config in caddy for an example. More
complicated services like nextcloud might require more in depth configuration
but we'll cross that bridge when we get to it.
I'm not going to include any references here as there's extensive documentation
out there and LLMs have a pretty good handle on it. One thing I will say, this
was quite hard to get set up. I'm not convinced my configuration file is 100%
correct and good but it does work. I have lldap running as the identity provider
(I guess) which is where you add users, and postgres as the database for both
lldap and authelia.
### Defguard
Mostly working, still need to work out the SSL for the gRPC endpoints.
Also, the gateway needs to run as root for reasons I can't quite work out but
its got something to do with creating the network devices for the VPN.
This is the first thing I've set up with proper use of env files which is nice
though.
Endid up deciding to move this to a vim instead.
I've completetly fucked this off, I'm keeping the files for posterity but even
the one click instill didn't work and given I have openvpn up and running just
fine I CBF.
### wg-easy
I'm trying to get a vpn set up and chose wg-easy, which is turing out not to be
easy. It's running but having trouble with the wg part of the whole thing.
references:
- [docker-compose.yml](https://github.com/wg-easy/wg-easy/blob/master/docker-compose.yml)
- [wg-easy Caddy
docs](https://wg-easy.github.io/wg-easy/Pre-release/examples/tutorials/caddy/)
- [wireguard in podman blog
post](https://www.procustodibus.com/blog/2022/10/wireguard-in-podman/)
I find it annoying that I have to make host changes to make this work but it
does sort of make sense given how tied to the network stack VPNs must be.
I found my solution [here in the wg-easy
faq](https://wg-easy.github.io/wg-easy/v15.1/faq/), it was a kernel modules
issue. Also some good info and content
[here](https://wg-easy.github.io/wg-easy/v15.0/examples/tutorials/podman-nft/).
I'm hoping I can have the container rootless but we'll see, might need tobe
rootful given their docs.
for reference:
```
# POST UP
nft add table inet wg_table; nft add chain inet wg_table prerouting { type nat hook prerouting priority 100 \; }; nft add chain inet wg_table postrouting { type nat hook postrouting priority 100 \; }; nft add rule inet wg_table postrouting ip saddr {{ipv4Cidr}} oifname {{device}} masquerade; nft add rule inet wg_table postrouting ip6 saddr {{ipv6Cidr}} oifname {{device}} masquerade; nft add chain inet wg_table input { type filter hook input priority 0 \; policy accept \; }; nft add rule inet wg_table input udp dport {{port}} accept; nft add rule inet wg_table input tcp dport {{uiPort}} accept; nft add chain inet wg_table forward { type filter hook forward priority 0 \; policy accept \; }; nft add rule inet wg_table forward iifname "wg0" accept; nft add rule inet wg_table forward oifname "wg0" accept;
# POST DOWN
nft delete table inet wg_table
```
seems to have done the trick, along with the kernel modules :D