SSL Configuration Issue with Nginx and ACME on my Home Server

Hi there,

I’m trying to enable SSL with ACME for my static website, which I’m hosting on my home server using Nginx. However, I’m encountering some issues. Here’s an overview of my current situation:

Nginx Configuration:

services.nginx = {
  enable = true;
  user = "nginx";
  group = "nginx";

  virtualHosts = {
    "gateway.oezilot.ch" = {
      serverName = "gateway.oezilot.ch";

      sslCertificate = "/var/lib/acme/gateway.oezilot.ch/fullchain.pem";
      sslCertificateKey = "/var/lib/acme/gateway.oezilot.ch/key.pem";
      forceSSL = true; # Redirects HTTP to HTTPS

      root = "/var/www/html";

      locations."/Salat" = {
        index = "salat.html";
      };

      extraConfig = ''
        error_log  /var/log/nginx/error.log;
        access_log /var/log/nginx/access.log;
      '';
    };
  };
};

Observations:

  1. Without SSL, the website is accessible via the following URL: http://gateway.oezilot.ch/Salat/.
  2. When forcing SSL, the website is not reachable through https://gateway.oezilot.ch/Salat/ nor http://gateway.oezilot.ch/Salat/.
  3. The following services are running:
    • acme-finished-gateway.oezilot.ch.target
    • acme-fixperms.service
    • acme-gateway.oezilot.ch.timer
    • acme-lockfiles.service
  4. The SSL certificate and key are located in the following files:
    • /var/lib/acme/gateway.oezilot.ch/fullchain.pem
    • /var/lib/acme/gateway.oezilot.ch/key.pem (There are even two certificates in the files!)
  5. I verified that the certificate is valid by running the following command:
    sudo openssl x509 -in /var/lib/acme/gateway.oezilot.ch/fullchain.pem -text -noout
    
  6. Both Nginx and ACME are running correctly.
  7. There are no entries in the error.log and access.log files of nginx; the GET requests are not being tracked.

What I Suspect:

It seems like HTTP requests are not being redirected to HTTPS, even though I’ve enabled forceSSL in the configuration. I assumed that this option would handle the redirection, but it doesn’t seem to be working as expected.

Can anyone offer guidance on what might be going wrong and how to resolve this? I am a complete beginner and don’t know what to do!

Thanks in advance for your help!

1 Like

This should be working; can you share the generated config file contents? It’ll either be in /etc/nginx/nginx.conf or you can find it somewhere in the stuff output by systemctl status nginx.

Hello there,

Thanks for the response. The /etc/nginx/nginx.conf does not exist, but I found a configuration file under /nix/store/q7dsnfydhpb8f46j1pc60vm3gvbsk31s-nginx.conf. Below is its content:

