Suppose we want to set up two apps (freshrss and Jellyfin) behind a reverse proxy (nginx).
Then we'd do something like this with Podman and the quadlet generator:
/etc/containers/systemd/[email protected]:
[Unit]
Description=LinuxServer Container %i
After=local-fs.target
[Container]
ContainerName=%i
Image=lscr.io/linuxserver/%i:latest
AutoUpdate=registry
Volume=/etc/%i:/config:Z
Network=ctr.network
Environment=TZ=Europe/Stockholm
[Service]
TimeoutStartSec=30min
Restart=on-failure
RestartSec=1s
RestartSteps=5
RestartMaxDelaySec=2m 30s
[Install]
WantedBy=default.target
/etc/containers/systemd/ctr.network:
[Network]
Subnet=192.168.100.0/24
Gateway=192.168.100.1
Just a symlink needed:
$ ln -s /etc/containers/systemd/ctr@{,freshrss}.container
$ ln -s /etc/containers/systemd/ctr@{,jellyfin}.container
/etc/containers/systemd/[email protected]/1.conf:
[Unit]
# Jellyfin needs to wait for this media library mount to be ready
Requires=media.mount
After=media.mount
[Container]
Volume=/path/to/jellyfin/library:/config
Volume=/media/series:/data/series
Volume=/media/movies:/data/movies
Environment=JELLYFIN_PublishedServerUrl=http://192.168.0.5
$ ln -s /etc/containers/systemd/ctr@{,nginx}.container
/etc/containers/systemd/[email protected]/1.conf:
[Container]
Image=docker.io/library/nginx:stable-alpine
Volume=
Volume=/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro,Z
PublishPort=80:80
user nginx;
worker_processes auto;
error_log stderr notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log stdout main;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream freshrss {
server freshrss:80;
}
upstream jellyfin {
server jellyfin:8096;
}
server {
listen 80;
server_name server.lan;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
server {
listen 80;
server_name jellyfin.lan;
location / {
proxy_pass http://jellyfin/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name freshrss.lan;
location / {
proxy_pass http://freshrss/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
For just two applications and one reverse proxy the above becomes a little bit
chatty compared to a docker-compose.yml
file with YAML anchors. But when you
scale up to many more containers it's fairly similar.
Of note though we're able to reliably depend on media.mount
to be mounted
before starting our Jellyfin container. That kind of thing you can't do with
regular docker-compose.yml
.