deploy nginx

This commit is contained in:
Yan Lin 2026-02-19 10:30:28 +01:00
parent eec16c0440
commit cebfe9c011
4 changed files with 108 additions and 167 deletions

View file

@ -1,105 +0,0 @@
{ config, ... }:
{
# Traefik dynamic configuration for vps host
services.traefik.dynamic.files."proxy".settings = {
http = {
serversTransports = {
longTimeout = {
forwardingTimeouts = {
dialTimeout = "30s";
responseHeaderTimeout = "1200s";
idleConnTimeout = "1200s";
};
};
};
routers = {
photo = {
rule = "Host(`photo.yanlincs.com`)";
service = "photo";
tls = {
certResolver = "cloudflare";
domains = [{
main = "*.yanlincs.com";
}];
};
};
music = {
rule = "Host(`music.yanlincs.com`)";
service = "music";
tls = {
certResolver = "cloudflare";
domains = [{
main = "*.yanlincs.com";
}];
};
};
deluge = {
rule = "Host(`deluge.yanlincs.com`)";
service = "deluge";
tls = {
certResolver = "cloudflare";
domains = [{
main = "*.yanlincs.com";
}];
};
};
git = {
rule = "Host(`git.yanlincs.com`)";
service = "git";
tls = {
certResolver = "cloudflare";
domains = [{
main = "*.yanlincs.com";
}];
};
};
};
services = {
photo = {
loadBalancer = {
serversTransport = "longTimeout";
servers = [{
url = "http://10.2.2.10:8080";
}];
};
};
music = {
loadBalancer = {
servers = [{
url = "http://10.2.2.10:4533";
}];
};
};
deluge = {
loadBalancer = {
servers = [{
url = "http://10.2.2.10:8112";
}];
};
};
git = {
loadBalancer = {
servers = [{
url = "http://127.0.0.1:3000";
}];
};
};
};
};
};
}

View file

@ -4,11 +4,10 @@
imports = [
./hardware-configuration.nix
./containers.nix
./proxy.nix
../system-default.nix
../../../modules/vpn/server.nix
../../../modules/podman.nix
../../../modules/traefik.nix
../../../modules/nginx.nix
../../../modules/borg/client.nix
../../../modules/git/server.nix
];
@ -77,6 +76,27 @@
];
};
services.reverse-proxy = {
enable = true;
defaultDomain = "yanlincs.com";
acmeEmail = "cloudflare@yanlincs.com";
proxies = {
photo = {
backend = "http://10.2.2.10:8080";
extraConfig = ''
client_max_body_size 0;
proxy_read_timeout 1200s;
proxy_send_timeout 1200s;
proxy_connect_timeout 30s;
'';
};
music.backend = "http://10.2.2.10:4533";
deluge.backend = "http://10.2.2.10:8112";
git.backend = "http://127.0.0.1:3000";
};
};
services.git-server-custom = {
enable = true;
domain = "git.yanlincs.com";

86
modules/nginx.nix Normal file
View file

@ -0,0 +1,86 @@
# NOTE: environment file at: `/etc/acme-env` with mode 600
# content (for Cloudflare API):
# CF_API_EMAIL=your-email@example.com
# CF_DNS_API_TOKEN=your-cloudflare-api-token
{ config, lib, ... }:
let
cfg = config.services.reverse-proxy;
proxySubmodule = lib.types.submodule {
options = {
domain = lib.mkOption {
type = lib.types.str;
default = cfg.defaultDomain;
};
backend = lib.mkOption {
type = lib.types.str;
example = "http://127.0.0.1:3000";
};
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
};
};
};
allDomains = lib.unique (lib.mapAttrsToList (_: p: p.domain) cfg.proxies);
in
{
options.services.reverse-proxy = {
enable = lib.mkEnableOption "nginx reverse proxy with ACME";
defaultDomain = lib.mkOption {
type = lib.types.str;
example = "example.com";
};
acmeEmail = lib.mkOption {
type = lib.types.str;
};
environmentFile = lib.mkOption {
type = lib.types.path;
default = "/etc/acme-env";
};
proxies = lib.mkOption {
type = lib.types.attrsOf proxySubmodule;
default = {};
};
};
config = lib.mkIf cfg.enable {
security.acme = {
acceptTerms = true;
defaults.email = cfg.acmeEmail;
certs = lib.genAttrs allDomains (domain: {
domain = "*.${domain}";
dnsProvider = "cloudflare";
inherit (cfg) environmentFile;
});
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
virtualHosts = lib.mapAttrs' (name: proxy:
lib.nameValuePair "${name}.${proxy.domain}" {
forceSSL = true;
useACMEHost = proxy.domain;
locations."/" = {
proxyPass = proxy.backend;
proxyWebsockets = true;
extraConfig = proxy.extraConfig;
};
}
) cfg.proxies;
};
users.users.nginx.extraGroups = [ "acme" ];
};
}

View file

@ -1,60 +0,0 @@
# NOTE: environment file at: `/etc/traefik-env` with mode 600
# content (for Cloudflare API):
# CF_API_EMAIL=your-email@example.com
# CF_DNS_API_TOKEN=your-cloudflare-api-token
{ ... }:
{
services.traefik = {
enable = true;
useEnvSubst = false;
dynamic.dir = "/var/lib/traefik/dynamic";
static.settings = {
entryPoints = {
http = {
address = ":80";
http.redirections.entryPoint = {
to = "websecure";
scheme = "https";
permanent = true;
};
};
websecure = {
address = ":443";
transport.respondingTimeouts.readTimeout = "0s";
};
};
certificatesResolvers.cloudflare = {
acme = {
email = "cloudflare@yanlincs.com";
storage = "/var/lib/traefik/acme.json";
dnsChallenge = {
provider = "cloudflare";
delayBeforeCheck = 60;
resolvers = [
"1.1.1.1:53"
"8.8.8.8:53"
];
};
};
};
log = {
level = "INFO";
};
accessLog = {};
global = {
checkNewVersion = false;
sendAnonymousUsage = false;
};
};
environmentFiles = [ "/etc/traefik-env" ];
};
}