diff options
Diffstat (limited to 'infra')
| -rw-r--r-- | infra/Caddyfile | 93 | ||||
| -rw-r--r-- | infra/Caddyfile.local | 37 | ||||
| -rw-r--r-- | infra/containers/cgit/.containerignore | 21 | ||||
| -rw-r--r-- | infra/containers/cgit/Containerfile | 27 | ||||
| -rw-r--r-- | infra/containers/cgit/cgitrc | 27 | ||||
| -rw-r--r-- | infra/containers/cgit/cgitrc.local | 27 | ||||
| -rw-r--r-- | infra/containers/cgit/entrypoint.sh | 20 | ||||
| -rw-r--r-- | infra/containers/cgit/nginx.conf | 46 | ||||
| -rw-r--r-- | infra/containers/cgit/supervisord.conf | 42 | ||||
| -rwxr-xr-x | infra/host-setup.sh | 28 | ||||
| -rw-r--r-- | infra/searxng/settings.yml | 24 | ||||
| -rw-r--r-- | infra/services.toml | 47 | ||||
| -rw-r--r-- | infra/stack.service | 33 |
13 files changed, 472 insertions, 0 deletions
diff --git a/infra/Caddyfile b/infra/Caddyfile new file mode 100644 index 0000000..3146529 --- /dev/null +++ b/infra/Caddyfile @@ -0,0 +1,93 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +(https_security) { + header >Strict-Transport-Security "max-age=31536000" +} + +luuduct.ai { + import https_security + handle /.well-known/openpgpkey/* { + root * /srv + header Content-Type application/octet-stream + file_server + } + + handle { + redir https://doan.luuduct.ai{uri} permanent + } +} + +www.luuduct.ai { + import https_security + redir https://doan.luuduct.ai{uri} permanent +} + +doan.luuduct.ai { + import https_security + root * /srv + file_server + + redir /git /git/ + + handle /cgit* { + reverse_proxy cgit:8080 + } + + handle /git/* { + reverse_proxy cgit:8080 + } +} + +openpgpkey.luuduct.ai { + import https_security + handle /.well-known/openpgpkey/* { + root * /srv + header Content-Type application/octet-stream + file_server + } +} + +git.doan.luuduct.ai { + import https_security + redir /{path}.git /{path} permanent + + reverse_proxy cgit:8080 +} + +search.doan.luuduct.ai { + import https_security + reverse_proxy searxng:8080 +} + +www.doan.luuduct.ai { + import https_security + redir https://doan.luuduct.ai{uri} permanent +} + +www.git.doan.luuduct.ai { + import https_security + redir https://git.doan.luuduct.ai{uri} permanent +} + +www.search.doan.luuduct.ai { + import https_security + redir https://search.doan.luuduct.ai{uri} permanent +} + +www.openpgpkey.luuduct.ai { + import https_security + redir https://openpgpkey.luuduct.ai{uri} permanent +} diff --git a/infra/Caddyfile.local b/infra/Caddyfile.local new file mode 100644 index 0000000..03b4a16 --- /dev/null +++ b/infra/Caddyfile.local @@ -0,0 +1,37 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +:80 { + @git path /git /git/* /cgit.js /cgit.png + handle @git { + redir /git /git/ + uri strip_prefix /git + reverse_proxy cgit:8080 + } + + @search path /search /search/* + handle @search { + redir /search /search/ + uri strip_prefix /search + reverse_proxy searxng:8080 { + header_up X-Script-Name /search + } + } + + handle { + root * /srv + file_server + } +} diff --git a/infra/containers/cgit/.containerignore b/infra/containers/cgit/.containerignore new file mode 100644 index 0000000..4fb13e4 --- /dev/null +++ b/infra/containers/cgit/.containerignore @@ -0,0 +1,21 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +* +!Containerfile +!entrypoint.sh +!nginx.conf +!supervisord.conf +!cgitrc diff --git a/infra/containers/cgit/Containerfile b/infra/containers/cgit/Containerfile new file mode 100644 index 0000000..3bd130a --- /dev/null +++ b/infra/containers/cgit/Containerfile @@ -0,0 +1,27 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +FROM docker.io/library/debian:trixie-slim@sha256:1e1a22175fbf1b32157ddaf0219e1db4e5401fab2b94ed285add64d18587cd2d +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + cgit fcgiwrap nginx-light supervisor curl ca-certificates git \ + && rm -rf /var/lib/apt/lists/* /etc/nginx/sites-enabled/default +COPY nginx.conf /etc/nginx/nginx.conf +COPY supervisord.conf /etc/supervisor/stack.conf +COPY cgitrc /etc/cgitrc +COPY entrypoint.sh /usr/local/bin/stack-cgit +RUN chmod 755 /usr/local/bin/stack-cgit +EXPOSE 8080 +ENTRYPOINT ["/usr/local/bin/stack-cgit"] diff --git a/infra/containers/cgit/cgitrc b/infra/containers/cgit/cgitrc new file mode 100644 index 0000000..0b563e0 --- /dev/null +++ b/infra/containers/cgit/cgitrc @@ -0,0 +1,27 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +root-title=Doan Luu Duc Tai's repositories +root-desc=Personal git repos +virtual-root=/ +clone-prefix=https://git.doan.luuduct.ai +css=/cgit.css +favicon=/favicon.ico +remove-suffix=1 +defbranch=main +cache-root=/var/cache/cgit +cache-size=1000 +cache-scanrc-ttl=1 +scan-path=/srv/git diff --git a/infra/containers/cgit/cgitrc.local b/infra/containers/cgit/cgitrc.local new file mode 100644 index 0000000..3c8d657 --- /dev/null +++ b/infra/containers/cgit/cgitrc.local @@ -0,0 +1,27 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +root-title=Doan Luu Duc Tai's repositories (local) +root-desc=Restored local copy +virtual-root=/git/ +clone-prefix=http://localhost:8080/git +css=/git/cgit.css +favicon=/git/favicon.ico +remove-suffix=1 +defbranch=main +cache-root=/var/cache/cgit +cache-size=1000 +cache-scanrc-ttl=1 +scan-path=/srv/git diff --git a/infra/containers/cgit/entrypoint.sh b/infra/containers/cgit/entrypoint.sh new file mode 100644 index 0000000..5de3a06 --- /dev/null +++ b/infra/containers/cgit/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -eu +mkdir -p /run/fcgiwrap /var/cache/cgit +chown www-data:www-data /run/fcgiwrap /var/cache/cgit +exec /usr/bin/supervisord -n -c /etc/supervisor/stack.conf diff --git a/infra/containers/cgit/nginx.conf b/infra/containers/cgit/nginx.conf new file mode 100644 index 0000000..df50345 --- /dev/null +++ b/infra/containers/cgit/nginx.conf @@ -0,0 +1,46 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +user www-data; +worker_processes auto; +pid /run/nginx.pid; +error_log /dev/stderr warn; +events { worker_connections 1024; } +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + access_log /dev/stdout; + map $http_x_forwarded_proto $cgi_https { + default ""; + https on; + } + server { + listen 8080; + server_name _; + root /usr/share/cgit; + location ~* ^/(cgit\.(css|png|js)|favicon\.ico|robots\.txt)$ { + expires 30d; + } + location / { + include /etc/nginx/fastcgi_params; + fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $http_host; + fastcgi_param HTTPS $cgi_https; + fastcgi_pass unix:/run/fcgiwrap/socket; + } + } +} diff --git a/infra/containers/cgit/supervisord.conf b/infra/containers/cgit/supervisord.conf new file mode 100644 index 0000000..1a93bb5 --- /dev/null +++ b/infra/containers/cgit/supervisord.conf @@ -0,0 +1,42 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +[supervisord] +nodaemon=true +user=root +logfile=/dev/null +pidfile=/run/supervisord.pid + +[program:fcgiwrap] +command=/usr/sbin/fcgiwrap -f -s unix:/run/fcgiwrap/socket +user=www-data +umask=0007 +autorestart=true +stopasgroup=true +killasgroup=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/fd/2 +stderr_logfile_maxbytes=0 + +[program:nginx] +command=/usr/sbin/nginx -g "daemon off;" +autorestart=true +stopasgroup=true +killasgroup=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/fd/2 +stderr_logfile_maxbytes=0 diff --git a/infra/host-setup.sh b/infra/host-setup.sh new file mode 100755 index 0000000..e73645b --- /dev/null +++ b/infra/host-setup.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -eu +[ "$(id -u)" = 0 ] || { echo 'Run this script through sudo.' >&2; exit 1; } +id ops >/dev/null +apt-get update +apt-get install -y --no-install-recommends podman uidmap passt slirp4netns fuse-overlayfs netavark aardvark-dns +awk -F: '$1 == "ops" && $3 >= 65536 { found=1 } END { exit !found }' /etc/subuid +awk -F: '$1 == "ops" && $3 >= 65536 { found=1 } END { exit !found }' /etc/subgid +install -d -m 755 /etc/sysctl.d +printf '%s\n' 'net.ipv4.ip_unprivileged_port_start=80' > /etc/sysctl.d/90-stack-rootless-ports.conf +sysctl -p /etc/sysctl.d/90-stack-rootless-ports.conf +loginctl enable-linger ops +printf '%s\n' 'Podman prerequisites ready. Existing production services remain running.' diff --git a/infra/searxng/settings.yml b/infra/searxng/settings.yml new file mode 100644 index 0000000..f8f7d6b --- /dev/null +++ b/infra/searxng/settings.yml @@ -0,0 +1,24 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +use_default_settings: true + +server: + limiter: true + public_instance: false + +search: + formats: + - html diff --git a/infra/services.toml b/infra/services.toml new file mode 100644 index 0000000..97091cf --- /dev/null +++ b/infra/services.toml @@ -0,0 +1,47 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +format = 1 + +[services.caddy] +image = "docker.io/library/caddy:2-alpine@sha256:5f5c8640aae01df9654968d946d8f1a56c497f1dd5c5cda4cf95ab7c14d58648" +gateway = true +health = ["caddy", "validate", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] +mounts = [ + { source = "@caddy", target = "/etc/caddy/Caddyfile", read_only = true }, + { source = "var/data/caddy/data", target = "/data" }, + { source = "var/data/caddy/config", target = "/config" }, + { source = "@web", target = "/srv", read_only = true }, +] + +[services.cgit] +image = "localhost/stack-cgit:0.1.0" +build = "infra/containers/cgit" +health = ["curl", "--fail", "--silent", "--max-time", "3", "http://127.0.0.1:8080/"] +mounts = [ + { source = "var/data/repos", target = "/srv/git", read_only = true }, + { source = "@cgit", target = "/etc/cgitrc", read_only = true }, +] +tmpfs = ["/run", "/var/cache/cgit"] + +[services.searxng] +image = "docker.io/searxng/searxng:latest@sha256:1dab138ea70a8ceb4d1c182f5c8f256088406c1742b99e279976157dbe1e9759" +environment = ["SEARXNG_SECRET"] +drop_capabilities = true +health = ["wget", "--quiet", "--spider", "http://127.0.0.1:8080/"] +mounts = [ + { source = "var/data/searxng", target = "/etc/searxng" }, +] +tmpfs = ["/var/cache/searxng:mode=1777"] diff --git a/infra/stack.service b/infra/stack.service new file mode 100644 index 0000000..64012a9 --- /dev/null +++ b/infra/stack.service @@ -0,0 +1,33 @@ +# Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +[Unit] +Description=Personal web stack +Wants=network-online.target +After=network-online.target + +[Service] +Type=oneshot +RemainAfterExit=yes +WorkingDirectory=%h/stack +ExecStart=%h/stack/bin/stack up --production +ExecStop=%h/stack/bin/stack down +TimeoutStartSec=300 +TimeoutStopSec=120 +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=default.target |
