--- # version: "3.2.3" networks: wg: driver: bridge hs: driver: bridge services: # @NOTE https://oneuptime.com/blog/post/2026-03-18-use-podman-containers-wireguard-vpn/view wgclient: image: lscr.io/linuxserver/wireguard:latest container_name: wgclient cap_add: # - SYS_MODULE - NET_ADMIN restart: unless-stopped volumes: # - /lib/modules:/lib/modules:ro - ~/.config/wireguard:/config/wg-confs:Z networks: - wg ports: - 51820:51820/udp environment: TZ: Etc/UTC PUID: 1000 GUID: 1000 sysctls: - net.ipv4.conf.all.src_valid_mark=1 - net.ipv6.conf.all.src_valid_mark=1 - net.ipv6.ip_forward=1data - net.ipv4.ip_forward=1 labels: glance.name: Wireguard glance.id: wireguard glance.icon: "si:wireguard" glance.description: VPN client connection # @NOTE https://tailscale.com/docs/features/containers/docker # @NOTE https://tailscale.com/blog/docker-tailscale-guide tailclient: image: tailscale/tailscale:latest container_name: tailclient cap_add: # - SYS_MODULE - NET_ADMIN restart: unless-stopped devices: - /dev/net/tun:/dev/net/tun volumes: # - /lib/modules:/lib/modules:ro - ~/.cvols/tailscale:/var/lib/tailscale - ~/.config/tailscale:/config:Z networks: - hs hostname: nirvana # env_file: [tailclient/prod.env] environment: TS_AUTHKEY: ${TS_AUTHKEY:?Provide authentication key}?ephemeral=false TS_SERVE_CONFIG: /config/${TS_SERVE_CONFIG_BASENAME:?Provide a basename for the Tailscale Serve configuration file}.json TS_EXTRA_ARGS: "--advertise-tags=tag:container" TS_STATE_DIR: "/var/lib/tailscale" # @TODO make subsequent containers have 'network_mode' attrbute set to value 'service:wgclient'/'service:tailclient' # OR make subsequent containers have 'networks' attribute set to list value with 'container:wgclient'/'contaner:tailclient' item revproxy0: image: caddy:latest restart: unless-stopped cap_add: - NET_ADMIN volumes: - ~/.caddy:/etc/caddy - ~/srv:/srv - ~/.local/share/caddy:/usr/share/caddy - ~/.cvols/caddy:/data - ~/.config/caddy:/config networks: - "container:wgclient" dns: - ${WG_INTFACE_ADDR:?Enter Wireguard client container's interface address} # env_file: [wg0-dns.env] depends_on: - wgclient labels: glance.name: Caddy glance.id: caddy glance.icon: "si:caddy" glance.description: HTTPS reverse proxy server glance: container_name: glance image: glanceapp/glance restart: unless-stopped volumes: # @NOTE https://github.com/glanceapp/glance/blob/main/docs/configuration.md#configuring-glance - ~/.config/glance:/app/config # @NOTE internal container server port is changed via 'glance.yml' config file; default is 8080 - ~/.local/share/glance:/app/assets - /etc/localtime:/etc/localtime:ro # Optionally, also mount docker socket if you want to use the docker containers widget - /var/run/docker.sock:/var/run/docker.sock:ro networks: - "container:tailclient" # env_file: [hs.env,glance/prod.env] depends_on: - tailclient labels: glance.name: Self glance.icon: "si:glance" glance.url: "${HS_URL_SCHEME:?Enter Headscale URL scheme for server}://${HS_DOMAIN:?Enter Headscale domain}" glance.description: Dashboard # @NOTE https://github.com/glanceapp/glance/blob/main/docs/configuration.md#docker-containers # @TODO apply labels to each container that allows it to show up in Glance dashboard stash: image: stashapp/stash:latest container_name: stash restart: unless-stopped volumes: - /etc/localtime:/etc/localtime:ro - ~/.config/stash:/root/.stash - ~/.xxx/media:/data - ~/.local/share/stash/metadata:/metadata - ~/.local/share/stash/cache:/cache - ~/.local/share/stash/blobs:/blobs - ~/.xxx/stash:/generated logging: driver: "json-file" options: max-file: "10" max-size: "2m" networks: - "container:tailclient" depends_on: - tailclient environment: STASH_PORT: "9999" labels: glance.name: Stash glance.icon: "si:stash" glance.url: "${HS_URL_SCHEME:?Enter Headscale URL scheme for server}://${HS_DOMAIN:?Enter Headscale domain}" glance.description: NSFW media streaming service and gallery