├── .dockerignore ├── LICENSE ├── conf ├── fastcgi_params ├── fastcgi.conf ├── nginx.conf └── mime.types ├── .github └── workflows │ └── release.yml ├── SSL.md ├── docker-bake.hcl ├── README.md └── Dockerfile /.dockerignore: -------------------------------------------------------------------------------- 1 | # Don't send build scripts, docs, or unnecessary files to the build context 2 | 3 | # Ignore Git and VCS files 4 | .git 5 | .gitignore 6 | *.swp 7 | *.swo 8 | 9 | # Ignore local OS metadata 10 | .DS_Store 11 | Thumbs.db 12 | 13 | # Ignore binaries, build outputs, and cache 14 | bin/ 15 | *.pyc 16 | *.o 17 | *.a 18 | *.so 19 | *.exe 20 | *.out 21 | 22 | # Ignore CI/CD artifacts 23 | *.log 24 | *.tmp 25 | *.bak 26 | 27 | # Ignore everything except what's needed 28 | README.md 29 | docker-bake.hcl 30 | Dockerfile 31 | 32 | # Don't ignore conf/ or your Dockerfile! 33 | # The minimal build needs Dockerfile and conf/ 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2025 James Dornan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /conf/fastcgi_params: -------------------------------------------------------------------------------- 1 | 2 | fastcgi_param QUERY_STRING $query_string; 3 | fastcgi_param REQUEST_METHOD $request_method; 4 | fastcgi_param CONTENT_TYPE $content_type; 5 | fastcgi_param CONTENT_LENGTH $content_length; 6 | 7 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 8 | fastcgi_param REQUEST_URI $request_uri; 9 | fastcgi_param DOCUMENT_URI $document_uri; 10 | fastcgi_param DOCUMENT_ROOT $document_root; 11 | fastcgi_param SERVER_PROTOCOL $server_protocol; 12 | fastcgi_param REQUEST_SCHEME $scheme; 13 | fastcgi_param HTTPS $https if_not_empty; 14 | 15 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 16 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 17 | 18 | fastcgi_param REMOTE_ADDR $remote_addr; 19 | fastcgi_param REMOTE_PORT $remote_port; 20 | fastcgi_param SERVER_ADDR $server_addr; 21 | fastcgi_param SERVER_PORT $server_port; 22 | fastcgi_param SERVER_NAME $server_name; 23 | 24 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 25 | fastcgi_param REDIRECT_STATUS 200; 26 | -------------------------------------------------------------------------------- /conf/fastcgi.conf: -------------------------------------------------------------------------------- 1 | 2 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 3 | fastcgi_param QUERY_STRING $query_string; 4 | fastcgi_param REQUEST_METHOD $request_method; 5 | fastcgi_param CONTENT_TYPE $content_type; 6 | fastcgi_param CONTENT_LENGTH $content_length; 7 | 8 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 9 | fastcgi_param REQUEST_URI $request_uri; 10 | fastcgi_param DOCUMENT_URI $document_uri; 11 | fastcgi_param DOCUMENT_ROOT $document_root; 12 | fastcgi_param SERVER_PROTOCOL $server_protocol; 13 | fastcgi_param REQUEST_SCHEME $scheme; 14 | fastcgi_param HTTPS $https if_not_empty; 15 | 16 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 17 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 18 | 19 | fastcgi_param REMOTE_ADDR $remote_addr; 20 | fastcgi_param REMOTE_PORT $remote_port; 21 | fastcgi_param SERVER_ADDR $server_addr; 22 | fastcgi_param SERVER_PORT $server_port; 23 | fastcgi_param SERVER_NAME $server_name; 24 | 25 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 26 | fastcgi_param REDIRECT_STATUS 200; 27 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes 1; 4 | 5 | error_log /dev/stdout; 6 | pid /nginx.pid; 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | http { 13 | include mime.types; 14 | default_type application/octet-stream; 15 | 16 | log_format standard '$remote_addr - $remote_user [$time_local] "$request" ' 17 | '$status $body_bytes_sent "$http_referer" ' 18 | '"$http_user_agent" "$http_x_forwarded_for"'; 19 | 20 | access_log /dev/stdout standard; 21 | 22 | sendfile on; 23 | keepalive_timeout 65; 24 | 25 | server { 26 | listen 80 default_server; 27 | server_name _; 28 | 29 | root /www; 30 | index index.html index.php; 31 | 32 | #charset koi8-r; 33 | 34 | location / { 35 | try_files $uri $uri/ =404; 36 | } 37 | 38 | #error_page 404 /404.html; 39 | 40 | # redirect server error pages to the static page /50x.html 41 | # 42 | #error_page 500 502 503 504 /50x.html; 43 | #location = /50x.html { 44 | # root html; 45 | #} 46 | 47 | # For PHP-FPM (if enabled/linked 48 | location ~ \.php$ { 49 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 50 | fastcgi_param HTTP_PROXY ""; 51 | fastcgi_pass php-fpm:9000; 52 | fastcgi_index index.php; 53 | include fastcgi_params; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release (build & push on tag) 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*.*.*" # Only runs on version tags like v1.29.0 7 | 8 | permissions: 9 | contents: read 10 | packages: write 11 | 12 | jobs: 13 | bake-push: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - uses: docker/setup-buildx-action@v3 19 | 20 | - name: Log in to Docker Hub 21 | uses: docker/login-action@v3 22 | with: 23 | username: ${{ secrets.DOCKERHUB_USERNAME }} 24 | password: ${{ secrets.DOCKERHUB_TOKEN }} 25 | 26 | - name: Log in to GHCR 27 | uses: docker/login-action@v3 28 | with: 29 | registry: ghcr.io 30 | username: ${{ github.actor }} 31 | password: ${{ secrets.GITHUB_TOKEN }} 32 | 33 | - name: Extract version/tag 34 | id: version 35 | run: | 36 | TAG=${GITHUB_REF##*/} 37 | echo "TAG=${TAG#v}" >> $GITHUB_OUTPUT 38 | 39 | - name: Bake and push all images 40 | uses: docker/bake-action@v5 41 | with: 42 | targets: default 43 | files: docker-bake.hcl 44 | push: true 45 | set: | 46 | nginx-micro.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 47 | nginx-micro-upx.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 48 | nginx-gzip.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 49 | nginx-gzip-upx.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 50 | nginx-ssl.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 51 | nginx-ssl-upx.args.NGINX_VERSION=${{ steps.version.outputs.TAG }} 52 | -------------------------------------------------------------------------------- /SSL.md: -------------------------------------------------------------------------------- 1 | # 🚀 Quick SSL/TLS Testing with nginx-micro 2 | 3 | **Test HTTPS with your ultra-minimal nginx-micro image on any platform in seconds. 4 | No need for shell access in the container—everything is mounted at runtime.** 5 | 6 | --- 7 | 8 | ## 1. Generate a Self-Signed SSL Certificate 9 | 10 | Run **on your host** (Linux/Mac/WSL/PowerShell), not inside the container: 11 | 12 | ```sh 13 | openssl req -x509 -newkey rsa:2048 -days 365 -nodes \ 14 | -keyout nginx.key -out nginx.crt \ 15 | -subj "/CN=localhost" 16 | ``` 17 | 18 | This creates two files: 19 | 20 | * `nginx.key` (private key) 21 | * `nginx.crt` (certificate) 22 | 23 | --- 24 | 25 | ## 2. Minimal SSL nginx.conf Example 26 | 27 | Create a file named `nginx.conf` with: 28 | 29 | ```nginx 30 | worker_processes 1; 31 | error_log /dev/stdout; 32 | pid /tmp/nginx.pid; 33 | 34 | events { worker_connections 1024; } 35 | 36 | http { 37 | access_log /dev/stdout; 38 | 39 | server { 40 | listen 443 ssl; 41 | server_name _; 42 | 43 | ssl_certificate /conf/nginx.crt; 44 | ssl_certificate_key /conf/nginx.key; 45 | 46 | root /www; 47 | index index.html; 48 | 49 | location / { 50 | try_files $uri $uri/ =404; 51 | } 52 | } 53 | } 54 | ``` 55 | 56 | --- 57 | 58 | ## 3. Run nginx-micro with SSL 59 | 60 | Make sure you have at least one file in your `./www` directory (e.g., `index.html`). 61 | 62 | ```sh 63 | docker run --rm -p 8443:443 \ 64 | -v $(pwd)/nginx.conf:/conf/nginx.conf:ro \ 65 | -v $(pwd)/nginx.crt:/conf/nginx.crt:ro \ 66 | -v $(pwd)/nginx.key:/conf/nginx.key:ro \ 67 | -v $(pwd)/www:/www:ro \ 68 | tigersmile/nginx-micro:1.29.4-ssl-upx 69 | ``` 70 | 71 | * The container listens on port 443 (exposed as 8443 on your host) 72 | * All configs and certs are mounted read-only 73 | 74 | --- 75 | 76 | ## 4. Test the HTTPS Endpoint 77 | 78 | ### In your browser: 79 | 80 | * Go to: [https://localhost:8443](https://localhost:8443) 81 | * You’ll see a certificate warning (expected for self-signed). Accept/ignore to proceed. 82 | 83 | ### With `curl`: 84 | 85 | ```sh 86 | curl -k https://localhost:8443 87 | ``` 88 | 89 | > `-k` skips certificate validation (perfect for dev/test use). 90 | 91 | --- 92 | 93 | ## 5. Troubleshooting 94 | 95 | * **Error about missing `/tmp/nginx.pid` or `/tmp/client_body_temp`?** 96 | Your build should have `--pid-path=/tmp/nginx.pid` and `--prefix=/tmp` in `./configure`. 97 | See [nginx-micro README](./README.md) for details. 98 | 99 | * **"user" directive warning?** 100 | Ignore unless you’re running as root. 101 | If running as a non-root user, the directive is ignored. 102 | 103 | --- 104 | 105 | ## 6. Notes 106 | 107 | * **Never use self-signed certs in production!** 108 | For real deployments, use certificates from a trusted CA (Let’s Encrypt, etc). 109 | 110 | * **For HTTP/2/3:** 111 | See [nginx.org docs](https://nginx.org/en/docs/http/ngx_http_v2_module.html) and [QUIC/HTTP3](https://quic.nginx.org/readme.html). 112 | 113 | --- 114 | 115 | ## 7. Example: FastCGI (PHP-FPM) behind SSL 116 | 117 | Add this to your `nginx.conf` inside the `server { ... }` block: 118 | 119 | ```nginx 120 | location ~ \.php$ { 121 | fastcgi_pass php-fpm:9000; 122 | fastcgi_index index.php; 123 | include fastcgi_params; 124 | } 125 | ``` 126 | 127 | Run a `php-fpm` container in the same Docker network, and mount your site to `/www`. 128 | 129 | --- 130 | 131 | **Ultra-minimal, blazing-fast SSL with nginx-micro—everywhere.** 132 | 133 | --- 134 | 135 | If you hit any issues, open a GitHub issue with your error and config. 136 | Happy hacking! 137 | -------------------------------------------------------------------------------- /docker-bake.hcl: -------------------------------------------------------------------------------- 1 | variable "NGINX_VERSION" { 2 | default = "1.29.4" 3 | } 4 | 5 | # UPX-supported platforms (based on Alpine's package availability) 6 | variable "UPX_PLATFORMS" { 7 | default = [ 8 | "linux/386", 9 | "linux/amd64", 10 | "linux/arm/v6", 11 | "linux/arm/v7", 12 | "linux/arm64", 13 | "linux/ppc64le" 14 | ] 15 | } 16 | 17 | # All platforms you want to build for 18 | variable "ALL_PLATFORMS" { 19 | default = [ 20 | "linux/386", 21 | "linux/amd64", 22 | "linux/arm/v6", 23 | "linux/arm/v7", 24 | "linux/arm64", 25 | "linux/ppc64le", 26 | "linux/s390x", 27 | "linux/riscv64" 28 | ] 29 | } 30 | 31 | group "default" { 32 | targets = [ 33 | "nginx-micro", 34 | "nginx-micro-upx", 35 | "nginx-gzip", 36 | "nginx-gzip-upx", 37 | "nginx-ssl", 38 | "nginx-ssl-upx" 39 | ] 40 | } 41 | 42 | target "nginx-micro" { 43 | context = "." 44 | dockerfile = "Dockerfile" 45 | target = "micro" 46 | tags = [ 47 | "tigersmile/nginx-micro:${NGINX_VERSION}", 48 | "tigersmile/nginx-micro:latest", 49 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}", 50 | "ghcr.io/johnnyjoy/nginx-micro:latest" 51 | ] 52 | cache-from = [ 53 | { 54 | type = "registry", 55 | ref = "tigersmile/nginx-micro-cache" 56 | } 57 | ] 58 | cache-to = [ 59 | { 60 | type = "registry", 61 | ref = "tigersmile/nginx-micro-cache" 62 | } 63 | ] 64 | args = { 65 | "NGINX_VERSION" = "${NGINX_VERSION}" 66 | } 67 | platforms = "${ALL_PLATFORMS}" 68 | } 69 | 70 | target "nginx-micro-upx" { 71 | context = "." 72 | dockerfile = "Dockerfile" 73 | target = "micro-upx" 74 | tags = [ 75 | "tigersmile/nginx-micro:${NGINX_VERSION}-upx", 76 | "tigersmile/nginx-micro:upx", 77 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}-upx", 78 | "ghcr.io/johnnyjoy/nginx-micro:upx" 79 | ] 80 | cache-from = [ 81 | { 82 | type = "registry", 83 | ref = "tigersmile/nginx-micro-cache" 84 | } 85 | ] 86 | cache-to = [ 87 | { 88 | type = "registry", 89 | ref = "tigersmile/nginx-micro-cache" 90 | } 91 | ] 92 | args = { 93 | "NGINX_VERSION" = "${NGINX_VERSION}" 94 | } 95 | platforms = "${UPX_PLATFORMS}" 96 | } 97 | 98 | target "nginx-gzip" { 99 | context = "." 100 | dockerfile = "Dockerfile" 101 | target = "gzip" 102 | tags = [ 103 | "tigersmile/nginx-micro:${NGINX_VERSION}-gzip", 104 | "tigersmile/nginx-micro:gzip", 105 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}-gzip", 106 | "ghcr.io/johnnyjoy/nginx-micro:gzip" 107 | ] 108 | cache-from = [ 109 | { 110 | type = "registry", 111 | ref = "tigersmile/nginx-micro-cache" 112 | } 113 | ] 114 | cache-to = [ 115 | { 116 | type = "registry", 117 | ref = "tigersmile/nginx-micro-cache" 118 | } 119 | ] 120 | args = { 121 | "NGINX_VERSION" = "${NGINX_VERSION}" 122 | } 123 | platforms = "${ALL_PLATFORMS}" 124 | } 125 | 126 | target "nginx-gzip-upx" { 127 | context = "." 128 | dockerfile = "Dockerfile" 129 | target = "gzip-upx" 130 | tags = [ 131 | "tigersmile/nginx-micro:${NGINX_VERSION}-gzip-upx", 132 | "tigersmile/nginx-micro:gzip-upx", 133 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}-gzip-upx", 134 | "ghcr.io/johnnyjoy/nginx-micro:gzip-upx" 135 | ] 136 | cache-from = [ 137 | { 138 | type = "registry", 139 | ref = "tigersmile/nginx-micro-cache" 140 | } 141 | ] 142 | cache-to = [ 143 | { 144 | type = "registry", 145 | ref = "tigersmile/nginx-micro-cache" 146 | } 147 | ] 148 | args = { 149 | "NGINX_VERSION" = "${NGINX_VERSION}" 150 | } 151 | platforms = "${UPX_PLATFORMS}" 152 | } 153 | 154 | target "nginx-ssl" { 155 | context = "." 156 | dockerfile = "Dockerfile" 157 | target = "ssl" 158 | tags = [ 159 | "tigersmile/nginx-micro:${NGINX_VERSION}-ssl", 160 | "tigersmile/nginx-micro:ssl", 161 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}-ssl", 162 | "ghcr.io/johnnyjoy/nginx-micro:ssl" 163 | ] 164 | cache-from = [ 165 | { 166 | type = "registry", 167 | ref = "tigersmile/nginx-micro-cache" 168 | } 169 | ] 170 | cache-to = [ 171 | { 172 | type = "registry", 173 | ref = "tigersmile/nginx-micro-cache" 174 | } 175 | ] 176 | args = { 177 | "NGINX_VERSION" = "${NGINX_VERSION}" 178 | } 179 | platforms = "${ALL_PLATFORMS}" 180 | } 181 | 182 | target "nginx-ssl-upx" { 183 | context = "." 184 | dockerfile = "Dockerfile" 185 | target = "ssl-upx" 186 | tags = [ 187 | "tigersmile/nginx-micro:${NGINX_VERSION}-ssl-upx", 188 | "tigersmile/nginx-micro:ssl-upx", 189 | "ghcr.io/johnnyjoy/nginx-micro:${NGINX_VERSION}-ssl-upx", 190 | "ghcr.io/johnnyjoy/nginx-micro:ssl-upx" 191 | ] 192 | cache-from = [ 193 | { 194 | type = "registry", 195 | ref = "tigersmile/nginx-micro-cache" 196 | } 197 | ] 198 | cache-to = [ 199 | { 200 | type = "registry", 201 | ref = "tigersmile/nginx-micro-cache" 202 | } 203 | ] 204 | args = { 205 | "NGINX_VERSION" = "${NGINX_VERSION}" 206 | } 207 | platforms = "${UPX_PLATFORMS}" 208 | } 209 | -------------------------------------------------------------------------------- /conf/mime.types: -------------------------------------------------------------------------------- 1 | 2 | types { 3 | text/html html htm shtml; 4 | text/css css; 5 | text/xml xml; 6 | image/gif gif; 7 | image/jpeg jpeg jpg; 8 | application/javascript js; 9 | application/atom+xml atom; 10 | application/rss+xml rss; 11 | 12 | text/mathml mml; 13 | text/plain txt; 14 | text/vnd.sun.j2me.app-descriptor jad; 15 | text/vnd.wap.wml wml; 16 | text/x-component htc; 17 | 18 | image/avif avif; 19 | image/png png; 20 | image/svg+xml svg svgz; 21 | image/tiff tif tiff; 22 | image/vnd.wap.wbmp wbmp; 23 | image/webp webp; 24 | image/x-icon ico; 25 | image/x-jng jng; 26 | image/x-ms-bmp bmp; 27 | 28 | font/woff woff; 29 | font/woff2 woff2; 30 | 31 | application/java-archive jar war ear; 32 | application/json json; 33 | application/mac-binhex40 hqx; 34 | application/msword doc; 35 | application/pdf pdf; 36 | application/postscript ps eps ai; 37 | application/rtf rtf; 38 | application/vnd.apple.mpegurl m3u8; 39 | application/vnd.google-earth.kml+xml kml; 40 | application/vnd.google-earth.kmz kmz; 41 | application/vnd.ms-excel xls; 42 | application/vnd.ms-fontobject eot; 43 | application/vnd.ms-powerpoint ppt; 44 | application/vnd.oasis.opendocument.graphics odg; 45 | application/vnd.oasis.opendocument.presentation odp; 46 | application/vnd.oasis.opendocument.spreadsheet ods; 47 | application/vnd.oasis.opendocument.text odt; 48 | application/vnd.openxmlformats-officedocument.presentationml.presentation 49 | pptx; 50 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 51 | xlsx; 52 | application/vnd.openxmlformats-officedocument.wordprocessingml.document 53 | docx; 54 | application/vnd.wap.wmlc wmlc; 55 | application/wasm wasm; 56 | application/x-7z-compressed 7z; 57 | application/x-cocoa cco; 58 | application/x-java-archive-diff jardiff; 59 | application/x-java-jnlp-file jnlp; 60 | application/x-makeself run; 61 | application/x-perl pl pm; 62 | application/x-pilot prc pdb; 63 | application/x-rar-compressed rar; 64 | application/x-redhat-package-manager rpm; 65 | application/x-sea sea; 66 | application/x-shockwave-flash swf; 67 | application/x-stuffit sit; 68 | application/x-tcl tcl tk; 69 | application/x-x509-ca-cert der pem crt; 70 | application/x-xpinstall xpi; 71 | application/xhtml+xml xhtml; 72 | application/xspf+xml xspf; 73 | application/zip zip; 74 | 75 | application/octet-stream bin exe dll; 76 | application/octet-stream deb; 77 | application/octet-stream dmg; 78 | application/octet-stream iso img; 79 | application/octet-stream msi msp msm; 80 | 81 | audio/midi mid midi kar; 82 | audio/mpeg mp3; 83 | audio/ogg ogg; 84 | audio/x-m4a m4a; 85 | audio/x-realaudio ra; 86 | 87 | video/3gpp 3gpp 3gp; 88 | video/mp2t ts; 89 | video/mp4 mp4; 90 | video/mpeg mpeg mpg; 91 | video/quicktime mov; 92 | video/webm webm; 93 | video/x-flv flv; 94 | video/x-m4v m4v; 95 | video/x-mng mng; 96 | video/x-ms-asf asx asf; 97 | video/x-ms-wmv wmv; 98 | video/x-msvideo avi; 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx-micro 2 | 3 | > **Ultra-minimal, statically-linked, multi-architecture NGINX Docker images.** 4 | 5 | A blazing-fast, container-native NGINX image—just **hundreds of kilobytes**—with no shell, no package manager, and no attack surface beyond static serving and FastCGI. 6 | **Purpose-built** for modern container stacks, edge deployments, and anyone who wants a rock-solid, tiny HTTP server. 7 | 8 | --- 9 | 10 | ## 🚀 Supported Platforms 11 | 12 | | Platform | Supported? | UPX-compressed Variant? | Typical Use Case | 13 | | -------- | :--------: | :---------------------: | -------------------------------- | 14 | | amd64 | ✅ | ✅ | Standard servers, laptops, cloud | 15 | | arm64 | ✅ | ✅ | Raspberry Pi 4/5, Apple Silicon | 16 | | arm/v7 | ✅ | ✅ | Older ARM SBCs, IoT devices | 17 | | 386 | ✅ | ✅ | Legacy x86 | 18 | | ppc64le | ✅ | ✅ | IBM Power, OpenPower | 19 | | s390x | ✅ | ❌ | IBM Mainframe | 20 | | riscv64 | ✅ | ❌ | Next-gen embedded/server | 21 | 22 | > **Note:** UPX-compressed images (`-upx` tags) are only published for platforms supported by UPX on Alpine Linux. 23 | 24 | --- 25 | 26 | ## 🏷️ Image Tags & Feature Matrix 27 | 28 | Multiple image variants are published for different use cases. 29 | **Choose the tag that matches your needs:** 30 | 31 | | Tag | Features | SSL/TLS | gzip | UPX-compressed | Platforms | Typical Use | 32 | | ------------------ | ------------------------------ | :-----: | :--: | :------------: | :------------------------------------------- | ------------------------ | 33 | | `:1.29.4` | Minimal HTTP, FastCGI | ❌ | ❌ | ❌ | All supported | Most minimal HTTP only | 34 | | `:1.29.4-upx` | Same as above (smaller binary) | ❌ | ❌ | ✅ | `amd64`, `arm64`, `arm/v7`, `386`, `ppc64le` | Smallest HTTP only | 35 | | `:1.29.4-gzip` | HTTP, FastCGI, gzip (encoding) | ❌ | ✅ | ❌ | All supported | gzip-compress HTTP | 36 | | `:1.29.4-gzip-upx` | gzip, UPX-compressed | ❌ | ✅ | ✅ | UPX platforms (see above) | Smallest with gzip | 37 | | `:1.29.4-ssl` | HTTP, FastCGI, SSL/TLS, gzip | ✅ | ✅ | ❌ | All supported | HTTPS support | 38 | | `:1.29.4-ssl-upx` | SSL/TLS, gzip, UPX-compressed | ✅ | ✅ | ✅ | UPX platforms (see above) | HTTPS, smallest with SSL | 39 | 40 | UPX-compressed images (`-upx` tags) are **not** built for `s390x` or `riscv64`, since UPX does not support them on Alpine. 41 | 42 | --- 43 | 44 | ## 📦 How Does the Size Compare? 45 | 46 | | Platform | Official nginx:1.29 | nginx-micro:1.29.4-upx | nginx-micro:1.29.4 | 47 | | -------- | :-----------------: | :--------------------: | :----------------: | 48 | | amd64 | 68.86 MB | **432 KB** | 1.19 MB | 49 | | arm64 | 65.54 MB | **423 KB** | 1.17 MB | 50 | | arm/v7 | 57.91 MB | **422 KB** | 1.16 MB | 51 | | 386 | 67.31 MB | **448 KB** | 1.22 MB | 52 | | ppc64le | 73.34 MB | **457 KB** | 1.26 MB | 53 | | s390x | 63.82 MB | *N/A* | 1.36 MB | 54 | | riscv64 | N/A | *N/A* | 1.30 MB | 55 | 56 | > That’s up to **160× smaller** than the official nginx images! 57 | 58 | --- 59 | 60 | ## ⚡️ Why nginx-micro? 61 | 62 | * **FROM scratch**: No shell, no package manager, no interpreter. Zero bloat. 63 | * **Attack surface**: *Minimized.* Only HTTP and FastCGI (for PHP) are supported by default. 64 | * **Security**: GPG-verified source, statically linked, no extraneous libraries. 65 | * **Multi-arch**: Works on virtually any Linux system—cloud, Pi, mainframe, or edge. 66 | * **Logs to stdout/stderr**: Perfect for Docker/Kubernetes observability. 67 | * **Plug-and-play config**: Use the included config, or mount your own. 68 | * **Built for insecure HTTP**: Use behind any SSL-terminating reverse proxy (Caddy, Traefik, HAProxy, nginx, Cloudflare, etc.). 69 | * **SSL/TLS and gzip**: Optional tags (`-ssl`, `-gzip`, and `-upx` variants) for more features. 70 | 71 | --- 72 | 73 | ## 🛡️ Intended Use 74 | 75 | * **NOT for direct SSL/public internet use by default!** 76 | 77 | * The `-ssl` tags add built-in HTTPS, but it’s still recommended to use a reverse proxy for cert management. 78 | * *Ideal for:* 79 | 80 | * Static sites and health checks 81 | * PHP apps via FastCGI (`php-fpm`) 82 | * Serving assets in microservices 83 | * Demo, staging, CI pipelines 84 | * Ultra-lightweight edge deployments 85 | 86 | --- 87 | 88 | ## 🏁 Quick Start 89 | 90 | ### **Serve static files from your current directory:** 91 | 92 | ```sh 93 | docker run --rm -p 8080:80 \ 94 | -v $(pwd):/www \ 95 | tigersmile/nginx-micro 96 | ``` 97 | 98 | Open [http://localhost:8080](http://localhost:8080) in your browser. 99 | 100 | --- 101 | 102 | ### **Mount your own `nginx.conf` for full control:** 103 | 104 | ```sh 105 | docker run --rm -p 8080:80 \ 106 | -v $(pwd)/nginx.conf:/conf/nginx.conf:ro \ 107 | -v $(pwd)/site:/www \ 108 | tigersmile/nginx-micro 109 | ``` 110 | 111 | --- 112 | 113 | ### **Use with PHP-FPM (e.g., WordPress/Drupal):** 114 | 115 | ```yaml 116 | # docker-compose.yml 117 | version: "3" 118 | services: 119 | nginx: 120 | image: tigersmile/nginx-micro 121 | ports: 122 | - "8080:80" 123 | volumes: 124 | - ./conf:/conf 125 | - ./www:/www 126 | depends_on: 127 | - php-fpm 128 | networks: [ web ] 129 | php-fpm: 130 | image: php:fpm 131 | volumes: 132 | - ./www:/www 133 | networks: [ web ] 134 | networks: 135 | web: 136 | ``` 137 | 138 | --- 139 | 140 | ## 📝 Default nginx.conf 141 | 142 | ```nginx 143 | user nginx; 144 | worker_processes 1; 145 | error_log /dev/stdout warn; 146 | pid /nginx.pid; 147 | 148 | events { worker_connections 1024; } 149 | 150 | http { 151 | include mime.types; 152 | default_type application/octet-stream; 153 | access_log /dev/stdout; 154 | 155 | sendfile on; 156 | keepalive_timeout 65; 157 | 158 | server { 159 | listen 80 default_server; 160 | server_name _; 161 | 162 | root /www; 163 | index index.html index.php; 164 | 165 | location / { 166 | try_files $uri $uri/ =404; 167 | } 168 | 169 | # For PHP-FPM 170 | location ~ \.php$ { 171 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 172 | fastcgi_param HTTP_PROXY ""; 173 | fastcgi_pass php-fpm:9000; 174 | fastcgi_index index.php; 175 | include fastcgi_params; 176 | } 177 | } 178 | } 179 | ``` 180 | 181 | --- 182 | 183 | ## 🏷️ Tag and Feature Reference 184 | 185 | | Tag | gzip | SSL/TLS | UPX | Description | Platforms | 186 | | ------------------ | :--: | :-----: | :-: | ---------------------------- | ------------- | 187 | | `:1.29.4` | ❌ | ❌ | ❌ | Minimal HTTP only | all | 188 | | `:1.29.4-upx` | ❌ | ❌ | ✅ | Minimal HTTP, smallest size | upx platforms | 189 | | `:1.29.4-gzip` | ✅ | ❌ | ❌ | gzip content-encoding | all | 190 | | `:1.29.4-gzip-upx` | ✅ | ❌ | ✅ | gzip, smallest size | upx platforms | 191 | | `:1.29.4-ssl` | ✅ | ✅ | ❌ | SSL/TLS, gzip | all | 192 | | `:1.29.4-ssl-upx` | ✅ | ✅ | ✅ | SSL/TLS, gzip, smallest size | upx platforms | 193 | 194 | **What’s a “UPX platform”?** 195 | Currently: `amd64`, `arm64`, `arm/v7`, `386`, `ppc64le` (but not `s390x` or `riscv64`). 196 | 197 | --- 198 | 199 | ## ⚙️ What’s Included / Not Included 200 | 201 | | Feature | Included? | Notes | 202 | | ------------------- | :-------: | ----------------------------------- | 203 | | Static file serving | ✅ | `/www` is default root | 204 | | FastCGI/PHP-FPM | ✅ | Use with `php-fpm` container | 205 | | gzip | *varies* | Use a `-gzip` or `-ssl` tag | 206 | | SSL/TLS | *varies* | Use a `-ssl` tag | 207 | | Proxy/Upstream | ❌ | Not included (smaller, more secure) | 208 | | SSI, autoindex | ❌ | Not included | 209 | | Custom config | ✅ | Mount `/conf/nginx.conf` | 210 | | Logs to stdout | ✅ | Container-native | 211 | | GPG-verified build | ✅ | Verified source integrity | 212 | 213 | --- 214 | 215 | ## 🔒 Security Notes 216 | 217 | * **Runs as non-root (`nginx`, uid 101) by default.** 218 | 219 | * Enforced by `USER 101:101` in the Dockerfile and `/etc/passwd`. 220 | * No privileged capabilities. 221 | * Cannot bind to ports below 1024 unless run as root. 222 | * No shell or package manager—cannot be “container escaped” by shell exploits. 223 | * No writable filesystem, no interpreters. 224 | 225 | > **Note:** 226 | > If you need to bind to privileged ports (like 80/443) on a host, you may override the user with `--user root` or by building your own image, but this is not recommended for security reasons. 227 | 228 | --- 229 | 230 | ## 🏗️ Building Yourself 231 | 232 | Requires Docker with Buildx and QEMU (for multi-arch): 233 | 234 | ```sh 235 | docker buildx bake 236 | ``` 237 | 238 | *(Uses included `docker-bake.hcl` for all architectures and tags.)* 239 | 240 | --- 241 | 242 | ## 🤝 Contribute & Contact 243 | 244 | * Issues and PRs welcome! [GitHub repo](https://github.com/tigersmile/nginx-micro) 245 | * Suggestions for features or new use-cases? Open an issue! 246 | * Show off your usage or share feedback—we want to hear from you! 247 | 248 | --- 249 | 250 | ## 📣 Why not just use the official nginx image? 251 | 252 | * **Ours is up to 160× smaller.** 253 | * **No shell, no bloat, no hidden dependencies.** 254 | * **Perfect for CI, health checks, microservices, edge, and cloud.** 255 | 256 | --- 257 | 258 | **Ultra-minimal nginx—secure, fast, tiny, everywhere.** 259 | 260 | --- 261 | 262 | *If you find this useful, star the repo, tell a friend, and help spread the word!* 263 | *(Project by [johnnyjoy](https://github.com/johnnyjoy).)* 264 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | ################################################################################ 4 | # GLOBAL BUILD ARGS 5 | ################################################################################ 6 | 7 | ARG NGINX_VERSION=1.29.4 8 | ARG OPENSSL_VERSION=3.6.0 9 | 10 | ARG CFLAGS="-flto -fmerge-all-constants -fno-unwind-tables -fvisibility=hidden -fuse-linker-plugin -Wimplicit -Os -s -ffunction-sections -fdata-sections -fno-ident -fno-asynchronous-unwind-tables -static -Wno-cast-function-type -Wno-implicit-function-declaration" 11 | ARG LDFLAGS="-flto -fuse-linker-plugin -static -s -Wl,--gc-sections" 12 | 13 | ################################################################################ 14 | # FETCH: download/verify nginx and openssl 15 | ################################################################################ 16 | FROM alpine:edge AS fetch 17 | 18 | ARG NGINX_VERSION 19 | ARG OPENSSL_VERSION 20 | 21 | RUN apk add --no-cache wget tar gnupg 22 | 23 | WORKDIR /build 24 | 25 | # OpenSSL 26 | ARG OPENSSL_CHECKSUM="b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9" 27 | RUN wget -O openssl.tar.gz "https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}.tar.gz" && \ 28 | echo "${OPENSSL_CHECKSUM} openssl.tar.gz" | sha256sum -c - && \ 29 | mkdir openssl && \ 30 | tar xzf openssl.tar.gz -C openssl --strip-components=1 31 | 32 | WORKDIR /build 33 | 34 | # nginx 35 | RUN set -eux; \ 36 | wget -O nginx.tar.gz "https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" && \ 37 | wget -O nginx.tar.gz.asc "https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz.asc" && \ 38 | export GNUPGHOME="$(mktemp -d)"; \ 39 | # Fetch the official PGP-keys page and import *all* .key files it references 40 | wget -qO- https://nginx.org/en/pgp_keys.html \ 41 | | grep -Eo 'href="(/keys/[A-Za-z0-9._-]+\.key)"' \ 42 | | sed -E 's/^href="(.*)"/\1/' \ 43 | | sort -u \ 44 | | while read -r path; do \ 45 | wget -qO- "https://nginx.org${path}" | gpg --import; \ 46 | done; \ 47 | # Verify signature (fails the build if invalid/unknown) 48 | gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz; \ 49 | # Unpack 50 | mkdir nginx && \ 51 | tar tvfz nginx.tar.gz && \ 52 | tar xvzf nginx.tar.gz -C nginx --strip-components=1 53 | 54 | ################################################################################ 55 | # BUILD DEPS: all static, pcre2, zlib, upx (for optional) 56 | ################################################################################ 57 | FROM alpine:edge AS build-deps 58 | 59 | ARG NGINX_VERSION 60 | ARG OPENSSL_VERSION 61 | ARG CFLAGS 62 | ARG LDFLAGS 63 | 64 | RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ 65 | apk add --no-cache gcc musl-dev linux-headers make binutils wget gnupg \ 66 | pcre2-dev pcre2-static zlib-dev zlib-static build-base perl 67 | 68 | RUN apk add upx || true 69 | 70 | COPY --from=fetch /build /build 71 | 72 | # Build minimal passwd and group to support user nginx (optional, but recommended) 73 | RUN echo 'nginx:x:101:101:nginx:/nonexistent:/sbin/nologin' > /nginx.passwd && \ 74 | echo 'nginx:x:101:' > /nginx.group 75 | 76 | ################################################################################ 77 | # BUILD OPENSSL (exact, robust, static, per-platform) 78 | ################################################################################ 79 | FROM build-deps AS build-openssl 80 | 81 | ARG OPENSSL_VERSION 82 | ARG CFLAGS 83 | ARG LDFLAGS 84 | 85 | WORKDIR /build/openssl 86 | 87 | # Add logic for target arch (for multi-platform builds) 88 | ARG TARGETARCH 89 | ENV TARGETARCH=${TARGETARCH} 90 | ARG TARGETPLATFORM 91 | ENV TARGETPLATFORM=${TARGETPLATFORM} 92 | 93 | RUN case "$TARGETPLATFORM" in \ 94 | "linux/amd64") CONF=linux-x86_64 ;; \ 95 | "linux/386") CONF=linux-x86 ;; \ 96 | "linux/arm/v6") CONF=linux-armv4 ;; \ 97 | "linux/arm/v7") CONF=linux-armv4 ;; \ 98 | "linux/arm64") CONF=linux-aarch64 ;; \ 99 | "linux/ppc64le") CONF=linux-ppc64le ;; \ 100 | "linux/s390x") CONF=linux64-s390x ;; \ 101 | "linux/riscv64") CONF=linux64-riscv64 ;; \ 102 | *) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \ 103 | esac && \ 104 | echo "Configuring for $CONF" && \ 105 | ./Configure ${CONF} \ 106 | --prefix=/usr \ 107 | no-cms \ 108 | no-md2 \ 109 | no-md4 \ 110 | no-mdc2 \ 111 | no-seed \ 112 | no-bf \ 113 | no-cast \ 114 | no-des \ 115 | no-sm2 \ 116 | no-sm3 \ 117 | no-sm4 \ 118 | no-rc2 \ 119 | no-rc4 \ 120 | no-idea \ 121 | no-aria \ 122 | no-camellia \ 123 | no-whirlpool \ 124 | no-rmd160 \ 125 | no-shared \ 126 | no-tests \ 127 | no-ssl3 \ 128 | no-ssl3-method \ 129 | no-srp \ 130 | no-psk \ 131 | no-weak-ssl-ciphers \ 132 | no-comp \ 133 | no-zlib \ 134 | no-dynamic-engine \ 135 | no-engine \ 136 | no-dso \ 137 | no-asm \ 138 | no-async \ 139 | no-filenames \ 140 | no-docs \ 141 | no-deprecated \ 142 | no-apps \ 143 | --with-rand-seed=devrandom && \ 144 | make install_sw 145 | 146 | ################################################################################ 147 | # BUILD NGINX Micro (no gzip, no ssl) 148 | ################################################################################ 149 | FROM build-deps AS build-micro 150 | 151 | ARG NGINX_VERSION CFLAGS LDFLAGS 152 | 153 | WORKDIR /build/nginx 154 | 155 | RUN ./configure \ 156 | --sbin-path=/nginx \ 157 | --pid-path="/tmp/nginx.pid" \ 158 | --lock-path="/tmp/nginx.lock" \ 159 | --error-log-path="/dev/stdout" \ 160 | --http-log-path="/dev/stdout" \ 161 | --conf-path=/conf/nginx.conf \ 162 | --prefix="/" \ 163 | --with-cc-opt="$CFLAGS" \ 164 | --with-ld-opt="$LDFLAGS" \ 165 | --with-pcre \ 166 | --with-threads \ 167 | --with-file-aio \ 168 | --without-select_module \ 169 | --without-poll_module \ 170 | --without-http_charset_module \ 171 | --without-http_auth_basic_module \ 172 | --without-http_browser_module \ 173 | --without-http_map_module \ 174 | --without-http_autoindex_module \ 175 | --without-http_geo_module \ 176 | --without-http_split_clients_module \ 177 | --without-http_userid_module \ 178 | --without-http_empty_gif_module \ 179 | --without-http_referer_module \ 180 | --without-http_proxy_module \ 181 | --without-http_uwsgi_module \ 182 | --without-http_scgi_module \ 183 | --without-http_ssi_module \ 184 | --without-http_gzip_module \ 185 | --without-http_memcached_module \ 186 | --without-http_mirror_module \ 187 | --without-http_upstream_hash_module \ 188 | --without-http_upstream_ip_hash_module \ 189 | --without-http_upstream_least_conn_module \ 190 | --without-http_upstream_random_module \ 191 | --without-http_upstream_keepalive_module \ 192 | --without-http_upstream_zone_module && \ 193 | make && \ 194 | cp objs/nginx /nginx && \ 195 | strip --strip-all /nginx && \ 196 | upx --ultra-brute /nginx -o /nginx-upx || cp /nginx /nginx-upx 197 | 198 | ################################################################################ 199 | # BUILD NGINX Gzip (no SSL) 200 | ################################################################################ 201 | FROM build-deps AS build-gzip 202 | 203 | ARG NGINX_VERSION CFLAGS LDFLAGS 204 | 205 | WORKDIR /build/nginx 206 | 207 | RUN ./configure \ 208 | --sbin-path=/nginx \ 209 | --pid-path="/tmp/nginx.pid" \ 210 | --lock-path="/tmp/nginx.lock" \ 211 | --error-log-path="/dev/stdout" \ 212 | --http-log-path="/dev/stdout" \ 213 | --conf-path=/conf/nginx.conf \ 214 | --prefix="/" \ 215 | --with-cc-opt="$CFLAGS" \ 216 | --with-ld-opt="$LDFLAGS" \ 217 | --with-pcre \ 218 | --with-threads \ 219 | --with-file-aio \ 220 | --without-select_module \ 221 | --without-poll_module \ 222 | --with-http_gunzip_module \ 223 | --with-http_gzip_static_module \ 224 | --without-http_charset_module \ 225 | --without-http_auth_basic_module \ 226 | --without-http_browser_module \ 227 | --without-http_map_module \ 228 | --without-http_autoindex_module \ 229 | --without-http_geo_module \ 230 | --without-http_split_clients_module \ 231 | --without-http_userid_module \ 232 | --without-http_empty_gif_module \ 233 | --without-http_referer_module \ 234 | --without-http_proxy_module \ 235 | --without-http_uwsgi_module \ 236 | --without-http_scgi_module \ 237 | --without-http_ssi_module \ 238 | --without-http_memcached_module \ 239 | --without-http_mirror_module \ 240 | --without-http_upstream_hash_module \ 241 | --without-http_upstream_ip_hash_module \ 242 | --without-http_upstream_least_conn_module \ 243 | --without-http_upstream_random_module \ 244 | --without-http_upstream_keepalive_module \ 245 | --without-http_upstream_zone_module && \ 246 | make && \ 247 | cp objs/nginx /nginx && \ 248 | strip --strip-all /nginx && \ 249 | upx --ultra-brute /nginx -o /nginx-upx || cp /nginx /nginx-upx 250 | 251 | ################################################################################ 252 | # BUILD NGINX SSL (includes gzip) 253 | ################################################################################ 254 | FROM build-openssl AS build-ssl 255 | 256 | ARG NGINX_VERSION OPENSSL_VERSION CFLAGS LDFLAGS 257 | 258 | WORKDIR /build/nginx 259 | 260 | RUN ./configure \ 261 | --sbin-path=/nginx \ 262 | --pid-path="/tmp/nginx.pid" \ 263 | --lock-path="/tmp/nginx.lock" \ 264 | --error-log-path="/dev/stdout" \ 265 | --http-log-path="/dev/stdout" \ 266 | --conf-path=/conf/nginx.conf \ 267 | --prefix="/" \ 268 | --with-cc-opt="$CFLAGS" \ 269 | --with-ld-opt="$LDFLAGS" \ 270 | --with-pcre \ 271 | --with-threads \ 272 | --with-file-aio \ 273 | --with-http_ssl_module \ 274 | --with-http_gunzip_module \ 275 | --with-http_gzip_static_module \ 276 | --with-http_v2_module \ 277 | --with-http_v3_module \ 278 | --with-http_auth_request_module \ 279 | --without-select_module \ 280 | --without-poll_module \ 281 | --without-http_charset_module \ 282 | --without-http_browser_module \ 283 | --without-http_map_module \ 284 | --without-http_autoindex_module \ 285 | --without-http_geo_module \ 286 | --without-http_split_clients_module \ 287 | --without-http_userid_module \ 288 | --without-http_empty_gif_module \ 289 | --without-http_referer_module \ 290 | --without-http_uwsgi_module \ 291 | --without-http_scgi_module \ 292 | --without-http_ssi_module \ 293 | --without-http_memcached_module \ 294 | --without-http_mirror_module \ 295 | --without-http_upstream_hash_module \ 296 | --without-http_upstream_ip_hash_module \ 297 | --without-http_upstream_least_conn_module \ 298 | --without-http_upstream_random_module \ 299 | --without-http_upstream_keepalive_module \ 300 | --without-http_upstream_zone_module && \ 301 | make && \ 302 | cp objs/nginx /nginx && \ 303 | strip --strip-all /nginx && \ 304 | upx --ultra-brute /nginx -o /nginx-upx || cp /nginx /nginx-upx 305 | 306 | ################################################################################ 307 | # Minimal /etc/passwd, /etc/group 308 | ################################################################################ 309 | FROM scratch AS nginx-user 310 | 311 | ARG NGINX_VERSION 312 | 313 | LABEL maintainer="James Dornan " \ 314 | org.opencontainers.image.source="https://github.com/johnnyjoy/nginx-micro" \ 315 | org.opencontainers.image.version="${NGINX_VERSION}" 316 | 317 | COPY --from=build-deps /nginx.passwd /etc/passwd 318 | COPY --from=build-deps /nginx.group /etc/group 319 | 320 | COPY conf /conf 321 | 322 | EXPOSE 80 323 | CMD ["/nginx", "-g", "daemon off;"] 324 | ################################################################################ 325 | # FINAL Nginx Micro 326 | ################################################################################ 327 | FROM nginx-user AS micro 328 | 329 | COPY --from=build-micro /nginx /nginx 330 | ################################################################################ 331 | # FINAL Nginx Micro Upx 332 | ################################################################################ 333 | FROM nginx-user AS micro-upx 334 | 335 | COPY --from=build-micro /nginx-upx /nginx 336 | ################################################################################ 337 | # FINAL Nginx Gzip 338 | ################################################################################ 339 | FROM nginx-user AS gzip 340 | 341 | COPY --from=build-gzip /nginx /nginx 342 | ################################################################################ 343 | # FINAL Nginx Gzip Upx 344 | ################################################################################ 345 | FROM nginx-user AS gzip-upx 346 | 347 | COPY --from=build-gzip /nginx-upx /nginx 348 | ################################################################################ 349 | # FINAL Nginx SSL 350 | ################################################################################ 351 | FROM nginx-user AS ssl 352 | 353 | COPY --from=build-ssl /nginx /nginx 354 | 355 | EXPOSE 443 356 | ################################################################################ 357 | # FINAL Nginx SSL Upx 358 | ################################################################################ 359 | FROM nginx-user AS ssl-upx 360 | 361 | COPY --from=build-ssl /nginx-upx /nginx 362 | 363 | EXPOSE 443 364 | --------------------------------------------------------------------------------