Skip to content

Forgejo Installation mit Podman Quadlet auf Hetzner VM

Podman
2 1 106
  • Meinen ersten Versuch findet man hier. Mittlerweile habe ich das Setup verfeinert und bin zufrieden. Das wollte ich hier teilen.

    Der Plan ist es einen Forgejo Server aufzusetzen. Die Dienste sollen alle als Podman Container laufen. Die Podman Installation soll auf Quadlet basieren.

    Ich brauche also einen Forgejo Pod mit folgenden Containern

    • Forgejo
    • Postgres
    • Nginx

    Das ganze soll auf Quadlet basieren. Was ist das?

    Quadlet is a tool for running Podman containers under systemd in an optimal way by allowing containers to run under systemd in a declarative way. It has been merged into Podman 4.4.

    Ok, wenn wir schon dran sind, was ist Podman?

    Podman (kurz für POD-Manager) ist ein Open Source-Tool, mit dem Sie Container entwickeln, managen und ausführen können. Das Tool wurde von Red Hat® Engineers in Zusammenarbeit mit der Open Source Community entwickelt, und es verwaltet das gesamte Container-IT-Ökosystem mithilfe der libpod-Library.

    Installation Server

    Ich nutze eine VM von Hetzner . Darauf läuft ein Debian 13 "Trixie". Also, die nächste Version die kommt.

    deb http://deb.debian.org/debian trixie main contrib non-free-firmware
    # deb-src http://deb.debian.org/debian bookworm main contrib non-free-firmware
    
    deb http://deb.debian.org/debian trixie-updates main contrib non-free-firmware
    # deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free-firmware
    
    # deb http://deb.debian.org/debian bookworm-backports main contrib non-free-firmware
    # deb-src http://deb.debian.org/debian bookworm-backports main contrib non-free-firmware
    
    deb http://security.debian.org/debian-security trixie-security main contrib non-free-firmware
    # deb-src http://security.debian.org/debian-security bookworm-security main contrib non-free-firmware
    

    Warum Trixie? Mein Profi Berater meint, die uralte Podman Version sollte man nicht mehr benutzen, man braucht etwas Frisches 🙂

    root@forgejo:/etc/apt# podman -v
    podman version 5.3.2
    

    Security Server

    Meine produktive Installation wird

    • Firewall wird über Hetzner gemacht. Port 22, 80, 443
    • zusätzlich nftables
    • fail2ban

    Voraussetzungen

    Nachinstallierte Pakete.

    apt install podman podman-compose fail2ban nftables git socat
    

    Ich hoffe, ich habe hier nichts vergessen. Wenn doch kommt ja eine Meldung, dann kann man das einfach nachinstallieren.

    ACME

    Wird benötigt für das SSL Zertifikat. @Nico schwört ja immer drauf 😉

    git clone --depth 1 https://github.com/acmesh-official/acme.sh.git
    cd acme.sh/
    ./acme.sh --server letsencrypt --standalone --issue -d forgejo.linux-nerds.org 
    ./acme.sh --install-cert -d forgejo.linux-nerds.org --cert-file      /root/nginx/letsencrypt/live/forgejo.linux-nerds.org/cert.pem  --key-file       /root/nginx/letsencrypt/live/forgejo.linux-nerds.org/key.pem  --fullchain-file /root/nginx/letsencrypt/live/forgejo.linux-nerds.org/fullchain.pem
    

    git und socat sind für acme nötig.

    Crontab zur Aktualisierung des Zertifikates anlegen

    Crontab anlegen

    crontab -e
    

    Inhalt

    03 09 1 * * /root/renew_new.sh >> /var/log/acme-renewal.log 2>&1
    

    Script (mit KI Hilfe)

    #!/bin/bash
    
    # Optimized SSL Certificate Renewal Script
    LOG_FILE="/var/log/acme-renewal.log"
    DOMAIN="forgejo.example.com"
    CERT_DIR="/etc/nginx/letsencrypt/live/${DOMAIN}"
    
    log() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
    }
    
    log "=== Starting SSL certificate renewal ==="
    
    # Check if force renewal is requested
    FORCE_RENEWAL=false
    if [[ "$1" == "--force" ]]; then
        FORCE_RENEWAL=true
        log "Force renewal requested"
    fi
    
    # Only stop nginx
    log "Stopping nginx service..."
    systemctl stop nginx.service
    sleep 2
    
    # Renew certificate
    log "Renewing certificate for $DOMAIN..."
    cd /root/acme.sh
    
    if [[ "$FORCE_RENEWAL" == true ]]; then
        RENEW_CMD="./acme.sh --renew -d $DOMAIN --standalone --server letsencrypt --home /root/.acme.sh --force"
    else
        RENEW_CMD="./acme.sh --renew -d $DOMAIN --standalone --server letsencrypt --home /root/.acme.sh"
    fi
    
    if $RENEW_CMD; then
        log "Certificate renewal successful"
        
        # Copy certificates
        cp /root/.acme.sh/${DOMAIN}_ecc/fullchain.cer "${CERT_DIR}/fullchain.pem"
        cp /root/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.key "${CERT_DIR}/key.pem"
        chown -R 999:996 "${CERT_DIR}"
        chmod 644 "${CERT_DIR}/fullchain.pem"
        chmod 600 "${CERT_DIR}/key.pem"
        
        log "Certificates installed successfully"
    else
        log "ERROR: Certificate renewal failed!"
        systemctl start nginx.service
        exit 1
    fi
    
    # Start nginx
    log "Starting nginx service..."
    systemctl start nginx.service
    log "=== SSL renewal completed successfully ==="
    

    Test auf der Konsole

    2025-06-06 13:54:47 - Renewing certificate for forgejo.example.org...
    [Fri Jun  6 01:54:47 PM UTC 2025] The domain 'forgejo.example.org' seems to already have an ECC cert, let's use it.
    [Fri Jun  6 01:54:47 PM UTC 2025] Renewing: 'forgejo.example.org'
    [Fri Jun  6 01:54:47 PM UTC 2025] Renewing using Le_API=https://acme-v02.api.letsencrypt.org/directory
    [Fri Jun  6 01:54:47 PM UTC 2025] Skipping. Next renewal time is: 2025-07-27T18:24:25Z
    [Fri Jun  6 01:54:47 PM UTC 2025] Add '--force' to force renewal.
    2025-06-06 13:54:47 - ERROR: Certificate renewal failed!
    

    Passt, Zertifikat noch gültig.

    User

    Ich brauche ein paar User auf dem Host.

    useradd -m -d /home/pguser pguser
    useradd -m -d /home/forgejo forgejo
    

    Secrets erstellen

    podman secret create POSTGRES_PASSWORD /root/secrets/POSTGRES_PASSWORD.txt
    

    Hier liegt das Postgres Passwort drin. Ich erläutere in einem anderen Artikel was Podman Secret ist.

    Pod erstellen

    /etc/containers/systemd/forgejo.pod

    Kurz nochmal der Hinweis, ich baue jetzt eine komplette Quadlet Installation. Dafür legt man verschiedene Textfiles an, die dann von systemd in DIenste umgewandelt werden und das alles starten und verwalten.

    Wir brauchen einen forgejo.pod

    [Unit]
    Description=Forgejo Pod
    Requires=network.target
    After=network-online.target
    
    [Pod]
    PodName=forgejo-pod
    Network=systemd-podman-ipv4
    PublishPort=3000:3000
    PublishPort=222:22
    PublishPort=80:80
    PublishPort=443:443
    #PublishPort=[::]:3000:3000
    #PublishPort=[::]:222:22
    #PublishPort=[::]:80:80
    #PublishPort=[::]:443:443
    
    [Install]
    WantedBy=multi-user.target
    

    Hier im Beispiel ist der POD nur IPv4 tauglich.

    Network erstellen

    /etc/containers/systemd/podman-ipv4.network

    Man sieht ja oben im Pod, das dort das Network systemd-podman-ipv4 aufgerufen. Dann erstellen wir das mal. Dazu brauchen wir das File podman-ipv4.network mit folgendem Inhalt.

    # /etc/containers/systemd/podman-ipv4.network
    [Unit]
    Description=Podman IPv4 Network
    Before=forgejo-pod.service
    
    [Network]
    Subnet=10.89.0.0/16
    Gateway=10.89.0.1
    IPRange=10.89.0.0/24
    DisableDNS=true
    
    [Install]
    WantedBy=multi-user.target
    

    Etwas verwirrend ist die Namensgebung. Hier sieht man aber was passiert.

    root@debian-4gb-nbg1-2-forgejo:/etc/containers/systemd# systemctl status podman-ipv4-network.service 
    ● podman-ipv4-network.service - Podman IPv4 Network
         Loaded: loaded (/etc/containers/systemd/podman-ipv4.network; generated)
         Active: active (exited) since Wed 2025-06-04 18:19:25 UTC; 1 day 19h ago
     Invocation: 4c270a199fbd4ac08bc25e1cbc0bf316
       Main PID: 854 (code=exited, status=0/SUCCESS)
       Mem peak: 18.1M
            CPU: 74ms
    
    Jun 04 18:19:24 debian-4gb-nbg1-2-forgejo systemd[1]: Starting podman-ipv4-network.service - Podman IPv4 Network...
    Jun 04 18:19:25 debian-4gb-nbg1-2-forgejo podman[854]: 2025-06-04 18:19:25.448483441 +0000 UTC m=+0.459031549 network create 1126fa6c1a9d35a035846e3710f9d1f9e7311d594487f6256487d060f4915>
    Jun 04 18:19:25 debian-4gb-nbg1-2-forgejo podman-ipv4-network[854]: systemd-podman-ipv4
    Jun 04 18:19:25 debian-4gb-nbg1-2-forgejo systemd[1]: Finished podman-ipv4-network.service - Podman IPv4 Network.
    

    Wer wissen will warum, kann ja mal das bei einer KI seiner Wahl eingeben.

    Im Pod steht "Network=systemd-podman-ipv4", der resultierende systemd Dienst "podman-ipv4-network.service" Warum ist das so?

    Das hier

    DisableDNS=true
    

    hat mich sehr viel Zeit gekostet. Eigentlich wird der DNS im POD bzw. in dem resultierenden Netzwerk verwaltet, es gibt da aber offensichtlich einen fiesen Bug, weil es mir nicht gelungen ist eine DNS Auflösung aus dem Forgejo Container hinzubekommen. Somit wurd die DNS Auflösung ausgeschaltet und muss dann in jedem Container seperat eingestellt werden.

    Der Rest kreiert ein internes Netzwerk, jetzt nichts besonderes.

    Jetzt kommen wir zu den Containern

    Forgejo Container

    Hinweis zu den Environment Einträgen!

    The Forgejo configuration is stored in the app.ini file as described in the Configuration Cheat Sheet. When using the Forgejo container image, this file is automatically created if it does not exist already. In addition it is possible to add settings using configuration variables. For instance:

    FORGEJO__repository__ENABLE_PUSH_CREATE_USER=true
    

    is the equivalent of adding the following to app.ini:

    [repository]
    ENABLE_PUSH_CREATE_USER = true
    

    NOTE: it is not possible to use environment variables to remove an existing value, it must be done by editing the app.ini file.

    NOTE: in case you are in a SELinux environment check the audit logs if you are having issues with containers.
    Quelle: https://forgejo.org/docs/latest/admin/installation-docker/

    /etc/containers/systemd/forgejo.container

    [Unit]
    Description=Forgejo Container im Pod forgejo-pod
    After=forgejo-pod.service
    Requires=forgejo-pod.service
    BindsTo=forgejo-pod.service
    Restart=always
    
    DNS=8.8.8.8
    DNS=1.1.1.1
        
    [Container]
    Image=codeberg.org/forgejo/forgejo:11.0.1
    AutoUpdate=registry
    Label=PODMAN_SYSTEMD_UNIT=%n
    PodmanArgs=--pod=forgejo-pod --name=forgejo
    
    ## User
    Environment=USER_UID=1001
    Environment=USER_GID=1001
    
    ## Mail
    Environment=FORGEJO__MAILER
    Environment=FORGEJO__MAILER__ENABLED=true
    Environment=FORGEJO__MAILER__FROM=forgejo@example.com
    Environment=FORGEJO__MAILER__PROTOCOL=smtps
    Environment=FORGEJO__MAILER__SMTP_ADDR=smtps.example.com
    Environment=FORGEJO__MAILER__SMTP_PORT=465
    Environment=FORGEJO__MAILER__USER=<user>
    Environment=FORGEJO__MAILER__PASSWD=<password>
    
    ## Registration
    Environment=FORGEJO__SERVICE__REGISTER_EMAIL_CONFIRM=true
    Environment=FORGEJO__SERVICE__ENABLE_NOTIFY_MAIL=true
    Environment=FORGEJO__SERVICE__DISABLE_REGISTRATION=false
    
    ## Captcha
    Environment=FORGEJO__SERVICE__ENABLE_CAPTCHA=true
    Environment=FORGEJO__SERVICE__CAPTCHA_TYPE=cfturnstile
    Environment=FORGEJO__SERVICE__CF_TURNSTILE_SECRET="<secret>"
    Environment=FORGEJO__SERVICE__CF_TURNSTILE_SITEKEY="<sitekey>"
    
    ## Other
    Environment=FORGEJO__SERVICE__DEFAULT_ALLOW_CREATE_ORGANIZATION=false
    
    # Setting für Repositories
    Environment=FORGEJO__repository__MAX_CREATION_LIMIT=0
    
    ## Log
    Environment=FORGEJO__LOG__LEVEL=warn
    Environment=FORGEJO__LOG__MODE=file
    Environment=FORGEJO__LOG__ROOT_PATH=/data/forgejo/log
    
    # Log-Rotation-Einstellungen
    Environment=FORGEJO__LOG__FILE_NAME=forgejo.log
    Environment=FORGEJO__LOG__ROTATE=true
    Environment=FORGEJO__LOG__MAX_SIZE=256
    Environment=FORGEJO__LOG__MAX_DAYS=7
    Environment=FORGEJO__LOG__MAX_BACKUPS=5
    Environment=FORGEJO__LOG__COMPRESS_BACKUPS=true
    Environment=FORGEJO__LOG__COMPRESS_ARCHIVE=true
    
    # Gleiche Einstellungen für Access- und Router-Logs
    Environment=FORGEJO__LOG__ACCESS__LEVEL=warn
    Environment=FORGEJO__LOG__ACCESS__MODE=file
    Environment=FORGEJO__LOG__ACCESS__FILE_NAME=access.log
    Environment=FORGEJO__LOG__ACCESS__ROTATE=true
    Environment=FORGEJO__LOG__ACCESS__MAX_SIZE=256
    Environment=FORGEJO__LOG__ACCESS__MAX_DAYS=7
    Environment=FORGEJO__LOG__ACCESS__MAX_BACKUPS=5
    
    Environment=FORGEJO__LOG__ROUTER__LEVEL=warn
    Environment=FORGEJO__LOG__ROUTER__MODE=file
    Environment=FORGEJO__LOG__ROUTER__FILE_NAME=router.log
    Environment=FORGEJO__LOG__ROUTER__ROTATE=true
    Environment=FORGEJO__LOG__ROUTER__MAX_SIZE=256
    Environment=FORGEJO__LOG__ROUTER__MAX_DAYS=7
    Environment=FORGEJO__LOG__ROUTER__MAX_BACKUPS=5
    
    # Volumes
    Volume=/home/forgejo:/data
    Volume=/etc/timezone:/etc/timezone:ro
    Volume=/etc/localtime:/etc/localtime:ro
    
    [Install]
    WantedBy=multi-user.target
    WantedBy=forgejo-pod.service
    

    NGINX Container

    Für NGINX brauchen wir folgende Files

    /etc/nginx/default.conf

    server {
        listen 80;
        server_name forgejo.example.org;
        return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name forgejo.example.org.org;
    
        # Use Mozilla's guidelines for SSL/TLS settings
        # https://mozilla.github.io/server-side-tls/ssl-config-generator/
        ssl_certificate      /etc/nginx/letsencrypt/live/forgejo.example.org/fullchain.pem;
        ssl_certificate_key  /etc/nginx/letsencrypt/live/forgejo.example.org/key.pem;
        ssl_dhparam /etc/nginx/letsencrypt/live/forgejo.example.org.org/dhparam.pem;
    
        # enables TLSv1.2 & TLSv1.3
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers off;
    
        # Prevent nginx HTTP Server Detection
        server_tokens off;
    
        # HSTS settings
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        # add_header Strict-Transport-Security "max-age=15552000; includeSubDomains;" always;
    
        # set max upload size and increase upload timeout:
        client_max_body_size 512M;
        client_body_timeout 300s;
        fastcgi_buffers 64 4K;
    
        # The settings allows you to optimize the HTTP2 bandwitdth.
        # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
        # for tunning hints
        client_body_buffer_size 512k;
    
        # Remove X-Powered-By, which is an information leak
        fastcgi_hide_header X-Powered-By;
    
        location / {
            proxy_pass http://<IP-Adresse Server>:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    
    }
    

    und einen Ordner

    /etc/nginx/letsencrypt/live/forgejo.linux-nerds.org/

    Darin liegen die Zertifikate

    root@forgejo:# ls -lha /etc/nginx/letsencrypt/live/forgejo.linux-nerds.org/
    total 24K
    drwxr-xr-x 2 999 996 4.0K Mar  2 18:36 .
    drwxr-xr-x 3 999 996 4.0K Feb 28 07:49 ..
    -rw-r--r-- 1 999 996 1.3K Feb 28 07:49 cert.pem
    -rw-r--r-- 1 999 996  428 Mar  2 18:30 dhparam.pem
    -rw-r--r-- 1 999 996 2.8K Feb 28 07:49 fullchain.pem
    -rw------- 1 999 996  227 Feb 28 07:49 key.pem
    

    Dann das File für den Container

    /etc/containers/systemd/nginx.container

    Auch der Nginx-Container wird im selben Pod gestartet. Dadurch nutzen alle Container denselben Netzwerk-Namespace, was u. a. bedeutet, dass sie sich über ihre Containernamen (z. B. postgres) erreichen können. Wichtig bei der Installation von Forgejo, dort gibt man dann postgres:5432 an.

    [Unit]
    Description=NGINX Container im Pod forgejo-pod
    After=forgejo-pod.service
    Requires=forgejo-pod.service
    BindsTo=forgejo-pod.service
    Restart=always
    
    [Container]
    Image=docker.io/library/nginx:latest
    AutoUpdate=registry
    Label=io.containers.autoupdate=registry
    Label=PODMAN_SYSTEMD_UNIT=%n
    PodmanArgs=--pod=forgejo-pod --name=nginx --label=io.containers.autoupdate=registry --label=PODMAN_SYSTEMD_UNIT=%n
    Volume=/etc/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    Volume=/etc/nginx/letsencrypt/live/forgejo.example.com/:/etc/nginx/letsencrypt/live/forgejo.example.com:ro
    Volume=/etc/nginx/blocklists/nginx-block-ai-bots.conf:/etc/nginx/blocklists/nginx-block-ai-bots.conf:ro
    Volume=/etc/nginx/blocklists/robots.txt:/var/www/html/robots.txt:ro
      
    [Install]
    WantedBy=multi-user.target
    WantedBy=forgejo-pod.service
    

    Postgres Container

    /etc/containers/systemd/postgres.container

    [Unit]
    Description=Postgres Container im Pod forgejo-pod
    After=forgejo-pod.service
    Requires=forgejo-pod.service
    BindsTo=forgejo-pod.service
    Restart=always
    
    [Container]
    Image=docker.io/library/postgres:17
    AutoUpdate=registry
    Label=PODMAN_SYSTEMD_UNIT=%n
    User=1000:1000
    PodmanArgs=--pod=forgejo-pod --name=postgres --secret=POSTGRES_PASSWORD,type=env,target=POSTGRES_PASSWORD
    Volume=/home/pguser/db-data:/var/lib/postgresql/data
    
    [Install]
    WantedBy=multi-user.target
    WantedBy=forgejo-pod.service
    

    Nachdem alle Files erstellt wurden, lädt man mal den Daemon neu

    systemctl daemon-reload
    

    Jetzt sollten alle Dienste angelegt worden sein.

    • postgres.service
    • forgejo.service
    • nginx.service

    Das kann so kontrollieren. Netzwerkliste

    root@forgejo:~# podman network list
    NETWORK ID    NAME                 DRIVER
    2f259bab93aa  podman               bridge
    1126fa6c1a9d  systemd-podman-ipv4  bridge
    

    Der Pod

    root@forgejo:~# podman pod list
        POD ID        NAME         STATUS      CREATED      INFRA ID      # OF CONTAINERS
        ed4aabd15fd7  forgejo-pod  Running     6 hours ago  90dea473c3be  4
    

    Die Container

    root@debian-4gb-nbg1-2-forgejo:~# podman ps
    CONTAINER ID  IMAGE                                    COMMAND               CREATED         STATUS         PORTS                                                                                            NAMES
    90dea473c3be  localhost/podman-pause:5.4.2-1748111104                        6 hours ago     Up 6 hours     0.0.0.0:80->80/tcp, 0.0.0.0:222->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:3000->3000/tcp            forgejo-pod-infra
    bd58246de050  codeberg.org/forgejo/forgejo:11.0.1      /usr/bin/s6-svsca...  6 hours ago     Up 6 hours     0.0.0.0:80->80/tcp, 0.0.0.0:222->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:3000->3000/tcp            forgejo
    4ad8f7e26210  docker.io/library/postgres:17            postgres              6 hours ago     Up 6 hours     0.0.0.0:80->80/tcp, 0.0.0.0:222->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:3000->3000/tcp, 5432/tcp  postgres
    8173e49790fd  docker.io/library/nginx:latest           nginx -g daemon o...  43 minutes ago  Up 44 minutes  0.0.0.0:80->80/tcp, 0.0.0.0:222->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:3000->3000/tcp            nginx
    

    Wenn was nicht startet, kann man hiermit mal eben schnell reinschauen wo es klemmt.

    systemctl status nginx.service
    

    Die anderen Dienste analog.

    Rechte

    Ein Thema was ich nicht wirklich verstehe, aber man kann ja dran arbeiten. Schauen wir uns mal die einzelnen Container an.

    nginx-proxy

    root@forgejo:/home/pguser# podman top nginx
    USER        PID         PPID        %CPU        ELAPSED              TTY         TIME        COMMAND
    root        1           0           0.000       11h22m59.211971839s  ?           0s          nginx: master process nginx -g daemon off; 
    nginx       16          1           0.000       11h22m59.212103517s  ?           0s          nginx: worker process 
    nginx       17          1           0.000       11h22m59.21219268s   ?           0s          nginx: worker process 
    

    NGINX läuft als root, die Worker als User nginx.

    postgres

    root@forgejo:/home/pguser# podman top postgres
    USER        PID         PPID        %CPU        ELAPSED              TTY         TIME        COMMAND
    pguser      1           0           0.005       11h23m46.923566147s  ?           2s          postgres 
    pguser      9           1           0.000       11h23m46.923736112s  ?           0s          postgres: checkpointer  
    pguser      10          1           0.000       11h23m46.923826476s  ?           0s          postgres: background writer  
    pguser      12          1           0.000       11h23m45.923891884s  ?           0s          postgres: walwriter  
    pguser      13          1           0.000       11h23m45.923977432s  ?           0s          postgres: autovacuum launcher  
    pguser      14          1           0.000       11h23m45.92404386s   ?           0s          postgres: logical replication launcher  
    pguser      350         1           0.003       8h53m41.924108998s   ?           1s          postgres: postgres postgres 127.0.0.1(51406) idle 
    pguser      1372        1           0.000       53m41.924171702s     ?           0s          postgres: postgres postgres 127.0.0.1(53832) idle 
    

    Postgres läuft wie eingestellt, mit dem User pguser.

    forgejo

    root@forgejo:/home/pguser# podman top forgejo 
    USER        PID         PPID        %CPU        ELAPSED              TTY         TIME        COMMAND
    root        1           0           0.000       11h24m30.390732597s  ?           0s          /bin/s6-svscan /etc/s6 
    root        11          1           0.000       11h24m30.390842417s  ?           0s          s6-supervise openssh 
    root        12          1           0.000       11h24m30.390906629s  ?           0s          s6-supervise gitea 
    git         13          12          0.285       11h24m30.390967669s  ?           1m57s       /usr/local/bin/gitea web 
    root        14          11          0.000       11h24m30.391030954s  ?           0s          sshd: /usr/sbin/sshd -D -e [listener] 0 of 10-100 startups 
    

    Forgejo läuft als root, aber die Dienste, die nach außen kommunizieren, werden als forgejo gestartet. Kann man sich mit htop ansehen.
    Backups

    Für Backups braucht ihr nur diese beiden Ordner sichern.

    • /home/pguser/db-data/
    • /home/forgero

    Anmerkungen

    Wer hier Fehler oder Verbesserungsvorschläge hat, schreibt es gerne hier unten drunter. Ich freue mich über jeden Tipp.

    Teile dieser Doku sind mit Text von ChatGPT erstellt worden. Dürfte aber mittlerweile nicht mehr viel von über sein, aber wegen der Transparenz sei dies hier erwähnt.

    Bei Gelegenheit ergänze ich noch die Installation von nftables & fail2ban.

  • FrankMF FrankM hat auf dieses Thema verwiesen
  • FrankMF FrankM hat auf dieses Thema verwiesen
  • Schauen wir uns mal an, wie man die Container aktuell hält.

    In der postgres.container steht das hier (als Beispiel)

    [Container]
    Image=docker.io/library/postgres:17
    AutoUpdate=registry
    

    Das AutoUpdate=registry ist die Voraussetzung, dass der Container aktualisiert werden darf.

    Mit diesem Befehl kann man sich anschauen, wie der Stand der DInge ist.

    root@debian-4gb-nbg1-2-forgejo:~# podman auto-update --dry-run
                UNIT                 CONTAINER                IMAGE                                POLICY      UPDATED
                forgejo-pod.service  6486189fb10c (postgres)  docker.io/library/postgres:17        registry    false
                forgejo-pod.service  7d5627e2d434 (forgejo)   codeberg.org/forgejo/forgejo:11.0.1  registry    false
                forgejo-pod.service  7fb26d4f8b58 (nginx)     docker.io/library/nginx:latest       registry    false
    

    Podman hat aber standardmäßig einen systemd Dienst, der sich darum kümmert 😉

    root@forgejo:/etc/containers/systemd# systemctl status podman-auto-update.service
    ○ podman-auto-update.service - Podman auto-update service
         Loaded: loaded (/usr/lib/systemd/system/podman-auto-update.service; enabled; preset: enabled)
         Active: inactive (dead) since Mon 2025-06-09 00:02:57 UTC; 12h ago
     Invocation: a098f0054b254a0888ee789200ac9507
    TriggeredBy: ● podman-auto-update.timer
           Docs: man:podman-auto-update(1)
        Process: 68939 ExecStart=/usr/bin/podman auto-update (code=exited, status=0/SUCCESS)
        Process: 68947 ExecStartPost=/usr/bin/podman image prune -f (code=exited, status=0/SUCCESS)
       Main PID: 68939 (code=exited, status=0/SUCCESS)
       Mem peak: 14.4M
            CPU: 292ms
    
    Jun 09 00:02:55 forgejo systemd[1]: Starting podman-auto-update.service - Podman auto-update service...
    Jun 09 00:02:55 forgejo podman[68939]: 2025-06-09 00:02:55.368941 +0000 UTC m=+0.059687227 system auto-update
    Jun 09 00:02:57 forgejo podman[68939]:             UNIT                 CONTAINER                IMAGE                                POLICY      UPDATED
    Jun 09 00:02:57 forgejo podman[68939]:             forgejo-pod.service  6486189fb10c (postgres)  docker.io/library/postgres:17        registry    false
    Jun 09 00:02:57 forgejo podman[68939]:             forgejo-pod.service  7d5627e2d434 (forgejo)   codeberg.org/forgejo/forgejo:11.0.1  registry    false
    Jun 09 00:02:57 forgejo podman[68939]:             forgejo-pod.service  f2e9eee72017 (nginx)     docker.io/library/nginx:latest       registry    false
    Jun 09 00:02:57 forgejo systemd[1]: podman-auto-update.service: Deactivated successfully.
    Jun 09 00:02:57 forgejo systemd[1]: Finished podman-auto-update.service - Podman auto-update service.
    

    postgres

    Ok, die Container sollten automatisch aktualisiert werden.

    docker.io/library/postgres:17
    

    Die Postgres DB ist auf die Version 17 festgezurrt. Aktuell ist

    root@forgejo:/etc/containers/systemd# podman exec postgres postgres --version
    postgres (PostgreSQL) 17.5 (Debian 17.5-1.pgdg120+1)
    

    Eine Version 17.6 wird jetzt automatisch installiert, eine Version 18 aber nicht.

    nginx

    docker.io/library/nginx:latest
    

    NGINX zieht sich also immer die letzte "latest" Version, die zur Verfügung gestellt wird.

    root@forgejo:/etc/containers/systemd# podman exec nginx nginx -v
    nginx version: nginx/1.27.5
    

    Gerade mal gecheckt, 1.27.5 ist die letzte Mainline Version. Also sind wir aktuell.

    forgejo

    Der Eintrag

    codeberg.org/forgejo/forgejo:11.0.1 
    

    aktuelle Version, die installiert ist.

    root@forgejo:/etc/containers/systemd# podman exec forgejo forgejo -v
    Forgejo version 11.0.1+gitea-1.22.0 (release name 11.0.1) built with GNU Make 4.4.1, go1.24.2 : bindata, timetzdata, sqlite, sqlite_unlock_notify
    

    Ok, wir sind auf Version 11.0.1 Wenn jetzt die Version 11.0.2 herauskommt, wird diese nicht installiert, da wir im forgejo.container folgendes stehen haben.

    [Container]
    Image=codeberg.org/forgejo/forgejo:11.0.1
    

    Das ist aber erst mal nicht so schlimm, ich lese da mit und bekomme das mit. Das mache ich auch lieber von Hand, dann kann ich besser sehen wo es klemmt 😉

  • 0 Stimmen
    1 Beiträge
    23 Aufrufe
    Niemand hat geantwortet
  • Minio - Objektspeicher selbst gehostet

    Linux minio linux restic
    1
    1
    0 Stimmen
    1 Beiträge
    205 Aufrufe
    Niemand hat geantwortet
  • Update 1.32.6

    Vaultwarden vaultwarden linux
    1
    0 Stimmen
    1 Beiträge
    152 Aufrufe
    Niemand hat geantwortet
  • Rest-Server v0.13.0 released

    Restic rest-server restic linux
    2
    0 Stimmen
    2 Beiträge
    399 Aufrufe
    FrankMF
    Download Rest-Server und installieren Im Github Repository den aktuellen Release suchen. Hier am Beispiel der aktuellen Version 0.13.0 (27.07.2024) Datei herunterladen wget https://github.com/restic/rest-server/releases/download/v0.13.0/rest-server_0.13.0_linux_amd64.tar.gz Die Datei entpacken tar -xf rest-server_0.13.0_linux_amd64.tar.gz Ins Verzeichnis wechseln cd rest-server_0.13.0_linux_amd64 Wenn der Rest-Server läuft, dann muss man diesen erst mal stoppen. systemctl stop rest-server Danach kopiert man das File nach bin. Wer mag sichert vorher das alte File. cp rest-server /usr/local/bin Danach kann man den Rest-Server wieder starten. systemctl start rest-server Versionskontrolle root@rest-server:~# rest-server -v rest-server version rest-server 0.13.0 compiled with go1.22.5 on linux/amd64 Die Hilfe vom Rest-Server root@rest-server:~# rest-server -h Run a REST server for use with restic Usage: rest-server [flags] Flags: --append-only enable append only mode --cpu-profile string write CPU profile to file --debug output debug messages -h, --help help for rest-server --htpasswd-file string location of .htpasswd file (default: "<data directory>/.htpasswd)" --listen string listen address (default ":8000") --log filename write HTTP requests in the combined log format to the specified filename (use "-" for logging to stdout) --max-size int the maximum size of the repository in bytes --no-auth disable .htpasswd authentication --no-verify-upload do not verify the integrity of uploaded data. DO NOT enable unless the rest-server runs on a very low-power device --path string data directory (default "/tmp/restic") --private-repos users can only access their private repo --prometheus enable Prometheus metrics --prometheus-no-auth disable auth for Prometheus /metrics endpoint --tls turn on TLS support --tls-cert string TLS certificate path --tls-key string TLS key path -v, --version version for rest-server Systemd Wer noch ein passendes systemd File benötigt. [Unit] Description=Rest Server After=syslog.target After=network.target [Service] Type=simple User=rest-server Group=rest-server ExecStart=/usr/local/bin/rest-server --private-repos --tls --tls-cert /mnt/rest-server/<DOMAIN>/fullchain.pem --tls-key /mnt/rest-server/<DOMAIN>/key.pem --path /mnt/rest-server Restart=always RestartSec=5 # Optional security enhancements NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/mnt/rest-server [Install] WantedBy=multi-user.target
  • Pycharm - AI Assistant

    Linux pycharm linux
    1
    2
    0 Stimmen
    1 Beiträge
    306 Aufrufe
    Niemand hat geantwortet
  • Debian Installer Bookworm RC3 released

    Linux debian linux
    2
    0 Stimmen
    2 Beiträge
    173 Aufrufe
    FrankMF
    Und da sind wir schon bei RC4 https://lists.debian.org/debian-devel-announce/2023/05/msg00003.html
  • Firefox mit .deb Paket

    Linux debian firefox linux
    3
    2
    0 Stimmen
    3 Beiträge
    214 Aufrufe
    FrankMF
    Wer auch wie ich das Problem hat, das manche Webseiten keinen Text mehr anzeigen. Ich habe da was gefunden. https://neilzone.co.uk/2023/04/flatpak-firefox-112-not-showing-some-bitmap-fonts-in-debian
  • ROCKPro64 - PCIe NVMe SSD installieren

    Hardware linux rockpro64
    1
    0 Stimmen
    1 Beiträge
    358 Aufrufe
    Niemand hat geantwortet