58 Commits

Author SHA1 Message Date
ElevenNotes
d5c15bb795 [fix] missing semver version 2025-05-20 16:00:26 +02:00
ElevenNotes
20d185b9cf Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-20 15:38:44 +02:00
ElevenNotes
4969a99521 [feature] use .json from 11notes/kms 2025-05-20 15:38:35 +02:00
github-actions[bot]
dff61f79cc github-actions[bot]: update README.md 2025-05-20 13:26:01 +00:00
ElevenNotes
f2bd5a0ab5 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-20 15:07:08 +02:00
ElevenNotes
4e4dd509dc [upgrade] 1.0.1 2025-05-20 15:06:58 +02:00
github-actions[bot]
db9df9ea0e github-actions[bot]: update README.md 2025-05-19 13:45:39 +00:00
ElevenNotes
599ba8c980 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-19 09:00:00 +02:00
ElevenNotes
fa5238dab7 [feature] add ARM v7 2025-05-19 08:59:53 +02:00
ElevenNotes
83708d3c58 [upgrade] latest workflow 2025-05-19 08:59:39 +02:00
github-actions[bot]
b8f0cdb975 github-actions[bot]: update README.md 2025-05-05 09:08:25 +00:00
ElevenNotes
b07ff70477 [breaking] switch to semver 2025-05-05 10:57:38 +02:00
ElevenNotes
7c274600f4 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-05 10:56:34 +02:00
ElevenNotes
8ff275bb7a [upgrade] to fork for default skin and semver for base image 2025-05-05 10:56:26 +02:00
github-actions[bot]
6fd38bbd74 github-actions[bot]: update README.md 2025-05-02 09:48:27 +00:00
github-actions[bot]
d4cf5e9f24 github-actions[bot]: update README.md 2025-05-02 08:37:48 +00:00
ElevenNotes
d094fe1357 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-02 10:26:44 +02:00
ElevenNotes
ab655ef97c [fix] invalidate cache 2025-05-02 10:26:36 +02:00
github-actions[bot]
915cc5bcdc github-actions[bot]: update README.md 2025-05-02 08:23:31 +00:00
ElevenNotes
f90bd43a16 [fix] upgrade all BUT pip 2025-05-02 10:14:51 +02:00
ElevenNotes
3a98954378 [fix] upgrade all BUT pip 2025-05-02 10:14:05 +02:00
ElevenNotes
9a990477d8 [fix] UID/GID defaults 2025-05-02 09:57:23 +02:00
ElevenNotes
63b38064e4 [fix] system packages 2025-05-02 09:56:34 +02:00
ElevenNotes
b17c50ef99 [fix] no cache-dir 2025-05-02 09:49:52 +02:00
ElevenNotes
131f719f0d [fix] upgrade 2025-05-02 09:40:47 +02:00
ElevenNotes
7f1f8b4096 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-05-02 09:04:02 +02:00
ElevenNotes
c16f825747 [feature] adjust to new workflow 2025-05-02 09:03:54 +02:00
ElevenNotes
6022fb0269 [feature] new workflow 2025-05-02 09:03:40 +02:00
ElevenNotes
73f27eb071 [upgrade] to latest workflow 2025-05-02 09:03:26 +02:00
ElevenNotes
dbcb40d456 [breaking] change port to 3000 to streamline app ports 2025-05-02 09:03:15 +02:00
ElevenNotes
02a2d538c8 [breaking] change port to 3000 to streamline app ports 2025-05-02 09:03:03 +02:00
ElevenNotes
779e562963 [cut] latest and stable (because there is none) 2025-05-02 09:02:48 +02:00
github-actions[bot]
543c345d80 auto update README.md 2025-03-10 11:02:37 +00:00
ElevenNotes
d1ac93f4b5 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-03-10 11:59:20 +01:00
ElevenNotes
405a874533 [feature] add products page again after tailwind fix 2025-03-10 11:59:10 +01:00
github-actions[bot]
b45314d58f auto update README.md 2025-03-07 23:48:17 +00:00
ElevenNotes
2f59f8c6e2 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-03-08 00:46:10 +01:00
ElevenNotes
03f63033c5 [fix] forgot APP_PREFIX & APP_SUFFIX in dynamic build args 2025-03-08 00:45:28 +01:00
github-actions[bot]
15d93c9643 auto update README.md 2025-03-07 11:14:14 +00:00
ElevenNotes
7637bf2c3d Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-03-07 12:09:25 +01:00
ElevenNotes
145c6a1d82 [fix] semver.length 2025-03-07 12:09:14 +01:00
github-actions[bot]
4221216db4 auto update README.md 2025-03-07 11:07:09 +00:00
github-actions[bot]
95fbe08011 auto update README.md 2025-03-07 10:58:09 +00:00
ElevenNotes
e34127b4c7 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-03-07 11:55:29 +01:00
ElevenNotes
75a3d5d474 [upgrade] docker.yml workflow to new javascript version 2025-03-07 11:55:20 +01:00
github-actions[bot]
24a59b471e auto update README.md 2025-02-21 06:22:45 +00:00
ElevenNotes
bf755ecf0d [cut] drop commit fix for fork of pykms-frontend 2025-02-21 07:17:01 +01:00
ElevenNotes
2ef047319a Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-02-21 07:15:59 +01:00
ElevenNotes
d608769727 [comment] different ico than custom-icon style 2025-02-21 07:15:49 +01:00
github-actions[bot]
72d8d9c55c auto update README.md 2025-02-21 06:05:47 +00:00
ElevenNotes
d20153c545 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-02-21 07:03:12 +01:00
ElevenNotes
ce91a1f421 [upgrade] bump pykms-frontend to 103935b 2025-02-21 07:02:58 +01:00
github-actions[bot]
dbce137fb8 auto update README.md 2025-02-21 05:59:45 +00:00
ElevenNotes
4aed569709 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-02-21 06:53:10 +01:00
ElevenNotes
8b1457602d [feature] APP_NO_CACHE to invalidate cache for styles 2025-02-21 06:53:02 +01:00
github-actions[bot]
847ff77077 auto update README.md 2025-02-21 05:50:53 +00:00
ElevenNotes
cfbf6347c2 Merge branch 'master' of https://github.com/11notes/docker-kms-gui 2025-02-21 06:45:57 +01:00
github-actions[bot]
971ba4ffe4 auto update README.md 2025-02-20 14:18:47 +00:00
9 changed files with 456 additions and 227 deletions

