2026-09-15 23:02:07 UTC
306 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:b893e4e8ae50bbe3f6f662d089d78bdcec599d1f4f6ffcc53ea4c77eba1418a5 - 15.84% (48.5 MB)
[#001] sha256:2cbd585a035d73fca87db311002f9018576d3dec015334fa598ad63a54edaab4 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:98936be4585c88ccfda8e996c3fa5604c6efdf2f8658a1bccdea2a2b2cd5b47f - 84.15% (258 MB)
[#009] sha256:8326b1aae7d18fe70c1d2ea3436db37281c2efa70efd396193e857559e5eae1f - 0.0% (5.76 KB)
[#010] sha256:4046bfe298734a2cfc7b339ef59a70b6df118b8f94d56d3d7e5bf3d3c481e190 - 0.0% (3.7 KB)
[#011] sha256:17bdde0555aa28228694fe665ac58a66c6ea0bbd07929fe8bdf44237f9351b1d - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'i386' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=386
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:02:06 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=386 TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:02:07 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:02:07 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:01:18 UTC
309 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:27ee9a8250487842a26b1ffa1215982ba9ae27010bce1997d52f9f8628578d17 - 15.22% (47.1 MB)
[#001] sha256:e00a3dc08dadb63a8f9e7a1f8ec5b69ac005ff1afac54b8f4e6908f6f99874a3 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:f1b7d3e62b60258f2a12e9818cd4fefefa454a32176ff453a0e4e59f3eb78425 - 84.77% (262 MB)
[#009] sha256:7a9b9ca72cd41dfdf11ffef53abc5b65544a80b87771f8cd26a6436e0a8d29b6 - 0.0% (5.76 KB)
[#010] sha256:f1f4656a2f5c943db3974e5cbf55df926c2441acd295df72032e1bed03b156c1 - 0.0% (3.7 KB)
[#011] sha256:801bb76793eedc49b7c1d7116fc85e379be2eecb3c0a4ef54619b3a43ea631d7 - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'amd64' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=amd64
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:34 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:01:17 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=amd64 TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:01:18 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:01:18 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:16:23 UTC
294 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:cdac0eac0749288813a078c4279ee1e58b9f6a38246ae0d43ef25f305013e0fc - 14.85% (43.6 MB)
[#001] sha256:2cbd585a035d73fca87db311002f9018576d3dec015334fa598ad63a54edaab4 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:ed255b9a0383ad7a223305a11f7a192f3e6abb35d3054271d62a4d206653e316 - 85.14% (250 MB)
[#009] sha256:bfc8f47b58c5004afd4a3a975ae93be30fb96f02c2a43277e7c68a5e48fc8cf6 - 0.0% (5.76 KB)
[#010] sha256:76c38f9e3b105f0d650265256ecc92633634c6269e037fc612ca76982a1cde08 - 0.0% (3.7 KB)
[#011] sha256:1bd589f63907c51294d6228d3c1c58c51ef0f67dde286e30ac5dfeceaefe91b8 - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'armhf' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=arm
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=v7
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=arm TARGETVARIANT=v7 VERSION=11.82 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} # 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" 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 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-09-15 23:16:23 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:16:23 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:17:06 UTC
308 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:7f50a08a25277c02b8dfc99818a21e12083215981e0aa03cb07cb74c9116f205 - 15.41% (47.4 MB)
[#001] sha256:2cbd585a035d73fca87db311002f9018576d3dec015334fa598ad63a54edaab4 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:54864667362381bac9e0cb15c2d80f392fe1bc4a3da2d36fe8a71f3e9d5b4392 - 0.0% (4.73 KB)
[#008] sha256:7019a5ff6c0c90ff911825c206766060ea80441bf90a9dc098944b104a53f006 - 84.58% (260 MB)
[#009] sha256:2bf817eb44d4f9c8d49184eeb020207193d741dce7a49f622493945d7f43f90a - 0.0% (5.76 KB)
[#010] sha256:62a939541f12213e2619a4246456c26fb88c831bc705f6fd5e732004bdf8745f - 0.0% (3.7 KB)
[#011] sha256:2f6ec9ab4160ec2225fce82fe9901d2e687affa022ad63e2cc38eb2135e8017c - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'arm64' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=arm64
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:34 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:17:05 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=arm64 TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:17:06 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:17:06 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:16:07 UTC
317 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:9e8ba95bc0f758aeefc6ee2893238edfdc36acd4c619b64346a7e620439fd6d7 - 15.98% (50.7 MB)
[#001] sha256:2cbd585a035d73fca87db311002f9018576d3dec015334fa598ad63a54edaab4 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:a18593157667eca7c0331d6324345c10d9dfacc86cff7380b273f93ac81cf2a7 - 84.0% (266 MB)
[#009] sha256:9e8c7d53a50b90a45c4b43375ca269df8406daa686e9352898321bbb733aa347 - 0.0% (5.76 KB)
[#010] sha256:cab74c53f757c4147eb841ff499fc43e18142a4a678e78658a27b407f270d1db - 0.0% (3.7 KB)
[#011] sha256:3211a0a8985a7f56dfb4c6cdebe23cf046913d39c7082a3722993fabf73d54a5 - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'ppc64el' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=ppc64le
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:16:06 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=ppc64le TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:16:07 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:16:07 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:17:28 UTC
308 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:acb3599234922b1535fad7591ba58ef476824d3d5c601ad25d9d566dd92a573a - 14.79% (45.6 MB)
[#001] sha256:e00a3dc08dadb63a8f9e7a1f8ec5b69ac005ff1afac54b8f4e6908f6f99874a3 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:6158f2998aa5bf8940e6aa740389765b03fd1857f40db45f2e84a02784f70fca - 85.19% (263 MB)
[#009] sha256:da6770e31c4bee48c63ef1361fa82ff7d860ac6f095e1f4bdfd9612da0010e9d - 0.0% (5.76 KB)
[#010] sha256:6de69604b5f9307c820bf336353b9cb3d80b813a8b37f6a78e6884c7f4d73ed9 - 0.0% (3.7 KB)
[#011] sha256:ec23e48cb5fc711d49ff164d0bb50af310ffcc6586ae4a6b58c1dba6b0efae8c - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 'riscv64' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=riscv64
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=riscv64 TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:17:28 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:17:28 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
2026-09-15 23:17:12 UTC
311 MB
90
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE3
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD60
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE3
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW15
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD60
ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM ATTACHMENTS_UPLOAD_MAX_SIZE0
ATTACHMENTS_UPLOAD_MIME_TYPES AVATARS_UPLOAD_EXTERNAL_PROGRAM AVATARS_UPLOAD_MAX_SIZE72000
AVATARS_UPLOAD_MIME_TYPES BIGEVENTS_PATTERNNONE
BROWSER_POLICY_ENABLEDtrue
BUILD_DEPSapt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
CARD_OPENED_WEBHOOK_ENABLEDfalse
CAS_BASE_URL CAS_ENABLEDfalse
CAS_LOGIN_URL CAS_VALIDATE_URL CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS DDP_TRANSPORTsockjs
DEBUGfalse
DEFAULT_AUTHENTICATION_METHOD DEFAULT_BOARD_ID EMAIL_NOTIFICATION_TIMEOUT30000
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_AUTHENTIFICATIONfalse
LDAP_AUTHENTIFICATION_PASSWORD LDAP_AUTHENTIFICATION_PASSWORD_FILE LDAP_AUTHENTIFICATION_USERDN LDAP_BACKGROUND_SYNCfalse
LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERSfalse
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERSfalse
LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATEDfalse
LDAP_BASEDN LDAP_CA_CERT LDAP_CONNECT_TIMEOUT10000
LDAP_DEFAULT_DOMAIN LDAP_EMAIL_FIELD LDAP_EMAIL_MATCH_ENABLEfalse
LDAP_EMAIL_MATCH_REQUIREfalse
LDAP_EMAIL_MATCH_VERIFIEDfalse
LDAP_ENABLEfalse
LDAP_ENCRYPTIONfalse
LDAP_FULLNAME_FIELD LDAP_GROUP_FILTER_ENABLEfalse
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_OBJECTCLASS LDAP_HOST LDAP_IDLE_TIMEOUT10000
LDAP_LOGIN_FALLBACKfalse
LDAP_LOG_ENABLEDfalse
LDAP_MERGE_EXISTING_USERSfalse
LDAP_PORT389
LDAP_RECONNECTtrue
LDAP_REJECT_UNAUTHORIZEDfalse
LDAP_SEARCH_PAGE_SIZE0
LDAP_SEARCH_SIZE_LIMIT0
LDAP_SYNC_ADMIN_GROUPS LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_GROUP_ROLES LDAP_SYNC_ORGANIZATIONSfalse
LDAP_SYNC_ORGANIZATIONS_GROUPS LDAP_SYNC_TEAMSfalse
LDAP_SYNC_TEAMS_GROUPS LDAP_SYNC_USER_DATAfalse
LDAP_SYNC_USER_DATA_FIELDMAP LDAP_TIMEOUT10000
LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_USERNAME_FIELD LDAP_USER_AUTHENTICATIONfalse
LDAP_USER_AUTHENTICATION_FIELDuid
LDAP_USER_SEARCH_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_UTF8_NAMES_SLUGIFYtrue
LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES LOGOUT_WITH_TIMERfalse
MAIL_SERVICE_PASSWORD_FILE MATOMO_ADDRESS MATOMO_DO_NOT_TRACKtrue
MATOMO_SITE_ID MATOMO_WITH_USERNAMEfalse
MAX_IMAGE_PIXEL METEOR_RELEASEMETEOR@3.6-beta.0
METRICS_ALLOWED_IP_ADDRESSES MONGO_OPLOG_URL MONGO_PASSWORD_FILE NODE_VERSIONv24.21.0
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE NOTIFY_DUE_AT_HOUR_OF_DAY NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_ON_ASSIGNtrue
NPM_VERSION11.12.1
OAUTH2_ADFS_ENABLEDfalse
OAUTH2_ADMIN_GROUPS OAUTH2_AUTH_ENDPOINT OAUTH2_AUTO_REGISTRATIONtrue
OAUTH2_B2C_ENABLEDfalse
OAUTH2_CA_CERT OAUTH2_CLIENT_ID OAUTH2_EMAIL_MAP OAUTH2_ENABLEDfalse
OAUTH2_FULLNAME_MAP OAUTH2_ID_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_LOGIN_STYLEredirect
OAUTH2_LOGOUT_ENDPOINT OAUTH2_REQUEST_PERMISSIONSopenid profile email
OAUTH2_SECRET OAUTH2_SECRET_FILE OAUTH2_SERVER_URL OAUTH2_TOKEN_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_USERNAME_MAP OAUTH_FACEBOOK_APP_ID OAUTH_FACEBOOK_ENABLEDfalse
OAUTH_FACEBOOK_SECRET OAUTH_FACEBOOK_SECRET_FILE OAUTH_GITHUB_CLIENT_ID OAUTH_GITHUB_ENABLEDfalse
OAUTH_GITHUB_SECRET OAUTH_GITHUB_SECRET_FILE OAUTH_GOOGLE_CLIENT_ID OAUTH_GOOGLE_ENABLEDfalse
OAUTH_GOOGLE_SECRET OAUTH_GOOGLE_SECRET_FILE OAUTH_MEETUP_CLIENT_ID OAUTH_MEETUP_ENABLEDfalse
OAUTH_MEETUP_SECRET OAUTH_MEETUP_SECRET_FILE OAUTH_METEOR_DEVELOPER_CLIENT_ID OAUTH_METEOR_DEVELOPER_ENABLEDfalse
OAUTH_METEOR_DEVELOPER_SECRET OAUTH_METEOR_DEVELOPER_SECRET_FILE OAUTH_PROVIDERS_LOGIN_STYLEpopup
OAUTH_PROVIDERS_MERGE_EXISTING_USERSfalse
OAUTH_TWITTER_CONSUMER_KEY OAUTH_TWITTER_ENABLEDfalse
OAUTH_TWITTER_SECRET OAUTH_TWITTER_SECRET_FILE OAUTH_WEIBO_CLIENT_ID OAUTH_WEIBO_ENABLEDfalse
OAUTH_WEIBO_SECRET OAUTH_WEIBO_SECRET_FILE OIDC_REDIRECTION_ENABLEDfalse
ORACLE_OIM_ENABLEDfalse
PASSWORDLESS_ENABLEDfalse
PASSWORD_LOGIN_ENABLEDtrue
PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT8080
RESULTS_PER_PAGE RICHER_CARD_COMMENT_EDITORfalse
S3 S3_SECRET_FILE SAML_ATTRIBUTES SAML_CERT SAML_ENABLEDfalse
SAML_ENTRYPOINT SAML_IDENTIFIER_FORMAT SAML_IDPSLO_REDIRECTURL SAML_ISSUER SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE SAML_PRIVATE_KEYFILE SAML_PROVIDER SAML_PUBLIC_CERTFILE SRC_PATH./
TRUSTED_URL USE_EDGEfalse
WAIT_SPINNER WEBHOOKS_ATTRIBUTES WITH_APItrue
WRITABLE_PATH/data
[#000] sha256:4415ebc808ead343ed2ff09e9ddd7fb38001c3cd021262fe1ae58bf5fa958333 - 15.15% (47.1 MB)
[#001] sha256:2cbd585a035d73fca87db311002f9018576d3dec015334fa598ad63a54edaab4 - 0.0% (4.93 KB)
[#002] sha256:032f2333eb5e73d6d31a1fe1518f121f393fb393851e0c70eb84cc032e9999b0 - 0.0% (2.15 KB)
[#003] sha256:b654d1660d95402ecf0551140fce8add21bdcfc9f956648db1e509ba0c949203 - 0.0% (2.13 KB)
[#004] sha256:382c56c9c7f39bca7d33483ecd5851b77644f329f3d5a214951ae1eb6cfe092e - 0.0% (3.62 KB)
[#005] sha256:5882eafa742da1c1874168d67d33cb94cfa77cff9476c9a83720a2cafaf7ca4e - 0.0% (1.45 KB)
[#006] sha256:2d9b6ec75ae9672447c124fd9d1b52e880967a2e09d3f143e7ef0995d2037d92 - 0.0% (5.65 KB)
[#007] sha256:5f57cdd373f73f2b4b43c2f4dd7bd0c4a483d7ffc292e3226d347aceb901dc4d - 0.0% (4.73 KB)
[#008] sha256:1a7e653b21ceded2cd148ab1e0705c20f4f901784cbfb71226807623d1c07c77 - 84.84% (264 MB)
[#009] sha256:b973d94520b99d296fb65108c26a60f1bed0d6f270f053addebb24f757774fa1 - 0.0% (5.76 KB)
[#010] sha256:2ed43fcd446098b745169703522b1ad84c0c92ea249a0218ccb09684fea65225 - 0.0% (3.7 KB)
[#011] sha256:45c444985cc097dfde50bf63b4dc887022e1fa6bc2bcf2e69c62fe768cb7b06b - 0.0% (2.32 KB)
[#012] sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 - 0.0% (32 Bytes)
# debian.sh --arch 's390x' out/ 'trixie' '@1787529600'
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL maintainer=wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.ref.name=debian
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.version=trixie
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)LABEL org.opencontainers.image.source=https://github.com/wekan/wekan
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETARCH=s390x
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG TARGETVARIANT=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG VERSION=11.82
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ARG DEBIAN_FRONTEND=noninteractive
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV BUILD_DEPS=apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)ENV DEBUG=false DDP_TRANSPORT=sockjs NODE_VERSION=v24.21.0 METEOR_RELEASE=METEOR@3.6-beta.0 USE_EDGE=false NPM_VERSION=11.12.1 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 RICHER_CARD_COMMENT_EDITOR=false 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=false 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_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= 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=popup OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false PASSWORDLESS_ENABLED=false ORACLE_OIM_ENABLED=false WAIT_SPINNER= WRITABLE_PATH=/data S3= MAIL_SERVICE_PASSWORD_FILE= MONGO_PASSWORD_FILE= S3_SECRET_FILE=
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/resolve-node-source.sh /tmp/resolve-node-source.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/fetch.sh /tmp/fetch.sh # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-build-only-modules.mjs /tmp/prune-build-only-modules.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bump-bundle-npm-deps.mjs /tmp/bump-bundle-npm-deps.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/bundle-npm-security-bumps.json /tmp/bundle-npm-security-bumps.json # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/bundle-trim.mjs /tmp/bundle-trim.mjs # buildkit
2026-09-15 22:58:33 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/prune-unreachable-npm.mjs /tmp/prune-unreachable-npm.mjs # buildkit
2026-09-15 23:17:11 UTC (buildkit.dockerfile.v0)RUN |4 TARGETARCH=s390x TARGETVARIANT= VERSION=11.82 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} # 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" 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 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-09-15 23:17:12 UTC (buildkit.dockerfile.v0)COPY --chmod=755 releases/ferretdb/wekan-entrypoint.sh /build/wekan-entrypoint.sh # buildkit
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/recovery-bridge.mjs /build/recovery-bridge.mjs # buildkit
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)COPY --chmod=644 releases/ferretdb/db-ready.mjs /build/db-ready.mjs # buildkit
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)USER wekan
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)ENV PORT=8080
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)EXPOSE [8080/tcp]
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)STOPSIGNAL SIGKILL
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)WORKDIR /build
2026-09-15 23:17:12 UTC (buildkit.dockerfile.v0)CMD ["bash" "/build/wekan-entrypoint.sh"]
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.