Add flake + jsonnet
parent
7a47c2137b
commit
0c7c027fba
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1666885127,
|
||||||
|
"narHash": "sha256-uXA/3lhLhwOTBMn9a5zJODKqaRT+SuL5cpEmOz2ULoo=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "0e101dbae756d35a376a5e1faea532608e4a4b9a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667629849,
|
||||||
|
"narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "3bacde6273b09a21a8ccfba15586fb165078fb62",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "lib",
|
||||||
|
"lastModified": 1665349835,
|
||||||
|
"narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "lib",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
description = "Homelab configuration tools";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, flake-parts, ... }:
|
||||||
|
flake-parts.lib.mkFlake { inherit self; } {
|
||||||
|
systems = [ "x86_64-linux" "aarch64-darwin" ];
|
||||||
|
perSystem = { config, self', inputs', pkgs, system, ... }: {
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [ jsonnet ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
local optional(object, field) = std.get(object, field, {});
|
||||||
|
|
||||||
|
local dockerSocket = '/var/run/docker.sock:/var/run/docker.sock';
|
||||||
|
|
||||||
|
local tz = 'America/New_York';
|
||||||
|
local mediaEnv = {
|
||||||
|
PUID: 1000,
|
||||||
|
PGID: 1000,
|
||||||
|
TZ: tz,
|
||||||
|
};
|
||||||
|
|
||||||
|
local formatHelper(fmt) = function(name, option) fmt % [name, option];
|
||||||
|
local toList(fmt) = function(object) std.objectValues(std.mapWithKey(formatHelper(fmt), object));
|
||||||
|
local toLabels = toList('%s=%s');
|
||||||
|
local toVolumes = toList('%s:%s');
|
||||||
|
local toCommand = toList('--%s=%s');
|
||||||
|
|
||||||
|
local traefikLabels(name, host, port, extras) = toLabels({
|
||||||
|
'traefik.enable': 'true',
|
||||||
|
['traefik.http.routers.%s.rule' % name]: 'Host(`%s.mat`)' % host,
|
||||||
|
['traefik.http.routers.%s.entrypoints' % name]: 'web',
|
||||||
|
['traefik.http.services.%s.loadbalancer.server.port' % name]: port,
|
||||||
|
['traefik.http.routers.%s.service' % name]: '%s' % name,
|
||||||
|
'traefik.docker.network': 'traefik',
|
||||||
|
} + extras);
|
||||||
|
|
||||||
|
local mkService(name, svc) = svc {
|
||||||
|
container_name: name,
|
||||||
|
networks: ['traefik'],
|
||||||
|
volumes: toVolumes(optional(svc, 'volumes'))
|
||||||
|
+ toVolumes(optional(svc, 'mounts'))
|
||||||
|
+ if std.get(svc, 'docker', false)
|
||||||
|
then [dockerSocket]
|
||||||
|
else [],
|
||||||
|
labels: traefikLabels(name, std.get(svc, 'host', name), svc.webPort, optional(svc, 'traefik')),
|
||||||
|
restart: 'always',
|
||||||
|
};
|
||||||
|
|
||||||
|
local extractVolumes(cfg) = {
|
||||||
|
[name]: { external: true }
|
||||||
|
for name in std.flattenArrays([
|
||||||
|
std.objectFields(optional(svc, 'volumes'))
|
||||||
|
for svc in std.objectValues(cfg)
|
||||||
|
])
|
||||||
|
};
|
||||||
|
|
||||||
|
local Compose(cfg) = {
|
||||||
|
services: std.mapWithKey(mkService, cfg),
|
||||||
|
volumes: extractVolumes(cfg),
|
||||||
|
networks: { traefik: { external: true } },
|
||||||
|
};
|
||||||
|
|
||||||
|
local Port(port, src=port, kind='tcp') =
|
||||||
|
local mapped = '%d:%d' % [port, src];
|
||||||
|
'%s/%s' % [mapped, kind];
|
||||||
|
|
||||||
|
local MediaMounts(mounts) = {
|
||||||
|
['/media/mat/%s' % path]: mounts[path]
|
||||||
|
for path in std.objectFields(mounts)
|
||||||
|
};
|
||||||
|
|
||||||
|
local MediaService(name, tag='latest', env={}, mounts={}, webPort, ports=[]) = {
|
||||||
|
image: 'lscr.io/linuxserver/%s:%s' % [name, tag],
|
||||||
|
environment: mediaEnv + env,
|
||||||
|
volumes: { ['%s_config' % name]: '/config' },
|
||||||
|
mounts:: MediaMounts(mounts),
|
||||||
|
webPort:: webPort,
|
||||||
|
ports: ports,
|
||||||
|
};
|
||||||
|
|
||||||
|
function(secrets={})
|
||||||
|
Compose({
|
||||||
|
traefik: {
|
||||||
|
image: 'traefik:latest',
|
||||||
|
command: toCommand({
|
||||||
|
'log.level': 'ERROR',
|
||||||
|
'api.insecure': 'true',
|
||||||
|
'providers.docker': 'true',
|
||||||
|
'providers.docker.exposedbydefault': 'false',
|
||||||
|
'entrypoints.web.address': ':80',
|
||||||
|
// 'entrypoints.websecure.address': ':443',
|
||||||
|
}),
|
||||||
|
docker:: true,
|
||||||
|
webPort:: 80,
|
||||||
|
ports: [Port(80), /* Port(443), */ Port(8080)],
|
||||||
|
traefik:: {
|
||||||
|
// 'traefik.http.routers.http-catchall.rule': 'hostregexp(`{host:.+}`)'
|
||||||
|
// 'traefik.http.routers.http-catchall.entrypoints': 'web'
|
||||||
|
// 'traefik.http.routers.http-catchall.middlewares': 'redirect-to-https'
|
||||||
|
// 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme': 'https'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
portainer: {
|
||||||
|
image: 'portainer/portainer-ce:latest',
|
||||||
|
docker:: true,
|
||||||
|
volumes: { portainer_data: '/data' },
|
||||||
|
webPort:: 9000,
|
||||||
|
ports: [Port(9443)],
|
||||||
|
},
|
||||||
|
deluge: MediaService(
|
||||||
|
name='deluge',
|
||||||
|
env={ DELUGE_LOGLEVEL: 'error' },
|
||||||
|
mounts={ torrents: '/downloads' },
|
||||||
|
webPort=8112,
|
||||||
|
ports=[Port(54979), Port(54979, kind='udp')],
|
||||||
|
),
|
||||||
|
prowlarr: MediaService(
|
||||||
|
name='prowlarr',
|
||||||
|
tag='develop',
|
||||||
|
webPort=9696,
|
||||||
|
mounts={
|
||||||
|
torrents: '/downloads',
|
||||||
|
'passport-5tb': '/passport-5tb',
|
||||||
|
'passport-1tb': '/passport-1tb',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
bazarr: MediaService(
|
||||||
|
name='bazarr',
|
||||||
|
webPort=6767,
|
||||||
|
mounts={
|
||||||
|
'passport-5tb': '/passport-5tb',
|
||||||
|
'passport-1tb': '/passport-1tb',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
radarr: MediaService(
|
||||||
|
name='radarr',
|
||||||
|
webPort=7878,
|
||||||
|
mounts={
|
||||||
|
'passport-5tb/movies': '/passport-5tb',
|
||||||
|
'passport-1tb/movies': '/passport-1tb',
|
||||||
|
torrents: '/downloads',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
sonarr: MediaService(
|
||||||
|
name='sonarr',
|
||||||
|
webPort=8989,
|
||||||
|
mounts={
|
||||||
|
'passport-5tb/tv': '/passport-5tb',
|
||||||
|
'passport-1tb/tv': '/passport-1tb',
|
||||||
|
torrents: '/downloads',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
plex: {
|
||||||
|
image: 'plexinc/pms-docker',
|
||||||
|
environment: {
|
||||||
|
TZ: tz,
|
||||||
|
PLEX_CLAIM: std.get(secrets, 'PLEX_CLAIM'),
|
||||||
|
ADVERTISE_IP: std.get(secrets, 'ADVERTISE_IP'),
|
||||||
|
},
|
||||||
|
volumes: { plex_config: '/config' },
|
||||||
|
mounts:: MediaMounts({
|
||||||
|
'torrents/plex-transcode': '/transcode',
|
||||||
|
'passport-5tb': '/passport-5tb',
|
||||||
|
'passport-1tb': '/passport-1tb',
|
||||||
|
}),
|
||||||
|
devices: ['/dev/dri:/dev/dri'],
|
||||||
|
webPort:: 32400,
|
||||||
|
ports: [
|
||||||
|
Port(56463, src=32400),
|
||||||
|
Port(3005),
|
||||||
|
Port(8324),
|
||||||
|
Port(32469),
|
||||||
|
Port(1900, kind='udp'),
|
||||||
|
Port(32410, kind='udp'),
|
||||||
|
Port(32412, kind='udp'),
|
||||||
|
Port(32413, kind='udp'),
|
||||||
|
Port(32414, kind='udp'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
archivebox: {
|
||||||
|
image: 'archivebox/archivebox:dev',
|
||||||
|
command: 'server --quick-init 0.0.0.0:8000',
|
||||||
|
environment: {
|
||||||
|
ALLOWED_HOSTS: '*',
|
||||||
|
MEDIA_MAX_SIZE: '750m',
|
||||||
|
RESOLUTION: '1024,768',
|
||||||
|
},
|
||||||
|
mounts:: MediaMounts({ 'passport-5tb/archivebox': '/data' }),
|
||||||
|
webPort:: 8000,
|
||||||
|
host:: 'archive',
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue