Skip to content

Commit f9fdd56

Browse files
committed
working
1 parent 530ec8e commit f9fdd56

File tree

6 files changed

+153
-21
lines changed

6 files changed

+153
-21
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.git/
2+
.github/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
6+
jobs:
7+
docker:
8+
runs-on: ubuntu-latest
9+
steps:
10+
-
11+
name: Set up QEMU
12+
uses: docker/setup-qemu-action@v2
13+
-
14+
name: Set up Docker Buildx
15+
uses: docker/setup-buildx-action@v2
16+
-
17+
name: Login to GitHub Container Registry
18+
uses: docker/login-action@v2
19+
with:
20+
registry: ghcr.io
21+
username: ${{ github.repository_owner }}
22+
password: ${{ secrets.GITHUB_TOKEN }}
23+
-
24+
name: Build and push
25+
uses: docker/build-push-action@v4
26+
with:
27+
platforms: linux/amd64,linux/arm64
28+
push: true
29+
tags: ghcr.io/deltablot/custom-http-nginx:latest

Dockerfile

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
FROM alpine:3.19 as nginx-builder
1+
# This builds an http only nginx, with no extra modules, and no openssl
2+
FROM alpine:3.20 AS nginx-builder
23

34
ENV NGINX_VERSION=1.26.1
4-
# pin nginx modules versions
5-
# see https://github.com/google/ngx_brotli/issues/120 for the lack of tags
6-
# BROKEN HASH: ENV NGX_BROTLI_COMMIT_HASH=63ca02abdcf79c9e788d2eedcc388d2335902e52
7-
ENV NGX_BROTLI_COMMIT_HASH=6e975bcb015f62e1f303054897783355e2a877dc
8-
# https://github.com/openresty/headers-more-nginx-module/tags
9-
ENV HEADERS_MORE_VERSION=v0.37
105
# releases can be signed by any key on this page https://nginx.org/en/pgp_keys.html
116
# so this might need to be updated for a new release
127
# available keys: mdounin, maxim, sb, thresh
138
# the "signing key" is used for linux packages, see https://trac.nginx.org/nginx/ticket/205
149
ENV PGP_SIGNING_KEY_OWNER=thresh
1510

1611
# install dependencies: here we use brotli-dev, newer brotli versions we can remove that and build it
17-
RUN apk add --no-cache git libc-dev pcre2-dev make gcc zlib-dev openssl-dev binutils gnupg cmake brotli-dev
12+
RUN apk add --no-cache git libc-dev pcre2-dev make gcc binutils gnupg cmake brotli-dev
1813

1914
# create a builder user and group
2015
RUN addgroup -S -g 3148 builder && adduser -D -S -G builder -u 3148 builder
@@ -23,8 +18,9 @@ WORKDIR /build
2318
USER builder
2419

2520
# clone the nginx modules
26-
RUN git clone https://github.com/google/ngx_brotli && cd ngx_brotli && git reset --hard $NGX_BROTLI_COMMIT_HASH && cd ..
27-
RUN git clone --depth 1 -b $HEADERS_MORE_VERSION https://github.com/openresty/headers-more-nginx-module
21+
RUN git clone --recurse-submodules https://github.com/google/ngx_brotli && cd ngx_brotli/deps/brotli && mkdir out && cd out \
22+
&& cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. \
23+
&& cmake --build . --config Release --target brotlienc && cd ../../../..
2824

2925
# now start the build
3026
# get nginx source
@@ -40,6 +36,8 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then gpg --verify nginx.tgz.asc; f
4036
# all good now untar and build!
4137
RUN tar xzf nginx.tgz
4238
WORKDIR /build/nginx-$NGINX_VERSION
39+
# change the hardcoded Server header value
40+
RUN sed -i 's/"Server: nginx" CRLF/"Server: d" CRLF/' src/http/ngx_http_header_filter_module.c
4341
# Compilation flags
4442
# -g0: Disable debugging symbols generation (decreases binary size)
4543
# -O3: Enable aggressive optimization level 3 (improves code execution speed)
@@ -57,29 +55,27 @@ WORKDIR /build/nginx-$NGINX_VERSION
5755
RUN ./configure \
5856
--prefix=/var/lib/nginx \
5957
--sbin-path=/usr/sbin/nginx \
60-
--with-cc-opt='-g0 -O3 -fstack-protector-strong -flto -pie --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -Wl,-z,noexecstack -fPIC'\
58+
--with-cc-opt='-g0 -O3 -fstack-protector-strong -flto -pie --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -Wl,-z,noexecstack -fPIC -static -static-libgcc' \
59+
--with-ld-opt='-static' \
6160
--modules-path=/usr/lib/nginx/modules \
6261
--conf-path=/etc/nginx/nginx.conf \
63-
--pid-path=/run/nginx.pid \
62+
--pid-path=/nginx/nginx.pid \
6463
--error-log-path=/var/log/nginx/error.log \
6564
--http-log-path=/var/log/nginx/access.log \
66-
--lock-path=/run/nginx.lock \
67-
--http-client-body-temp-path=/run/nginx-client_body \
68-
--http-fastcgi-temp-path=/run/nginx-fastcgi \
69-
--user=nginx \
70-
--group=nginx \
65+
--lock-path=/nginx/nginx.lock \
66+
--http-client-body-temp-path=/nginx/nginx-client_body \
67+
--http-fastcgi-temp-path=/nginx/nginx-fastcgi \
68+
--user=nobody \
69+
--group=nobody \
7170
--with-threads \
72-
--with-http_ssl_module \
73-
--with-http_v2_module \
7471
--with-http_realip_module \
75-
--with-http_gzip_static_module \
7672
--with-http_stub_status_module \
7773
--add-module=/build/ngx_brotli \
78-
--add-module=/build/headers-more-nginx-module \
7974
--without-http_autoindex_module \
8075
--without-http_browser_module \
8176
--without-http_empty_gif_module \
8277
--without-http_geo_module \
78+
--without-http_gzip_module \
8379
--without-http_limit_conn_module \
8480
--without-http_limit_req_module \
8581
--without-http_map_module \
@@ -97,3 +93,19 @@ RUN ./configure \
9793