nginx.conf 
pid /run/nginx/nginx.pid;
error_log stderr;
daemon off;
events {
}
http {
        # Load mime types and configure maximum size of the types hash tables.
        include /nix/store/g6z5zm84089411zmiqs74g5v2v379ww1-mailcap-2.1.54/etc/nginx/mime.types;
        types_hash_max_size 2688;
        include /nix/store/8lncw1wjkrywc0shnwhpsgwgj9cn4da1-nginx-1.26.2/conf/fastcgi.conf;
        include /nix/store/8lncw1wjkrywc0shnwhpsgwgj9cn4da1-nginx-1.26.2/conf/uwsgi_params;
        default_type application/octet-stream;
        # optimisation
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        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:DHE-RSA-CHACHA20-POLY1305;
        # Keep in sync with https://ssl-config.mozilla.org/#server=nginx&config=intermediate
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;
        # Breaks forward secrecy: https://github.com/mozilla/server-side-tls/issues/135
        ssl_session_tickets off;
        # We don't enable insecure ciphers by default, so this allows
        # clients to pick the most performant, per https://github.com/mozilla/server-side-tls/issues/260
        ssl_prefer_server_ciphers off;
        # OCSP stapling
        ssl_stapling on;
        ssl_stapling_verify on;
        gzip on;
        gzip_static on;
        gzip_vary on;
        gzip_comp_level 5;
        gzip_min_length 256;
        gzip_proxied expired no-cache no-store private auth;
        gzip_types application/atom+xml application/geo+json application/javascript application/json application/ld+json application/manifest+json application/rdf+xml application/vnd.ms-fontobject application/wasm application/x-rss+xml application/x-web-app-manifest+json application/xhtml+xml application/xliff+xml application/xml font/collection font/otf font/ttf image/bmp image/svg+xml image/vnd.microsoft.icon text/cache-manifest text/calendar text/css text/csv text/javascript text/markdown text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/xml;
        proxy_redirect          off;
        proxy_connect_timeout   60s;
        proxy_send_timeout      60s;
        proxy_read_timeout      60s;
        proxy_http_version      1.1;
        # don't let clients close the keep-alive connection to upstream. See the nginx blog for details:
        # https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives
        proxy_set_header        "Connection" "";
        include /nix/store/z899kqvxx33f874yn8rj05gmh836cvxb-nginx-recommended-proxy-headers.conf;
        # $connection_upgrade is used for websocket proxying
        map $http_upgrade $connection_upgrade {
                default upgrade;
                ''      close;
        }
        client_max_body_size 10m;
        server_tokens off;
        server {
                listen 0.0.0.0:80 ;
                listen [::0]:80 ;
                server_name freundschaftsbuch.oezilot.ch ;
                root /home/zoef/Projects/Freundschaftsbuch;
                location / {
                        proxy_pass http://127.0.0.1:8000/;
                        include /nix/store/z899kqvxx33f874yn8rj05gmh836cvxb-nginx-recommended-proxy-headers.conf;
                }
        }
        server {
                listen 0.0.0.0:443 ssl ;
                listen [::0]:443 ssl ;
                listen 0.0.0.0:80 ;
                listen [::0]:80 ;
                server_name gateway.oezilot.ch ;
                http2 on;
                ssl_certificate /var/lib/acme/gateway.oezilot.ch/fullchain.pem;
                ssl_certificate_key /var/lib/acme/gateway.oezilot.ch/key.pem;
                root /var/www/html;
                location /Hello {
                        index hello.html;

root /var/www/html;
                }
                location /Salat {
                        index salat.html;
                }
                error_log  /var/log/nginx/error.log;
                access_log /var/log/nginx/access.log;
        }
}

Did you make sure that’s the configuration file nginx is actually using by checking with systemctl status nginx? That doesn’t look like a file using forceSSL, it looks like addSSL, and may be one of many obsolete config files you created while experimenting.

I am so sorry, I sent the wrong file earlier. It was a version where I had mistakenly used addSSL instead of forceSSL.
Here the updated contents…

The path of the configuration File: /nix/store/mzvl93y1j7kfvsibc24j4sp0mzmhiwv8-nginx.conf

How i found it:

● nginx.service - Nginx Web Server
     Loaded: loaded (/etc/systemd/system/nginx.service; enabled; preset: ignored)
     Active: active (running) since Mon 2025-01-27 18:59:19 CET; 27s ago
 Invocation: 51a34a60a33f48558c80629ca7533601
    Process: 86087 ExecStartPre=/nix/store/yskw9scmq2fggl4avbz6f9i1g875pqh0-unit-script-nginx-pre-start/bin/nginx-pre-start (code=exited, status=0/SUCCESS)
   Main PID: 86090 (nginx)
         IP: 0B in, 0B out
         IO: 0B read, 0B written
      Tasks: 2 (limit: 18440)
     Memory: 2.7M (peak: 3.9M)
        CPU: 77ms
     CGroup: /system.slice/nginx.service
             ├─86090 "nginx: master process /nix/store/8lncw1wjkrywc0shnwhpsgwgj9cn4da1-nginx-1.26.2/bin/nginx -c /nix/store/mzvl93y1j7kfvsibc24j4sp0mzmhiwv8-nginx.conf"
             └─86107 "nginx: worker process"

jan 27 18:59:19 nixos systemd[1]: Starting Nginx Web Server...
jan 27 18:59:19 nixos nginx-pre-start[86088]: nginx: the configuration file /nix/store/mzvl93y1j7kfvsibc24j4sp0mzmhiwv8-nginx.conf syntax is ok
jan 27 18:59:19 nixos nginx-pre-start[86088]: nginx: configuration file /nix/store/mzvl93y1j7kfvsibc24j4sp0mzmhiwv8-nginx.conf test is successful
jan 27 18:59:19 nixos systemd[1]: Started Nginx Web Server.

The configuration file:

