lol
1outer@{
2 lib,
3 stdenv,
4 fetchurl,
5 fetchpatch,
6 openssl,
7 zlib-ng,
8 pcre2,
9 libxml2,
10 libxslt,
11 nginx-doc,
12
13 nixosTests,
14 installShellFiles,
15 replaceVars,
16 removeReferencesTo,
17 gd,
18 geoip,
19 perl,
20 withDebug ? false,
21 withGeoIP ? false,
22 withImageFilter ? false,
23 withKTLS ? true,
24 withStream ? true,
25 withMail ? false,
26 withPerl ? true,
27 withSlice ? false,
28 modules ? [ ],
29 ...
30}:
31
32{
33 pname ? "nginx",
34 version,
35 nginxVersion ? version,
36 src ? null, # defaults to upstream nginx ${version}
37 hash ? null, # when not specifying src
38 configureFlags ? [ ],
39 nativeBuildInputs ? [ ],
40 buildInputs ? [ ],
41 extraPatches ? [ ],
42 fixPatch ? p: p,
43 postPatch ? null,
44 preConfigure ? "",
45 preInstall ? "",
46 postInstall ? "",
47 meta ? null,
48 nginx-doc ? outer.nginx-doc,
49 passthru ? {
50 tests = { };
51 },
52}:
53
54let
55
56 moduleNames = map (
57 mod:
58 mod.name
59 or (throw "The nginx module with source ${toString mod.src} does not have a `name` attribute. This prevents duplicate module detection and is no longer supported.")
60 ) modules;
61
62 mapModules =
63 attrPath:
64 lib.flip lib.concatMap modules (
65 mod:
66 let
67 supports = mod.supports or (_: true);
68 in
69 if supports nginxVersion then
70 mod.${attrPath} or [ ]
71 else
72 throw "Module at ${toString mod.src} does not support nginx version ${nginxVersion}!"
73 );
74
75in
76
77assert lib.assertMsg (lib.unique moduleNames == moduleNames)
78 "nginx: duplicate modules: ${lib.concatStringsSep ", " moduleNames}. A common cause for this is that services.nginx.additionalModules adds a module which the nixos module itself already adds.";
79
80stdenv.mkDerivation {
81 inherit pname version nginxVersion;
82
83 outputs = [
84 "out"
85 "doc"
86 ];
87
88 src =
89 if src != null then
90 src
91 else
92 fetchurl {
93 url = "https://nginx.org/download/nginx-${version}.tar.gz";
94 inherit hash;
95 };
96
97 nativeBuildInputs = [
98 installShellFiles
99 removeReferencesTo
100 ] ++ nativeBuildInputs;
101
102 buildInputs =
103 [
104 openssl
105 zlib-ng
106 pcre2
107 libxml2
108 libxslt
109 perl
110 ]
111 ++ buildInputs
112 ++ mapModules "inputs"
113 ++ lib.optional withGeoIP geoip
114 ++ lib.optional withImageFilter gd;
115
116 configureFlags =
117 [
118 "--sbin-path=bin/nginx"
119 "--with-http_ssl_module"
120 "--with-http_v2_module"
121 "--with-http_realip_module"
122 "--with-http_addition_module"
123 "--with-http_xslt_module"
124 "--with-http_sub_module"
125 "--with-http_dav_module"
126 "--with-http_flv_module"
127 "--with-http_mp4_module"
128 "--with-http_gunzip_module"
129 "--with-http_gzip_static_module"
130 "--with-http_auth_request_module"
131 "--with-http_random_index_module"
132 "--with-http_secure_link_module"
133 "--with-http_degradation_module"
134 "--with-http_stub_status_module"
135 "--with-threads"
136 "--with-pcre-jit"
137 "--http-log-path=/var/log/nginx/access.log"
138 "--error-log-path=/var/log/nginx/error.log"
139 "--pid-path=/var/log/nginx/nginx.pid"
140 "--http-client-body-temp-path=/tmp/nginx_client_body"
141 "--http-proxy-temp-path=/tmp/nginx_proxy"
142 "--http-fastcgi-temp-path=/tmp/nginx_fastcgi"
143 "--http-uwsgi-temp-path=/tmp/nginx_uwsgi"
144 "--http-scgi-temp-path=/tmp/nginx_scgi"
145 ]
146 ++ lib.optionals withDebug [
147 "--with-debug"
148 ]
149 ++ lib.optionals withKTLS [
150 "--with-openssl-opt=enable-ktls"
151 ]
152 ++ lib.optionals withStream [
153 "--with-stream"
154 "--with-stream_realip_module"
155 "--with-stream_ssl_module"
156 "--with-stream_ssl_preread_module"
157 ]
158 ++ lib.optionals withMail [
159 "--with-mail"
160 "--with-mail_ssl_module"
161 ]
162 ++ lib.optionals withPerl [
163 "--with-http_perl_module"
164 "--with-perl=${perl}/bin/perl"
165 "--with-perl_modules_path=lib/perl5"
166 ]
167 ++ lib.optional withImageFilter "--with-http_image_filter_module"
168 ++ lib.optional withSlice "--with-http_slice_module"
169 ++ lib.optionals withGeoIP (
170 [ "--with-http_geoip_module" ] ++ lib.optional withStream "--with-stream_geoip_module"
171 )
172 ++ lib.optional (with stdenv.hostPlatform; isLinux || isFreeBSD) "--with-file-aio"
173 ++ lib.optional (
174 stdenv.buildPlatform != stdenv.hostPlatform
175 ) "--crossbuild=${stdenv.hostPlatform.uname.system}::${stdenv.hostPlatform.uname.processor}"
176 ++ configureFlags
177 ++ map (mod: "--add-module=${mod.src}") modules;
178
179 env.NIX_CFLAGS_COMPILE = toString (
180 [
181 "-I${libxml2.dev}/include/libxml2"
182 "-Wno-error=implicit-fallthrough"
183 (
184 # zlig-ng patch needs this
185 if stdenv.cc.isGNU then
186 "-Wno-error=discarded-qualifiers"
187 else
188 "-Wno-error=incompatible-pointer-types-discards-qualifiers"
189 )
190 ]
191 ++ lib.optionals (stdenv.cc.isGNU && lib.versionAtLeast stdenv.cc.version "11") [
192 # fix build vts module on gcc11
193 "-Wno-error=stringop-overread"
194 ]
195 ++ lib.optionals stdenv.cc.isClang [
196 "-Wno-error=deprecated-declarations"
197 "-Wno-error=gnu-folding-constant"
198 "-Wno-error=unused-but-set-variable"
199 ]
200 ++ lib.optionals stdenv.hostPlatform.isMusl [
201 # fix sys/cdefs.h is deprecated
202 "-Wno-error=cpp"
203 ]
204 );
205
206 configurePlatforms = [ ];
207
208 # Disable _multioutConfig hook which adds --bindir=$out/bin into configureFlags,
209 # which breaks build, since nginx does not actually use autoconf.
210 preConfigure =
211 ''
212 setOutputFlags=
213 ''
214 + preConfigure
215 + lib.concatMapStringsSep "\n" (mod: mod.preConfigure or "") modules;
216
217 patches =
218 map fixPatch (
219 [
220 ./nix-etag-1.15.4.patch
221 ./nix-skip-check-logs-path.patch
222 ]
223 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
224 (fetchpatch {
225 url = "https://raw.githubusercontent.com/openwrt/packages/c057dfb09c7027287c7862afab965a4cd95293a3/net/nginx/patches/102-sizeof_test_fix.patch";
226 sha256 = "0i2k30ac8d7inj9l6bl0684kjglam2f68z8lf3xggcc2i5wzhh8a";
227 })
228 (fetchpatch {
229 url = "https://raw.githubusercontent.com/openwrt/packages/c057dfb09c7027287c7862afab965a4cd95293a3/net/nginx/patches/101-feature_test_fix.patch";
230 sha256 = "0v6890a85aqmw60pgj3mm7g8nkaphgq65dj4v9c6h58wdsrc6f0y";
231 })
232 (fetchpatch {
233 url = "https://raw.githubusercontent.com/openwrt/packages/c057dfb09c7027287c7862afab965a4cd95293a3/net/nginx/patches/103-sys_nerr.patch";
234 sha256 = "0s497x6mkz947aw29wdy073k8dyjq8j99lax1a1mzpikzr4rxlmd";
235 })
236 ]
237 ++ mapModules "patches"
238 )
239 ++ extraPatches;
240
241 postPatch = lib.defaultTo ''
242 substituteInPlace src/http/ngx_http_core_module.c \
243 --replace-fail '@nixStoreDir@' "$NIX_STORE" \
244 --replace-fail '@nixStoreDirLen@' "''${#NIX_STORE}"
245 '' postPatch;
246
247 hardeningEnable = lib.optional (!stdenv.hostPlatform.isDarwin) "pie";
248
249 enableParallelBuilding = true;
250
251 preInstall =
252 ''
253 mkdir -p $doc
254 cp -r ${nginx-doc}/* $doc
255
256 # TODO: make it unconditional when `openresty` and `nginx` are not
257 # sharing this code.
258 if [[ -e man/nginx.8 ]]; then
259 installManPage man/nginx.8
260 fi
261 ''
262 + preInstall;
263
264 disallowedReferences = map (m: m.src) modules;
265
266 postInstall =
267 let
268 noSourceRefs = lib.concatMapStrings (
269 m: "remove-references-to -t ${m.src} $(readlink -fn $out/bin/nginx)\n"
270 ) modules;
271 in
272 postInstall + noSourceRefs;
273
274 passthru = {
275 inherit modules;
276 tests = {
277 inherit (nixosTests)
278 nginx
279 nginx-auth
280 nginx-etag
281 nginx-etag-compression
282 nginx-globalredirect
283 nginx-http3
284 nginx-proxyprotocol
285 nginx-pubhtml
286 nginx-sso
287 nginx-status-page
288 nginx-unix-socket
289 ;
290 variants = lib.recurseIntoAttrs nixosTests.nginx-variants;
291 acme-integration = nixosTests.acme.nginx;
292 } // passthru.tests;
293 };
294
295 meta =
296 if meta != null then
297 meta
298 else
299 with lib;
300 {
301 description = "Reverse proxy and lightweight webserver";
302 mainProgram = "nginx";
303 homepage = "http://nginx.org";
304 license = [ licenses.bsd2 ] ++ concatMap (m: m.meta.license) modules;
305 broken = lib.any (m: m.meta.broken or false) modules;
306 platforms = platforms.all;
307 maintainers = with maintainers; [
308 fpletz
309 raitobezarius
310 ];
311 teams = with teams; [
312 helsinki-systems
313 stridtech
314 ];
315 };
316}