7 Commits

Author SHA1 Message Date
ElevenNotes
ca2d9fb104 Merge branch 'master' of https://github.com/11notes/docker-nginx 2025-06-04 21:25:57 +02:00
ElevenNotes
6053097470 [cut] latest 2025-06-04 21:25:49 +02:00
ElevenNotes
a165c1c5b4 [upgrade] to latest workflow 2025-06-04 21:25:40 +02:00
ElevenNotes
5f8b5ee790 [cut] --without-http_map_module 2025-06-04 21:25:16 +02:00
github-actions[bot]
a2d2fbc193 auto update README.md 2025-04-28 10:12:03 +00:00
github-actions[bot]
712d64e484 auto update README.md 2025-04-28 09:03:23 +00:00
ElevenNotes
1c78ef6e04 [feature] add comparison 2025-04-28 10:58:10 +02:00
7 changed files with 84 additions and 42 deletions

View File

@@ -16,6 +16,11 @@ on:
required: false
default: 'ubuntu-22.04'
build:
description: 'set WORKFLOW_BUILD'
required: false
default: 'true'
release:
description: 'set WORKFLOW_GITHUB_RELEASE'
required: false
@@ -45,7 +50,6 @@ jobs:
actions: read
contents: write
packages: write
security-events: write
steps:
- name: init / checkout
@@ -105,7 +109,7 @@ jobs:
app:{
image:opt.dot.image,
name:opt.dot.name,
version:(opt.input?.etc?.version || opt.dot.semver.version),
version:(opt.input?.etc?.version || opt.dot?.semver?.version),
root:opt.dot.root,
UID:(opt.input?.etc?.uid || 1000),
GID:(opt.input?.etc?.gid || 1000),
@@ -123,22 +127,25 @@ jobs:
docker.app.suffix = docker.image.suffix;
// setup tags
if(!opt.dot?.semver?.disable?.rolling){
docker.image.tags.push('rolling');
}
if(opt.input?.etc?.dockerfile !== 'arch.dockerfile' && opt.input?.etc?.tag){
docker.image.tags.push(`${context.sha.substring(0,7)}`);
docker.image.tags.push(opt.input.etc.tag);
docker.image.tags.push(`${opt.input.etc.tag}-${docker.app.version}`);
docker.cache.name = `${docker.image.name}:buildcache-${opt.input.etc.tag}`;
}else if(opt.dot?.semver?.version){
const semver = opt.dot.semver.version.split('.');
}else if(docker.app.version !== 'latest'){
const semver = docker.app.version.split('.');
docker.image.tags.push(`${context.sha.substring(0,7)}`);
if(Array.isArray(semver)){
if(semver.length >= 1) docker.image.tags.push(`${semver[0]}`);
if(semver.length >= 2) docker.image.tags.push(`${semver[0]}.${semver[1]}`);
if(semver.length >= 3) docker.image.tags.push(`${semver[0]}.${semver[1]}.${semver[2]}`);
}
if(opt.dot.semver?.stable && new RegExp(opt.dot.semver.stable, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('stable');
if(opt.dot.semver?.latest && new RegExp(opt.dot.semver.latest, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('latest');
}else if(opt.input?.etc?.version && opt.input.etc.version === 'latest'){
if(opt.dot?.semver?.stable && new RegExp(opt.dot?.semver.stable, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('stable');
if(opt.dot?.semver?.latest && new RegExp(opt.dot?.semver.latest, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('latest');
}else{
docker.image.tags.push('latest');
}
@@ -154,6 +161,11 @@ jobs:
docker.app[arg] = opt.input.etc.build.args[arg];
}
}
if(opt.dot?.build?.args){
for(const arg in opt.dot.build.args){
docker.app[arg] = opt.dot.build.args[arg];
}
}
const arguments = [];
for(const argument in docker.app){
arguments.push(`APP_${argument.toUpperCase()}=${docker.app[argument]}`);
@@ -171,6 +183,7 @@ jobs:
core.exportVariable('DOCKER_IMAGE_ARGUMENTS', arguments.join("\r\n"));
core.exportVariable('DOCKER_IMAGE_DOCKERFILE', opt.input?.etc?.dockerfile || 'arch.dockerfile');
core.exportVariable('WORKFLOW_BUILD', (opt.input?.build === undefined) ? false : opt.input.build);
core.exportVariable('WORKFLOW_CREATE_RELEASE', (opt.input?.release === undefined) ? false : opt.input.release);
core.exportVariable('WORKFLOW_CREATE_README', (opt.input?.readme === undefined) ? false : opt.input.readme);
core.exportVariable('WORKFLOW_GRYPE_FAIL_ON_SEVERITY', (opt.dot?.grype?.fail === undefined) ? true : opt.dot.grype.fail);
@@ -205,14 +218,17 @@ jobs:
password: ${{ secrets.QUAY_TOKEN }}
- name: docker / setup qemu
if: env.WORKFLOW_BUILD == 'true'
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a
- name: docker / setup buildx
if: env.WORKFLOW_BUILD == 'true'
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5
with:
driver-opts: network=host
- name: docker / build & push & tag grype
if: env.WORKFLOW_BUILD == 'true'
id: docker-build
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d
with:
@@ -228,6 +244,7 @@ jobs:
${{ env.DOCKER_CACHE_GRYPE }}
- name: grype / scan
if: env.WORKFLOW_BUILD == 'true'
id: grype
uses: anchore/scan-action@dc6246fcaf83ae86fcc6010b9824c30d7320729e
with:
@@ -239,7 +256,7 @@ jobs:
cache-db: true
- name: grype / fail
if: failure() || steps.grype.outcome == 'failure'
if: env.WORKFLOW_BUILD == 'true' && (failure() || steps.grype.outcome == 'failure')
uses: anchore/scan-action@dc6246fcaf83ae86fcc6010b9824c30d7320729e
with:
image: ${{ env.DOCKER_CACHE_GRYPE }}
@@ -250,6 +267,7 @@ jobs:
cache-db: true
- name: docker / build & push
if: env.WORKFLOW_BUILD == 'true'
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d
with:
context: .
@@ -338,27 +356,27 @@ jobs:
# README
- name: github / checkout master
- name: github / checkout HEAD
continue-on-error: true
run: |
git pull
git checkout master
run: |
git checkout HEAD
- name: docker / setup comparison images
if: env.WORKFLOW_CREATE_COMPARISON == 'true'
continue-on-error: true
run: |
docker image prune -af
docker image pull ${{ env.WORKFLOW_CREATE_COMPARISON_IMAGE }}
docker image ls --filter "reference=${{ env.WORKFLOW_CREATE_COMPARISON_IMAGE }}" --format json | jq --raw-output '.Size' &> ./comparison.size0.log
docker image pull ${{ env.WORKFLOW_CREATE_COMPARISON_FOREIGN_IMAGE }}
docker image ls &> ./docker.image.ls
echo "${PWD}"
cat ./docker.image.ls
docker image ls --filter "reference=${{ env.WORKFLOW_CREATE_COMPARISON_FOREIGN_IMAGE }}" --format json | jq --raw-output '.Size' &> ./comparison.size1.log
docker run --entrypoint "/bin/sh" --rm ${{ env.WORKFLOW_CREATE_COMPARISON_FOREIGN_IMAGE }} -c id &> ./comparison.id.log
- name: github / create README.md
id: github-readme
continue-on-error: true
if: env.WORKFLOW_CREATE_README == 'true' && steps.docker-build.outcome == 'success'
if: env.WORKFLOW_CREATE_README == 'true'
uses: 11notes/action-docker-readme@v1
# WHY IS THIS ACTION NOT SHA256 PINNED? SECURITY MUCH?!?!?!
# ---------------------------------------------------------------------------------
@@ -384,17 +402,6 @@ jobs:
short_description: ${{ env.DOCKER_IMAGE_DESCRIPTION }}
readme_file: 'README_NONGITHUB.md'
- name: quay / push README.md to quay
continue-on-error: true
if: steps.github-readme.outcome == 'success' && hashFiles('README_NONGITHUB.md') != ''
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8
env:
DOCKER_APIKEY: ${{ secrets.QUAY_TOKEN }}
with:
destination_container_repo: quay.io/${{ env.DOCKER_IMAGE_NAME }}
provider: quay
readme_file: 'README_NONGITHUB.md'
- name: github / commit & push
continue-on-error: true
if: steps.github-readme.outcome == 'success' && hashFiles('README.md') != ''
@@ -408,8 +415,8 @@ jobs:
if [ -f LICENSE ]; then
git add LICENSE
fi
git commit -m "auto update README.md"
git push
git commit -m "github-actions[bot]: update README.md"
git push origin HEAD:master

16
.github/workflows/readme.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: readme
on:
workflow_dispatch:
jobs:
readme:
runs-on: ubuntu-latest
steps:
- name: update README.md
uses: the-actions-org/workflow-dispatch@3133c5d135c7dbe4be4f9793872b6ef331b53bc7
with:
wait-for-completion: false
workflow: docker.yml
token: "${{ secrets.REPOSITORY_TOKEN }}"
inputs: '{ "build":"false", "release":"false", "readme":"true" }'

6
.json
View File

@@ -6,8 +6,7 @@
"semver":{
"version":"1.28.0",
"stable":"1.28.0",
"latest":"1.28.0"
"stable":"1.28.0"
},
"readme":{
@@ -20,6 +19,9 @@
"11notes/distroless",
"11notes/distroless:curl"
]
},
"comparison":{
"image":"nginx:1.28.0-alpine-slim"
}
}
}

View File

@@ -1,22 +1,22 @@
![banner](https://github.com/11notes/defaults/blob/main/static/img/banner.png?raw=true)
# NGINX
[<img src="https://img.shields.io/badge/github-source-blue?logo=github&color=040308">](https://github.com/11notes/docker-NGINX)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![size](https://img.shields.io/docker/image-size/11notes/nginx/1.26.3?color=0eb305)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![version](https://img.shields.io/docker/v/11notes/nginx/1.26.3?color=eb7a09)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![pulls](https://img.shields.io/docker/pulls/11notes/nginx?color=2b75d6)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)[<img src="https://img.shields.io/github/issues/11notes/docker-NGINX?color=7842f5">](https://github.com/11notes/docker-NGINX/issues)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![swiss_made](https://img.shields.io/badge/Swiss_Made-FFFFFF?labelColor=FF0000&logo=data:image/svg%2bxml;base64,PHN2ZyB2ZXJzaW9uPSIxIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iI2YwMCIvPjxwYXRoIGQ9Im0xMyA2aDZ2N2g3djZoLTd2N2gtNnYtN2gtN3YtNmg3eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==)
[<img src="https://img.shields.io/badge/github-source-blue?logo=github&color=040308">](https://github.com/11notes/docker-NGINX)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![size](https://img.shields.io/docker/image-size/11notes/nginx/1.28.0?color=0eb305)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![version](https://img.shields.io/docker/v/11notes/nginx/1.28.0?color=eb7a09)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![pulls](https://img.shields.io/docker/pulls/11notes/nginx?color=2b75d6)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)[<img src="https://img.shields.io/github/issues/11notes/docker-NGINX?color=7842f5">](https://github.com/11notes/docker-NGINX/issues)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![swiss_made](https://img.shields.io/badge/Swiss_Made-FFFFFF?labelColor=FF0000&logo=data:image/svg%2bxml;base64,PHN2ZyB2ZXJzaW9uPSIxIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iI2YwMCIvPjxwYXRoIGQ9Im0xMyA2aDZ2N2g3djZoLTd2N2gtNnYtN2gtN3YtNmg3eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==)
Nginx, slim and distroless to be used behind a reverse proxy or as full version
# MAIN TAGS 🏷️
These are the main tags for the image. There is also a tag for each commit and its shorthand sha256 value.
* [1.26.3](https://hub.docker.com/r/11notes/nginx/tags?name=1.26.3)
* [1.28.0](https://hub.docker.com/r/11notes/nginx/tags?name=1.28.0)
* [stable](https://hub.docker.com/r/11notes/nginx/tags?name=stable)
* [latest](https://hub.docker.com/r/11notes/nginx/tags?name=latest)
# REPOSITORIES ☁️
```
docker pull 11notes/nginx:1.26.3
docker pull ghcr.io/11notes/nginx:1.26.3
docker pull quay.io/11notes/nginx:1.26.3
docker pull 11notes/nginx:1.28.0
docker pull ghcr.io/11notes/nginx:1.28.0
docker pull quay.io/11notes/nginx:1.28.0
```
# SYNOPSIS 📖
@@ -32,9 +32,22 @@ docker pull quay.io/11notes/nginx:1.26.3
>* This image is created via a secure, pinned CI/CD process and immune to upstream attacks, most other images have upstream dependencies that can be exploited
>* This image contains a proper health check that verifies the app is actually working, most other images have either no health check or only check if a port is open or ping works
>* This image works as read-only, most other images need to write files to the image filesystem
>* This image is a lot smaller than most other images
If you value security, simplicity and the ability to interact with the maintainer and developer of an image. Using my images is a great start in that direction.
# COMPARISON 🏁
Below you find a comparison between this image and the most used or original one.
| ![128px](https://github.com/11notes/defaults/blob/main/static/img/transparent128x1px.png?raw=true)**image** | 11notes/nginx:1.28.0 | nginx:1.28.0-alpine-slim |
| ---: | :---: | :---: |
| **image size on disk** | 4.4MB | 11.9MB |
| **process UID/GID** | 1000/1000 | 0/0 |
| **distroless?** | ✅ | ❌ |
| **rootless?** | ✅ | ❌ |
# DEFAULT CONFIG 📑
```yaml
worker_processes auto;
@@ -124,7 +137,7 @@ The default configuration contains no special settings. It enables brotli compre
name: "nginx"
services:
nginx:
image: "11notes/nginx:1.26.3"
image: "11notes/nginx:1.28.0"
read_only: true
environment:
TZ: "Europe/Zurich"
@@ -183,4 +196,4 @@ networks:
# ElevenNotes™
This image is provided to you at your own risk. Always make backups before updating an image to a different version. Check the [releases](https://github.com/11notes/docker-nginx/releases) for breaking changes. If you have any problems with using this image simply raise an [issue](https://github.com/11notes/docker-nginx/issues), thanks. If you have a question or inputs please create a new [discussion](https://github.com/11notes/docker-nginx/discussions) instead of an issue. You can find all my other repositories on [github](https://github.com/11notes?tab=repositories).
*created 14.04.2025, 08:54:33 (CET)*
*created 28.04.2025, 12:12:02 (CET)*

View File

@@ -176,7 +176,6 @@ ARG APP_GID=1000
--without-http_empty_gif_module \
--without-http_geo_module \
--without-http_memcached_module \
--without-http_map_module \
--without-http_ssi_module \
--without-http_split_clients_module \
--without-http_fastcgi_module \
@@ -318,7 +317,8 @@ ARG APP_GID=1000
VOLUME ["${APP_ROOT}/etc", "${APP_ROOT}/var"]
# :: Monitor
HEALTHCHECK --interval=5s --timeout=2s CMD ["/usr/local/bin/curl", "-kILs", "--fail", "http://localhost:3000/ping"]
HEALTHCHECK --interval=5s --timeout=2s --start-interval=5s \
CMD ["/usr/local/bin/curl", "-kILs", "--fail", "http://localhost:3000/ping"]
# :: Start
USER ${APP_UID}:${APP_GID}

View File

@@ -1,7 +1,7 @@
name: "nginx"
services:
nginx:
image: "11notes/nginx:1.26.3"
image: "11notes/nginx:1.28.0"
read_only: true
environment:
TZ: "Europe/Zurich"

View File

@@ -9,9 +9,13 @@ ${{ github:> }}* This image does not ship with any critical or high rated CVE an
${{ github:> }}* This image is created via a secure, pinned CI/CD process and immune to upstream attacks, most other images have upstream dependencies that can be exploited
${{ github:> }}* This image contains a proper health check that verifies the app is actually working, most other images have either no health check or only check if a port is open or ping works
${{ github:> }}* This image works as read-only, most other images need to write files to the image filesystem
${{ github:> }}* This image is a lot smaller than most other images
If you value security, simplicity and the ability to interact with the maintainer and developer of an image. Using my images is a great start in that direction.
${{ content_comparison }}
${{ title_config }}
```yaml
${{ include: ./rootfs/etc/nginx/nginx.conf }}