homelab-apps/compose.libsonnet

82 lines
2.4 KiB
Plaintext
Raw Normal View History

local optional(object, field) = std.get(object, field, {});
local dockerSocket = '/var/run/docker.sock:/var/run/docker.sock';
local mediaEnv = {
PUID: 1000,
PGID: 1000,
TZ: 'America/New_York',
};
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 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);
2023-07-24 01:13:23 +00:00
local mkNetwork(svc) = if std.get(svc, 'gluetun', false) then {
network_mode: 'service:gluetun',
} else {
networks: ['traefik'],
};
local mkService(name, svc) = svc {
container_name: name,
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')),
2023-07-24 01:24:23 +00:00
restart: std.get(svc, 'restart', 'always'),
2023-07-24 01:13:23 +00:00
} + mkNetwork(svc);
local extractVolumes(cfg) = {
2022-11-17 18:44:48 +00:00
[name]: {
// this is very ugly, a data driven approach would be better but very verbose
external: std.length(std.findSubstr('_', name)) >= 2,
}
for name in std.flattenArrays([
std.objectFields(optional(svc, 'volumes'))
for svc in std.objectValues(cfg)
])
};
local mediaMounts(mounts) = {
['/media/mat/%s' % path]: mounts[path]
for path in std.objectFields(mounts)
};
{
Compose(cfg):: {
services: std.mapWithKey(mkService, cfg),
volumes: extractVolumes(cfg),
networks: { traefik: { external: true } },
},
Port(port, src=port, kind='tcp')::
local mapped = '%d:%d' % [port, src];
'%s/%s' % [mapped, kind],
Command:: toList('--%s=%s'),
MediaMounts:: mediaMounts,
2023-07-24 01:13:23 +00:00
MediaService(name, tag='latest', env={}, mounts={}, webPort, ports=[], extras={}):: {
image: 'lscr.io/linuxserver/%s:%s' % [name, tag],
environment: mediaEnv + env,
2022-11-17 18:44:48 +00:00
volumes: { ['media_%s_config' % name]: '/config' },
mounts:: mediaMounts(mounts),
webPort:: webPort,
ports: ports,
2023-07-24 01:13:23 +00:00
} + extras,
}