Compare commits
	
		
			8 commits
		
	
	
		
			c4fa991b62
			...
			72e7eed9d1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 72e7eed9d1 | |||
| efa1558af3 | |||
| da5c339552 | |||
| a994fd8ba0 | |||
| 669b87efe9 | |||
| 23a867de84 | |||
| 99ca90be92 | |||
| d6bb65f739 | 
					 15 changed files with 655 additions and 746 deletions
				
			
		|  | @ -1,18 +1,29 @@ | ||||||
| { | { | ||||||
|   config, |  | ||||||
|   pkgs, |   pkgs, | ||||||
|   lib, |   lib, | ||||||
|  |   modulesPath, | ||||||
|   ... |   ... | ||||||
| }: { | }: { | ||||||
|   imports = [ |   imports = [ | ||||||
|  |     "${modulesPath}/profiles/headless.nix" | ||||||
|  |     (import ../modules) | ||||||
|  | 
 | ||||||
|     ./services/gitea.nix |     ./services/gitea.nix | ||||||
|     ./services/nextcloud.nix |     ./services/nextcloud.nix | ||||||
|     ./services/webserver.nix |     ./services/webserver.nix | ||||||
|     ./services/starbound.nix |     ./services/starbound.nix | ||||||
|     ./ids.nix |     ./services/postgres.nix | ||||||
|     ./sops.nix |     ./sops.nix | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|  |   nixpkgs.overlays = [ | ||||||
|  |     (final: prev: { | ||||||
|  |       local = import ../pkgs { | ||||||
|  |         pkgs = prev; | ||||||
|  |       }; | ||||||
|  |     }) | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|   nix = { |   nix = { | ||||||
|     package = pkgs.nixFlakes; |     package = pkgs.nixFlakes; | ||||||
|     extraOptions = '' |     extraOptions = '' | ||||||
|  | @ -24,7 +35,7 @@ | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   nixpkgs.config.allowUnfreePredicate = pkg: |   nixpkgs.config.allowUnfreePredicate = pkg: | ||||||
|     builtins.elem (lib.getName pkg) ["steam-runtime" "steamcmd"]; |     builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steamcmd"]; | ||||||
| 
 | 
 | ||||||
|   # Optimization for minecraft servers, see: |   # Optimization for minecraft servers, see: | ||||||
|   # https://bugs.mojang.com/browse/MC-183518 |   # https://bugs.mojang.com/browse/MC-183518 | ||||||
|  | @ -37,7 +48,7 @@ | ||||||
|     useDHCP = false; |     useDHCP = false; | ||||||
|     interfaces.eth0.useDHCP = true; |     interfaces.eth0.useDHCP = true; | ||||||
| 
 | 
 | ||||||
|     firewall.allowedTCPPorts = [80 443 2222 2221 21025]; |     firewall.allowedTCPPorts = [80 443 2222 21025]; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   time.timeZone = "Europe/London"; |   time.timeZone = "Europe/London"; | ||||||
|  | @ -66,32 +77,33 @@ | ||||||
|     recommendedProxySettings = true; |     recommendedProxySettings = true; | ||||||
|     clientMaxBodySize = "10G"; |     clientMaxBodySize = "10G"; | ||||||
|     domain = "tlater.net"; |     domain = "tlater.net"; | ||||||
| 
 |  | ||||||
|     virtualHosts = let |  | ||||||
|       proxyPassToPort = port: extra: |  | ||||||
|         lib.recursiveUpdate { |  | ||||||
|           forceSSL = true; |  | ||||||
|           enableACME = true; |  | ||||||
|           locations."/".proxyPass = "http://127.0.0.1:${toString port}"; |  | ||||||
|           extraConfig = '' |  | ||||||
|             add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; |  | ||||||
|           ''; |  | ||||||
|         } |  | ||||||
|         extra; |  | ||||||
|       domain = config.services.nginx.domain; |  | ||||||
|     in { |  | ||||||
|       "${domain}" = proxyPassToPort 3002 {serverAliases = ["www.${domain}"];}; |  | ||||||
|       "gitea.${domain}" = proxyPassToPort 3000 {}; |  | ||||||
|       "nextcloud.${domain}" = proxyPassToPort 3001 {}; |  | ||||||
|     }; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   security.acme = { |   security.acme = { | ||||||
|     email = "tm@tlater.net"; |     defaults.email = "tm@tlater.net"; | ||||||
|     acceptTerms = true; |     acceptTerms = true; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   virtualisation.oci-containers.backend = "podman"; |   services.fail2ban = { | ||||||
|  |     enable = true; | ||||||
|  |     extraPackages = [pkgs.ipset]; | ||||||
|  |     banaction = "iptables-ipset-proto6-allports"; | ||||||
|  |     bantime-increment.enable = true; | ||||||
|  | 
 | ||||||
|  |     jails = { | ||||||
|  |       nginx-botsearch = '' | ||||||
|  |         enabled = true | ||||||
|  |         logpath = /var/log/nginx/access.log | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     ignoreIP = [ | ||||||
|  |       "127.0.0.0/8" | ||||||
|  |       "10.0.0.0/8" | ||||||
|  |       "172.16.0.0/12" | ||||||
|  |       "192.168.0.0/16" | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   system.stateVersion = "20.09"; |   system.stateVersion = "20.09"; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								configuration/hardware-specific/vm.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								configuration/hardware-specific/vm.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | {lib, ...}: { | ||||||
|  |   users.users.tlater.password = "insecure"; | ||||||
|  | 
 | ||||||
|  |   # Disable graphical tty so -curses works | ||||||
|  |   boot.kernelParams = ["nomodeset"]; | ||||||
|  | 
 | ||||||
|  |   # Sets the base domain for nginx to localhost so that we | ||||||
|  |   # can easily test locally with the VM. | ||||||
|  |   services.nginx.domain = lib.mkOverride 99 "localhost"; | ||||||
|  | 
 | ||||||
|  |   # Use the staging secrets | ||||||
|  |   sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml; | ||||||
|  | 
 | ||||||
|  |   # # Set up VM settings to match real VPS | ||||||
|  |   # virtualisation.memorySize = 3941; | ||||||
|  |   # virtualisation.cores = 2; | ||||||
|  | } | ||||||
|  | @ -1,11 +0,0 @@ | ||||||
| {...}: { |  | ||||||
|   ids.uids = { |  | ||||||
|     # System user ids start at 400 (see nixos/modules/programs/shadow.nix) |  | ||||||
|     webserver = 400; |  | ||||||
|     # The limit is 999 |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   ids.gids = { |  | ||||||
|     webserver = 400; |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
|  | @ -1,167 +0,0 @@ | ||||||
| worker_processes auto; |  | ||||||
| 
 |  | ||||||
| error_log  /var/log/nginx/error.log warn; |  | ||||||
| pid        /var/run/nginx.pid; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| events { |  | ||||||
|     worker_connections  1024; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| http { |  | ||||||
|     include       /etc/nginx/mime.types; |  | ||||||
|     default_type  application/octet-stream; |  | ||||||
| 
 |  | ||||||
|     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' |  | ||||||
|                       '$status $body_bytes_sent "$http_referer" ' |  | ||||||
|                       '"$http_user_agent" "$http_x_forwarded_for"'; |  | ||||||
| 
 |  | ||||||
|     access_log  /var/log/nginx/access.log  main; |  | ||||||
| 
 |  | ||||||
|     sendfile        on; |  | ||||||
|     #tcp_nopush     on; |  | ||||||
| 
 |  | ||||||
|     keepalive_timeout  65; |  | ||||||
| 
 |  | ||||||
|     #gzip  on; |  | ||||||
| 
 |  | ||||||
|     upstream php-handler { |  | ||||||
|         server localhost:9000; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     server { |  | ||||||
|         listen 80; |  | ||||||
| 
 |  | ||||||
|         # 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=15768000; includeSubDomains; preload;" always; |  | ||||||
| 
 |  | ||||||
|         # HTTP response headers borrowed from Nextcloud `.htaccess` |  | ||||||
|         add_header Referrer-Policy                      "no-referrer"   always; |  | ||||||
|         add_header X-Content-Type-Options               "nosniff"       always; |  | ||||||
|         add_header X-Download-Options                   "noopen"        always; |  | ||||||
|         add_header X-Frame-Options                      "SAMEORIGIN"    always; |  | ||||||
|         add_header X-Permitted-Cross-Domain-Policies    "none"          always; |  | ||||||
|         add_header X-Robots-Tag                         "none"          always; |  | ||||||
|         add_header X-XSS-Protection                     "1; mode=block" always; |  | ||||||
| 
 |  | ||||||
|         # Remove X-Powered-By, which is an information leak |  | ||||||
|         fastcgi_hide_header X-Powered-By; |  | ||||||
| 
 |  | ||||||
|         # Path to the root of your installation |  | ||||||
|         root /var/www/html; |  | ||||||
| 
 |  | ||||||
|         # Specify how to handle directories -- specifying `/index.php$request_uri` |  | ||||||
|         # here as the fallback means that Nginx always exhibits the desired behaviour |  | ||||||
|         # when a client requests a path that corresponds to a directory that exists |  | ||||||
|         # on the server. In particular, if that directory contains an index.php file, |  | ||||||
|         # that file is correctly served; if it doesn't, then the request is passed to |  | ||||||
|         # the front-end controller. This consistent behaviour means that we don't need |  | ||||||
|         # to specify custom rules for certain paths (e.g. images and other assets, |  | ||||||
|         # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus |  | ||||||
|         # `try_files $uri $uri/ /index.php$request_uri` |  | ||||||
|         # always provides the desired behaviour. |  | ||||||
|         index index.php index.html /index.php$request_uri; |  | ||||||
| 
 |  | ||||||
|         # Rule borrowed from `.htaccess` to handle Microsoft DAV clients |  | ||||||
|         location = / { |  | ||||||
|             if ( $http_user_agent ~ ^DavClnt ) { |  | ||||||
|                 return 302 /remote.php/webdav/$is_args$args; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         location = /robots.txt { |  | ||||||
|             allow all; |  | ||||||
|             log_not_found off; |  | ||||||
|             access_log off; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         # Make a regex exception for `/.well-known` so that clients can still |  | ||||||
|         # access it despite the existence of the regex rule |  | ||||||
|         # `location ~ /(\.|autotest|...)` which would otherwise handle requests |  | ||||||
|         # for `/.well-known`. |  | ||||||
|         location ^~ /.well-known { |  | ||||||
|             # The rules in this block are an adaptation of the rules |  | ||||||
|             # in `.htaccess` that concern `/.well-known`. |  | ||||||
| 
 |  | ||||||
|             location = /.well-known/carddav { return 301 /remote.php/dav/; } |  | ||||||
|             location = /.well-known/caldav  { return 301 /remote.php/dav/; } |  | ||||||
| 
 |  | ||||||
|             location /.well-known/acme-challenge    { try_files $uri $uri/ =404; } |  | ||||||
|             location /.well-known/pki-validation    { try_files $uri $uri/ =404; } |  | ||||||
| 
 |  | ||||||
|             # Let Nextcloud's API for `/.well-known` URIs handle all other |  | ||||||
|             # requests by passing them to the front-end controller. |  | ||||||
|             return 301 /index.php$request_uri; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         # set max upload size |  | ||||||
|         client_max_body_size 10G; |  | ||||||
|         fastcgi_buffers 64 4K; |  | ||||||
| 
 |  | ||||||
|         # Enable gzip but do not remove ETag headers |  | ||||||
|         gzip on; |  | ||||||
|         gzip_vary on; |  | ||||||
|         gzip_comp_level 4; |  | ||||||
|         gzip_min_length 256; |  | ||||||
|         gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; |  | ||||||
|         gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; |  | ||||||
| 
 |  | ||||||
|         # Pagespeed is not supported by Nextcloud, so if your server is built |  | ||||||
|         # with the `ngx_pagespeed` module, uncomment this line to disable it. |  | ||||||
|         #pagespeed off; |  | ||||||
| 
 |  | ||||||
|         # Rules borrowed from `.htaccess` to hide certain paths from clients |  | ||||||
|         location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; } |  | ||||||
|         location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; } |  | ||||||
| 
 |  | ||||||
|         # Ensure this block, which passes PHP files to the PHP process, is above the blocks |  | ||||||
|         # which handle static assets (as seen below). If this block is not declared first, |  | ||||||
|         # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` |  | ||||||
|         # to the URI, resulting in a HTTP 500 error response. |  | ||||||
|         location ~ \.php(?:$|/) { |  | ||||||
|             fastcgi_split_path_info ^(.+?\.php)(/.*)$; |  | ||||||
|             set $path_info $fastcgi_path_info; |  | ||||||
| 
 |  | ||||||
|             try_files $fastcgi_script_name =404; |  | ||||||
| 
 |  | ||||||
|             include fastcgi_params; |  | ||||||
|             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; |  | ||||||
|             fastcgi_param PATH_INFO $path_info; |  | ||||||
|             #fastcgi_param HTTPS on; |  | ||||||
| 
 |  | ||||||
|             fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice |  | ||||||
|             fastcgi_param front_controller_active true;     # Enable pretty urls |  | ||||||
|             fastcgi_pass php-handler; |  | ||||||
| 
 |  | ||||||
|             fastcgi_intercept_errors on; |  | ||||||
|             fastcgi_request_buffering off; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         location ~ \.(?:css|js|svg|gif)$ { |  | ||||||
|             try_files $uri /index.php$request_uri; |  | ||||||
|             expires 6M;         # Cache-Control policy borrowed from `.htaccess` |  | ||||||
|             access_log off;     # Optional: Don't log access to assets |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         location ~ \.woff2?$ { |  | ||||||
|             try_files $uri /index.php$request_uri; |  | ||||||
|             expires 7d;         # Cache-Control policy borrowed from `.htaccess` |  | ||||||
|             access_log off;     # Optional: Don't log access to assets |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         # Rule borrowed from `.htaccess` |  | ||||||
|         location /remote { |  | ||||||
|             return 301 /remote.php$request_uri; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         location / { |  | ||||||
|             try_files $uri $uri/ /index.php$request_uri; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -1,48 +1,50 @@ | ||||||
| {config, ...}: { | {config, ...}: let | ||||||
|   users = { |   domain = "gitea.${config.services.nginx.domain}"; | ||||||
|     extraUsers.gitea = { | in { | ||||||
|       uid = config.ids.uids.git; |   services.gitea = { | ||||||
|       isSystemUser = true; |     inherit domain; | ||||||
|       description = "Gitea Service"; |     enable = true; | ||||||
|       group = config.users.extraGroups.gitea.name; | 
 | ||||||
|     }; |     httpAddress = "127.0.0.1"; | ||||||
|     extraGroups.gitea = {gid = config.ids.gids.git;}; |     database.type = "postgres"; | ||||||
|  | 
 | ||||||
|  |     ssh.clonePort = 2222; | ||||||
|  |     rootUrl = "https://${domain}/"; | ||||||
|  |     cookieSecure = true; | ||||||
|  | 
 | ||||||
|  |     appName = "Gitea: Git with a cup of tea"; | ||||||
|  |     disableRegistration = true; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   virtualisation.pods.gitea = { |   # Set up SSL | ||||||
|     hostname = "gitea.tlater.net"; |   services.nginx.virtualHosts."${domain}" = let | ||||||
|     publish = ["3000:3000" "2221:2221"]; |     inherit (config.services.gitea) httpAddress httpPort; | ||||||
|     network = "slirp4netns"; |   in { | ||||||
|  |     forceSSL = true; | ||||||
|  |     enableACME = true; | ||||||
|  |     extraConfig = '' | ||||||
|  |       add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; | ||||||
|  |     ''; | ||||||
| 
 | 
 | ||||||
|     containers = { |     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}"; | ||||||
|       gitea = { |  | ||||||
|         image = "gitea/gitea:latest"; |  | ||||||
|         volumes = ["gitea:/data:Z" "/etc/localtime:/etc/localtime:ro"]; |  | ||||||
|         dependsOn = ["postgres"]; |  | ||||||
| 
 |  | ||||||
|         environment = { |  | ||||||
|           DB_TYPE = "postgres"; |  | ||||||
|           DB_HOST = "localhost:5432"; |  | ||||||
|           DB_NAME = "gitea"; |  | ||||||
|           DB_USER = "gitea"; |  | ||||||
| 
 |  | ||||||
|           USER_UID = toString config.users.extraUsers.gitea.uid; |  | ||||||
|           USER_GID = toString config.users.extraGroups.gitea.gid; |  | ||||||
| 
 |  | ||||||
|           RUN_MODE = "prod"; |  | ||||||
|           DOMAIN = "gitea.tlater.net"; |  | ||||||
|           SSH_PORT = "2221"; |  | ||||||
|         }; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|       postgres = { |   # Block repeated failed login attempts | ||||||
|         image = "postgres:alpine"; |   # | ||||||
|         environment = { |   # TODO(tlater): Update to the new regex, since apparently this one | ||||||
|           POSTGRES_DB = "gitea"; |   # is deprecated (but the new one doesn't work on the current version | ||||||
|           POSTGRES_USER = "gitea"; |   # of gitea yet): https://docs.gitea.io/en-us/fail2ban-setup/ | ||||||
|         }; |   environment.etc = { | ||||||
|         volumes = ["gitea-postgres-14:/var/lib/postgresql/data"]; |     "fail2ban/filter.d/gitea.conf".text = '' | ||||||
|       }; |       [Definition] | ||||||
|  |       failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST> | ||||||
|  |       journalmatch = _SYSTEMD_UNIT=gitea.service + _COMM=gitea + SYSLOG_IDENTIFIER=gitea | ||||||
|  |     ''; | ||||||
|   }; |   }; | ||||||
|  | 
 | ||||||
|  |   services.fail2ban.jails = { | ||||||
|  |     gitea = '' | ||||||
|  |       enabled = true | ||||||
|  |     ''; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,53 +1,66 @@ | ||||||
| {config, ...}: { | { | ||||||
|   virtualisation.pods.nextcloud = { |   pkgs, | ||||||
|     hostname = "nextcloud.tlater.net"; |   config, | ||||||
|     publish = ["3001:80"]; |   ... | ||||||
|     network = "slirp4netns"; | }: let | ||||||
|  |   inherit (pkgs) fetchNextcloudApp; | ||||||
|  |   nextcloud = pkgs.nextcloud24; | ||||||
|  |   hostName = "nextcloud.${config.services.nginx.domain}"; | ||||||
|  | in { | ||||||
|  |   services.nextcloud = { | ||||||
|  |     inherit hostName; | ||||||
| 
 | 
 | ||||||
|     containers = { |     package = nextcloud; | ||||||
|       nextcloud = { |     enable = true; | ||||||
|         image = "nextcloud:fpm-alpine"; |     maxUploadSize = "2G"; | ||||||
|         dependsOn = ["postgres"]; |     https = true; | ||||||
|         volumes = [ | 
 | ||||||
|           "nextcloud-root:/var/www/html" |     config = { | ||||||
|           "nextcloud-apps:/var/www/html/custom_apps" |       overwriteProtocol = "https"; | ||||||
|           "nextcloud-config:/var/www/html/config" | 
 | ||||||
|           "nextcloud-data:/var/www/html/data" |       dbtype = "pgsql"; | ||||||
|         ]; |       dbhost = "/run/postgresql"; | ||||||
|         environment = { | 
 | ||||||
|           POSTGRES_DB = "nextcloud"; |       adminuser = "tlater"; | ||||||
|           POSTGRES_USER = "nextcloud"; |       adminpassFile = config.sops.secrets."nextcloud/tlater".path; | ||||||
|           POSTGRES_HOST = "localhost"; | 
 | ||||||
|           OVERWRITEPROTOCOL = "https"; |       defaultPhoneRegion = "AT"; | ||||||
|           TRUSTED_PROXIES = "127.0.0.1"; |  | ||||||
|         }; |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|       cron = { |     # TODO(tlater): Add redis config. This will be much easier | ||||||
|         image = "nextcloud:fpm-alpine"; |     # starting with 22.11, since this will add an `extraOptions` where | ||||||
|         entrypoint = "/cron.sh"; |     # the necessary redis config can go. | ||||||
|         dependsOn = ["postgres" "nextcloud"]; |  | ||||||
|         extraOptions = ["--volumes-from=nextcloud-nextcloud"]; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|       nginx = { |   # Ensure that this service doesn't start before postgres is ready | ||||||
|         image = "nginx:alpine"; |   systemd.services.nextcloud-setup.after = ["postgresql.service"]; | ||||||
|         dependsOn = ["nextcloud"]; | 
 | ||||||
|         volumes = [ |   # Set up SSL | ||||||
|           "nextcloud-root:/var/www/html:ro" |   services.nginx.virtualHosts."${hostName}" = { | ||||||
|           "${./configs/nginx-nextcloud.conf}:/etc/nginx/nginx.conf:ro" |     forceSSL = true; | ||||||
|         ]; |     enableACME = true; | ||||||
|         extraOptions = ["--volumes-from=nextcloud-nextcloud"]; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|       postgres = { |   # Block repeated failed login attempts | ||||||
|         image = "postgres:alpine"; |   environment.etc = { | ||||||
|         environment = { |     "fail2ban/filter.d/nextcloud.conf".text = '' | ||||||
|           POSTGRES_DB = "nextcloud"; |       [Definition] | ||||||
|           POSTGRES_USER = "nextcloud"; |       _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*) | ||||||
|         }; |       failregex = \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed: | ||||||
|         volumes = ["nextcloud-postgres-14:/var/lib/postgresql/data"]; |                   \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error. | ||||||
|       }; |       datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?" | ||||||
|  |       journalmatch = SYSLOG_IDENTIFIER=Nextcloud | ||||||
|  |     ''; | ||||||
|   }; |   }; | ||||||
|  | 
 | ||||||
|  |   services.fail2ban.jails = { | ||||||
|  |     nextcloud = '' | ||||||
|  |       enabled = true | ||||||
|  | 
 | ||||||
|  |       # Nextcloud does some throttling already, so we need to set | ||||||
|  |       # these to something bigger. | ||||||
|  |       findtime = 43200 | ||||||
|  |       bantime = 86400 | ||||||
|  |     ''; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								configuration/services/postgres.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								configuration/services/postgres.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | ||||||
|  | {pkgs, ...}: { | ||||||
|  |   services.postgresql = { | ||||||
|  |     package = pkgs.postgresql_14; | ||||||
|  |     enable = true; | ||||||
|  | 
 | ||||||
|  |     # Only enable connections via the unix socket, and check with the | ||||||
|  |     # OS to make sure the user matches the database name. | ||||||
|  |     # | ||||||
|  |     # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html | ||||||
|  |     authentication = '' | ||||||
|  |       local sameuser all peer | ||||||
|  |     ''; | ||||||
|  | 
 | ||||||
|  |     # Note: The following options with ensure.* are set-only; i.e., | ||||||
|  |     # when permissions/users/databases are removed from these lists, | ||||||
|  |     # that operation needs to be performed manually on the system as | ||||||
|  |     # well. | ||||||
|  |     ensureUsers = [ | ||||||
|  |       { | ||||||
|  |         name = "nextcloud"; | ||||||
|  |         ensurePermissions = { | ||||||
|  |           "DATABASE nextcloud" = "ALL PRIVILEGES"; | ||||||
|  |         }; | ||||||
|  |       } | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|  |     ensureDatabases = [ | ||||||
|  |       "nextcloud" | ||||||
|  |     ]; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | @ -1,47 +1,26 @@ | ||||||
| { | {config, ...}: let | ||||||
|   config, |   domain = config.services.nginx.domain; | ||||||
|   pkgs, | in { | ||||||
|   ... |   services.tlaternet-webserver = { | ||||||
| }: { |     enable = true; | ||||||
|   users = { |     listen = { | ||||||
|     extraUsers.webserver = { |       addr = "127.0.0.1"; | ||||||
|       uid = config.ids.uids.webserver; |       port = 8000; | ||||||
|       group = config.users.extraGroups.webserver.name; |  | ||||||
|       isSystemUser = true; |  | ||||||
|       description = "tlater.net web server user"; |  | ||||||
|     }; |     }; | ||||||
|     extraGroups.webserver = {gid = config.ids.gids.webserver;}; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   virtualisation.oci-containers.containers.webserver = { |   # Set up SSL | ||||||
|     image = "tlaternet/webserver"; |   services.nginx.virtualHosts."${domain}" = let | ||||||
| 
 |     inherit (config.services.tlaternet-webserver.listen) addr port; | ||||||
|     imageFile = pkgs.dockerTools.buildImage { |  | ||||||
|       name = "tlaternet/webserver"; |  | ||||||
|       tag = "latest"; |  | ||||||
|       contents = pkgs.tlaternet-webserver.webserver; |  | ||||||
| 
 |  | ||||||
|       config = let |  | ||||||
|         uid = toString config.users.extraUsers.webserver.uid; |  | ||||||
|         gid = toString config.users.extraGroups.webserver.gid; |  | ||||||
|   in { |   in { | ||||||
|         Cmd = ["tlaternet-webserver"]; |     serverAliases = ["www.${domain}"]; | ||||||
|         Volumes = {"/srv/mail" = {};}; |  | ||||||
|         Env = [ |  | ||||||
|           "ROCKET_PORT=3002" |  | ||||||
|           "ROCKET_TEMPLATE_DIR=${pkgs.tlaternet-templates.templates}/browser/" |  | ||||||
|         ]; |  | ||||||
|         ExposedPorts = {"3002" = {};}; |  | ||||||
|         User = "${uid}:${gid}"; |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     ports = ["3002:3002"]; |     forceSSL = true; | ||||||
|     volumes = ["tlaternet-mail:/srv/mail"]; |     enableACME = true; | ||||||
|     extraOptions = [ |     extraConfig = '' | ||||||
|       "--hostname=tlater.net" |       add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; | ||||||
|       # Rocket 0.4 doesn't support SIGTERM anyway, so SIGKILL is the cleanest exit possible. |     ''; | ||||||
|       "--stop-signal=SIGKILL" | 
 | ||||||
|     ]; |     locations."/".proxyPass = "http://${addr}:${toString port}"; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										462
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										462
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1,119 +1,377 @@ | ||||||
| { | { | ||||||
|   "nodes": { |   "nodes": { | ||||||
|     "flake-utils": { |     "alejandra": { | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1659877975, |  | ||||||
|         "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "flake-utils_2": { |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1659877975, |  | ||||||
|         "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", |  | ||||||
|         "type": "github" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "owner": "numtide", |  | ||||||
|         "repo": "flake-utils", |  | ||||||
|         "type": "github" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "naersk": { |  | ||||||
|       "inputs": { |       "inputs": { | ||||||
|  |         "fenix": "fenix", | ||||||
|  |         "flakeCompat": "flakeCompat", | ||||||
|         "nixpkgs": [ |         "nixpkgs": [ | ||||||
|           "tlaternet-webserver", |           "tlaternet-webserver", | ||||||
|  |           "dream2nix", | ||||||
|           "nixpkgs" |           "nixpkgs" | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1632266297, |         "lastModified": 1658427149, | ||||||
|         "narHash": "sha256-J1yeJk6Gud9ef2pEf6aKQemrfg1pVngYDSh+SAY94xk=", |         "narHash": "sha256-ToD/1z/q5VHsLMrS2h96vjJoLho59eNRtknOUd19ey8=", | ||||||
|         "owner": "nmattia", |         "owner": "kamadorueda", | ||||||
|         "repo": "naersk", |         "repo": "alejandra", | ||||||
|         "rev": "ee7edec50b49ab6d69b06d62f1de554efccb1ccd", |         "rev": "f5a22afd2adfb249b4e68e0b33aa1f0fb73fb1be", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "owner": "nmattia", |         "owner": "kamadorueda", | ||||||
|         "repo": "naersk", |         "repo": "alejandra", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "nixos-hardware": { |     "crane": { | ||||||
|  |       "flake": false, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1650522846, |         "lastModified": 1661875961, | ||||||
|         "narHash": "sha256-SxWHXRI3qJwswyXAtzsi6PKVY3KLNNnb072KaJthII8=", |         "narHash": "sha256-f1h/2c6Teeu1ofAHWzrS8TwBPcnN+EEu+z1sRVmMQTk=", | ||||||
|         "owner": "nixos", |         "owner": "ipetkov", | ||||||
|         "repo": "nixos-hardware", |         "repo": "crane", | ||||||
|         "rev": "6b4ebea9093c997c5f275c820e679108de4871ab", |         "rev": "d9f394e4e20e97c2a60c3ad82c2b6ef99be19e24", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "owner": "nixos", |         "owner": "ipetkov", | ||||||
|         "ref": "master", |         "repo": "crane", | ||||||
|         "repo": "nixos-hardware", |  | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "deploy-rs": { | ||||||
|  |       "inputs": { | ||||||
|  |         "flake-compat": "flake-compat", | ||||||
|  |         "nixpkgs": "nixpkgs", | ||||||
|  |         "utils": "utils" | ||||||
|  |       }, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1659725433, | ||||||
|  |         "narHash": "sha256-1ZxuK67TL29YLw88vQ18Y2Y6iYg8Jb7I6/HVzmNB6nM=", | ||||||
|  |         "owner": "serokell", | ||||||
|  |         "repo": "deploy-rs", | ||||||
|  |         "rev": "41f15759dd8b638e7b4f299730d94d5aa46ab7eb", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "serokell", | ||||||
|  |         "repo": "deploy-rs", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "devshell": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1653917170, | ||||||
|  |         "narHash": "sha256-FyxOnEE/V4PNEcMU62ikY4FfYPo349MOhMM97HS0XEo=", | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "devshell", | ||||||
|  |         "rev": "fc7a3e3adde9bbcab68af6d1e3c6eb738e296a92", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "devshell", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "dream2nix": { | ||||||
|  |       "inputs": { | ||||||
|  |         "alejandra": "alejandra", | ||||||
|  |         "crane": "crane", | ||||||
|  |         "devshell": "devshell", | ||||||
|  |         "flake-utils-pre-commit": "flake-utils-pre-commit", | ||||||
|  |         "gomod2nix": "gomod2nix", | ||||||
|  |         "mach-nix": "mach-nix", | ||||||
|  |         "nixpkgs": "nixpkgs_3", | ||||||
|  |         "poetry2nix": "poetry2nix", | ||||||
|  |         "pre-commit-hooks": "pre-commit-hooks" | ||||||
|  |       }, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1663323895, | ||||||
|  |         "narHash": "sha256-ZmI9C8HNVz2w3OnB79WR/LIgVEY8tDnR8tEPi3hMiJk=", | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "dream2nix", | ||||||
|  |         "rev": "25be741ec92c77b8308ca6a7ab89593fe37b6542", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "dream2nix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "fenix": { | ||||||
|  |       "inputs": { | ||||||
|  |         "nixpkgs": [ | ||||||
|  |           "tlaternet-webserver", | ||||||
|  |           "dream2nix", | ||||||
|  |           "alejandra", | ||||||
|  |           "nixpkgs" | ||||||
|  |         ], | ||||||
|  |         "rust-analyzer-src": "rust-analyzer-src" | ||||||
|  |       }, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1657607339, | ||||||
|  |         "narHash": "sha256-HaqoAwlbVVZH2n4P3jN2FFPMpVuhxDy1poNOR7kzODc=", | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "fenix", | ||||||
|  |         "rev": "b814c83d9e6aa5a28d0cf356ecfdafb2505ad37d", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "fenix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "fenix_2": { | ||||||
|  |       "inputs": { | ||||||
|  |         "nixpkgs": [ | ||||||
|  |           "tlaternet-webserver", | ||||||
|  |           "nixpkgs" | ||||||
|  |         ], | ||||||
|  |         "rust-analyzer-src": "rust-analyzer-src_2" | ||||||
|  |       }, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1663396212, | ||||||
|  |         "narHash": "sha256-dlK10QPTDYNpJ/vl2QPKOTrqEbQwAR/v2f4+xsetTkw=", | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "fenix", | ||||||
|  |         "rev": "263cd7f991c07a9592a6e825bfc37b23b00eb244", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "fenix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "flake-compat": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1648199409, | ||||||
|  |         "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=", | ||||||
|  |         "owner": "edolstra", | ||||||
|  |         "repo": "flake-compat", | ||||||
|  |         "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "edolstra", | ||||||
|  |         "repo": "flake-compat", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "flake-utils-pre-commit": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1644229661, | ||||||
|  |         "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "flake-utils", | ||||||
|  |         "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "flake-utils", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "flakeCompat": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1650374568, | ||||||
|  |         "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", | ||||||
|  |         "owner": "edolstra", | ||||||
|  |         "repo": "flake-compat", | ||||||
|  |         "rev": "b4a34015c698c7793d592d66adbab377907a2be8", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "edolstra", | ||||||
|  |         "repo": "flake-compat", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "gomod2nix": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1627572165, | ||||||
|  |         "narHash": "sha256-MFpwnkvQpauj799b4QTBJQFEddbD02+Ln5k92QyHOSk=", | ||||||
|  |         "owner": "tweag", | ||||||
|  |         "repo": "gomod2nix", | ||||||
|  |         "rev": "67f22dd738d092c6ba88e420350ada0ed4992ae8", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "tweag", | ||||||
|  |         "repo": "gomod2nix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "mach-nix": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1634711045, | ||||||
|  |         "narHash": "sha256-m5A2Ty88NChLyFhXucECj6+AuiMZPHXNbw+9Kcs7F6Y=", | ||||||
|  |         "owner": "DavHau", | ||||||
|  |         "repo": "mach-nix", | ||||||
|  |         "rev": "4433f74a97b94b596fa6cd9b9c0402104aceef5d", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "id": "mach-nix", | ||||||
|  |         "type": "indirect" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "nixpkgs": { |     "nixpkgs": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1650501692, |         "lastModified": 1648219316, | ||||||
|         "narHash": "sha256-ApKf0/dc0SyB7zZ6yiiOQgcXAhCXxbSDyihHfRDIzx0=", |         "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=", | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "ref": "nixpkgs-unstable", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "nixpkgs-22_05": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1665279158, | ||||||
|  |         "narHash": "sha256-TpbWNzoJ5RaZ302dzvjY2o//WxtOJuYT3CnDj5N69Hs=", | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "rev": "b3783bcfb8ec54e0de26feccfc6cc36b8e202ed5", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "ref": "release-22.05", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "nixpkgs_2": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1665466769, | ||||||
|  |         "narHash": "sha256-L+qcHpb4Ac3PipMXJY/Ktbu1+KXy23WCZ8pXWmsf7zY=", | ||||||
|         "owner": "nixos", |         "owner": "nixos", | ||||||
|         "repo": "nixpkgs", |         "repo": "nixpkgs", | ||||||
|         "rev": "9887f024766aa27704d1f89f623efd1d063da92a", |         "rev": "0b20bf89e0035b6d62ad58f9db8fdbc99c2b01e8", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "owner": "nixos", |         "owner": "nixos", | ||||||
|         "ref": "nixos-21.11", |         "ref": "nixos-22.05", | ||||||
|         "repo": "nixpkgs", |         "repo": "nixpkgs", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "nixpkgs_3": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1657638268, | ||||||
|  |         "narHash": "sha256-blBNtQSslAFkg0Gym9fWNJk+bPxGSZib4SOcPrmTPi4=", | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "rev": "d80993b5f885515254746ba6d1917276ee386149", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "id": "nixpkgs", | ||||||
|  |         "ref": "nixos-unstable", | ||||||
|  |         "type": "indirect" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "poetry2nix": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1632969109, | ||||||
|  |         "narHash": "sha256-jPDclkkiAy5m2gGLBlKgH+lQtbF7tL4XxBrbSzw+Ioc=", | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "repo": "poetry2nix", | ||||||
|  |         "rev": "aee8f04296c39d88155e05d25cfc59dfdd41cc77", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "nix-community", | ||||||
|  |         "ref": "1.21.0", | ||||||
|  |         "repo": "poetry2nix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "pre-commit-hooks": { | ||||||
|  |       "inputs": { | ||||||
|  |         "flake-utils": [ | ||||||
|  |           "tlaternet-webserver", | ||||||
|  |           "dream2nix", | ||||||
|  |           "flake-utils-pre-commit" | ||||||
|  |         ], | ||||||
|  |         "nixpkgs": [ | ||||||
|  |           "tlaternet-webserver", | ||||||
|  |           "dream2nix", | ||||||
|  |           "nixpkgs" | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1646153636, | ||||||
|  |         "narHash": "sha256-AlWHMzK+xJ1mG267FdT8dCq/HvLCA6jwmx2ZUy5O8tY=", | ||||||
|  |         "owner": "cachix", | ||||||
|  |         "repo": "pre-commit-hooks.nix", | ||||||
|  |         "rev": "b6bc0b21e1617e2b07d8205e7fae7224036dfa4b", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "cachix", | ||||||
|  |         "repo": "pre-commit-hooks.nix", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "root": { |     "root": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "nixos-hardware": "nixos-hardware", |         "deploy-rs": "deploy-rs", | ||||||
|         "nixpkgs": "nixpkgs", |         "nixpkgs": "nixpkgs_2", | ||||||
|         "sops-nix": "sops-nix", |         "sops-nix": "sops-nix", | ||||||
|         "tlaternet-templates": "tlaternet-templates", |  | ||||||
|         "tlaternet-webserver": "tlaternet-webserver" |         "tlaternet-webserver": "tlaternet-webserver" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "rust-overlay": { |     "rust-analyzer-src": { | ||||||
|       "inputs": { |       "flake": false, | ||||||
|         "flake-utils": [ |  | ||||||
|           "tlaternet-webserver", |  | ||||||
|           "flake-utils" |  | ||||||
|         ], |  | ||||||
|         "nixpkgs": [ |  | ||||||
|           "tlaternet-webserver", |  | ||||||
|           "nixpkgs" |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1633400100, |         "lastModified": 1657557289, | ||||||
|         "narHash": "sha256-kHQV7jZ2vVHVI9sfda1mUROVBbQbdfKcbIpKG9WdqGo=", |         "narHash": "sha256-PRW+nUwuqNTRAEa83SfX+7g+g8nQ+2MMbasQ9nt6+UM=", | ||||||
|         "owner": "oxalica", |         "owner": "rust-lang", | ||||||
|         "repo": "rust-overlay", |         "repo": "rust-analyzer", | ||||||
|         "rev": "9c2fc6a62ccbc6f420d71ecac6bf0b84dbbee64f", |         "rev": "caf23f29144b371035b864a1017dbc32573ad56d", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "owner": "oxalica", |         "owner": "rust-lang", | ||||||
|         "repo": "rust-overlay", |         "ref": "nightly", | ||||||
|  |         "repo": "rust-analyzer", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "rust-analyzer-src_2": { | ||||||
|  |       "flake": false, | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1662896065, | ||||||
|  |         "narHash": "sha256-1LkSsXzI1JTAmP/GMTz4fTJd8y/tw8R79l96q+h7mu8=", | ||||||
|  |         "owner": "rust-lang", | ||||||
|  |         "repo": "rust-analyzer", | ||||||
|  |         "rev": "2e9f1204ca01c3e20898d4a67c8b84899d394a88", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "rust-lang", | ||||||
|  |         "ref": "nightly", | ||||||
|  |         "repo": "rust-analyzer", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  | @ -121,14 +379,15 @@ | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "nixpkgs": [ |         "nixpkgs": [ | ||||||
|           "nixpkgs" |           "nixpkgs" | ||||||
|         ] |         ], | ||||||
|  |         "nixpkgs-22_05": "nixpkgs-22_05" | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1649756291, |         "lastModified": 1665289655, | ||||||
|         "narHash": "sha256-KTll8bCINAzIUGaaMrbn9wb5nfhkXRLgmFrWGR/Dku0=", |         "narHash": "sha256-j1Q9mNBhbzeJykhObiXwEGres9qvP4vH7gxdJ+ihkLI=", | ||||||
|         "owner": "Mic92", |         "owner": "Mic92", | ||||||
|         "repo": "sops-nix", |         "repo": "sops-nix", | ||||||
|         "rev": "c2614c4fe61943b3d280ac1892fcebe6e8eaf8c8", |         "rev": "0ce0449e6404c4ff9d1b7bd657794ae5ca54deb3", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|  | @ -137,42 +396,20 @@ | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "tlaternet-templates": { |  | ||||||
|       "inputs": { |  | ||||||
|         "flake-utils": "flake-utils", |  | ||||||
|         "nixpkgs": [ |  | ||||||
|           "nixpkgs" |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "locked": { |  | ||||||
|         "lastModified": 1633432574, |  | ||||||
|         "narHash": "sha256-IjGaJAQuFIJ1Is9gtHXsryPOnTDE6tlA61PUKuS8dzw=", |  | ||||||
|         "ref": "master", |  | ||||||
|         "rev": "555a2949bdf643c74b535bd0c623d98f99d33628", |  | ||||||
|         "revCount": 61, |  | ||||||
|         "type": "git", |  | ||||||
|         "url": "https://gitea.tlater.net/tlaternet/tlaternet-templates.git" |  | ||||||
|       }, |  | ||||||
|       "original": { |  | ||||||
|         "type": "git", |  | ||||||
|         "url": "https://gitea.tlater.net/tlaternet/tlaternet-templates.git" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "tlaternet-webserver": { |     "tlaternet-webserver": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "flake-utils": "flake-utils_2", |         "dream2nix": "dream2nix", | ||||||
|         "naersk": "naersk", |         "fenix": "fenix_2", | ||||||
|         "nixpkgs": [ |         "nixpkgs": [ | ||||||
|           "nixpkgs" |           "nixpkgs" | ||||||
|         ], |         ] | ||||||
|         "rust-overlay": "rust-overlay" |  | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1633433130, |         "lastModified": 1665402451, | ||||||
|         "narHash": "sha256-jkW+HV8cJvE86gppOEXQl2ke+bDHJ7SAp8eJp8pJ0N8=", |         "narHash": "sha256-zWaEzUJh0WFVoaLQsMoIj2D+QFhUBJw+f+XzoYqw3es=", | ||||||
|         "ref": "master", |         "ref": "master", | ||||||
|         "rev": "1232950c06ae16bf17fb16ac1f5f2231e971936b", |         "rev": "6c29bc5db001e75f5ca06fec726369b87d007a03", | ||||||
|         "revCount": 16, |         "revCount": 47, | ||||||
|         "type": "git", |         "type": "git", | ||||||
|         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" |         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" | ||||||
|       }, |       }, | ||||||
|  | @ -180,6 +417,21 @@ | ||||||
|         "type": "git", |         "type": "git", | ||||||
|         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" |         "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" | ||||||
|       } |       } | ||||||
|  |     }, | ||||||
|  |     "utils": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1648297722, | ||||||
|  |         "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=", | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "flake-utils", | ||||||
|  |         "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "numtide", | ||||||
|  |         "repo": "flake-utils", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "root": "root", |   "root": "root", | ||||||
|  |  | ||||||
							
								
								
									
										147
									
								
								flake.nix
									
										
									
									
									
								
							
							
						
						
									
										147
									
								
								flake.nix
									
										
									
									
									
								
							|  | @ -2,134 +2,127 @@ | ||||||
|   description = "tlater.net host configuration"; |   description = "tlater.net host configuration"; | ||||||
| 
 | 
 | ||||||
|   inputs = { |   inputs = { | ||||||
|     nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11"; |     nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05"; | ||||||
|     nixos-hardware.url = "github:nixos/nixos-hardware/master"; |     deploy-rs.url = "github:serokell/deploy-rs"; | ||||||
|     sops-nix = { |     sops-nix = { | ||||||
|       url = "github:Mic92/sops-nix"; |       url = "github:Mic92/sops-nix"; | ||||||
|       inputs.nixpkgs.follows = "nixpkgs"; |       inputs.nixpkgs.follows = "nixpkgs"; | ||||||
|     }; |     }; | ||||||
| 
 |  | ||||||
|     tlaternet-webserver = { |     tlaternet-webserver = { | ||||||
|       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git"; |       url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git"; | ||||||
|       inputs.nixpkgs.follows = "nixpkgs"; |       inputs.nixpkgs.follows = "nixpkgs"; | ||||||
|     }; |     }; | ||||||
|     tlaternet-templates = { |  | ||||||
|       url = "git+https://gitea.tlater.net/tlaternet/tlaternet-templates.git"; |  | ||||||
|       inputs.nixpkgs.follows = "nixpkgs"; |  | ||||||
|     }; |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   outputs = { |   outputs = { | ||||||
|     self, |     self, | ||||||
|     nixpkgs, |     nixpkgs, | ||||||
|     nixos-hardware, |  | ||||||
|     sops-nix, |     sops-nix, | ||||||
|  |     deploy-rs, | ||||||
|     tlaternet-webserver, |     tlaternet-webserver, | ||||||
|     tlaternet-templates, |  | ||||||
|   }: let |   }: let | ||||||
|     system = "x86_64-linux"; |     system = "x86_64-linux"; | ||||||
| 
 |  | ||||||
|     overlays = [ |  | ||||||
|       (final: prev: { |  | ||||||
|         tlaternet-webserver = |  | ||||||
|           tlaternet-webserver.legacyPackages.${prev.system}.packages; |  | ||||||
|         tlaternet-templates = |  | ||||||
|           tlaternet-templates.legacyPackages.${prev.system}.packages; |  | ||||||
|         local = import ./pkgs { |  | ||||||
|           pkgs = prev; |  | ||||||
|         }; |  | ||||||
|       }) |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     pkgs = import nixpkgs {inherit system overlays;}; |  | ||||||
|     sops-pkgs = sops-nix.packages.${system}; |  | ||||||
|   in { |   in { | ||||||
|     nixosConfigurations = { |     ################## | ||||||
|  |     # Configurations # | ||||||
|  |     ################## | ||||||
|  |     nixosConfigurations = let | ||||||
|  |       # Modules that should be generic to all systems | ||||||
|  |       genericModule = {...}: { | ||||||
|  |         imports = [ | ||||||
|  |           # Inject flake dependencies | ||||||
|  |           sops-nix.nixosModules.sops | ||||||
|  |           tlaternet-webserver.nixosModules.default | ||||||
|  | 
 | ||||||
|  |           # Import actual configuration | ||||||
|  |           (import ./configuration) | ||||||
|  |         ]; | ||||||
|  |       }; | ||||||
|  |     in { | ||||||
|  |       # The actual system definition | ||||||
|       tlaternet = nixpkgs.lib.nixosSystem { |       tlaternet = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
| 
 |  | ||||||
|         modules = [ |         modules = [ | ||||||
|           ({modulesPath, ...}: { |           genericModule | ||||||
|             imports = [(modulesPath + "/profiles/headless.nix")]; |           (import ./configuration/hardware-specific/linode) | ||||||
|             nixpkgs.overlays = overlays; |  | ||||||
|           }) |  | ||||||
|           (import ./modules) |  | ||||||
| 
 |  | ||||||
|           (import ./configuration) |  | ||||||
|           (import ./configuration/linode.nix) |  | ||||||
|           (import ./configuration/hardware-configuration.nix) |  | ||||||
|           sops-nix.nixosModules.sops |  | ||||||
|         ]; |         ]; | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|  |       # A qemu VM to test the above with | ||||||
|       vm = nixpkgs.lib.nixosSystem { |       vm = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
| 
 |  | ||||||
|         modules = [ |         modules = [ | ||||||
|           ({modulesPath, ...}: { |           genericModule | ||||||
|             imports = [(modulesPath + "/profiles/headless.nix")]; |           (import ./configuration/hardware-specific/vm.nix) | ||||||
|             nixpkgs.overlays = overlays; |  | ||||||
|           }) |  | ||||||
|           (import ./modules) |  | ||||||
| 
 |  | ||||||
|           (import ./configuration) |  | ||||||
|           sops-nix.nixosModules.sops |  | ||||||
|           ({lib, ...}: { |  | ||||||
|             users.users.tlater.password = "insecure"; |  | ||||||
| 
 |  | ||||||
|             # Disable graphical tty so -curses works |  | ||||||
|             boot.kernelParams = ["nomodeset"]; |  | ||||||
| 
 |  | ||||||
|             # Sets the base domain for nginx to localhost so that we |  | ||||||
|             # can easily test locally with the VM. |  | ||||||
|             services.nginx.domain = lib.mkOverride 99 "localhost"; |  | ||||||
| 
 |  | ||||||
|             # Use the staging secrets |  | ||||||
|             sops.defaultSopsFile = lib.mkOverride 99 ./keys/staging.yaml; |  | ||||||
| 
 |  | ||||||
|             # # Set up VM settings to match real VPS |  | ||||||
|             # virtualisation.memorySize = 3941; |  | ||||||
|             # virtualisation.cores = 2; |  | ||||||
|           }) |  | ||||||
|         ]; |         ]; | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     ############################ | ||||||
|  |     # Deployment configuration # | ||||||
|  |     ############################ | ||||||
|  |     deploy.nodes.tlaternet = { | ||||||
|  |       hostname = "tlater.net"; | ||||||
|  | 
 | ||||||
|  |       profiles.system = { | ||||||
|  |         user = "root"; | ||||||
|  |         path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.tlaternet; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       sshUser = "tlater"; | ||||||
|  |       sshOpts = ["-p" "2222"]; | ||||||
|  |       fastConnection = true; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     ######### | ||||||
|  |     # Tests # | ||||||
|  |     ######### | ||||||
|  |     checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib; | ||||||
|  | 
 | ||||||
|  |     #################### | ||||||
|  |     # Helper functions # | ||||||
|  |     #################### | ||||||
|  |     lib = import ./lib {lib = nixpkgs.lib;}; | ||||||
|  | 
 | ||||||
|  |     #################### | ||||||
|  |     # VM launch script # | ||||||
|  |     #################### | ||||||
|     apps.${system}.default = let |     apps.${system}.default = let | ||||||
|       inherit (self.nixosConfigurations.vm.config.system.build) vm; |       inherit (self.nixosConfigurations.vm.config.system.build) vm; | ||||||
|       inherit (nixpkgs.legacyPackages.${system}) writeShellScript; |       inherit (nixpkgs.legacyPackages.${system}) writeShellScript; | ||||||
|       inherit (nixpkgs.lib.attrsets) mapAttrsToList; |       qemuNetOpts = self.lib.makeQemuNetOpts { | ||||||
|       inherit (nixpkgs.lib.strings) concatStringsSep; |  | ||||||
|       ports = { |  | ||||||
|         "2222" = "2222"; |         "2222" = "2222"; | ||||||
|         "3080" = "80"; |         "3080" = "80"; | ||||||
|         "3443" = "443"; |         "3443" = "443"; | ||||||
|         "2221" = "2221"; |  | ||||||
|         "21025" = "21025"; # Starbound |         "21025" = "21025"; # Starbound | ||||||
|       }; |       }; | ||||||
|       QEMU_NET_OPTS = |  | ||||||
|         concatStringsSep "," |  | ||||||
|         (mapAttrsToList |  | ||||||
|           (host: vm: "hostfwd=::${host}-:${vm}") |  | ||||||
|           ports); |  | ||||||
|     in { |     in { | ||||||
|       type = "app"; |       type = "app"; | ||||||
|       program = builtins.toString (writeShellScript "run-vm" '' |       program = builtins.toString (writeShellScript "run-vm" '' | ||||||
|         export QEMU_OPTS="-m 3941 -smp 2 -curses" |         export QEMU_OPTS="-m 3941 -smp 2 -display curses" | ||||||
|         export QEMU_NET_OPTS="${QEMU_NET_OPTS}" |         export QEMU_NET_OPTS="${qemuNetOpts}" | ||||||
|         "${vm}/bin/run-tlaternet-vm" |         "${vm}/bin/run-tlaternet-vm" | ||||||
|       ''); |       ''); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     devShells.${system}.default = pkgs.mkShell { |     ########################### | ||||||
|  |     # Development environment # | ||||||
|  |     ########################### | ||||||
|  |     devShells.${system}.default = let | ||||||
|  |       inherit (sops-nix.packages.${system}) sops-import-keys-hook sops-init-gpg-key; | ||||||
|  |       deploy-rs-bin = deploy-rs.packages.${system}.default; | ||||||
|  |       pkgs = nixpkgs.legacyPackages.${system}; | ||||||
|  |     in | ||||||
|  |       nixpkgs.legacyPackages.${system}.mkShell { | ||||||
|         sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"]; |         sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"]; | ||||||
|         nativeBuildInputs = [ |         nativeBuildInputs = [ | ||||||
|         sops-pkgs.sops-import-keys-hook |           sops-import-keys-hook | ||||||
|         ]; |         ]; | ||||||
|       buildInputs = with pkgs; [ |         packages = with pkgs; [ | ||||||
|           nixfmt |           nixfmt | ||||||
|           git-lfs |           git-lfs | ||||||
|         sops-pkgs.sops-init-gpg-key |           sops-init-gpg-key | ||||||
|  |           deploy-rs-bin | ||||||
|         ]; |         ]; | ||||||
| 
 | 
 | ||||||
|         shellHook = '' |         shellHook = '' | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								lib/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | {lib}: let | ||||||
|  |   inherit (lib.attrsets) mapAttrsToList; | ||||||
|  |   inherit (lib.strings) concatStringsSep; | ||||||
|  | in { | ||||||
|  |   makeQemuNetOpts = portMapping: | ||||||
|  |     concatStringsSep "," | ||||||
|  |     (mapAttrsToList | ||||||
|  |       (host: vm: "hostfwd=::${host}-:${vm}") | ||||||
|  |       portMapping); | ||||||
|  | } | ||||||
|  | @ -1,222 +0,0 @@ | ||||||
| { |  | ||||||
|   lib, |  | ||||||
|   config, |  | ||||||
|   options, |  | ||||||
|   ... |  | ||||||
| }: |  | ||||||
| with lib; let |  | ||||||
|   cfg = config.virtualisation.pods; |  | ||||||
|   list-to-args = arg: list: |  | ||||||
|     concatStringsSep " " (map (e: "--${arg}=${escapeShellArg e}") list); |  | ||||||
|   possibly-unset-arg = arg: val: (optionalString (val != null) "--${arg}=${escapeShellArg val}"); |  | ||||||
| 
 |  | ||||||
|   mkPod = name: pod: rec { |  | ||||||
|     path = [config.virtualisation.podman.package]; |  | ||||||
| 
 |  | ||||||
|     wants = ["network.target"]; |  | ||||||
|     after = ["network-online.target"]; |  | ||||||
|     wantedBy = ["multi-user.target" "default.target"]; |  | ||||||
| 
 |  | ||||||
|     environment.PODMAN_SYSTEMD_UNIT = "%n"; |  | ||||||
| 
 |  | ||||||
|     preStart = concatStringsSep " " [ |  | ||||||
|       "mkdir -p /run/podman/pods/ ;" |  | ||||||
|       "podman pod create" |  | ||||||
|       "--infra-conmon-pidfile=${escapeShellArg "/run/podman/pods/${name}.pid"}" |  | ||||||
|       "--name=${escapeShellArg name}" |  | ||||||
|       "--replace" |  | ||||||
|       (list-to-args "add-host" pod.added-hosts) |  | ||||||
|       (possibly-unset-arg "cgroup-parent" pod.cgroup-parent) |  | ||||||
|       (list-to-args "dns" pod.dns) |  | ||||||
|       (list-to-args "dns-opt" pod.dns-opt) |  | ||||||
|       (list-to-args "dns-search" pod.dns-search) |  | ||||||
|       (possibly-unset-arg "hostname" pod.hostname) |  | ||||||
|       (possibly-unset-arg "infra" pod.infra) |  | ||||||
|       (possibly-unset-arg "infra-command" pod.infra-command) |  | ||||||
|       (possibly-unset-arg "infra-image" pod.infra-image) |  | ||||||
|       (possibly-unset-arg "ip" pod.ip) |  | ||||||
|       (possibly-unset-arg "mac-address" pod.mac-address) |  | ||||||
|       (possibly-unset-arg "network" pod.network) |  | ||||||
|       (possibly-unset-arg "network-alias" pod.network-alias) |  | ||||||
|       (possibly-unset-arg "no-hosts" pod.no-hosts) |  | ||||||
|       (list-to-args "publish" pod.publish) |  | ||||||
|       (list-to-args "share" pod.share) |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
|     script = "podman pod start ${escapeShellArg name}"; |  | ||||||
|     preStop = "podman pod stop ${escapeShellArg name}"; |  | ||||||
|     # `podman generate systemd` generates a second stop after the |  | ||||||
|     # first; not sure why but clearly it's recommended. |  | ||||||
|     postStop = preStop; |  | ||||||
| 
 |  | ||||||
|     serviceConfig = rec { |  | ||||||
|       Type = "forking"; |  | ||||||
|       TimeoutStopSec = 70; |  | ||||||
|       Restart = "on-failure"; |  | ||||||
|       PIDFile = "/run/podman/pods/${name}.pid"; |  | ||||||
|     }; |  | ||||||
|   }; |  | ||||||
| in { |  | ||||||
|   options.virtualisation.pods = mkOption { |  | ||||||
|     type = with types; |  | ||||||
|       attrsOf (submodule { |  | ||||||
|         options = { |  | ||||||
|           added-hosts = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "Additional hosts to add to /etc/hosts for each container."; |  | ||||||
|             example = literalExample '' |  | ||||||
|               [ "database:10.0.0.1" ] |  | ||||||
|             ''; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           cgroup-parent = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "The cgroups path under which the pod cgroup will be created."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           dns = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "The dns servers to set in /etc/resolv.conf."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           dns-opt = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "dns options to set in /etc/resolv.conf."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           dns-search = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "Search domains to set in /etc/resolv.conf."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           hostname = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "The pod hostname."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           infra = mkOption { |  | ||||||
|             type = nullOr bool; |  | ||||||
|             default = null; |  | ||||||
|             description = "Whether to create the infra container for the pod."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           infra-command = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "The command to run in the infra container."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           infra-image = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "The image to use for the infra container."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           ip = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "A static IP address for the pod network."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           # TODO: set up label file stuff. |  | ||||||
|           # |  | ||||||
|           # labels = mkOption {}; |  | ||||||
| 
 |  | ||||||
|           mac-address = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "A static mac address for the pod network."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           network = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "Network configuration for the pod."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           network-alias = mkOption { |  | ||||||
|             type = nullOr str; |  | ||||||
|             default = null; |  | ||||||
|             description = "DNS alias for the pod."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           no-hosts = mkOption { |  | ||||||
|             type = nullOr bool; |  | ||||||
|             default = null; |  | ||||||
|             description = "Whether to disable /etc/hosts creation for the pod."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           publish = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "List of ports to publish from the pod."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           share = mkOption { |  | ||||||
|             type = listOf str; |  | ||||||
|             default = []; |  | ||||||
|             description = "List of kernel namespaces to share."; |  | ||||||
|           }; |  | ||||||
| 
 |  | ||||||
|           containers = options.virtualisation.oci-containers.containers; |  | ||||||
|         }; |  | ||||||
|       }); |  | ||||||
|     default = {}; |  | ||||||
|     description = "Podman pods to run as systemd services."; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   config = let |  | ||||||
|     # Merge a list of attribute sets together |  | ||||||
|     # |  | ||||||
|     # TODO: See if there's a generic version for this somewhere in the |  | ||||||
|     # pkgs lib? |  | ||||||
|     mergeAttrs = attrList: foldr (a: b: a // b) {} attrList; |  | ||||||
| 
 |  | ||||||
|     # Create services for all defined pods |  | ||||||
|     pod-services = mapAttrs' (n: v: nameValuePair "pod-${n}" (mkPod n v)) cfg; |  | ||||||
| 
 |  | ||||||
|     # Override the systemd-specific settings of containers defined in |  | ||||||
|     # pods. |  | ||||||
|     # |  | ||||||
|     # I.e., make a systemd unit dependency on the pod service. |  | ||||||
|     pod-container-services = mergeAttrs (mapAttrsToList (pname: pod: |  | ||||||
|       mapAttrs' (cname: container: |  | ||||||
|         nameValuePair "podman-${pname}-${cname}" rec { |  | ||||||
|           after = ["pod-${pname}.service"]; |  | ||||||
|           requires = after; |  | ||||||
|         }) |  | ||||||
|       pod.containers) |  | ||||||
|     cfg); |  | ||||||
| 
 |  | ||||||
|     # Override the oci-container settings for containers defined in pods. |  | ||||||
|     # |  | ||||||
|     # I.e., set the --pod=podname setting, and update the dependsOn so |  | ||||||
|     # it points to containers in the same pod. |  | ||||||
|     podifyContainer = container: podname: |  | ||||||
|       container |  | ||||||
|       // { |  | ||||||
|         dependsOn = |  | ||||||
|           map (dependency: "${podname}-${dependency}") container.dependsOn; |  | ||||||
|         extraOptions = container.extraOptions ++ ["--pod=${podname}"]; |  | ||||||
|       }; |  | ||||||
|   in |  | ||||||
|     lib.mkIf (cfg != {}) { |  | ||||||
|       virtualisation.podman.enable = true; |  | ||||||
|       virtualisation.oci-containers.backend = "podman"; |  | ||||||
| 
 |  | ||||||
|       systemd.services = pod-services // pod-container-services; |  | ||||||
| 
 |  | ||||||
|       virtualisation.oci-containers.containers = mergeAttrs (mapAttrsToList |  | ||||||
|         (pname: pod: |  | ||||||
|           mapAttrs' (cname: container: |  | ||||||
|             nameValuePair "${pname}-${cname}" (podifyContainer container pname)) |  | ||||||
|           pod.containers) |  | ||||||
|         cfg); |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| {pkgs, ...}: let | {pkgs, ...}: let | ||||||
|   inherit (pkgs.lib) callPackage; |   inherit (pkgs) callPackage; | ||||||
| in { | in { | ||||||
|   starbound = callPackage ./starbound {}; |   starbound = callPackage ./starbound {}; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue