Compare commits

..

3 Commits

Author SHA1 Message Date
mat ess ae2160851c Add gluetun 2023-07-23 21:13:23 -04:00
mat ess 7124e2c0a5 Update flake 2023-07-23 21:12:11 -04:00
mat ess 1178986367 Update configs 2023-07-23 21:11:55 -04:00
6 changed files with 69 additions and 34 deletions

2
.envrc
View File

@ -1,2 +1,2 @@
use flake use flake
dotenv .env dotenv_if_exists .env

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
.env .env
.direnv .direnv
.secrets.jsonnet

View File

@ -22,9 +22,14 @@ local traefikLabels(name, host, port, extras) = toLabels({
'traefik.docker.network': 'traefik', 'traefik.docker.network': 'traefik',
} + extras); } + extras);
local mkNetwork(svc) = if std.get(svc, 'gluetun', false) then {
network_mode: 'service:gluetun',
} else {
networks: ['traefik'],
};
local mkService(name, svc) = svc { local mkService(name, svc) = svc {
container_name: name, container_name: name,
networks: ['traefik'],
volumes: toVolumes(optional(svc, 'volumes')) volumes: toVolumes(optional(svc, 'volumes'))
+ toVolumes(optional(svc, 'mounts')) + toVolumes(optional(svc, 'mounts'))
+ if std.get(svc, 'docker', false) + if std.get(svc, 'docker', false)
@ -32,7 +37,7 @@ local mkService(name, svc) = svc {
else [], else [],
labels: traefikLabels(name, std.get(svc, 'host', name), svc.webPort, optional(svc, 'traefik')), labels: traefikLabels(name, std.get(svc, 'host', name), svc.webPort, optional(svc, 'traefik')),
restart: 'always', restart: 'always',
}; } + mkNetwork(svc);
local extractVolumes(cfg) = { local extractVolumes(cfg) = {
[name]: { [name]: {
@ -65,12 +70,12 @@ local mediaMounts(mounts) = {
MediaMounts:: mediaMounts, MediaMounts:: mediaMounts,
MediaService(name, tag='latest', env={}, mounts={}, webPort, ports=[]):: { MediaService(name, tag='latest', env={}, mounts={}, webPort, ports=[], extras={}):: {
image: 'lscr.io/linuxserver/%s:%s' % [name, tag], image: 'lscr.io/linuxserver/%s:%s' % [name, tag],
environment: mediaEnv + env, environment: mediaEnv + env,
volumes: { ['media_%s_config' % name]: '/config' }, volumes: { ['media_%s_config' % name]: '/config' },
mounts:: mediaMounts(mounts), mounts:: mediaMounts(mounts),
webPort:: webPort, webPort:: webPort,
ports: ports, ports: ports,
}, } + extras,
} }

View File

@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1666885127, "lastModified": 1688466019,
"narHash": "sha256-uXA/3lhLhwOTBMn9a5zJODKqaRT+SuL5cpEmOz2ULoo=", "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "0e101dbae756d35a376a5e1faea532608e4a4b9a", "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1667629849, "lastModified": 1690031011,
"narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=", "narHash": "sha256-kzK0P4Smt7CL53YCdZCBbt9uBFFhE0iNvCki20etAf4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "3bacde6273b09a21a8ccfba15586fb165078fb62", "rev": "12303c652b881435065a98729eb7278313041e49",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -37,11 +37,11 @@
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"lastModified": 1665349835, "lastModified": 1688049487,
"narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=", "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1", "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -6,24 +6,17 @@
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
}; };
outputs = { self, flake-parts, ... }: outputs = inputs@{ self, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit self; } { flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-darwin" ]; systems = [ "x86_64-linux" "aarch64-darwin" ];
perSystem = { config, self', inputs', pkgs, system, ... }: perSystem = { config, self', inputs', pkgs, system, ... }:
let let
to-docker-compose = pkgs.writeShellApplication { to-docker-compose = pkgs.writeShellApplication {
name = "to-docker-compose"; name = "to-docker-compose";
runtimeInputs = [ pkgs.jsonnet ]; runtimeInputs = [ pkgs.go-jsonnet ];
text = text =
let
vars = [ "PLEX_CLAIM" "PLEX_ADVERTISE_IP" "FIREFLY_APP_KEY" ];
varRow = var: "${var}: '\$${var}',";
in
'' ''
jsonnet services.jsonnet \ jsonnet services.jsonnet --tla-code-file secrets=.secrets.jsonnet
--tla-code secrets="{
${pkgs.lib.concatMapStrings varRow vars}
}"
''; '';
}; };
remote-docker-compose = pkgs.writeShellApplication { remote-docker-compose = pkgs.writeShellApplication {
@ -41,7 +34,7 @@
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
jsonnet go-jsonnet
to-docker-compose to-docker-compose
remote-docker-compose remote-docker-compose
]; ];

View File

@ -7,6 +7,30 @@ local MediaMounts = compose.MediaMounts;
function(secrets={}) function(secrets={})
Compose({ Compose({
gluetun: {
image: 'qmcgaw/gluetun',
cap_add: ['NET_ADMIN'],
devices: ['/dev/net/tun:/dev/net/tun'],
environment: {
TZ: 'America/New_York',
VPN_SERVICE_PROVIDER: 'custom',
VPN_TYPE: 'wireguard',
// VPN_PORT_FORWARDING: 'on',
// VPN_PORT_FORWARDING_PROVIDER: 'protonvpn',
VPN_ENDPOINT_IP: std.get(secrets, 'VPN_ENDPOINT_IP'),
VPN_ENDPOINT_PORT: std.get(secrets, 'VPN_ENDPOINT_PORT'),
WIREGUARD_PUBLIC_KEY: std.get(secrets, 'WIREGUARD_PUBLIC_KEY'),
WIREGUARD_PRIVATE_KEY: std.get(secrets, 'WIREGUARD_PRIVATE_KEY'),
WIREGUARD_ADDRESSES: std.get(secrets, 'WIREGUARD_ADDRESSES'),
},
ports: [
Port(8888),
Port(8388),
Port(8388, kind='udp'),
],
webPort:: 8000,
volumes: { gluetun_data: '/gluetun' },
},
traefik: { traefik: {
image: 'traefik:latest', image: 'traefik:latest',
command: Command({ command: Command({
@ -19,7 +43,10 @@ function(secrets={})
}), }),
docker:: true, docker:: true,
webPort:: 8080, webPort:: 8080,
ports: [Port(80) /* Port(443) */], ports: [
Port(80),
// Port(443),
],
traefik:: { traefik:: {
// 'traefik.http.routers.http-catchall.rule': 'hostregexp(`{host:.+}`)' // 'traefik.http.routers.http-catchall.rule': 'hostregexp(`{host:.+}`)'
// 'traefik.http.routers.http-catchall.entrypoints': 'web' // 'traefik.http.routers.http-catchall.entrypoints': 'web'
@ -39,7 +66,11 @@ function(secrets={})
env={ DELUGE_LOGLEVEL: 'error' }, env={ DELUGE_LOGLEVEL: 'error' },
mounts={ torrents: '/downloads' }, mounts={ torrents: '/downloads' },
webPort=8112, webPort=8112,
ports=[Port(54979), Port(54979, kind='udp')], // ports=[
// Port(54979),
// Port(54979, kind='udp'),
// ],
extras={ gluetun:: true },
), ),
prowlarr: MediaService( prowlarr: MediaService(
name='prowlarr', name='prowlarr',
@ -50,6 +81,7 @@ function(secrets={})
'passport-5tb': '/passport-5tb', 'passport-5tb': '/passport-5tb',
'passport-1tb': '/passport-1tb', 'passport-1tb': '/passport-1tb',
}, },
extras={ gluetun:: true },
), ),
bazarr: MediaService( bazarr: MediaService(
name='bazarr', name='bazarr',
@ -58,6 +90,7 @@ function(secrets={})
'passport-5tb': '/passport-5tb', 'passport-5tb': '/passport-5tb',
'passport-1tb': '/passport-1tb', 'passport-1tb': '/passport-1tb',
}, },
extras={ gluetun:: true },
), ),
radarr: MediaService( radarr: MediaService(
name='radarr', name='radarr',
@ -67,6 +100,7 @@ function(secrets={})
'passport-1tb/movies': '/passport-1tb', 'passport-1tb/movies': '/passport-1tb',
torrents: '/downloads', torrents: '/downloads',
}, },
extras={ gluetun:: true },
), ),
sonarr: MediaService( sonarr: MediaService(
name='sonarr', name='sonarr',
@ -75,14 +109,15 @@ function(secrets={})
'passport-5tb/tv': '/passport-5tb', 'passport-5tb/tv': '/passport-5tb',
'passport-1tb/tv': '/passport-1tb', 'passport-1tb/tv': '/passport-1tb',
torrents: '/downloads', torrents: '/downloads',
} },
extras={ gluetun:: true },
), ),
plex: { plex: {
image: 'plexinc/pms-docker', image: 'plexinc/pms-docker',
environment: { environment: {
TZ: 'America/New_York', TZ: 'America/New_York',
PLEX_CLAIM: std.get(secrets, 'PLEX_CLAIM'), PLEX_CLAIM: std.get(secrets, 'PLEX_CLAIM'),
ADVERTISE_IP: std.get(secrets, 'PLEX_ADVERTISE_IP'), // ADVERTISE_IP: std.get(secrets, 'PLEX_ADVERTISE_IP'),
}, },
volumes: { media_plex_config: '/config' }, volumes: { media_plex_config: '/config' },
mounts:: MediaMounts({ mounts:: MediaMounts({
@ -93,7 +128,7 @@ function(secrets={})
devices: ['/dev/dri:/dev/dri'], devices: ['/dev/dri:/dev/dri'],
webPort:: 32400, webPort:: 32400,
ports: [ ports: [
Port(56463, src=32400), Port(32400),
Port(3005), Port(3005),
Port(8324), Port(8324),
Port(32469), Port(32469),
@ -106,10 +141,10 @@ function(secrets={})
}, },
archivebox: { archivebox: {
image: 'archivebox/archivebox:dev', image: 'archivebox/archivebox:dev',
// command: 'server --quick-init 0.0.0.0:8000', command: 'server --quick-init 0.0.0.0:8000',
// TODO: hack to workaround https://github.com/ArchiveBox/ArchiveBox/issues/1002 // TODO: hack to workaround https://github.com/ArchiveBox/ArchiveBox/issues/1002
entrypoint: '/bin/bash', // entrypoint: '/bin/bash',
command: '-c "chown -R archivebox:archivebox /app/archivebox/core/migrations && /app/bin/docker_entrypoint.sh server --quick-init 0.0.0.0:8000"', // command: '-c "chown -R archivebox:archivebox /app/archivebox/core/migrations && /app/bin/docker_entrypoint.sh server --quick-init 0.0.0.0:8000"',
environment: { environment: {
ALLOWED_HOSTS: '*', ALLOWED_HOSTS: '*',
MEDIA_MAX_SIZE: '750m', MEDIA_MAX_SIZE: '750m',