cat /nix/store/mzvl93y1j7kfvsibc24j4sp0mzmhiwv8-nginx.conf
pid /run/nginx/nginx.pid;
error_log stderr;
daemon off;
events {
}
http {
    # Load mime types and configure maximum size of the types hash tables.
    include /nix/store/g6z5zm84089411zmiqs74g5v2v379ww1-mailcap-2.1.54/etc/nginx/mime.types;
    types_hash_max_size 2688;
    include /nix/store/8lncw1wjkrywc0shnwhpsgwgj9cn4da1-nginx-1.26.2/conf/fastcgi.conf;
    include /nix/store/8lncw1wjkrywc0shnwhpsgwgj9cn4da1-nginx-1.26.2/conf/uwsgi_params;
    default_type application/octet-stream;

    # Optimization settings
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;

    # SSL settings
    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:DHE-RSA-CHACHA20-POLY1305;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_prefer_server_ciphers off;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Gzip compression settings
    gzip on;
    gzip_static on;
    gzip_vary on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types application/atom+xml application/geo+json application/javascript application/json application/ld+json application/manifest+json application/rdf+xml application/vnd.ms-fontobject application/wasm application/x-rss+xml application/x-web-app-manifest+json application/xhtml+xml application/xliff+xml application/xml font/collection font/otf font/ttf image/bmp image/svg+xml image/vnd.microsoft.icon text/cache-manifest text/calendar text/css text/csv text/javascript text/markdown text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/xml;

    # Proxy settings
    proxy_redirect off;
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    proxy_http_version 1.1;
    proxy_set_header "Connection" "";

    include /nix/store/z899kqvxx33f874yn8rj05gmh836cvxb-nginx-recommended-proxy-headers.conf;

    # Websocket settings
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    client_max_body_size 10m;
    server_tokens off;

    # Server blocks
    server {
        listen 0.0.0.0:80;
        listen [::0]:80;
        server_name freundschaftsbuch.oezilot.ch;
        root /home/zoef/Projects/Freundschaftsbuch;
        location / {
            proxy_pass http://127.0.0.1:8000/;
            include /nix/store/z899kqvxx33f874yn8rj05gmh836cvxb-nginx-recommended-proxy-headers.conf;
        }
    }

    server {
        listen 0.0.0.0:80;
        listen [::0]:80;
        server_name gateway.oezilot.ch;
        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 0.0.0.0:443 ssl;
        listen [::0]:443 ssl;
        server_name gateway.oezilot.ch;
        http2 on;
        ssl_certificate /var/lib/acme/gateway.oezilot.ch/fullchain.pem;
        ssl_certificate_key /var/lib/acme/gateway.oezilot.ch/key.pem;
        root /var/www/html;

        location /Hello {
            index hello.html;
            root /var/www/html;
        }

        location /Salat {
            index salat.html;
        }

        error_log /var/log/nginx/error.log;
        access_log /var/log/nginx/access.log;
    }
}

That certainly looks like a working nginx config. My guess is that connections never reach nginx.

Do you get any logs from dmesg -w when you try to connect with https? I.e., is a firewall getting in the way? Anything from lsof -i tcp:443?

Can you share more of your config?

1 Like

I have tried the following commands you recommended:

Command: lsof -i tcp:443:
Output:

COMMAND     PID USER  FD   TYPE DEVICE SIZE/OFF NODE NAME
.firefox- 54499 zoef  63u  IPv6 429423      0t0  TCP nixos:38290->[2001:67c:4e8:f004::9]:https (ESTABLISHED)
.firefox- 54499 zoef 127u  IPv4 429418      0t0  TCP nixos:37966->lb-140-82-121-4-fra.github.com:https (ESTABLISHED)
.firefox- 54499 zoef 130u  IPv4 427628      0t0  TCP nixos:58268->lb-140-82-113-26-iad.github.com:https (ESTABLISHED)
.firefox- 54499 zoef 134u  IPv6 430292      0t0  TCP nixos:57434->[2001:67c:4e8:f004::9]:https (ESTABLISHED)
.firefox- 54499 zoef 138u  IPv4 421305      0t0  TCP nixos:38742->93.243.107.34.bc.googleusercontent.com:https (ESTABLISHED)
.firefox- 54499 zoef 139u  IPv4 429419      0t0  TCP nixos:38748->93.243.107.34.bc.googleusercontent.com:https (ESTABLISHED)
.firefox- 54499 zoef 142u  IPv6 429420      0t0  TCP nixos:57442->[2001:67c:4e8:f004::9]:https (ESTABLISHED)
.firefox- 54499 zoef 150u  IPv4 429421      0t0  TCP nixos:58186->209.100.149.34.bc.googleusercontent.com:https (ESTABLISHED)
.firefox- 54499 zoef 161u  IPv6 429422      0t0  TCP nixos:38840->[2600:1901:0:92a9::]:https (ESTABLISHED)