View File

@@ -10,6 +10,17 @@ on:
required: false
default: 'docker'
runs-on:
description: 'set runs-on for workflow (github or selfhosted)'
type: string
required: false
default: 'ubuntu-22.04'
build:
description: 'set WORKFLOW_BUILD'
required: false
default: 'true'
release:
description: 'set WORKFLOW_GITHUB_RELEASE'
required: false
@@ -19,35 +30,26 @@ on:
description: 'set WORKFLOW_GITHUB_README'
required: false
default: 'false'
image:
description: 'set IMAGE'
required: false
uid:
description: 'set IMAGE_UID'
required: false
gid:
description: 'set IMAGE_GID'
required: false
semverprefix:
description: 'prefix for semver tags'
required: false
semversuffix:
description: 'suffix for semver tags'
etc:
description: 'base64 encoded json string'
required: false
jobs:
docker:
runs-on: ubuntu-22.04
runs-on: ${{ inputs.runs-on }}
timeout-minutes: 1440
services:
registry:
image: registry:2
ports:
- 5000:5000
permissions:
actions: read
contents: write
packages: write
security-events: write
steps:
- name: init / checkout
@@ -56,153 +58,236 @@ jobs:
ref: ${{ github.ref_name }}
fetch-depth: 0
- name: init / inputs to env
if: github.event_name == 'workflow_dispatch'
run: |
cat << 'EOF' > .inputs
${{ toJSON(github.event.inputs) }}
EOF
for KEY in $(cat .inputs | jq --raw-output 'keys[]' | tr '\n' ' '); do echo "input_$(echo ${KEY} | tr '[:upper:]' '[:lower:]')=$(cat .inputs | jq --raw-output '.'${KEY}'')" >> $GITHUB_ENV; done
rm -rf .inputs
- name: init / .json to env
uses: rgarcia-phi/json-to-variables@9835d537368468c4e4de5254dc3efeadda183793
with:
filename: '.json'
- name: init / setup environment
run: |
: # set image
LOCAL_IMAGE=${json_image}
if [ ! -z ${input_image} ]; then LOCAL_IMAGE=${input_image}; fi
echo "IMAGE=${LOCAL_IMAGE}" >> $GITHUB_ENV
uses: actions/github-script@62c3794a3eb6788d9a2a72b219504732c0c9a298
with:
script: |
const { existsSync, readFileSync } = require('node:fs');
const { resolve } = require('node:path');
const { inspect } = require('node:util');
const { Buffer } = require('node:buffer');
const inputs = `${{ toJSON(github.event.inputs) }}`;
const opt = {input:{}, dot:{}};
: # set defaults
echo "IMAGE_ARCH=${json_arch:-linux/amd64,linux/arm64}" >> $GITHUB_ENV
echo "WORKFLOW_GITHUB_RELEASE=${input_release:-true}" >> $GITHUB_ENV;
echo "WORKFLOW_GITHUB_README=${input_readme:-true}" >> $GITHUB_ENV;
echo "WORKFLOW_GRYPE_SCAN=${json_grype_scan:-true}" >> $GITHUB_ENV;
echo "WORKFLOW_GRYPE_SEVERITY_CUTOFF=${json_grype_severity:-high}" >> $GITHUB_ENV;
try{
if(inputs.length > 0){
opt.input = JSON.parse(inputs);
if(opt.input?.etc){
opt.input.etc = JSON.parse(Buffer.from(opt.input.etc, 'base64').toString('ascii'));
}
}
}catch(e){
core.warning('could not parse github.event.inputs');
}
: # create tags for semver, stable and other shenanigans
LOCAL_SHA=$(git rev-parse --short HEAD)
LOCAL_SEMVER_MAJOR=$(awk -F. '{ print $1 }' <<< ${json_semver_version})
LOCAL_SEMVER_MINOR=$(awk -F. '{ print $2 }' <<< ${json_semver_version})
LOCAL_SEMVER_PATCH=$(awk -F. '{ print $3 }' <<< ${json_semver_version})
LOCAL_SEMVER_PREFIX=""
LOCAL_SEMVER_SUFFIX=""
LOCAL_SEMVER_RC=""
LOCAL_TAGS="${LOCAL_IMAGE}:${LOCAL_SHA}"
if [ ! -z ${input_semverprefix} ]; then LOCAL_SEMVER_PREFIX="${input_semverprefix}-"; fi
if [ ! -z ${input_semversuffix} ]; then LOCAL_SEMVER_SUFFIX="-${input_semversuffix}"; fi
if [ ! -z ${json_semver_rc} ]; then LOCAL_SEMVER_RC="${json_semver_rc}"; fi
if [ ! -z ${LOCAL_SEMVER_MAJOR} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}${LOCAL_SEMVER_SUFFIX}"; fi
if [ ! -z ${LOCAL_SEMVER_MINOR} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}.${LOCAL_SEMVER_MINOR}${LOCAL_SEMVER_SUFFIX}"; fi
if [ ! -z ${LOCAL_SEMVER_PATCH} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}.${LOCAL_SEMVER_MINOR}.${LOCAL_SEMVER_PATCH}${LOCAL_SEMVER_SUFFIX}"; fi
if echo "${LOCAL_TAGS}" | grep -q "${json_semver_stable}" ; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}stable${LOCAL_SEMVER_SUFFIX}"; fi
if echo "${LOCAL_TAGS}" | grep -q "${json_semver_latest}" ; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}latest${LOCAL_SEMVER_SUFFIX}"; fi
if [ ! -z ${json_semver_tags} ]; then SPECIAL_LOCAL_TAGS=$(echo ${json_semver_tags} | sed 's/,/ /g'); for LOCAL_TAG in ${json_semver_tags}; do LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_TAG}${LOCAL_SEMVER_SUFFIX}"; done; fi
echo "IMAGE_TAGS=${LOCAL_TAGS}" >> $GITHUB_ENV
try{
const path = resolve('.json');
if(existsSync(path)){
try{
opt.dot = JSON.parse(readFileSync(path).toString());
}catch(e){
throw new Error('could not parse .json');
}
}else{
throw new Error('.json does not exist');
}
}catch(e){
core.setFailed(e);
}
: # if for whatever reason UID/GID must be changed at build time
if [ ! -z ${input_uid} ]; then echo "IMAGE_UID=${input_uid}" >> $GITHUB_ENV; else echo "IMAGE_UID=${json_uid:-1000}" >> $GITHUB_ENV; fi
if [ ! -z ${input_gid} ]; then echo "IMAGE_GID=${input_gid}" >> $GITHUB_ENV; else echo "IMAGE_GID=${json_gid:-1000}" >> $GITHUB_ENV; fi
core.info(inspect(opt, {showHidden:false, depth:null, colors:true}));
: # set rc, prefix or suffix globally for semver and version
echo "IMAGE_SEMVER_PREFIX=${LOCAL_SEMVER_PREFIX}" >> $GITHUB_ENV
echo "IMAGE_SEMVER_SUFFIX=${LOCAL_SEMVER_SUFFIX}" >> $GITHUB_ENV
echo "IMAGE_VERSION_RC=${LOCAL_SEMVER_RC}" >> $GITHUB_ENV
const docker = {
image:{
name:opt.dot.image,
arch:(opt.dot.arch || 'linux/amd64,linux/arm64'),
prefix:((opt.input?.etc?.semverprefix) ? `${opt.input?.etc?.semverprefix}-` : ''),
suffix:((opt.input?.etc?.semversuffix) ? `-${opt.input?.etc?.semversuffix}` : ''),
description:(opt.dot?.readme?.description || ''),
tags:[],
},
app:{
image:opt.dot.image,
name:opt.dot.name,
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),
no_cache:new Date().getTime(),
},
cache:{
registry:'localhost:5000/',
},
tags:[],
};
docker.cache.name = `${docker.image.name}:${docker.image.prefix}buildcache${docker.image.suffix}`;
docker.cache.grype = `${docker.cache.registry}${docker.image.name}:${docker.image.prefix}grype${docker.image.suffix}`;
docker.app.prefix = docker.image.prefix;
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('.');
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'){
docker.image.tags.push('latest');
}
for(const tag of docker.image.tags){
docker.tags.push(`${docker.image.name}:${docker.image.prefix}${tag}${docker.image.suffix}`);
docker.tags.push(`ghcr.io/${docker.image.name}:${docker.image.prefix}${tag}${docker.image.suffix}`);
docker.tags.push(`quay.io/${docker.image.name}:${docker.image.prefix}${tag}${docker.image.suffix}`);
}
// setup build arguments
if(opt.input?.etc?.build?.args){
for(const arg in opt.input.etc.build.args){
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]}`);
}
// export to environment
core.exportVariable('DOCKER_CACHE_REGISTRY', docker.cache.registry);
core.exportVariable('DOCKER_CACHE_NAME', docker.cache.name);
core.exportVariable('DOCKER_CACHE_GRYPE', docker.cache.grype);
core.exportVariable('DOCKER_IMAGE_NAME', docker.image.name);
core.exportVariable('DOCKER_IMAGE_ARCH', docker.image.arch);
core.exportVariable('DOCKER_IMAGE_TAGS', docker.tags.join(','));
core.exportVariable('DOCKER_IMAGE_DESCRIPTION', docker.image.description);
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);
core.exportVariable('WORKFLOW_GRYPE_SEVERITY_CUTOFF', (opt.dot?.grype?.severity || 'high'));
if(opt.dot?.readme?.comparison){
core.exportVariable('WORKFLOW_CREATE_COMPARISON', true);
core.exportVariable('WORKFLOW_CREATE_COMPARISON_FOREIGN_IMAGE', opt.dot.readme.comparison.image);
core.exportVariable('WORKFLOW_CREATE_COMPARISON_IMAGE', `${docker.image.name}:${docker.app.version}`);
}
# DOCKER
- name: docker / login to hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
username: 11notes
password: ${{ secrets.DOCKER_TOKEN }}
- name: github / login to ghcr
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
registry: ghcr.io
username: 11notes
password: ${{ secrets.GITHUB_TOKEN }}
- name: quay / login to quay
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
registry: quay.io
username: 11notes+github
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: grype / build & push & tag
id: grype-tag
- name: docker / build & push & tag grype
if: env.WORKFLOW_BUILD == 'true'
id: docker-build
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d
with:
context: .
file: arch.dockerfile
file: ${{ env.DOCKER_IMAGE_DOCKERFILE }}
push: true
platforms: ${{ env.IMAGE_ARCH }}
cache-from: type=registry,ref=${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}buildcache${{ env.IMAGE_SEMVER_SUFFIX }}
cache-to: type=registry,ref=${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}buildcache${{ env.IMAGE_SEMVER_SUFFIX }},mode=max,compression=zstd,force-compression=true
platforms: ${{ env.DOCKER_IMAGE_ARCH }}
cache-from: type=registry,ref=${{ env.DOCKER_CACHE_NAME }}
cache-to: type=registry,ref=${{ env.DOCKER_CACHE_REGISTRY }}${{ env.DOCKER_CACHE_NAME }},mode=max,compression=zstd,force-compression=true
build-args: |
APP_IMAGE=${{ env.IMAGE }}
APP_NAME=${{ env.json_name }}
APP_VERSION=${{ env.json_semver_version }}
APP_ROOT=${{ env.json_root }}
APP_UID=${{ env.IMAGE_UID }}
APP_GID=${{ env.IMAGE_GID }}
APP_VERSION_PREFIX=${{ env.IMAGE_SEMVER_PREFIX }}
APP_VERSION_SUFFIX=${{ env.IMAGE_SEMVER_SUFFIX }}
APP_VERSION_RC=${{ env.IMAGE_VERSION_RC }}
APP_NO_CACHE=$(date +%s)
${{ env.DOCKER_IMAGE_ARGUMENTS }}
tags: |
${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}grype${{ env.IMAGE_SEMVER_SUFFIX }}
${{ env.DOCKER_CACHE_GRYPE }}
- name: grype / scan
if: env.WORKFLOW_GRYPE_SCAN == 'true'
id: grype-scan
uses: anchore/scan-action@abae793926ec39a78ab18002bc7fc45bbbd94342
if: env.WORKFLOW_BUILD == 'true'
id: grype
uses: anchore/scan-action@dc6246fcaf83ae86fcc6010b9824c30d7320729e
with:
image: ${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}grype${{ env.IMAGE_SEMVER_SUFFIX }}
image: ${{ env.DOCKER_CACHE_GRYPE }}
fail-build: ${{ env.WORKFLOW_GRYPE_FAIL_ON_SEVERITY }}
severity-cutoff: ${{ env.WORKFLOW_GRYPE_SEVERITY_CUTOFF }}
by-cve: true
output-format: 'sarif'
by-cve: true
cache-db: true
- name: grype / delete tag
if: steps.grype-tag.outcome == 'success'
run: |
curl --request DELETE \
--url https://hub.docker.com/v2/repositories/${{ env.IMAGE }}/tags/${{ env.IMAGE_SEMVER_PREFIX }}grype${{ env.IMAGE_SEMVER_SUFFIX }}/ \
--header 'authorization: jwt ${{ secrets.DOCKER_TOKEN }}' \
--header 'content-type: application/json' \
--fail
- name: codeql / upload
id: codeql-upload
if: steps.grype-scan.outcome == 'success'
uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169
- name: grype / fail
if: env.WORKFLOW_BUILD == 'true' && (failure() || steps.grype.outcome == 'failure')
uses: anchore/scan-action@dc6246fcaf83ae86fcc6010b9824c30d7320729e
with:
sarif_file: ${{ steps.grype-scan.outputs.sarif }}
wait-for-processing: false
category: grype
image: ${{ env.DOCKER_CACHE_GRYPE }}
fail-build: false
severity-cutoff: ${{ env.WORKFLOW_GRYPE_SEVERITY_CUTOFF }}
output-format: 'table'
by-cve: true
cache-db: true
- name: docker / build & push
if: env.WORKFLOW_BUILD == 'true'
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d
with:
context: .
file: arch.dockerfile
file: ${{ env.DOCKER_IMAGE_DOCKERFILE }}
push: true
sbom: true
provenance: mode=max
platforms: ${{ env.IMAGE_ARCH }}
cache-from: type=registry,ref=${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}buildcache${{ env.IMAGE_SEMVER_SUFFIX }}
cache-to: type=registry,ref=${{ env.IMAGE }}:${{ env.IMAGE_SEMVER_PREFIX }}buildcache${{ env.IMAGE_SEMVER_SUFFIX }},mode=max,compression=zstd,force-compression=true
platforms: ${{ env.DOCKER_IMAGE_ARCH }}
cache-from: type=registry,ref=${{ env.DOCKER_CACHE_REGISTRY }}${{ env.DOCKER_CACHE_NAME }}
cache-to: type=registry,ref=${{ env.DOCKER_CACHE_NAME }},mode=max,compression=zstd,force-compression=true
build-args: |
APP_IMAGE=${{ env.IMAGE }}
APP_NAME=${{ env.json_name }}
APP_VERSION=${{ env.json_semver_version }}
APP_ROOT=${{ env.json_root }}
APP_UID=${{ env.IMAGE_UID }}
APP_GID=${{ env.IMAGE_GID }}
APP_VERSION_PREFIX=${{ env.IMAGE_SEMVER_PREFIX }}
APP_VERSION_SUFFIX=${{ env.IMAGE_SEMVER_SUFFIX }}
APP_VERSION_RC=${{ env.IMAGE_VERSION_RC }}
APP_NO_CACHE=$(date +%s)
${{ env.DOCKER_IMAGE_ARGUMENTS }}
tags: |
${{ env.IMAGE_TAGS }}
${{ env.DOCKER_IMAGE_TAGS }}
# RELEASE
- name: github / release / log
continue-on-error: true
id: git-log
run: |
LOCAL_LAST_TAG=$(git describe --abbrev=0 --tags `git rev-list --tags --skip=1 --max-count=1`)
@@ -215,14 +300,20 @@ jobs:
echo "${EOF}" >> ${GITHUB_OUTPUT}
- name: github / release / markdown
if: env.WORKFLOW_GITHUB_RELEASE == 'true'
if: env.WORKFLOW_CREATE_RELEASE == 'true' && steps.git-log.outcome == 'success'
id: git-release
uses: 11notes/action-docker-release@v1
# WHY IS THIS ACTION NOT SHA256 PINNED? SECURITY MUCH?!?!?!
# ---------------------------------------------------------------------------------
# the next step "github / release / create" creates a new release based on the code
# in the repo. This code is not modified and can't be modified by this action.
# It does create the markdown for the release, which could be abused, but to what
# extend? Adding a link to a malicious repo?
with:
git_log: ${{ steps.git-log.outputs.commits }}
- name: github / release / create
if: env.WORKFLOW_GITHUB_RELEASE == 'true' && steps.git-release.outcome == 'success'
if: env.WORKFLOW_CREATE_RELEASE == 'true' && steps.git-release.outcome == 'success'
uses: actions/create-release@4c11c9fe1dcd9636620a16455165783b20fc7ea0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -233,41 +324,104 @@ jobs:
draft: false
prerelease: false
- name: github / checkout master
# LICENSE
- name: license / update year
continue-on-error: true
run: |
git checkout master
uses: actions/github-script@62c3794a3eb6788d9a2a72b219504732c0c9a298
with:
script: |
const { existsSync, readFileSync, writeFileSync } = require('node:fs');
const { resolve } = require('node:path');
const file = 'LICENSE';
const year = new Date().getFullYear();
try{
const path = resolve(file);
if(existsSync(path)){
let license = readFileSync(file).toString();
if(!new RegExp(`Copyright \\(c\\) ${year} 11notes`, 'i').test(license)){
license = license.replace(/Copyright \(c\) \d{4} /i, `Copyright (c) ${new Date().getFullYear()} `);
writeFileSync(path, license);
}
}else{
throw new Error(`file ${file} does not exist`);
}
}catch(e){
core.setFailed(e);
}
# README
- name: github / checkout HEAD
continue-on-error: true
run: |
git checkout HEAD
- name: docker / setup comparison images
if: env.WORKFLOW_CREATE_COMPARISON == 'true'
continue-on-error: true
run: |
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 --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
continue-on-error: true
if: env.WORKFLOW_GITHUB_README == 'true'
id: github-readme
uses: 11notes/action-docker-readme@v1
with:
sarif_file: ${{ steps.grype-scan.outputs.sarif }}
- name: github / commit & push
continue-on-error: true
if: steps.github-readme.outcome == 'success'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md
git commit -m "auto update README.md"
git push
if: env.WORKFLOW_CREATE_README == 'true'
uses: 11notes/action-docker-readme@v1
# WHY IS THIS ACTION NOT SHA256 PINNED? SECURITY MUCH?!?!?!
# ---------------------------------------------------------------------------------
# the next step "github / commit & push" only adds the README and LICENSE as well as
# compose.yaml to the repository. This does not pose a security risk if this action
# would be compromised. The code of the app can't be changed by this action. Since
# only the files mentioned are commited to the repo. Sure, someone could make a bad
# compose.yaml, but since this serves only as an example I see no harm in that.
with:
sarif_file: ${{ steps.grype.outputs.sarif }}
build_output_metadata: ${{ steps.docker-build.outputs.metadata }}
- name: docker / push README.md to docker hub
if: hashFiles('README.md') != ''
continue-on-error: true
if: steps.github-readme.outcome == 'success' && hashFiles('README_NONGITHUB.md') != ''
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8
env:
DOCKER_USER: 11notes
DOCKER_PASS: ${{ secrets.DOCKER_TOKEN }}
with:
destination_container_repo: ${{ env.IMAGE }}
destination_container_repo: ${{ env.DOCKER_IMAGE_NAME }}
provider: dockerhub
short_description: ${{ env.json_readme_description }}
readme_file: 'README.md'
short_description: ${{ env.DOCKER_IMAGE_DESCRIPTION }}
readme_file: 'README_NONGITHUB.md'
- name: github / commit & push
continue-on-error: true
if: steps.github-readme.outcome == 'success' && hashFiles('README.md') != ''
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md
if [ -f compose.yaml ]; then
git add compose.yaml
fi
if [ -f LICENSE ]; then
git add LICENSE
fi
git commit -m "github-actions[bot]: update README.md"
git push origin HEAD:master
# REPOSITORY SETTINGS
- name: github / update description and set repo defaults
run: |
curl --request PATCH \
@@ -275,7 +429,7 @@ jobs:
--header 'authorization: Bearer ${{ secrets.REPOSITORY_TOKEN }}' \
--header 'content-type: application/json' \
--data '{
"description":"${{ env.json_readme_description }}",
"description":"${{ env.DOCKER_IMAGE_DESCRIPTION }}",
"homepage":"",
"has_issues":true,
"has_discussions":true,

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" }'

View File

@@ -6,20 +6,60 @@ on:
jobs:
docker:
runs-on: ubuntu-latest
steps:
steps:
- name: init / base64 nested json
uses: actions/github-script@62c3794a3eb6788d9a2a72b219504732c0c9a298
with:
script: |
const { Buffer } = require('node:buffer');
(async()=>{
try{
const master = await fetch('https://raw.githubusercontent.com/11notes/docker-kms/refs/heads/master/.json');
const dot = await master.json();
const etc = {
version:dot.semver.version,
};
core.exportVariable('WORKFLOW_BASE64JSON', Buffer.from(JSON.stringify(etc)).toString('base64'));
}catch(e){
core.setFailed(`workflow failed: ${e}`);
}
})();
- name: build docker image
uses: the-actions-org/workflow-dispatch@3133c5d135c7dbe4be4f9793872b6ef331b53bc7
with:
workflow: docker.yml
token: "${{ secrets.REPOSITORY_TOKEN }}"
inputs: '{ "release":"true", "readme":"true" }'
inputs: '{ "release":"true", "readme":"true", "etc":"${{ env.WORKFLOW_BASE64JSON }}" }'
docker-unraid:
runs-on: ubuntu-latest
steps:
steps:
- name: init / base64 nested json
uses: actions/github-script@62c3794a3eb6788d9a2a72b219504732c0c9a298
with:
script: |
const { Buffer } = require('node:buffer');
(async()=>{
try{
const master = await fetch('https://raw.githubusercontent.com/11notes/docker-kms/refs/heads/master/.json');
const dot = await master.json();
const etc = {
version:dot.semver.version,
semversuffix:"unraid",
uid:99,
gid:100,
};
core.exportVariable('WORKFLOW_BASE64JSON', Buffer.from(JSON.stringify(etc)).toString('base64'));
}catch(e){
core.setFailed(`workflow failed: ${e}`);
}
})();
- name: build docker image for unraid community
uses: the-actions-org/workflow-dispatch@3133c5d135c7dbe4be4f9793872b6ef331b53bc7
with:
wait-for-completion: false
workflow: docker.yml
token: "${{ secrets.REPOSITORY_TOKEN }}"
inputs: '{ "release":"false", "readme":"false", "uid":"99", "gid":"100", "semversuffix":"unraid", "run-name":"docker-unraid" }'
inputs: '{ "release":"false", "readme":"false", "run-name":"unraid", "etc":"${{ env.WORKFLOW_BASE64JSON }}" }'

12
.json
View File

@@ -2,21 +2,15 @@
"image":"11notes/kms-gui",
"name":"kms-gui",
"root":"/kms",
"arch":"linux/amd64,linux/arm64,linux/arm/v7",
"semver":{
"version":"465f4d1",
"stable":"465f4d1",
"latest":"465f4d1"
},
"readme":{
"description":"Activate any version of Windows and Office, forever",
"parent":{
"image":"11notes/kms:465f4d1"
"image":"11notes/kms"
},
"built":{
"py-kms":"https://github.com/Py-KMS-Organization/py-kms",
"CustomIcon/pykms-frontend":"https://github.com/CustomIcon/pykms-frontend"
"11notes/fork-pykms-frontend":"https://github.com/11notes/fork-pykms-frontend"
}
}
}

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 11notes
Copyright (c) 2025 11notes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,24 +1,11 @@
![banner](https://github.com/11notes/defaults/blob/main/static/img/banner.png?raw=true)
# ⛰️ kms-gui
[<img src="https://img.shields.io/badge/github-source-blue?logo=github&color=040308">](https://github.com/11notes/docker-kms-gui)![size](https://img.shields.io/docker/image-size/11notes/kms-gui/465f4d1?color=0eb305)![version](https://img.shields.io/docker/v/11notes/kms-gui/465f4d1?color=eb7a09)![pulls](https://img.shields.io/docker/pulls/11notes/kms-gui?color=2b75d6)[<img src="https://img.shields.io/github/issues/11notes/docker-kms-gui?color=7842f5">](https://github.com/11notes/docker-kms-gui/issues)
# KMS-GUI
[<img src="https://img.shields.io/badge/github-source-blue?logo=github&color=040308">](https://github.com/11notes/docker-KMS-GUI)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![size](https://img.shields.io/docker/image-size/11notes/kms-gui/1.0.1?color=0eb305)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![version](https://img.shields.io/docker/v/11notes/kms-gui/1.0.1?color=eb7a09)![5px](https://github.com/11notes/defaults/blob/main/static/img/transparent5x2px.png?raw=true)![pulls](https://img.shields.io/docker/pulls/11notes/kms-gui?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-KMS-GUI?color=7842f5">](https://github.com/11notes/docker-KMS-GUI/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==)
Activate any version of Windows and Office, forever
# MAIN TAGS 🏷️
These are the main tags for the image. There is also a tag for each commit and its shorthand sha256 value.
* [465f4d1](https://hub.docker.com/r/11notes/kms-gui/tags?name=465f4d1)
* [stable](https://hub.docker.com/r/11notes/kms-gui/tags?name=stable)
* [latest](https://hub.docker.com/r/11notes/kms-gui/tags?name=latest)
* [465f4d1-unraid](https://hub.docker.com/r/11notes/kms-gui/tags?name=465f4d1-unraid)
* [stable-unraid](https://hub.docker.com/r/11notes/kms-gui/tags?name=stable-unraid)
* [latest-unraid](https://hub.docker.com/r/11notes/kms-gui/tags?name=latest-unraid)
# UNRAID VERSION 🟠
This image supports unraid by default. Simply add **-unraid** to any tag and the image will run as 99:100 instead of 1000:1000 causing no issues on unraid. Enjoy.
![Web GUI](https://github.com/11notes/docker-kms-gui/blob/master/img/webGUICustomIcon.png?raw=true)
![Web GUI](https://github.com/11notes/docker-KMS-GUI/blob/master/img/webGUICustomIcon.png?raw=true)
# SYNOPSIS 📖
**What can I do with this?** This image will run a web GUI for your [11notes/kms](https://hub.docker.com/r/11notes/kms) server.
@@ -27,26 +14,30 @@ This image supports unraid by default. Simply add **-unraid** to any tag and the
```yaml
name: "kms"
services:
kms:
image: "11notes/kms:stable"
container_name: "kms"
app:
image: "11notes/kms:1.0.0"
environment:
TZ: Europe/Zurich
TZ: "Europe/Zurich"
volumes:
- "var:/kms/var"
ports:
- "1688:1688/tcp"
restart: always
kms-gui:
image: "11notes/kms-gui:465f4d1"
container_name: "kms-gui"
restart: "always"
gui:
image: "11notes/kms-gui:1.0.0"
depends_on:
app:
condition: "service_healthy"
restart: true
environment:
TZ: Europe/Zurich
TZ: "Europe/Zurich"
volumes:
- "var:/kms/var"
ports:
- "8080:8080/tcp"
restart: always
- "3000:3000/tcp"
restart: "always"
volumes:
var:
```
@@ -66,27 +57,43 @@ volumes:
| `DEBUG` | Will activate debug option for container image and app (if available) | |
| `KMS_GUI_STYLE` | switch the UI style of the webinterface (py-kms, custom-icon) | custom-icon |
# MAIN TAGS 🏷️
These are the main tags for the image. There is also a tag for each commit and its shorthand sha256 value.
* [1.0.1](https://hub.docker.com/r/11notes/kms-gui/tags?name=1.0.1)
* [1.0.1-unraid](https://hub.docker.com/r/11notes/kms-gui/tags?name=1.0.1-unraid)
### There is no latest tag, what am I supposed to do about updates?
It is of my opinion that the ```:latest``` tag is super dangerous. Many times, Ive introduced **breaking** changes to my images. This would have messed up everything for some people. If you dont want to change the tag to the latest [semver](https://semver.org/), simply use the short versions of [semver](https://semver.org/). Instead of using ```:1.0.1``` you can use ```:1``` or ```:1.0```. Since on each new version these tags are updated to the latest version of the software, using them is identical to using ```:latest``` but at least fixed to a major or minor version.
If you still insist on having the bleeding edge release of this app, simply use the ```:rolling``` tag, but be warned! You will get the latest version of the app instantly, regardless of breaking changes or security issues or what so ever. You do this at your own risk!
# REGISTRIES ☁️
```
docker pull 11notes/kms-gui:1.0.1
docker pull ghcr.io/11notes/kms-gui:1.0.1
docker pull quay.io/11notes/kms-gui:1.0.1
```
# UNRAID VERSION 🟠
This image supports unraid by default. Simply add **-unraid** to any tag and the image will run as 99:100 instead of 1000:1000 causing no issues on unraid. Enjoy.
# SOURCE 💾
* [11notes/kms-gui](https://github.com/11notes/docker-kms-gui)
* [11notes/kms-gui](https://github.com/11notes/docker-KMS-GUI)
# PARENT IMAGE 🏛️
* [11notes/kms:465f4d1](https://hub.docker.com/r/11notes/kms)
* [11notes/kms:1.0.1](https://hub.docker.com/r/11notes/kms)
# BUILT WITH 🧰
* [py-kms](https://github.com/Py-KMS-Organization/py-kms)
* [CustomIcon/pykms-frontend](https://github.com/CustomIcon/pykms-frontend)
* [11notes/fork-pykms-frontend](https://github.com/11notes/fork-pykms-frontend)
* [11notes/util](https://github.com/11notes/docker-util)
# GENERAL TIPS 📌
* Use a reverse proxy like Traefik, Nginx, HAproxy to terminate TLS and to protect your endpoints
* Use Lets Encrypt DNS-01 challenge to obtain valid SSL certificates for your services
# SECURITY VULNERABILITIES REPORT ⚡
| Severity | Package | Version | Fix Version | Type | Location | Data Namespace | Link |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 4.7 (Medium) | linux-pam | 1.6.1-r1 | | apk | /lib/apk/db/installed | nvd:cpe | [CVE-2024-10041](https://nvd.nist.gov/vuln/detail/CVE-2024-10041) |
> [!TIP]
>* Use a reverse proxy like Traefik, Nginx, HAproxy to terminate TLS and to protect your endpoints
>* Use Lets Encrypt DNS-01 challenge to obtain valid SSL certificates for your services
# 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-kms-gui/releases) for breaking changes. If you have any problems with using this image simply raise an [issue](https://github.com/11notes/docker-kms-gui/issues), thanks. If you have a question or inputs please create a new [discussion](https://github.com/11notes/docker-kms-gui/discussions) instead of an issue. You can find all my other repositories on [github](https://github.com/11notes?tab=repositories).
*created Thu, 20 Feb 2025 05:57:37 GMT*
*created 20.05.2025, 15:26:00 (CET)*

View File

@@ -1,16 +1,20 @@
ARG APP_VERSION=stable
ARG APP_VERSION_PREFIX=""
ARG APP_VERSION_SUFFIX=""
ARG APP_PREFIX=""
ARG APP_SUFFIX=""
ARG APP_UID=1000
ARG APP_GID=1000
ARG BUILD_ROOT=/git/fork-pykms-frontend
# :: Build / styles
FROM alpine/git AS styles
ARG APP_NO_CACHE
ARG BUILD_ROOT
RUN set -ex; \
git clone https://github.com/11notes/pykms-frontend.git; \
cd /git/pykms-frontend; \
git reset --hard 9785b65;
git clone https://github.com/11notes/fork-pykms-frontend.git; \
cd ${BUILD_ROOT};
# :: Header
FROM 11notes/kms:${APP_VERSION_PREFIX}${APP_VERSION}${APP_VERSION_SUFFIX}
FROM 11notes/kms:${APP_PREFIX}${APP_VERSION}${APP_SUFFIX}
# :: arguments
ARG TARGETARCH
@@ -20,6 +24,14 @@ ARG APP_VERSION_SUFFIX=""
ARG APP_ROOT
ARG APP_UID
ARG APP_GID
ARG APP_NO_CACHE
ARG BUILD_ROOT
# :: python image
ARG PIP_ROOT_USER_ACTION=ignore
ARG PIP_BREAK_SYSTEM_PACKAGES=1
ARG PIP_DISABLE_PIP_VERSION_CHECK=1
ARG PIP_NO_CACHE_DIR=1
# :: environment
ENV APP_IMAGE=${APP_IMAGE}
@@ -32,7 +44,7 @@ ARG APP_VERSION_SUFFIX=""
ENV PYKMS_SQLITE_DB_PATH=/kms/var/kms.db
ENV PYKMS_LICENSE_PATH=/opt/py-kms/LICENSE
ENV PYKMS_VERSION_PATH=/opt/py-kms/VERSION
ENV PORT=8080
ENV PORT=3000
ENV LOG_LEVEL=INFO
# :: multi-stage
@@ -52,8 +64,10 @@ ARG APP_VERSION_SUFFIX=""
cd /opt/py-kms; \
echo "${APP_VERSION}" > VERSION; \
echo "master" >> VERSION; \
pip3 install --no-cache-dir -r /opt/py-kms/requirements.gui.txt --break-system-packages; \
apk del --no-network .build;
pip3 install -r /opt/py-kms/requirements.gui.txt; \
pip3 list -o | sed 's/pip.*//' | grep . | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U; \
apk del --no-network .build; \
rm -rf /usr/lib/python3.12/site-packages/pip;
# :: copy filesystem changes
COPY ./rootfs /
@@ -67,8 +81,8 @@ ARG APP_VERSION_SUFFIX=""
rm -rf /opt/py-kms/templates; \
rm -rf /opt/py-kms/static;
COPY --from=styles /git/pykms-frontend/templates ${APP_ROOT}/styles/custom-icon/templates
COPY --from=styles /git/pykms-frontend/static ${APP_ROOT}/styles/custom-icon/static
COPY --from=styles ${BUILD_ROOT}/templates ${APP_ROOT}/styles/custom-icon/templates
COPY --from=styles ${BUILD_ROOT}/static ${APP_ROOT}/styles/custom-icon/static
# :: set correct permissions
RUN set -ex; \
@@ -81,4 +95,4 @@ ARG APP_VERSION_SUFFIX=""
HEALTHCHECK --interval=5s --timeout=2s CMD curl -X GET -kILs --fail http://localhost:${PORT}/livez || exit 1
# :: Start
USER docker
USER ${APP_UID}:${APP_GID}

View File

@@ -1,24 +1,28 @@
name: "kms"
services:
kms:
image: "11notes/kms:stable"
container_name: "kms"
app:
image: "11notes/kms:1.0.0"
environment:
TZ: Europe/Zurich
TZ: "Europe/Zurich"
volumes:
- "var:/kms/var"
ports:
- "1688:1688/tcp"
restart: always
kms-gui:
image: "11notes/kms-gui:465f4d1"
container_name: "kms-gui"
restart: "always"
gui:
image: "11notes/kms-gui:1.0.0"
depends_on:
app:
condition: "service_healthy"
restart: true
environment:
TZ: Europe/Zurich
TZ: "Europe/Zurich"
volumes:
- "var:/kms/var"
ports:
- "8080:8080/tcp"
restart: always
- "3000:3000/tcp"
restart: "always"
volumes:
var:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB