Compare commits
2 Commits
3b5d99fba5
...
ab7a7c2ef3
Author | SHA1 | Date | |
---|---|---|---|
ab7a7c2ef3
|
|||
289c649bc3
|
8
flake.lock
generated
8
flake.lock
generated
@@ -511,11 +511,11 @@
|
|||||||
"secrets": {
|
"secrets": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757583391,
|
"lastModified": 1757873556,
|
||||||
"narHash": "sha256-q5ZXkTv0SJw7OMbu2K3b03Fbb+1Hz6ZafqdqGneyX9A=",
|
"narHash": "sha256-WYrV46if1XsiQKOQEMNtHdAPeFDeu7YBdcoNSXc3sf8=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "42df461dac05dccd22df0c36007174dd73aa0aea",
|
"rev": "21ab0b0a59264b1da501f90725bf2c03e07ae941",
|
||||||
"revCount": 40,
|
"revCount": 43,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@karaolidis.com/karaolidis/nix-secrets.git"
|
"url": "ssh://git@karaolidis.com/karaolidis/nix-secrets.git"
|
||||||
},
|
},
|
||||||
|
@@ -0,0 +1,60 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hmConfig = config.home-manager.users.${user};
|
||||||
|
inherit (hmConfig.virtualisation.quadlet) volumes networks;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home-manager.users.${user} = {
|
||||||
|
sops = {
|
||||||
|
secrets."blog/apiKey".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
|
||||||
|
templates.blog-receiver-env.content = ''
|
||||||
|
AUTH_KEY=${hmConfig.sops.placeholder."blog/apiKey"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.quadlet = {
|
||||||
|
volumes.blog = { };
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
blog.containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.nginx}";
|
||||||
|
networks = [ networks.traefik.ref ];
|
||||||
|
volumes = [
|
||||||
|
"${volumes.blog.ref}:/var/www/nginx:ro"
|
||||||
|
];
|
||||||
|
labels = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.blog.rule=Host(`blog.karaolidis.com`)"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
blog-receiver = {
|
||||||
|
containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.nginx-receiver}";
|
||||||
|
networks = [ networks.traefik.ref ];
|
||||||
|
volumes = [ "${volumes.blog.ref}:/var/www/nginx" ];
|
||||||
|
environments = {
|
||||||
|
TARGET_DIR = "/var/www/nginx";
|
||||||
|
SUBPATH = "/upload";
|
||||||
|
};
|
||||||
|
environmentFiles = [ hmConfig.sops.templates.blog-receiver-env.path ];
|
||||||
|
labels = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.blog-receiver.rule=Host(`blog.karaolidis.com`) && PathPrefix(`/upload`)"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig.After = [ "sops-nix.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -12,6 +12,7 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
(import ./attic { inherit user home; })
|
(import ./attic { inherit user home; })
|
||||||
(import ./authelia { inherit user home; })
|
(import ./authelia { inherit user home; })
|
||||||
|
(import ./blog { inherit user home; })
|
||||||
(import ./comentario { inherit user home; })
|
(import ./comentario { inherit user home; })
|
||||||
(import ./gitea { inherit user home; })
|
(import ./gitea { inherit user home; })
|
||||||
(import ./grafana { inherit user home; })
|
(import ./grafana { inherit user home; })
|
||||||
|
@@ -61,7 +61,12 @@ in
|
|||||||
home-manager.users.${user} =
|
home-manager.users.${user} =
|
||||||
let
|
let
|
||||||
autheliaClientId = "I2ZYDFGWP1bzfiauXe94IaiReZF6SqoEskSp6phoL2L8l16Cq7YX3Vr4pkQOSYfNDOwuFjTRIpqQ8eAqK0M93NeEgpr8YoPhKHyR";
|
autheliaClientId = "I2ZYDFGWP1bzfiauXe94IaiReZF6SqoEskSp6phoL2L8l16Cq7YX3Vr4pkQOSYfNDOwuFjTRIpqQ8eAqK0M93NeEgpr8YoPhKHyR";
|
||||||
inherit (hmConfig.virtualisation.quadlet) containers volumes networks;
|
inherit (hmConfig.virtualisation.quadlet)
|
||||||
|
containers
|
||||||
|
volumes
|
||||||
|
networks
|
||||||
|
images
|
||||||
|
;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
sops = {
|
sops = {
|
||||||
@@ -214,6 +219,16 @@ in
|
|||||||
gitea-act-runner-cache = { };
|
gitea-act-runner-cache = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
images.gitea-act-runner-worker.imageConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.gitea-act-runner-worker}";
|
||||||
|
tag =
|
||||||
|
let
|
||||||
|
name = pkgs.dockerImages.gitea-act-runner-worker.passthru.buildArgs.name;
|
||||||
|
tag = pkgs.dockerImages.gitea-act-runner-worker.passthru.imageTag;
|
||||||
|
in
|
||||||
|
"localhost/${name}:${tag}";
|
||||||
|
};
|
||||||
|
|
||||||
containers = {
|
containers = {
|
||||||
gitea = {
|
gitea = {
|
||||||
containerConfig = {
|
containerConfig = {
|
||||||
@@ -278,8 +293,22 @@ in
|
|||||||
volumes =
|
volumes =
|
||||||
let
|
let
|
||||||
uid = builtins.toString config.users.users.${user}.uid;
|
uid = builtins.toString config.users.users.${user}.uid;
|
||||||
|
|
||||||
|
runnerConfig = (pkgs.formats.yaml { }).generate "config.yaml" {
|
||||||
|
runner = {
|
||||||
|
file = "/var/lib/gitea-act-runner/registration";
|
||||||
|
capacity = 4;
|
||||||
|
labels = [ "nix:docker://${images.gitea-act-runner-worker.imageConfig.tag}" ];
|
||||||
|
};
|
||||||
|
cache.dir = "/tmp/gitea-act-runner/";
|
||||||
|
container = {
|
||||||
|
privileged = true;
|
||||||
|
docker_host = "-";
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
|
"${runnerConfig}:/etc/gitea-act-runner/config.yaml:ro"
|
||||||
"/run/user/${uid}/podman/podman.sock:/var/run/docker.sock"
|
"/run/user/${uid}/podman/podman.sock:/var/run/docker.sock"
|
||||||
"${volumes.gitea-act-runner-data.ref}:/var/lib/gitea-act-runner"
|
"${volumes.gitea-act-runner-data.ref}:/var/lib/gitea-act-runner"
|
||||||
"${volumes.gitea-act-runner-cache.ref}:/tmp/gitea-act-runner"
|
"${volumes.gitea-act-runner-cache.ref}:/tmp/gitea-act-runner"
|
||||||
|
@@ -170,14 +170,14 @@ in
|
|||||||
];
|
];
|
||||||
volumes =
|
volumes =
|
||||||
let
|
let
|
||||||
post-setup = pkgs.writeTextFile {
|
postSetup = pkgs.writeTextFile {
|
||||||
name = "post-setup.sh";
|
name = "post-setup.sh";
|
||||||
executable = true;
|
executable = true;
|
||||||
text = builtins.readFile ./post-setup.sh;
|
text = builtins.readFile ./post-setup.sh;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
"${post-setup}:/etc/nextcloud/post-setup.sh:ro"
|
"${postSetup}:/etc/nextcloud/post-setup.sh:ro"
|
||||||
"/mnt/storage/private/storm/containers/storage/volumes/nextcloud-data/_data:/var/lib/nextcloud"
|
"/mnt/storage/private/storm/containers/storage/volumes/nextcloud-data/_data:/var/lib/nextcloud"
|
||||||
"${volumes.nextcloud-log.ref}:/var/log/nextcloud"
|
"${volumes.nextcloud-log.ref}:/var/log/nextcloud"
|
||||||
"${volumes.nextcloud-config.ref}:/var/www/nextcloud/config"
|
"${volumes.nextcloud-config.ref}:/var/www/nextcloud/config"
|
||||||
|
@@ -20,6 +20,7 @@ final: prev:
|
|||||||
flaresolverr = final.docker-image-flaresolverr;
|
flaresolverr = final.docker-image-flaresolverr;
|
||||||
gitea = final.docker-image-gitea;
|
gitea = final.docker-image-gitea;
|
||||||
gitea-act-runner = final.docker-image-gitea-act-runner;
|
gitea-act-runner = final.docker-image-gitea-act-runner;
|
||||||
|
gitea-act-runner-worker = final.docker-image-gitea-act-runner-worker;
|
||||||
grafana = final.docker-image-grafana;
|
grafana = final.docker-image-grafana;
|
||||||
grafana-image-renderer = final.docker-image-grafana-image-renderer;
|
grafana-image-renderer = final.docker-image-grafana-image-renderer;
|
||||||
jellyfin = final.docker-image-jellyfin;
|
jellyfin = final.docker-image-jellyfin;
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
docker-image-flaresolverr = import ./docker/flaresolverr { inherit pkgs; };
|
docker-image-flaresolverr = import ./docker/flaresolverr { inherit pkgs; };
|
||||||
docker-image-gitea = import ./docker/gitea { inherit pkgs; };
|
docker-image-gitea = import ./docker/gitea { inherit pkgs; };
|
||||||
docker-image-gitea-act-runner = import ./docker/gitea-act-runner { inherit pkgs; };
|
docker-image-gitea-act-runner = import ./docker/gitea-act-runner { inherit pkgs; };
|
||||||
|
docker-image-gitea-act-runner-worker = import ./docker/gitea-act-runner-worker { inherit pkgs; };
|
||||||
docker-image-grafana = import ./docker/grafana { inherit pkgs; };
|
docker-image-grafana = import ./docker/grafana { inherit pkgs; };
|
||||||
docker-image-grafana-image-renderer = import ./docker/grafana-image-renderer { inherit pkgs; };
|
docker-image-grafana-image-renderer = import ./docker/grafana-image-renderer { inherit pkgs; };
|
||||||
docker-image-jellyfin = import ./docker/jellyfin { inherit pkgs; };
|
docker-image-jellyfin = import ./docker/jellyfin { inherit pkgs; };
|
||||||
|
38
packages/docker/gitea-act-runner-worker/default.nix
Normal file
38
packages/docker/gitea-act-runner-worker/default.nix
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
containerPolicy = pkgs.writeTextDir "/etc/containers/policy.json" (
|
||||||
|
builtins.readFile (
|
||||||
|
(pkgs.formats.json { }).generate "policy.json" {
|
||||||
|
default = [ { type = "insecureAcceptAnything"; } ];
|
||||||
|
transports.docker-daemon."" = [ { type = "insecureAcceptAnything"; } ];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "gitea-act-runner-worker";
|
||||||
|
fromImage = pkgs.docker-image-base;
|
||||||
|
|
||||||
|
copyToRoot = pkgs.buildEnv {
|
||||||
|
name = "root";
|
||||||
|
paths = with pkgs; [
|
||||||
|
git
|
||||||
|
git-lfs
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
nix
|
||||||
|
nodejs
|
||||||
|
buildah
|
||||||
|
skopeo
|
||||||
|
containerPolicy
|
||||||
|
];
|
||||||
|
pathsToLink = [
|
||||||
|
"/bin"
|
||||||
|
"/etc"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
runAsRoot = ''
|
||||||
|
mkdir -p /var/tmp
|
||||||
|
'';
|
||||||
|
}
|
@@ -10,16 +10,7 @@ let
|
|||||||
runnerConfig = pkgs.writeTextDir "/etc/gitea-act-runner/config.yaml" (
|
runnerConfig = pkgs.writeTextDir "/etc/gitea-act-runner/config.yaml" (
|
||||||
builtins.readFile (
|
builtins.readFile (
|
||||||
(pkgs.formats.yaml { }).generate "config.yaml" {
|
(pkgs.formats.yaml { }).generate "config.yaml" {
|
||||||
runner = {
|
runner.file = "/var/lib/gitea-act-runner/registration";
|
||||||
file = "/var/lib/gitea-act-runner/registration";
|
|
||||||
capacity = 4;
|
|
||||||
labels = [
|
|
||||||
"ubuntu-latest:docker://catthehacker/ubuntu:act-latest"
|
|
||||||
"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04"
|
|
||||||
"ubuntu-20.04:docker://catthehacker/ubuntu:act-20.04"
|
|
||||||
"ubuntu-18.04:docker://catthehacker/ubuntu:act-18.04"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
cache.dir = "/tmp/gitea-act-runner/";
|
cache.dir = "/tmp/gitea-act-runner/";
|
||||||
# https://gitea.com/gitea/act_runner/issues/223#issuecomment-743748
|
# https://gitea.com/gitea/act_runner/issues/223#issuecomment-743748
|
||||||
container.docker_host = "-";
|
container.docker_host = "-";
|
||||||
|
@@ -27,11 +27,14 @@ var (
|
|||||||
maxUploadSize int64 = 1 << 30 // 1GB
|
maxUploadSize int64 = 1 << 30 // 1GB
|
||||||
|
|
||||||
deployLock sync.Mutex
|
deployLock sync.Mutex
|
||||||
|
|
||||||
|
infoLog = log.New(os.Stdout, "", log.LstdFlags)
|
||||||
|
errorLog = log.New(os.Stderr, "", log.LstdFlags)
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if authenticationKey == "" || targetDirectory == "" {
|
if authenticationKey == "" || targetDirectory == "" {
|
||||||
log.Fatal("AUTH_KEY and TARGET_DIR must be set")
|
errorLog.Fatal("AUTH_KEY and TARGET_DIR must be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if port == "" {
|
if port == "" {
|
||||||
@@ -43,15 +46,15 @@ func main() {
|
|||||||
basePath = "/" + subPath
|
basePath = "/" + subPath
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("starting server on :%s, endpoint %q, target directory %q", port, basePath, targetDirectory)
|
infoLog.Printf("starting server on :%s, endpoint %q, target directory %q", port, basePath, targetDirectory)
|
||||||
http.HandleFunc(basePath, withRecovery(handle))
|
http.HandleFunc(basePath, withRecovery(handle))
|
||||||
log.Fatal(http.ListenAndServe(":"+port, nil))
|
errorLog.Fatal(http.ListenAndServe(":"+port, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle(w http.ResponseWriter, r *http.Request) {
|
func handle(w http.ResponseWriter, r *http.Request) {
|
||||||
remoteIP := realIP(r)
|
remoteIP := realIP(r)
|
||||||
|
|
||||||
log.Printf("incoming %q request on %q from %s", r.Method, r.URL.Path, remoteIP)
|
infoLog.Printf("incoming %q request on %q from %s", r.Method, r.URL.Path, remoteIP)
|
||||||
|
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
@@ -60,7 +63,7 @@ func handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
auth := r.Header.Get("Authorization")
|
auth := r.Header.Get("Authorization")
|
||||||
if subtle.ConstantTimeCompare([]byte(auth), []byte(authenticationKey)) != 1 {
|
if subtle.ConstantTimeCompare([]byte(auth), []byte(authenticationKey)) != 1 {
|
||||||
log.Printf("unauthorized request from %s", remoteIP)
|
errorLog.Printf("unauthorized request from %s", remoteIP)
|
||||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ func handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer os.RemoveAll(extractDir)
|
defer os.RemoveAll(extractDir)
|
||||||
|
|
||||||
if err := extractor.Extract(ctx, archiveStream, extract(extractDir)); err != nil {
|
if err := extractor.Extract(ctx, archiveStream, extract(extractDir)); err != nil {
|
||||||
log.Printf("failed to extract archive: %v", err)
|
errorLog.Printf("failed to extract archive: %v", err)
|
||||||
http.Error(w, "bad archive", http.StatusBadRequest)
|
http.Error(w, "bad archive", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -131,7 +134,7 @@ func handle(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
log.Printf("upload successful from %s", remoteIP)
|
infoLog.Printf("upload successful from %s", remoteIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func realIP(r *http.Request) string {
|
func realIP(r *http.Request) string {
|
||||||
@@ -235,7 +238,7 @@ func withRecovery(next http.HandlerFunc) http.HandlerFunc {
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if v := recover(); v != nil {
|
if v := recover(); v != nil {
|
||||||
log.Printf("panic: %v", v)
|
errorLog.Printf("panic: %v", v)
|
||||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
11
patches.nix
11
patches.nix
@@ -1 +1,10 @@
|
|||||||
{ patcher, ... }: { }
|
{ patcher, ... }:
|
||||||
|
{
|
||||||
|
quadlet-nix.patches = [
|
||||||
|
(patcher.fetchpatch {
|
||||||
|
name = "feat: supports images";
|
||||||
|
url = "https://github.com/SEIAROTg/quadlet-nix/compare/main...karaolidis:quadlet-nix:image.diff";
|
||||||
|
hash = "sha256-XLdOrSJ/gyLARGI0psBejtpX9Z2NSRTaUbFtBi8BxPw=";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
Submodule submodules/secrets updated: 42df461dac...21ab0b0a59
Reference in New Issue
Block a user