Command: sudo lsof -nP -iTCP -sTCP:LISTEN:
Output:

COMMAND    PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd      1  root 2046u  IPv4 198270      0t0  TCP 127.0.0.1:631 (LISTEN)
sshd     50910  root    7u  IPv4 219471      0t0  TCP *:22 (LISTEN)
sshd     50910  root    8u  IPv6 219473      0t0  TCP *:22 (LISTEN)
gunicorn 50917  zoef    5u  IPv4 219522      0t0  TCP 127.0.0.1:8000 (LISTEN)
gunicorn 50956  zoef    5u  IPv4 219522      0t0  TCP 127.0.0.1:8000 (LISTEN)
gunicorn 50971  zoef    5u  IPv4 219522      0t0  TCP 127.0.0.1:8000 (LISTEN)
gunicorn 50991  zoef    5u  IPv4 219522      0t0  TCP 127.0.0.1:8000 (LISTEN)
gunicorn 51005  zoef    5u  IPv4 219522      0t0  TCP 127.0.0.1:8000 (LISTEN)
cupsd    51061  root    4u  IPv4 198270      0t0  TCP 127.0.0.1:631 (LISTEN)
cupsd    51061  root    8u  IPv6 223287      0t0  TCP [::1]:631 (LISTEN)
nginx    86090 nginx    6u  IPv4 403461      0t0  TCP *:80 (LISTEN)
nginx    86090 nginx    7u  IPv6 403462      0t0  TCP *:80 (LISTEN)
nginx    86090 nginx    8u  IPv4 403463      0t0  TCP *:443 (LISTEN)
nginx    86090 nginx    9u  IPv6 403464      0t0  TCP *:443 (LISTEN)
nginx    86107 nginx    6u  IPv4 403461      0t0  TCP *:80 (LISTEN)
nginx    86107 nginx    7u  IPv6 403462      0t0  TCP *:80 (LISTEN)
nginx    86107 nginx    8u  IPv4 403463      0t0  TCP *:443 (LISTEN)
nginx    86107 nginx    9u  IPv6 403464      0t0  TCP *:443 (LISTEN)

Command: dmesg -w
Output: the file did not change when trying to reach the website using https!

[32310.535323] OOM killer enabled.
[32310.535326] Restarting tasks ... done.
[32310.537760] random: crng reseeded on system resumption
[32310.539534] PM: suspend exit
[32310.708882] RTL8226B_RTL8221B 2.5Gbps PHY r8169-0-100:00: attached PHY driver (mii_bus:phy_addr=r8169-0-100:00, irq=MAC)
[32310.866373] r8169 0000:01:00.0 enp1s0: Link is Down
[32310.899999] RTL8226B_RTL8221B 2.5Gbps PHY r8169-0-200:00: attached PHY driver (mii_bus:phy_addr=r8169-0-200:00, irq=MAC)
[32311.065994] r8169 0000:02:00.0 enp2s0: Link is Down
[32311.106737] r8152 2-1:1.0 enp5s0f3u1: carrier on

Command: firewall: nc -zv localhost 443
Output:

Connection to localhost (::1) 443 port [tcp/https] succeeded!

