Created
October 14, 2025 19:54
-
-
Save stancl/589c44ea4044ed7ffe9fba5f6823a453 to your computer and use it in GitHub Desktop.
Forgejo NixOS server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| description = "System configuration"; | |
| inputs = { | |
| nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; | |
| }; | |
| outputs = { self, nixpkgs, ... }@inputs: { | |
| nixosConfigurations = let | |
| system = "aarch64-linux"; # Change to x86-64 if necessary | |
| pkgs = nixpkgs.legacyPackages.${system}; | |
| lib = pkgs.lib; | |
| in { | |
| nixos = nixpkgs.lib.nixosSystem { | |
| inherit system; | |
| modules = [ | |
| ./configuration.nix # This flake expects that you have the "original" system config in ./configuration.nix | |
| { | |
| nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; | |
| security.acme.defaults.email = "<YOUR EMAIL>"; | |
| security.acme.acceptTerms = true; | |
| } | |
| ({ config, ...}: { | |
| services.forgejo = { | |
| enable = true; | |
| # See https://forgejo.org/docs/latest/admin/config-cheat-sheet | |
| settings.server.DOMAIN = "<YOUR DOMAIN>"; | |
| settings.server.ROOT_URL = "https://<YOUR DOMAIN>"; | |
| settings.server.PROTOCOL = "http+unix"; | |
| settings.server.DISABLE_SSH = true; | |
| settings.service.DISABLE_REGISTRATION = true; # Set this to false, register your account, then set this to true. | |
| settings.ui.DEFAULT_THEME = "gitea-auto"; | |
| settings.DEFAULT.APP_NAME = "<YOUR SITE NAME>"; | |
| settings.api.ENABLE_SWAGGER = false; | |
| settings.database.SQLITE_TIMEOUT = 1000; | |
| settings.database.SQLITE_JOURNAL_MODE = "WAL"; | |
| }; | |
| networking.firewall.allowedTCPPorts = [ 80 443 ]; | |
| services.nginx.enable = true; | |
| services.nginx.virtualHosts."<YOUR DOMAIN>" = { | |
| forceSSL = true; | |
| enableACME = true; | |
| # The default home page is pointless without registration | |
| # so we just redirect to the repo list. | |
| locations."= /".extraConfig = '' | |
| return 302 /explore/repos; | |
| ''; | |
| # HTTP addr contains the unix socket path when server.PROTOCOL = "http+unix"; | |
| locations."/".proxyPass = "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:"; | |
| # Global nginx extra config - use Cloudflare Authenticated Origin Pulls | |
| # (= easy way to block non-CF traffic) | |
| # See https://github.com/archtechx/nix#authenticated-origin-pulls-aop | |
| extraConfig = '' | |
| ssl_verify_client on; | |
| ssl_client_certificate ${pkgs.fetchurl { | |
| url = "https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem"; | |
| sha256 = "0hxqszqfzsbmgksfm6k0gp0hsx9k1gqx24gakxqv0391wl6fsky1"; | |
| }}; | |
| ''; | |
| }; | |
| }) | |
| { | |
| # Override the user's IP with CF-Connecting-IP when the request comes from | |
| # one of the IP addresses in this list. | |
| # This list barely updates but it's okay if it becomes outdated, at worst some users | |
| # will be shown as connecting from a CF IP instead of their real IP. The IP list becoming | |
| # outdated would be a bigger issue with blocking non-CF traffic, hence why we use AOP | |
| # instead of an IP list above. | |
| # If this list were to become outdated when you're building this config, the checksum would catch that. | |
| services.nginx.commonHttpConfig = | |
| let | |
| realIpsFromList = lib.strings.concatMapStringsSep "\n" (x: "set_real_ip_from ${x};"); | |
| fileToList = x: lib.strings.splitString "\n" (builtins.readFile x); | |
| cfipv4 = fileToList (pkgs.fetchurl { | |
| url = "https://www.cloudflare.com/ips-v4"; | |
| sha256 = "0ywy9sg7spafi3gm9q5wb59lbiq0swvf0q3iazl0maq1pj1nsb7h"; | |
| }); | |
| cfipv6 = fileToList (pkgs.fetchurl { | |
| url = "https://www.cloudflare.com/ips-v6"; | |
| sha256 = "1ad09hijignj6zlqvdjxv7rjj8567z357zfavv201b9vx3ikk7cy"; | |
| }); | |
| in | |
| '' | |
| ${realIpsFromList cfipv4} | |
| ${realIpsFromList cfipv6} | |
| real_ip_header CF-Connecting-IP; | |
| ''; | |
| } | |
| ]; | |
| }; | |
| }; | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment