Compare commits

..

11 Commits

Author SHA1 Message Date
Hilton Chain 1deb97ada4
services: Add jellyfin-service-type. 2 months ago
Hilton Chain fa1bcd5018
services: cloudflare-warp: Don't log stdout. 2 months ago
Hilton Chain 21ba2f200f
services: Add home-qbittorrent-service-type. 2 months ago
Hilton Chain bd6508000e
services: Add misskey-service-type. 2 months ago
Hilton Chain a367c5c974
services: Add vaultwarden-service-type. 2 months ago
Hilton Chain 7409288c70
services: tailscale: Reduce configuration fields. 2 months ago
Hilton Chain 1d40787105
services: miniflux: Support proxy. 2 months ago
Hilton Chain f42f8e258b
services: cloudflare-tunnel: Reduce configuration fields. 2 months ago
Hilton Chain f9dc2afc50
rosenthal: cloudflared: Update to 2024.9.1. 2 months ago
Hilton Chain 82619c24fe
rosenthal: tailscale-bin: Update to 1.74.1. 2 months ago
Hilton Chain 81d1a87938
rosenthal: mihomo-bin: Update to 1.18.9. 2 months ago
  1. 8
      rosenthal/packages/binaries.scm
  2. 6
      rosenthal/packages/networking.scm
  3. 42
      rosenthal/services/bittorrent.scm
  4. 43
      rosenthal/services/child-error.scm
  5. 66
      rosenthal/services/networking.scm
  6. 311
      rosenthal/services/web.scm