9894
USER root
9995
RUN make install
96+
97+
FROM alpine:3.20
98+
COPY --from=nginx-builder /usr/sbin/nginx /usr/sbin/nginx
99+
COPY --from=nginx-builder /etc/nginx/mime.types /etc/nginx/mime.types
100+
COPY --from=nginx-builder /etc/nginx/fastcgi.conf /etc/nginx/fastcgi.conf
101+
COPY --from=nginx-builder /var/lib/nginx /var/lib/nginx
102+
# create the log folder and make the logfiles links to stdout/stderr so docker logs will catch it
103+
RUN mkdir -p /var/log/nginx \
104+
&& ln -sf /dev/stdout /var/log/nginx/access.log \
105+
&& ln -sf /dev/stderr /var/log/nginx/error.log
106+
ADD nginx.conf /etc/nginx/nginx.conf
107+
ADD common.conf /etc/nginx/common.conf
108+
RUN mkdir /etc/nginx/conf.d
109+
RUN mkdir /nginx && chown nobody:nobody /nginx
110+
USER nobody
111+
ENTRYPOINT ["nginx"]

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,51 @@
22

33
This Docker image builds a custom nginx, stripped of many features.
44

5+
Its purpose is to be a barebone HTTP server, no HTTPS, no HTTP/2, perfect for serving static files behind a reverse proxy.
6+
7+
It runs as the `nobody` user.
8+
59
## Usage
610

11+
Use it as a base for a website
12+
13+
~~~bash
14+
FROM deltablot/custom-http-nginx
15+
COPY site/ /app
16+
COPY site.conf /etc/nginx/conf.d
17+
~~~
18+
19+
Example site.conf
20+
21+
~~~conf
22+
server {
23+
server_name your-domain.tld;
24+
25+
listen 8080;
26+
root /app;
27+
index index.html;
28+
29+
# restrict allowed methods
30+
if ($request_method !~ ^(GET|HEAD)$) {
31+
return 405;
32+
}
33+
34+
error_page 404 /404.html;
35+
36+
add_header X-Frame-Options DENY;
37+
add_header X-XSS-Protection "1; mode=block";
38+
add_header X-Content-Type-Options nosniff;
39+
add_header Content-Security-Policy "default-src 'self'; style-src 'unsafe-inline'; object-src 'none';";
40+
add_header Strict-Transport-Security "max-age=31536100; includeSubDomains; preload";
41+
42+
# redirect server error pages to the static page /50x.html
43+
error_page 500 502 503 504 /50x.html;
44+
location = /50x.html {
45+
root /usr/share/nginx/html;
46+
}
747
48+
location / {
49+
try_files $uri $uri/ =404;
50+
}
51+
include common.conf;
52+
}

common.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# this file can be included in a server block with:
2+
# include common.conf;
3+
4+
# add a healthcheck endpoint
5+
# 204 is OK No Content
6+
location /healthcheck {
7+
access_log off;
8+
return 204;
9+
}
10+
# set cache for assets
11+
location ~* .(jpg|jpeg|png|gif|ico|css|js|ttf|webm|woff2)$ {
12+
expires 1M;
13+
}
14+
# deny access to hidden files/folders
15+
location ~ /\. { access_log off; log_not_found off; deny all; }
16+
17+
# disable access log for assets
18+
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
19+
access_log off;
20+
log_not_found off;
21+
}

nginx.conf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
daemon off;
2+
worker_processes auto;
3+
worker_rlimit_nofile 1024;
4+
5+
events {
6+
worker_connections 1024;
7+
}
8+
9+
http {
10+
include mime.types;
11+
server_tokens off;
12+
default_type application/octet-stream;
13+
sendfile on;
14+
# timeouts
15+
# see CIS benchmark nginx 2.4.4
16+
client_body_timeout 10s;
17+
client_header_timeout 10s;
18+
send_timeout 10s;
19+
keepalive_timeout 10s;
20+
client_max_body_size 1;
21+
client_body_buffer_size 1;
22+
include conf.d/*.conf;
23+
}

0 commit comments

Comments
 (0)