Namespace
wekanteam
Image / Tag
wekan:v12.25
Content Digest
sha256:62ccbac566770775d64975425c07482935752898f98b07b37e38fd4bf89e194b
Details
Created

2026-10-08 16:16:02 UTC

Size

321 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:ace453750484672581012d135658fd142a37f3cc1464965baca36cee819b3d13 - 15.13% (48.5 MB)

[#001] sha256:70b8c978b6d4565c33bd4bd5ce2bc5a68b71a0911d4f941fdb5ba5aec6a2e434 - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:4be3dae7e5b4a419373a68076a21e896e37a482f86b7fc2c54b16bc74beac76b - 84.84% (272 MB)

[#012] sha256:5d548e3f9575ada8bea02bc1dd096451ce4a58025200b47ba9c091bfcad082c6 - 0.0% (6.13 KB)

[#013] sha256:30873de9dbdbfa81ca9e3e19e48f7ecacd819ac8a27333b2f711ce278d6e50c6 - 0.0% (3.7 KB)

[#014] sha256:a0ba8a1cd63e2b5c320ae0d7267829e8295fdde5d5c07d55f2bd94142e957a3b - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'i386' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=386

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:16:01 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=386 TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:16:02 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:15:04 UTC

Size

325 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 - 14.51% (47.1 MB)

[#001] sha256:4bdd6443d7b3dd364ddeb8c25d92016aedcbf85184581734626667b9a0e62eec - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:fd644c2a13bf3fa5a2224c219b63db710a4141ca6ec1ac463834177f453c2347 - 85.45% (277 MB)

[#012] sha256:31a18428360d3ce265827566622afe917480046cdc6abb75f5b63a32da3cc71d - 0.0% (6.13 KB)

[#013] sha256:a0d4f8b58fed40f87a30bdbe3101331b4ddc05359c89993109c963492a08b144 - 0.0% (3.7 KB)

[#014] sha256:54c9971323952ec86734ff2cb0ed532f101178670558023c91265111da09aa35 - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'amd64' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=amd64

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:15:03 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=amd64 TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:15:04 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:34:40 UTC

Size

310 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:b2e7b40559933644a31714a37346ff1796717d607ea763ad445b388befffd0bb - 14.12% (43.7 MB)

[#001] sha256:4bdd6443d7b3dd364ddeb8c25d92016aedcbf85184581734626667b9a0e62eec - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:587ef655be4b1dd93fa61d6fb622585772d7a15e97e884f28f41e6ecd53d1558 - 85.85% (266 MB)

[#012] sha256:e379eadb60ea3bfceeba40b76b3c8f58a4a18e401152ef3270264c75b318dc2d - 0.0% (6.13 KB)

[#013] sha256:d434ca18d44cb5423d7f00183f51288993fb0198e440340e43a45e0a156d85d5 - 0.0% (3.7 KB)

[#014] sha256:f0568fb63db7b4c9363f9a88cea324879954e2439360f90eb78daedd56176c0a - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'armhf' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=arm

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=v7

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:34:39 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=arm TARGETVARIANT=v7 VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:34:40 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:35:38 UTC

Size

323 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:df9831efb49cab24dec437e8482f2a9ddbd9e239131fa3ffe095dc1492081e1d - 14.7% (47.5 MB)

[#001] sha256:70b8c978b6d4565c33bd4bd5ce2bc5a68b71a0911d4f941fdb5ba5aec6a2e434 - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:43decda018fad393c8fd0accf8be2bc4bfcac11b6932011a7968a4f1a9901e9e - 85.27% (275 MB)

[#012] sha256:2c937133315802e36f4116b49de4265eeb607e2d47c0c6958104a1c2481cb6df - 0.0% (6.13 KB)

[#013] sha256:140fd83aeb11300aa84cfd4688b4fc2cb932639740c4d754e52af6861daba5d2 - 0.0% (3.7 KB)

[#014] sha256:f7dd72aad84f7193bcd4a125278f52b0294bc0c7ed30044f592d3e7c066cb4b2 - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'arm64' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=arm64

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=arm64 TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:35:38 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:35:15 UTC

Size

331 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:1216778738c2d0f00bc38a90447aff403e59888e07d78e8b1c4f2dde2aa2eded - 15.34% (50.7 MB)

[#001] sha256:70b8c978b6d4565c33bd4bd5ce2bc5a68b71a0911d4f941fdb5ba5aec6a2e434 - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:bb762946fb3dda409625673d1b1b18826e24cd047540f5e7b451e71b79db6dc0 - 84.63% (280 MB)

[#012] sha256:6245c4a8839bba9d26b978d3029aee17ee6d20b96b7c03f1ef61f4684eb74469 - 0.0% (6.13 KB)

[#013] sha256:9c2360563ad5730fd4bcdcfe30a8698668e0872d58a5bb533edc6036b401fab7 - 0.0% (3.7 KB)

[#014] sha256:9253b8ae3782f32a2349434a23c96836e29d767e5e80c47c0f4854c2c6c52ac7 - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'ppc64el' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=ppc64le

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=ppc64le TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:35:15 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:36:16 UTC

Size

320 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:45e9f88af4f41939baf397baad507403b0b2ad7362c860679e184bbd563c9aca - 14.26% (45.7 MB)

[#001] sha256:4bdd6443d7b3dd364ddeb8c25d92016aedcbf85184581734626667b9a0e62eec - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:d9ce9797228d39629dd258c9acf79e4ad5b8def51defa791711b3722a25413c6 - 85.71% (274 MB)

[#012] sha256:4df6c15532c38f82f5b9fd71cb6ec18a44ce6dd1e16ed192801d31a46523b44d - 0.0% (6.13 KB)

[#013] sha256:0a70e2aef0423415b66a8e1853806fd876f335cbdc8d235bb81f897d6dc3f01a - 0.0% (3.7 KB)

[#014] sha256:947dd4d188b909353c557e9c07aa6c0c6c235f70544ccb51990a85712d338baa - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 'riscv64' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=riscv64

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=riscv64 TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:36:16 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Details
Created

2026-10-08 16:36:12 UTC

Size

330 MB

Content Digest
Labels
  • maintainer
    wekan
  • org.opencontainers.image.ref.name
    debian
  • org.opencontainers.image.source
    https://github.com/wekan/wekan
  • org.opencontainers.image.version
    trixie

Environment
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS

90

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE

3

ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD

60

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE

3

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW

15

ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD

60

ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM

ATTACHMENTS_UPLOAD_MAX_SIZE

0

ATTACHMENTS_UPLOAD_MIME_TYPES

AVATARS_UPLOAD_EXTERNAL_PROGRAM

AVATARS_UPLOAD_MAX_SIZE

72000

AVATARS_UPLOAD_MIME_TYPES

BIGEVENTS_PATTERN

NONE

BROWSER_POLICY_ENABLED

true

BUILD_DEPS

apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

CARD_OPENED_WEBHOOK_ENABLED

false

CAS_BASE_URL

CAS_ENABLED

false

CAS_LOGIN_URL

CAS_MERGE_EXISTING_USERS

CAS_VALIDATE_URL

CORS

CORS_ALLOW_HEADERS

CORS_EXPOSE_HEADERS

DDP_TRANSPORT

sockjs

DEBUG

false

DEFAULT_AUTHENTICATION_METHOD

DEFAULT_AVATAR_URL

DEFAULT_BOARD_ID

EMAIL_NOTIFICATION_TIMEOUT

30000

HEADER_LOGIN_EMAIL

HEADER_LOGIN_FIRSTNAME

HEADER_LOGIN_ID

HEADER_LOGIN_LASTNAME

HEADER_LOGIN_TRUSTED_IPS

HEADER_LOGIN_TRUSTED_PROXIES

IMAGE_COMPRESS_RATIO

LDAP_AD_SIMPLE_AUTH

LDAP_AUTHENTIFICATION

false

LDAP_AUTHENTIFICATION_PASSWORD

LDAP_AUTHENTIFICATION_PASSWORD_FILE

LDAP_AUTHENTIFICATION_USERDN

LDAP_BACKGROUND_SYNC

false

LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS

false

LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS

false

LDAP_BACKGROUND_SYNC_INTERVAL

LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED

false

LDAP_BASEDN

LDAP_CA_CERT

LDAP_CONNECT_TIMEOUT

10000

LDAP_DEFAULT_DOMAIN

LDAP_EMAIL_FIELD

LDAP_EMAIL_MATCH_ENABLE

false

LDAP_EMAIL_MATCH_REQUIRE

false

LDAP_EMAIL_MATCH_VERIFIED

false

LDAP_ENABLE

false

LDAP_ENCRYPTION

false

LDAP_FULLNAME_FIELD

LDAP_GROUP_BASEDN

LDAP_GROUP_FILTER_ENABLE

false

LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE

LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT

LDAP_GROUP_FILTER_GROUP_NAME

LDAP_GROUP_FILTER_NESTED

false

LDAP_GROUP_FILTER_OBJECTCLASS

LDAP_HOST

LDAP_IDLE_TIMEOUT

10000

LDAP_LOGIN_FALLBACK

false

LDAP_LOG_ENABLED

false

LDAP_MERGE_EXISTING_USERS

false

LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN

LDAP_PORT

389

LDAP_RECONNECT

true

LDAP_REJECT_UNAUTHORIZED

true

LDAP_SEARCH_PAGE_SIZE

0

LDAP_SEARCH_SIZE_LIMIT

0

LDAP_SYNC_ADMIN_GROUPS

LDAP_SYNC_ADMIN_STATUS

LDAP_SYNC_GROUP_ROLES

LDAP_SYNC_ORGANIZATIONS

false

LDAP_SYNC_ORGANIZATIONS_GROUPS

LDAP_SYNC_TEAMS

false

LDAP_SYNC_TEAMS_GROUPS

LDAP_SYNC_USER_DATA

false

LDAP_SYNC_USER_DATA_FIELDMAP

LDAP_TIMEOUT

10000

LDAP_UNIQUE_IDENTIFIER_FIELD

LDAP_USERNAME_FIELD

LDAP_USER_ATTRIBUTES

LDAP_USER_AUTHENTICATION

false

LDAP_USER_AUTHENTICATION_FIELD

uid

LDAP_USER_SEARCH_FIELD

LDAP_USER_SEARCH_FILTER

LDAP_USER_SEARCH_SCOPE

LDAP_UTF8_NAMES_SLUGIFY

true

LOGOUT_IN

LOGOUT_ON_HOURS

LOGOUT_ON_MINUTES

LOGOUT_WITH_TIMER

false

MAIL_URL_FILE

MATOMO_ADDRESS

MATOMO_DO_NOT_TRACK

true

MATOMO_SITE_ID

MATOMO_WITH_USERNAME

false

MAX_IMAGE_PIXEL

METEOR_RELEASE

METEOR@3.6-beta.3

METRICS_ALLOWED_IP_ADDRESSES

MONGO_OPLOG_URL

MONGO_URL_FILE

NODE_VERSION

v26.11.1

NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE

NOTIFY_DUE_AT_HOUR_OF_DAY

NOTIFY_DUE_DAYS_BEFORE_AND_AFTER

NOTIFY_ON_ASSIGN

true

NPM_VERSION

12.2.0

OAUTH2_ADFS_ENABLED

false

OAUTH2_ADMIN_GROUPS

OAUTH2_ALLOWED_EMAIL_DOMAINS

OAUTH2_AUTH_ENDPOINT

OAUTH2_AUTO_REGISTRATION

true

OAUTH2_AVATAR_MAP

OAUTH2_B2C_ENABLED

false

OAUTH2_CA_CERT

OAUTH2_CLIENT_ID

OAUTH2_DEFAULT_ORGANIZATION

OAUTH2_EMAIL_MAP

OAUTH2_ENABLED

false

OAUTH2_FULLNAME_MAP

OAUTH2_ID_MAP

OAUTH2_ID_TOKEN_WHITELIST_FIELDS

OAUTH2_LOGIN_STYLE

redirect

OAUTH2_LOGOUT_ENDPOINT

OAUTH2_MERGE_EXISTING_USERS

OAUTH2_REQUEST_PERMISSIONS

openid profile email

OAUTH2_SECRET

OAUTH2_SECRET_FILE

OAUTH2_SECRET_JWT_AUDIENCE

OAUTH2_SECRET_JWT_EXPIRES_IN

OAUTH2_SECRET_JWT_ISSUER

OAUTH2_SECRET_JWT_KEY_ID

OAUTH2_SECRET_JWT_KEY_PATH

OAUTH2_SECRET_JWT_SUBJECT

OAUTH2_SERVER_URL

OAUTH2_TOKEN_ENDPOINT

OAUTH2_USERINFO_ENDPOINT

OAUTH2_USERNAME_MAP

OAUTH_FACEBOOK_APP_ID

OAUTH_FACEBOOK_ENABLED

false

OAUTH_FACEBOOK_SECRET

OAUTH_FACEBOOK_SECRET_FILE

OAUTH_GITHUB_CLIENT_ID

OAUTH_GITHUB_ENABLED

false

OAUTH_GITHUB_SECRET

OAUTH_GITHUB_SECRET_FILE

OAUTH_GOOGLE_CLIENT_ID

OAUTH_GOOGLE_ENABLED

false

OAUTH_GOOGLE_SECRET

OAUTH_GOOGLE_SECRET_FILE

OAUTH_MEETUP_CLIENT_ID

OAUTH_MEETUP_ENABLED

false

OAUTH_MEETUP_SECRET

OAUTH_MEETUP_SECRET_FILE

OAUTH_METEOR_DEVELOPER_CLIENT_ID

OAUTH_METEOR_DEVELOPER_ENABLED

false

OAUTH_METEOR_DEVELOPER_SECRET

OAUTH_METEOR_DEVELOPER_SECRET_FILE

OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS

OAUTH_PROVIDERS_LOGIN_STYLE

redirect

OAUTH_PROVIDERS_MERGE_EXISTING_USERS

false

OAUTH_TWITTER_CONSUMER_KEY

OAUTH_TWITTER_ENABLED

false

OAUTH_TWITTER_SECRET

OAUTH_TWITTER_SECRET_FILE

OAUTH_WEIBO_CLIENT_ID

OAUTH_WEIBO_ENABLED

false

OAUTH_WEIBO_SECRET

OAUTH_WEIBO_SECRET_FILE

OIDC_REDIRECTION_ENABLED

false

ORACLE_OIM_ENABLED

false

PASSWORDLESS_ENABLED

false

PASSWORD_LOGIN_ENABLED

true

PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

PORT

8080

PROPAGATE_OIDC_DATA

RESULTS_PER_PAGE

S3

S3_SECRET_KEY_FILE

SAML_ATTRIBUTES

SAML_CERT

SAML_ENABLED

false

SAML_ENTRYPOINT

SAML_IDENTIFIER_FORMAT

SAML_IDPSLO_REDIRECTURL

SAML_IDP_PROFILE

SAML_ISSUER

SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE

SAML_LOGIN_FLOW

SAML_MERGE_EXISTING_USERS

false

SAML_PRIVATE_KEYFILE

SAML_PROVIDER

SAML_PUBLIC_CERTFILE

SAML_WANT_ASSERTIONS_SIGNED

SAML_WANT_RESPONSE_SIGNED

SRC_PATH

./

TRUSTED_URL

USE_EDGE

false

WAIT_SPINNER

WEBHOOKS_ATTRIBUTES

WITH_API

true

WRITABLE_PATH

/data


Layers

[#000] sha256:e171de089919cf9725221bfd863a1283919b0c9a94568de0bbce5db73d2ddff0 - 14.29% (47.2 MB)

[#001] sha256:70b8c978b6d4565c33bd4bd5ce2bc5a68b71a0911d4f941fdb5ba5aec6a2e434 - 0.0% (4.93 KB)

[#002] sha256:f049fd3f0d4a0ad7fe0d1dd05a8ac4283e12923fc53ba100e9fad0cfa9c0a3c6 - 0.0% (2.15 KB)

[#003] sha256:e38f8684c822fe64cb4edafed726cf7267b995ded9ba4ee44668afa429356faf - 0.0% (3.44 KB)

[#004] sha256:e3b03601a1ca97649814347af0b9dbb9268d6e4cd44b3393d80906338a65f9ba - 0.02% (64.8 KB)

[#005] sha256:e8ac37ae2563c96502934cdf1fd3b01434e8c15f2456903ee1ad11fd643a301b - 0.0% (1.82 KB)

[#006] sha256:3d29314e4e6ccd232b06c1bbfae45b8c96c2cb23ee5c05b7b0492cbf1586aec2 - 0.0% (2.13 KB)

[#007] sha256:6e311ce1f9294e19703f7acd273e7f2431a509f166e75cfa76b36227a6356e1b - 0.0% (3.62 KB)

[#008] sha256:1e668b870b6d497c4fbeb2be8a061597970a7ac70811766e330ce4bdb0df4bb8 - 0.0% (1.45 KB)

[#009] sha256:445f0062470d3b318cab77987e9db84254f8be772387c078f92632315d4bd4ae - 0.0% (6.07 KB)

[#010] sha256:d05814f9f3f1a38076f138bc323478fa9df0d08d7d5462cb09ab07665c8d9dea - 0.0% (4.74 KB)

[#011] sha256:222520125519e7063b6f014b3ae333f97fb9b024ddb94dd8deef95baa00fa890 - 85.68% (283 MB)

[#012] sha256:028b467f7b49b6bdb7fb7b86f637dc924ffa63b0212aaf8bd7aa7d8ee49889ae - 0.0% (6.13 KB)

[#013] sha256:cef519700543b8585c006a6cb7ec53cf377b20bddc57ddebe1b9e9fc9c69ac12 - 0.0% (3.7 KB)

[#014] sha256:3fc9eacc618e55941f606067f8a2e7603ba911638c8a4b0bf10daad961b69f7e - 0.0% (2.32 KB)

[#015] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)


History
2026-10-05 00:00:00 UTC (debuerreotype 0.17)

# debian.sh --arch 's390x' out/ 'trixie' '@1791158400'

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL maintainer=wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.ref.name=debian

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.version=trixie

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

LABEL org.opencontainers.image.source=https://github.com/wekan/wekan

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETARCH=s390x

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG TARGETVARIANT=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG VERSION=12.25

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ARG DEBIAN_FRONTEND=noninteractive

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v26.11.1 METEOR_RELEASE=METEOR@3.6-beta.3 USE_EDGE=false NPM_VERSION=12.2.0 SRC_PATH=./ WITH_API=true MONGO_OPLOG_URL= RESULTS_PER_PAGE= DEFAULT_BOARD_ID= ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM= ATTACHMENTS_UPLOAD_MIME_TYPES= ATTACHMENTS_UPLOAD_MAX_SIZE=0 AVATARS_UPLOAD_EXTERNAL_PROGRAM= AVATARS_UPLOAD_MIME_TYPES= AVATARS_UPLOAD_MAX_SIZE=72000 DEFAULT_AVATAR_URL= CARD_OPENED_WEBHOOK_ENABLED=false MAX_IMAGE_PIXEL= IMAGE_COMPRESS_RATIO= NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE= BIGEVENTS_PATTERN=NONE NOTIFY_ON_ASSIGN=true NOTIFY_DUE_DAYS_BEFORE_AND_AFTER= NOTIFY_DUE_AT_HOUR_OF_DAY= EMAIL_NOTIFICATION_TIMEOUT=30000 MATOMO_ADDRESS= MATOMO_SITE_ID= MATOMO_DO_NOT_TRACK=true MATOMO_WITH_USERNAME=false METRICS_ALLOWED_IP_ADDRESSES= BROWSER_POLICY_ENABLED=true TRUSTED_URL= WEBHOOKS_ATTRIBUTES= OAUTH2_ENABLED=false OIDC_REDIRECTION_ENABLED=false OAUTH2_CA_CERT= OAUTH2_ADFS_ENABLED=false OAUTH2_B2C_ENABLED=false OAUTH2_LOGIN_STYLE=redirect OAUTH2_CLIENT_ID= OAUTH2_SECRET= OAUTH2_SECRET_FILE= OAUTH2_SERVER_URL= OAUTH2_AUTH_ENDPOINT= OAUTH2_USERINFO_ENDPOINT= OAUTH2_TOKEN_ENDPOINT= OAUTH2_LOGOUT_ENDPOINT= OAUTH2_ID_MAP= OAUTH2_USERNAME_MAP= OAUTH2_AUTO_REGISTRATION=true OAUTH2_ADMIN_GROUPS= OAUTH2_FULLNAME_MAP= OAUTH2_ID_TOKEN_WHITELIST_FIELDS= OAUTH2_REQUEST_PERMISSIONS=openid profile email OAUTH2_EMAIL_MAP= LDAP_ENABLE=false LDAP_PORT=389 LDAP_HOST= LDAP_AD_SIMPLE_AUTH= LDAP_USER_AUTHENTICATION=false LDAP_USER_AUTHENTICATION_FIELD=uid LDAP_BASEDN= LDAP_LOGIN_FALLBACK=false LDAP_RECONNECT=true LDAP_TIMEOUT=10000 LDAP_IDLE_TIMEOUT=10000 LDAP_CONNECT_TIMEOUT=10000 LDAP_AUTHENTIFICATION=false LDAP_AUTHENTIFICATION_USERDN= LDAP_AUTHENTIFICATION_PASSWORD= LDAP_AUTHENTIFICATION_PASSWORD_FILE= LDAP_LOG_ENABLED=false LDAP_BACKGROUND_SYNC=false LDAP_BACKGROUND_SYNC_INTERVAL= LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false LDAP_ENCRYPTION=false LDAP_CA_CERT= LDAP_REJECT_UNAUTHORIZED=true LDAP_USER_SEARCH_FILTER= LDAP_USER_SEARCH_SCOPE= LDAP_USER_SEARCH_FIELD= LDAP_SEARCH_PAGE_SIZE=0 LDAP_SEARCH_SIZE_LIMIT=0 LDAP_GROUP_FILTER_ENABLE=false LDAP_GROUP_FILTER_OBJECTCLASS= LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE= LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT= LDAP_GROUP_FILTER_NESTED=false LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN= LDAP_USER_ATTRIBUTES= LDAP_GROUP_BASEDN= OAUTH2_AVATAR_MAP= OAUTH2_MERGE_EXISTING_USERS= OAUTH2_ALLOWED_EMAIL_DOMAINS= OAUTH2_DEFAULT_ORGANIZATION= PROPAGATE_OIDC_DATA= OAUTH2_SECRET_JWT_KEY_PATH= OAUTH2_SECRET_JWT_ISSUER= OAUTH2_SECRET_JWT_KEY_ID= OAUTH2_SECRET_JWT_AUDIENCE= OAUTH2_SECRET_JWT_SUBJECT= OAUTH2_SECRET_JWT_EXPIRES_IN= CAS_MERGE_EXISTING_USERS= LDAP_GROUP_FILTER_GROUP_NAME= LDAP_UNIQUE_IDENTIFIER_FIELD= LDAP_UTF8_NAMES_SLUGIFY=true LDAP_USERNAME_FIELD= LDAP_FULLNAME_FIELD= LDAP_MERGE_EXISTING_USERS=false LDAP_EMAIL_FIELD= LDAP_EMAIL_MATCH_ENABLE=false LDAP_EMAIL_MATCH_REQUIRE=false LDAP_EMAIL_MATCH_VERIFIED=false LDAP_SYNC_USER_DATA=false LDAP_SYNC_USER_DATA_FIELDMAP= LDAP_SYNC_GROUP_ROLES= LDAP_DEFAULT_DOMAIN= LDAP_SYNC_ADMIN_STATUS= LDAP_SYNC_ADMIN_GROUPS= LDAP_SYNC_ORGANIZATIONS=false LDAP_SYNC_ORGANIZATIONS_GROUPS= LDAP_SYNC_TEAMS=false LDAP_SYNC_TEAMS_GROUPS= HEADER_LOGIN_ID= HEADER_LOGIN_FIRSTNAME= HEADER_LOGIN_LASTNAME= HEADER_LOGIN_EMAIL= HEADER_LOGIN_TRUSTED_IPS= HEADER_LOGIN_TRUSTED_PROXIES= LOGOUT_WITH_TIMER=false LOGOUT_IN= LOGOUT_ON_HOURS= LOGOUT_ON_MINUTES= CORS= CORS_ALLOW_HEADERS= CORS_EXPOSE_HEADERS= DEFAULT_AUTHENTICATION_METHOD= PASSWORD_LOGIN_ENABLED=true CAS_ENABLED=false CAS_BASE_URL= CAS_LOGIN_URL= CAS_VALIDATE_URL= SAML_ENABLED=false SAML_PROVIDER= SAML_ENTRYPOINT= SAML_ISSUER= SAML_CERT= SAML_IDPSLO_REDIRECTURL= SAML_PRIVATE_KEYFILE= SAML_PUBLIC_CERTFILE= SAML_IDENTIFIER_FORMAT= SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE= SAML_ATTRIBUTES= SAML_MERGE_EXISTING_USERS=false SAML_IDP_PROFILE= SAML_WANT_RESPONSE_SIGNED= SAML_WANT_ASSERTIONS_SIGNED= SAML_LOGIN_FLOW= OAUTH_GOOGLE_ENABLED=false OAUTH_GOOGLE_CLIENT_ID= OAUTH_GOOGLE_SECRET= OAUTH_GOOGLE_SECRET_FILE= OAUTH_GITHUB_ENABLED=false OAUTH_GITHUB_CLIENT_ID= OAUTH_GITHUB_SECRET= OAUTH_GITHUB_SECRET_FILE= OAUTH_FACEBOOK_ENABLED=false OAUTH_FACEBOOK_APP_ID= OAUTH_FACEBOOK_SECRET= OAUTH_FACEBOOK_SECRET_FILE= OAUTH_TWITTER_ENABLED=false OAUTH_TWITTER_CONSUMER_KEY= OAUTH_TWITTER_SECRET= OAUTH_TWITTER_SECRET_FILE= OAUTH_METEOR_DEVELOPER_ENABLED=false OAUTH_METEOR_DEVELOPER_CLIENT_ID= OAUTH_METEOR_DEVELOPER_SECRET= OAUTH_METEOR_DEVELOPER_SECRET_FILE= OAUTH_WEIBO_ENABLED=false OAUTH_WEIBO_CLIENT_ID= OAUTH_WEIBO_SECRET= OAUTH_WEIBO_SECRET_FILE= OAUTH_MEETUP_ENABLED=false OAUTH_MEETUP_CLIENT_ID= OAUTH_MEETUP_SECRET= OAUTH_MEETUP_SECRET_FILE= OAUTH_PROVIDERS_LOGIN_STYLE=redirect OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS= PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_URL_FILE= MONGO_URL_FILE= S3_SECRET_KEY_FILE=

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/check-telemetry.py /tmp/check-telemetry.py # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY releases/risk-baseline.json /tmp/risk-baseline.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prepare-bundle-npm.mjs /tmp/prepare-bundle-npm.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit

2026-10-08 16:11:35 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

RUN |4 TARGETARCH=s390x TARGETVARIANT= VERSION=12.25 DEBIAN_FRONTEND=noninteractive /bin/sh -c set -o xtrace # Fail hard on any error so a missing release zip / failed download can never # produce a "successful" image with an empty /build (Cannot find /build/main.js). set -eo pipefail # Create Wekan user. --create-home is required because --system users do not # get a home directory by default; without it /home/wekan never exists and the # later `chown ... /home/wekan/` aborts the build (now that set -e is active). useradd --user-group --system --create-home --home-dir /home/wekan wekan # OS Updates apt-get update --assume-yes apt-get upgrade --assume-yes apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS} # Runtime MIME detection and Node.js atomic operations survive build cleanup. apt-get install --assume-yes --no-install-recommends file libatomic1 # Multi-arch mapping: Docker TARGETARCH -> WeKan's own platform name, which is # both the bundle .zip's name and what resolve-node-source.sh is asked about. # amd64/arm64 have MongoDB Community; ppc64le/s390x/riscv64 have no MongoDB # server and ship FerretDB v1 instead (the ferretdb binary is baked into their # .zip and started by wekan-entrypoint.sh). Debian's 32-bit ARM port is armhf # (ARMv7, VFPv3-D16), which is what linux/arm/v7 runs. case "${TARGETARCH}" in "amd64") WEKAN_ARCH="amd64" ;; "arm64") WEKAN_ARCH="arm64" ;; "ppc64le") WEKAN_ARCH="ppc64le" ;; "s390x") WEKAN_ARCH="s390x" ;; "riscv64") WEKAN_ARCH="riscv64" ;; "386") WEKAN_ARCH="i386" ;; # BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU # generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read # the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6 # board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's # ARMv7-A baseline and whose instructions that board cannot execute. "arm") case "${TARGETVARIANT}" in "v6") WEKAN_ARCH="armv6" ;; # v7, and an unset variant, are Debian's armhf port: ARMv7-A, # VFPv3-D16 hard-float. That is what linux/arm/v7 runs. "v7"|"") WEKAN_ARCH="armhf" ;; # v5 is armel: FerretDB and the MongoDB tools publish it (they are Go), # but Node.js does not exist for ARMv5 at all, so there is no bundle to # put in an image and refusing is the only honest answer. *) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;; esac ;; *) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;; esac # Node.js installation - official nodejs.org, then unofficial-builds.nodejs.org, # then wekan/node-patches, in that order, for EVERY architecture. # # The choice is made by releases/resolve-node-source.sh, copied in above and used # by the .zip bundles and the snap as well, so the image and the bundle of one # architecture always carry the same Node.js from the same place. It is asked # about the MAJOR, so a CPU whose newest build lags a release still gets its # newest: it answers with the exact file, what shape that file is, and the # SHA256 the source published for it. # # npm is arch-independent JavaScript, so it is grafted from the official amd64 # tarball of the version that was resolved - a build-time tool, not the shipped # node. (node-patches publishes a bare node binary and no npm at all, which is # why npm is fetched separately rather than taken from the archive above.) cd /tmp NODE_MAJOR="${NODE_VERSION#v}"; NODE_MAJOR="${NODE_MAJOR%%.*}" if ! NODE_META="$(bash /tmp/resolve-node-source.sh "${WEKAN_ARCH}" "${NODE_MAJOR}")"; then echo "No Node.js ${NODE_MAJOR}.x for ${WEKAN_ARCH} at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches, so this image cannot be built for it. Build node-${WEKAN_ARCH} in wekan/node-patches, or drop ${TARGETARCH} from the image's platform list." >&2 exit 1 fi eval "${NODE_META}" echo "Node.js ${node_full} for ${WEKAN_ARCH}: ${node_from} (${node_url})" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 -O node-download "${node_url}" echo "${node_sha256} node-download" | sha256sum -c - case "${node_kind}" in binary) cp node-download /usr/local/bin/node ;; tar.xz|tar.gz|tar) # bsdtar (libarchive-tools) is installed below for the bundle; plain tar # here, letting it detect the compression rather than naming it. tar -xf node-download --no-same-owner "${node_member}" cp "${node_member}" /usr/local/bin/node ;; *) echo "resolve-node-source.sh returned an unknown kind '${node_kind}'." >&2 exit 1 ;; esac chmod +x /usr/local/bin/node # npm + npx from the official amd64 tarball of the SAME version; extract only # those paths, not the amd64 node binary. # Same flags as the download above: a bare wget treats a 503 as fatal, and # nodejs.org has them. wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/node-${node_full}-linux-x64.tar.gz" wget --tries=20 --waitretry=20 --retry-on-http-error=403,500,502,503 \ "https://nodejs.org/dist/${node_full}/SHASUMS256.txt" grep " node-${node_full}-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - tar xzf "node-${node_full}-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner \ "node-${node_full}-linux-x64/lib/node_modules/npm" \ "node-${node_full}-linux-x64/bin/npm" \ "node-${node_full}-linux-x64/bin/npx" rm -rf node-download "node-${node_full}-linux-x64.tar.gz" "node-${node_full}-linux-x64" SHASUMS256.txt ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs" # NPM configuration npm install -g npm@${NPM_VERSION} chown --recursive wekan:wekan /home/wekan/ # Temporary Tar swap for Meteor bundle cp $(which tar) $(which tar)~ ln -sf $(which bsdtar) $(which tar) # WeKan Bundle Installation mkdir -p /home/wekan/app cd /home/wekan/app # Retry the release-asset download: even though the CI `docker` job needs the # `release` job (so the asset is already uploaded), GitHub's # releases/download/<tag>/<asset> URL can briefly return 404 right after upload # (CDN/propagation lag). A plain wget treats 404 as fatal, which failed the # build; retry on transient HTTP errors so propagation lag no longer breaks it. WEKAN_ZIP_URL="https://github.com/wekan/wekan/releases/download/v${VERSION}/wekan-${VERSION}-${WEKAN_ARCH}.zip" wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 "${WEKAN_ZIP_URL}" \ || { echo "Failed to download ${WEKAN_ZIP_URL} after retries"; exit 8; } unzip "wekan-${VERSION}-${WEKAN_ARCH}.zip" rm "wekan-${VERSION}-${WEKAN_ARCH}.zip" node /tmp/prepare-bundle-npm.mjs ./bundle npm install --prefix ./bundle/programs/server # node-gyp and @mapbox/node-pre-gyp compiled nothing here - every native module # in the bundle is a prebuilt .node - and nothing in boot.js reaches them. Their # tree is what shipped `tar` 6.2.1 (CRITICAL) and npm's networking stack to the # published image, so it goes now that the install is done. node /tmp/prune-build-only-modules.mjs ./bundle # The .zip already carries the bumped meteor/ tree; this install put back # meteor-dev-bundle's own underscore 1.13.7 pin (CVE-2026-27601) over it, so the # same pass runs here. node /tmp/bump-bundle-npm-deps.mjs ./bundle # No uWebSockets.js, no legacy client, no source maps: this image runs sockjs, # serves web.browser to every browser, and has no debugger attached to it. node /tmp/bundle-trim.mjs ./bundle --transport sockjs --drop-legacy-client # And the npm tree rspack cannot tree-shake, because Atmosphere packages load it # through Npm.require(). Only what it can prove nothing requires. node /tmp/prune-unreachable-npm.mjs ./bundle python3 /tmp/check-telemetry.py --bundle ./bundle mv /home/wekan/app/bundle /build # The .zip bundle now ships a self-contained launcher + its own Node.js for the # offline downloads; the Docker image installs its own Node and uses # wekan-entrypoint.sh, so drop the redundant bundled node + launchers. Keeps # /build/ferretdb (used by the entrypoint) and the per-arch MongoDB Database Tools # (bsondump, mongodump, mongorestore, … from wekan/mongo-tools-patches, embedded in the # bundle) for backup/restore inside the container. Saves ~80 MB per arch. rm -f /build/node /build/start-wekan.sh /build/start-wekan.bat # Restore original tar mv $(which tar)~ $(which tar) # Cleanup # npm is a BUILD tool in this image and nothing else: the only thing it does is # the `npm install` above, and the container starts bash + wekan-entrypoint.sh, # which never calls it. Shipping it shipped npm's own bundled dependencies - its # `tar` (CRITICAL), `sigstore`, `@sigstore/*`, `ip-address`, `brace-expansion` - # as image content that no code path can reach. node itself stays, because that # is what runs WeKan. rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx # Remove unused Go-based pebble binary shipped by base image to reduce CVE surface. apt-get remove --purge --assume-yes pebble || true rm -f /usr/bin/pebble apt-get remove --purge --assume-yes ${BUILD_DEPS} apt-get autoremove --assume-yes apt-get clean --assume-yes rm -Rf /tmp/* rm -Rf /var/lib/apt/lists/* rm -Rf /home/wekan/app mkdir -p /data chown wekan:wekan --recursive /data # buildkit

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

USER wekan

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

ENV PORT=8080

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

EXPOSE [8080/tcp]

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

STOPSIGNAL SIGKILL

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

WORKDIR /build

2026-10-08 16:36:12 UTC (buildkit.dockerfile.v0)

CMD ["bash" "/build/wekan-entrypoint.sh"]

Danger Zone
Delete Tag

Please be careful as this will not just delete the reference but also the actual content!

For example when you have latest and v1.2.3 both pointing to the same image
the deletion of latest will also permanently remove v1.2.3.

Delete