@ -52,7 +52,7 @@ protocols out-of-the-box.")
(define-public mihomo-bin
(package
(name "mihomo-bin")
(version "1.18.7")
(version "1.18.9")
(source (origin
(method url-fetch)
(uri (string-append
@ -60,7 +60,7 @@ protocols out-of-the-box.")
version "/mihomo-linux-amd64-v" version ".gz"))
(sha256
(base32
"1mfbh21x1vzmi0vglk68r21rfbklllxpa5q4978li7n44r0v6hbr"))))
"0xq2baqcfd6hnyl1h3q34ymqd227dm06r7dz76s46k7mx7yz7jsb"))))
(build-system copy-build-system)
(arguments
(list #:install-plan
@ -242,14 +242,14 @@ monster-in-the-middle}.")
(define-public tailscale-bin
(package
(name "tailscale-bin")
(version "1.72.1")
(version "1.74.1")
(source (origin
(method url-fetch)
(uri (string-append "https://pkgs.tailscale.com"
"/stable/tailscale_" version "_amd64.tgz"))
(sha256
(base32
"1dngi0cs3p423b9j5ihypq3s95w4ns0pjlmyi54kpfwi31nk3s0i"))))
"12196z8dhdzxq8mjj0rlvhr6wchmi6z33ym36yqqrp4m52xjz7q5"))))
(build-system copy-build-system)
(arguments
(list #:install-plan

@ -14,7 +14,7 @@
(define-public cloudflared
(package
(name "cloudflared")
(version "2024.8.3")
(version "2024.9.1")
(source (origin
(method git-fetch)
(uri (git-reference
@ -26,10 +26,10 @@
;; (snippet '(delete-file-recursively "vendor"))
(sha256
(base32
"1q97279qjajbdblg6ggvgkw2x02p8vvzcv3f9jw5na9psdq6hif3"))))
"0391nrvxi1hlqgd20p0jh0c8smgqfazviijs5ins8wsbszrbjmrw"))))
(build-system go-build-system)
(arguments
(list #:go go-1.22
(list #:go go-1.23
#:install-source? #f
#:import-path "github.com/cloudflare/cloudflared/cmd/cloudflared"
#:unpack-path "github.com/cloudflare/cloudflared"

@ -11,9 +11,12 @@
#:use-module (gnu services)
#:use-module (gnu services configuration)
#:use-module (gnu services shepherd)
#:use-module (gnu home services)
#:use-module (gnu home services shepherd)
#:use-module (gnu system shadow)
#:export (qbittorrent-configuration
qbittorrent-service-type))
qbittorrent-service-type
home-qbittorrent-service-type))
;;
;; qBittorrent
@ -106,3 +109,40 @@ WebUI\\Password_PBKDF2=\"@ByteArray(ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtH
(const %qbittorrent-accounts))))
(default-value (qbittorrent-configuration))
(description "Run qBittorrent daemon.")))
(define home-qbittorrent-activation
#~(let ((config-file
(string-append
(or (getenv "XDG_CONFIG_HOME")
(string-append user-homedir "/.config"))
"/qBittorrent/qBittorrent.conf")))
(unless (file-exists? config-file)
(mkdir-p (dirname config-file))
(copy-file #$%qbittorrent-default-config-file config-file))))
(define home-qbittorrent-shepherd-service
(match-record-lambda <qbittorrent-configuration>
(qbittorrent webui-port extra-options)
(list (shepherd-service
(documentation "Run qbittorrent.")
(provision '(qbittorrent))
(requirement '())
(start
#~(make-forkexec-constructor
(list
#$(file-append qbittorrent "/bin/qbittorrent-nox")
#$(string-append "--webui-port=" (number->string webui-port))
#$@extra-options)))
(stop #~(make-kill-destructor #:grace-period 1800))
(auto-start? #f)))))
(define home-qbittorrent-service-type
(service-type
(name 'qbittorrent)
(extensions
(list (service-extension home-activation-service-type
(const home-qbittorrent-activation))
(service-extension home-shepherd-service-type
home-qbittorrent-shepherd-service)))
(default-value (qbittorrent-configuration))
(description "Run qBittorrent daemon.")))

@ -146,9 +146,6 @@
"The cloudflared executable.")
;; Tunnel options
(metrics
(string "localhost:")
"Listen address for metrics reporting.")
(log-level
(string "info")
"Application logging level (@code{debug}, @code{info}, @code{warn},
@ -166,12 +163,6 @@ headers. This can expose sensitive information in your logs.")
(token
(string "")
"The Tunnel token.")
(http2-origin?
(boolean #f)
"Enable HTTP/2 origin servers.")
(post-quantum?
(boolean #f)
"Create an experimental post-quantum secure tunnel.")
(extra-options
(list-of-strings '())
"List of extra options.")
@ -183,8 +174,8 @@ headers. This can expose sensitive information in your logs.")
(define cloudflare-tunnel-shepherd-service
(match-record-lambda <cloudflare-tunnel-configuration>
(cloudflared metrics log-level log-file extra-tunnel-options
token http2-origin? post-quantum? extra-options)
(cloudflared log-level log-file extra-tunnel-options
token extra-options)
(list (shepherd-service
(documentation "Run cloudflared.")
(provision '(cloudflare-tunnel))
@ -193,17 +184,9 @@ headers. This can expose sensitive information in your logs.")
(list #$(file-append cloudflared "/bin/cloudflared")
"tunnel"
"--no-autoupdate"
"--metrics" #$metrics
"--loglevel" #$log-level
#$@extra-tunnel-options
"run"
#$@(if http2-origin?
'("--http2-origin")
'())
#$@(if post-quantum?
'("--post-quantum")
'())
#$@extra-options)
#:user "nobody"
#:group "nogroup"
@ -242,7 +225,10 @@ headers. This can expose sensitive information in your logs.")
(documentation "Run warp-svc.")
(provision '(cloudflare-warp))
(start #~(make-forkexec-constructor
(list #$(file-append cloudflare-warp "/bin/warp-svc"))))
(list #$(file-append cloudflare-warp "/bin/warp-svc"))
;; Logs are written to
;; /var/lib/cloudflare-warp/cfwarp_service_log.txt.
#:log-file "/dev/null"))
(stop #~(make-kill-destructor))))))
(define cloudflare-warp-service-type
@ -263,6 +249,8 @@ headers. This can expose sensitive information in your logs.")
;;
(define-maybe string)
(define-configuration miniflux-configuration
(miniflux
(file-like miniflux)
@ -270,6 +258,9 @@ headers. This can expose sensitive information in your logs.")
(log-file
(string "/var/log/miniflux.log")
"Where the logs go.")
(proxy-url
maybe-string
"Proxy URL to use.")
(options
(alist '())
"Association list of miniflux configuration options.")
@ -290,7 +281,7 @@ headers. This can expose sensitive information in your logs.")
(define miniflux-shepherd-service
(match-record-lambda <miniflux-configuration>
(miniflux log-file options)
(miniflux log-file proxy-url options)
(let ((config-file (mixed-text-file
"miniflux.conf"
(apply string-append
@ -303,10 +294,16 @@ headers. This can expose sensitive information in your logs.")
(provision '(miniflux))
(requirement '(postgres user-processes))
(start #~(make-forkexec-constructor
(list #$miniflux "-config-file" #$config-file)
(list #$(file-append miniflux "/bin/miniflux")
"-config-file" #$config-file)
#:user "miniflux"
#:group "nogroup"
#:log-file #$log-file))
#:log-file #$log-file
#:environment-variables
'#$(if (maybe-value-set? proxy-url)
(list (string-append "HTTP_PROXY=" proxy-url)
(string-append "HTTPS_PROXY=" proxy-url))
'())))
(stop #~(make-kill-destructor)))))))
(define miniflux-service-type

@ -375,56 +375,23 @@ list, power save will be disabled."))
"The tailscale package to use.")
(iptables
(file-like iptables)
(file-like iptables-nft)
"The iptables package to use.")
(log-file
(string "/var/log/tailscaled.log")
"Path to log file.")
(bird-socket
maybe-string
"Path of the bird UNIX socket.")
(debug-server
maybe-string
"Listen address ([ip]:port) of optional debug server.")
(port
(integer 0)
"UDP port to listen for WireGuard and peer-to-peer traffic; 0 means
automatically select.")
(socket
(string "/var/run/tailscale/tailscaled.sock")
(string "/run/tailscale/tailscaled.sock")
"Path of the service UNIX socket.")
(http-proxy-server
maybe-string
"[ip]:port to run an outbound HTTP proxy (e.g. \"localhost:8080\").")
(socks5-server
maybe-string
"[ip]:port to run a SOCKS5 server (e.g. \"localhost:1080\").")
(state-directory
(string "/var/lib/tailscale")
"Path to directory for storage of config state, TLS certs, temporary incoming
Taildrop files, etc. If empty, it's derived from @code{state-file} when
possible.")
(state-file
maybe-string
"Absolute path of state file; use @code{kube:<secret-name>} to use Kubernetes
secrets or @code{arn:aws:ssm:...} to store in AWS SSM; use 'mem:' to not store
state and register as an ephemeral node. If empty and @code{state-directory} is
provided, the default is @code{<state-directory>/tailscaled.state}.")
(tunnel-interface
(string "tailscale0")
"Tunnel interface name; use @code{\"userspace-networking\"} (beta) to not use
TUN.")
(upload-log?
(boolean #f)
"Whether to upload logs or not, technical support is also disabled when set
@ -433,6 +400,10 @@ to #f.")
(verbosity
(integer 0)
"Log verbosity level; 0 is default, 1 or higher are increasingly verbose.")
(extra-options
(list-of-strings '())
"List of extra options.")
(no-serialization))
(define (tailscale-log-rotations config)
@ -441,9 +412,8 @@ to #f.")
(define tailscale-shepherd-service
(match-record-lambda <tailscale-configuration>
(tailscale iptables log-file bird-socket debug-server port socket
http-proxy-server socks5-server state-directory state-file
tunnel-interface upload-log? verbosity)
(tailscale iptables log-file socket state-directory
upload-log? verbosity extra-options)
(let ((environment
#~(list (string-append "PATH="
(string-join
@ -458,29 +428,13 @@ to #f.")
#~(make-forkexec-constructor
(list
#$(file-append tailscale "/bin/tailscaled")
#$@(if (maybe-value-set? bird-socket)
`("-bird-socket" ,bird-socket)
'())
#$@(if (maybe-value-set? debug-server)
`("-debug" ,debug-server)
'())
#$@(if upload-log?
'()
'("-no-logs-no-support"))
#$@(if (maybe-value-set? http-proxy-server)
`("-outbound-http-proxy-listen" ,http-proxy-server)
'())
"-port" #$(number->string port)
"-socket" #$socket
#$@(if (maybe-value-set? socks5-server)
`("-socks5-server" ,socks5-server)
'())
#$@(if (maybe-value-set? state-file)
`("-state" ,state-file)
'())
"-statedir" #$state-directory
"-tun" #$tunnel-interface
"-verbose" #$(number->string verbosity))
"-verbose" #$(number->string verbosity)
#$@extra-options)
#:environment-variables #$environment
#:log-file #$log-file))
(stop #~(make-kill-destructor)))))))

@ -0,0 +1,311 @@
;; SPDX-FileCopyrightText: 2024 Hilton Chain <hako@ultrarare.space>
;;
;; SPDX-License-Identifier: GPL-3.0-or-later
(define-module (rosenthal services web)
#:use-module (guix gexp)
#:use-module (guix records)
#:use-module (gnu packages admin)
#:use-module (gnu services)
#:use-module (gnu services admin)
#:use-module (gnu services configuration)
#:use-module (gnu services databases)
#:use-module (gnu services docker)
#:use-module (gnu system shadow)
#:use-module (rosenthal utils home-services-utils)
#:export (jellyfin-configuration
jellyfin-service-type
misskey-configuration
misskey-service-type
vaultwarden-configuration
vaultwarden-service-type))
;;
;; Jellyfin
;;
(define-maybe string)
(define-configuration jellyfin-configuration
(cache-directory
(string "/var/cache/jellyfin")
"Path to cache directory.")
(config-directory
(string "/var/lib/jellyfin")
"Path to configuration directory.")
(proxy-url
maybe-string
"Proxy URL.")
(log-file
(string "/var/log/jellyfin.log")
"Path to log file.")
(extra-options
(list-of-strings '())
"List of extra options.")
(no-serialization))
(define %jellyfin-accounts
(list (user-account
(name "jellyfin")
(group "docker")
(system? #t)
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
(define jellyfin-log-rotations
(match-record-lambda <jellyfin-configuration>
(log-file)
(list (log-rotation
(files (list log-file))))))
(define jellyfin-activation
(match-record-lambda <jellyfin-configuration>
(cache-directory config-directory)
#~(let ((user (getpwnam "jellyfin")))
(for-each
(lambda (directory)
(unless (file-exists? directory)
(mkdir-p directory)
(chown directory (passwd:uid user) (passwd:gid user))))
'#$(list cache-directory config-directory)))))
(define jellyfin-oci-containers
(match-record-lambda <jellyfin-configuration>
(cache-directory config-directory proxy-url log-file extra-options)
(list (oci-container-configuration
(user "jellyfin")
(group "docker")
(environment
(if (maybe-value-set? proxy-url)
`(("http_proxy" . ,proxy-url)
("https_proxy" . ,proxy-url))
'()))
(image "jellyfin/jellyfin:latest")
(provision "jellyfin")
(log-file log-file)
(respawn? #t)
(network "host")
(volumes
`((,cache-directory . "/cache")
(,config-directory . "/config")))
(extra-arguments extra-options)))))
(define jellyfin-service-type
(service-type
(name 'jellyfin)
(extensions
(list (service-extension account-service-type
(const %jellyfin-accounts))
(service-extension activation-service-type
jellyfin-activation)
(service-extension rottlog-service-type
jellyfin-log-rotations)
(service-extension oci-container-service-type
jellyfin-oci-containers)))
(default-value (jellyfin-configuration))
(description "Run Jellyfin, a media system.")))
;;
;; Misskey
;;
(define-configuration misskey-configuration
(image
(string "misskey/misskey:latest")
"Misskey docker image to use.")
(config
(yaml-config '())
"Alist of Misskey configuration, to be serialized to YAML format.")
(data-directory
(string "/var/lib/misskey")
"Directory to store @file{files} in.")
(log-file
(string "/var/log/misskey.log")
"Log file to use.")
(no-serialization))
(define %misskey-accounts
(list (user-account
(name "misskey")
(group "docker")
(system? #t)
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
(define %misskey-postgresql-role
(list (postgresql-role
(name "misskey")
(create-database? #t))))
(define misskey-log-rotations
(match-record-lambda <misskey-configuration>
(log-file)
(list (log-rotation
(files (list log-file))))))
(define misskey-activation
(match-record-lambda <misskey-configuration>
(data-directory)
#~(begin
(use-modules (guix build utils))
(let ((user (getpwnam "misskey")))
(unless (file-exists? #$data-directory)
(mkdir-p #$data-directory)
(chown #$data-directory (passwd:uid user) (passwd:gid user)))))))
(define misskey-oci-containers
(match-record-lambda <misskey-configuration>
(image config data-directory log-file )
(let ((config-file
(mixed-text-file
"misskey.yaml"
#~(string-append #$@(serialize-yaml-config config) "\n"))))
(list (oci-container-configuration
(user "misskey")
(group "docker")
(image image)
(provision "misskey")
(requirement '(postgresql redis))
(log-file log-file)
(respawn? #t)
(network "host")
(volumes
`((,(string-append data-directory "/files") . "/misskey/files")
(,config-file . "/misskey/.config/default.yml"))))))))
(define misskey-service-type
(service-type
(name 'misskey)
(extensions
(list (service-extension account-service-type
(const %misskey-accounts))
(service-extension postgresql-role-service-type
(const %misskey-postgresql-role))
(service-extension rottlog-service-type
misskey-log-rotations)
(service-extension activation-service-type
misskey-activation)
(service-extension oci-container-service-type
misskey-oci-containers)))
(default-value (misskey-configuration))
(description "Run Misskey, an interplanetary microblogging platform.")))
;;
;; Vaultwarden
;;
(define-configuration vaultwarden-configuration
(admin-token
maybe-string
"Token for the admin interface, preferably an Argon2 PCH string.")
(database-url
(string "postgresql://user:password@host:port/database")
"Database URL.")
(port
(integer 8000)
"Port to listen on.")
(data-directory
(string "/var/lib/vaultwarden")
"Main data folder.")
(log-file
(string "/var/log/vaultwarden.log")
"Logging to this file.")
(proxy-url
maybe-string
"Proxy URL to use.")
(extra-options
(alist '())
"Extra options.")
(no-serialization))
(define %vaultwarden-accounts
(list (user-account
(name "vaultwarden")
(group "docker")
(system? #t)
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
(define %vaultwarden-postgresql-role
(list (postgresql-role
(name "vaultwarden")
(create-database? #t))))
(define vaultwarden-log-rotations
(match-record-lambda <vaultwarden-configuration>
(log-file)
(list (log-rotation
(files (list log-file))))))
(define vaultwarden-activation
(match-record-lambda <vaultwarden-configuration>
(data-directory log-file)
#~(begin
(use-modules (guix build utils))
(let ((user (getpwnam "vaultwarden")))
(unless (file-exists? #$data-directory)
(mkdir-p #$data-directory)
(chown #$data-directory (passwd:uid user) (passwd:gid user)))
(unless (file-exists? #$log-file)
(mkdir-p (dirname #$log-file))
(call-with-output-file #$log-file
(lambda (port)
(write-char #\newline port)))
(chown #$log-file (passwd:uid user) (passwd:gid user)))))))
(define vaultwarden-oci-containers
(match-record-lambda <vaultwarden-configuration>
(admin-token database-url port data-directory log-file proxy-url extra-options)
(list (oci-container-configuration
(user "vaultwarden")
(group "docker")
(host-environment
`(,@(if (maybe-value-set? admin-token)
`(("ADMIN_TOKEN" . ,admin-token))
'())
("DATABASE_URL" . ,database-url)))
(environment
`(,@(if (maybe-value-set? proxy-url)
`(("HTTP_PROXY" . ,proxy-url))
'())
("LOG_FILE" . "vaultwarden.log")
("ROCKET_PORT" . ,(number->string port))
("USE_SYSLOG" . "True")
,@extra-options))
(image "vaultwarden/server:latest-alpine")
(provision "vaultwarden")
(requirement '(postgresql))
(respawn? #t)
(network "host")
(volumes
`((,data-directory . "/data")
(,log-file . "/vaultwarden.log")))
(extra-arguments
`(,@(if (maybe-value-set? admin-token)
'("--env" "ADMIN_TOKEN")
'())
"--env" "DATABASE_URL"))))))
(define vaultwarden-service-type
(service-type
(name 'vaultwarden)
(extensions
(list (service-extension account-service-type
(const %vaultwarden-accounts))
(service-extension postgresql-role-service-type
(const %vaultwarden-postgresql-role))
(service-extension activation-service-type
vaultwarden-activation)
(service-extension rottlog-service-type
vaultwarden-log-rotations)
(service-extension oci-container-service-type
vaultwarden-oci-containers)))
(default-value (vaultwarden-configuration))
(description "Run Vaultwarden, a Bitwarden compatible server.")))
Loading…
Cancel
Save