My config-File: /etc/nixos/configuration.nix

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  networking.firewall = {
  enable = true; # Aktiviert die Firewall
  allowedTCPPorts = [ 80 443 ]; # Erlaubt HTTP/HTTPS
  allowedUDPPorts = [];
  };


  # Set your time zone.
  time.timeZone = "Europe/Amsterdam";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "nl_NL.UTF-8";
    LC_IDENTIFICATION = "nl_NL.UTF-8";
    LC_MEASUREMENT = "nl_NL.UTF-8";
    LC_MONETARY = "nl_NL.UTF-8";
    LC_NAME = "nl_NL.UTF-8";
    LC_NUMERIC = "nl_NL.UTF-8";
    LC_PAPER = "nl_NL.UTF-8";
    LC_TELEPHONE = "nl_NL.UTF-8";
    LC_TIME = "nl_NL.UTF-8";
  };

  # Enable the X11 windowing system.
  services.xserver.enable = true;

  # Enable the GNOME Desktop Environment.
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "ch";
    variant = "legacy";
  };

  # Configure console keymap
  console.keyMap = "sg";

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  hardware.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.zoef = {
    isNormalUser = true;
    description = "Zoe Flumini";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [
    #  thunderbird
    brave
    ];
  };

  # Install firefox.
  programs.firefox.enable = true;

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
  #  vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
  #  wget
     git
     python314
     cron
     vscode
     certbot
     openssl
     nginx
     #selinux.selinux-tools  # Für Tools wie semanage und restorecon
     #selinux.checkpolicy    # Für das Arbeiten mit Richtlinien
  ];

  #security.selinux.enable = true;

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable
  services.openssh.enable = true;
  services.cron.enable = true;



  #hier definiere ich die nginx-konfiguration
  
  services.nginx = {

    enable = true; # Aktiviert Nginx
    user = "nginx";
    group = "nginx";

    recommendedGzipSettings = true;
    recommendedOptimisation = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;

# salat-website und das default handlcng für statische seiten!
    virtualHosts = {

      "gateway.oezilot.ch" = { # Deine Server-IP
      serverName = "gateway.oezilot.ch";
      
      # SSL-Zertifikate verwenden
      sslCertificate = "/var/lib/acme/gateway.oezilot.ch/fullchain.pem";
      sslCertificateKey = "/var/lib/acme/gateway.oezilot.ch/key.pem";
      forceSSL = true; # Leitet HTTP zu HTTPS um
      #listen = [{ addr = "0.0.0.0"; port = 443; ssl = true; }];

      
      root = "/var/www/html";

      locations."/Salat" = {
        index = "salat.html";
      };

      locations."/Hello" = {
        root = "/var/www/html";
        index = "hello.html";
      };

      extraConfig = ''
      error_log  /var/log/nginx/error.log;
      access_log /var/log/nginx/access.log;
      '';
      };

      

      # freundschaftsbuch
      "freundschaftsbuch.oezilot.ch" = {
        serverName = "freundschaftsbuch.oezilot.ch";
        root = "/home/zoef/Projects/Freundschaftsbuch";
        locations."/" = {
          proxyPass = "http://127.0.0.1:8000/";
        };
        # SSL
        #enableACME = true;
        #forceSSL = true;

        # SSL-Zertifikate konfigurieren (stellen sicher, dass diese Pfade korrekt sind)
        #listen = [{ addr = "0.0.0.0"; port = 443; ssl = true; }];
        #sslCertificate = "/var/lib/acme/freundschaftsbuch.oezilot.ch/fullchain.pem";
        #sslCertificateKey = "/var/lib/acme/freundschaftsbuch.oezilot.ch/key.pem";
      };
    };
  };

security.acme = {
  acceptTerms = true; # Akzeptiere die Nutzungsbedingungen von Let's Encrypt
  defaults.email = "zoe.flumini@gmail.com"; # Deine E-Mail-Adresse für Benachrichtigungen
  certs = {
    "gateway.oezilot.ch" = {
      # Füge hier die Domain hinzu
      webroot = "/var/www/html"; # Der Webroot für die Validierung
      #domains = [ "gateway.oezilot.ch" ];
      group = "nginx";
    };
  };
};


# service für das freundebuch definieren!
  systemd.services.freundschaftsbuch = {
    description = "Gunicorn Service for Freundschaftsbuch";
    after = [ "network.target" ];
    wantedBy = [ "multi-user.target" ];

    serviceConfig = {
      User = "zoef";
      WorkingDirectory = "/home/zoef/Projects/Freundschaftsbuch/";
      ExecStart = "/home/zoef/Projects/Freundschaftsbuch/venv/bin/gunicorn app:app --bind 127.0.0.1:8000 --workers 4";
      Restart = "always" ;
    };
  };

  systemd.tmpfiles.rules = [
    "d /home/zoef/Projects/Salat 0755 nginx nginx - -"
  ];
  
  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "24.11"; # Did you read the comment?
}

to me everything network-related seems to be alright…