mirror of
https://github.com/11notes/docker-kms-gui.git
synced 2025-11-03 04:33:13 +00:00
Compare commits
58 Commits
v1.1.3
...
d5c15bb795
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5c15bb795 | ||
|
|
20d185b9cf | ||
|
|
4969a99521 | ||
|
|
dff61f79cc | ||
|
|
f2bd5a0ab5 | ||
|
|
4e4dd509dc | ||
|
|
db9df9ea0e | ||
|
|
599ba8c980 | ||
|
|
fa5238dab7 | ||
|
|
83708d3c58 | ||
|
|
b8f0cdb975 | ||
|
|
b07ff70477 | ||
|
|
7c274600f4 | ||
|
|
8ff275bb7a | ||
|
|
6fd38bbd74 | ||
|
|
d4cf5e9f24 | ||
|
|
d094fe1357 | ||
|
|
ab655ef97c | ||
|
|
915cc5bcdc | ||
|
|
f90bd43a16 | ||
|
|
3a98954378 | ||
|
|
9a990477d8 | ||
|
|
63b38064e4 | ||
|
|
b17c50ef99 | ||
|
|
131f719f0d | ||
|
|
7f1f8b4096 | ||
|
|
c16f825747 | ||
|
|
6022fb0269 | ||
|
|
73f27eb071 | ||
|
|
dbcb40d456 | ||
|
|
02a2d538c8 | ||
|
|
779e562963 | ||
|
|
543c345d80 | ||
|
|
d1ac93f4b5 | ||
|
|
405a874533 | ||
|
|
b45314d58f | ||
|
|
2f59f8c6e2 | ||
|
|
03f63033c5 | ||
|
|
15d93c9643 | ||
|
|
7637bf2c3d | ||
|
|
145c6a1d82 | ||
|
|
4221216db4 | ||
|
|
95fbe08011 | ||
|
|
e34127b4c7 | ||
|
|
75a3d5d474 | ||
|
|
24a59b471e | ||
|
|
bf755ecf0d | ||
|
|
2ef047319a | ||
|
|
d608769727 | ||
|
|
72d8d9c55c | ||
|
|
d20153c545 | ||
|
|
ce91a1f421 | ||
|
|
dbce137fb8 | ||
|
|
4aed569709 | ||
|
|
8b1457602d | ||
|
|
847ff77077 | ||
|
|
cfbf6347c2 | ||
|
|
971ba4ffe4 |
454
.github/workflows/docker.yml
vendored
454
.github/workflows/docker.yml
vendored
@@ -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
16
.github/workflows/readme.yml
vendored
Normal 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" }'
|
||||
48
.github/workflows/tags.yml
vendored
48
.github/workflows/tags.yml
vendored
@@ -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
12
.json
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
87
README.md
87
README.md
@@ -1,24 +1,11 @@
|
||||

|
||||
|
||||
# ⛰️ kms-gui
|
||||
[<img src="https://img.shields.io/badge/github-source-blue?logo=github&color=040308">](https://github.com/11notes/docker-kms-gui)[<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)[<img src="https://img.shields.io/github/issues/11notes/docker-KMS-GUI?color=7842f5">](https://github.com/11notes/docker-KMS-GUI/issues)
|
||||
|
||||
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.
|
||||
|
||||

|
||||

|
||||
|
||||
# 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, I’ve introduced **breaking** changes to my images. This would have messed up everything for some people. If you don’t 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 Let’s 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 Let’s 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)*
|
||||
@@ -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}
|
||||
26
compose.yaml
26
compose.yaml
@@ -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 |
Reference in New Issue
Block a user