docker-compose-mongodb-v7.yml
Rama main · réplica de lectura del repositorio original.
# WeKan with MongoDB 7 (docker-compose-mongodb-v7.yml)
#
# This is the classic MongoDB 7 setup. It is NOT the default anymore: the default
# docker-compose.yml now uses FerretDB v1 with SQLite (see docker-compose.yml).
# To use this MongoDB 7 file, either run it explicitly with
# docker compose -f docker-compose-mongodb-v7.yml up -d
# or rename/copy it to docker-compose.yml. The examples below use the bare
# "docker compose ..." form, which assumes you renamed it to docker-compose.yml.
#---------------------------------------------------------------------------------------------------------
# Note: Do not add single quotes '' to variables. Having spaces still works without quotes where required.
#---------------------------------------------------------------------------------------------------------
# ==== CREATING USERS AND LOGGING IN TO WEKAN ====
# https://github.com/wekan/wekan/blob/main/docs/Login/Adding-users.md
#---------------------------------------------------------------------------------------------------------
# ==== FORGOT PASSWORD ====
# https://github.com/wekan/wekan/blob/main/docs/Login/Forgot-Password.md
#---------------------------------------------------------------------------------------------------------
# ==== Upgrading Wekan to new version =====
# NOTE: MongoDB has changed from 3.x to 4.x, in that case you need backup/restore with --noIndexRestore
# see https://github.com/wekan/wekan/tree/main/docs/Backup
# 1) Stop Wekan:
# docker compose stop
# 2) Remove old Wekan app (wekan-app only, not that wekan-db container that has all your data)
# docker rm wekan-app
# 3) Get newest docker-compose-mongodb-v7.yml from https://github.com/wekan/wekan to have correct image,
# for example: "image: quay.io/wekan/wekan" or version tag "image: quay.io/wekan/wekan:v4.52"
# 4) Start Wekan:
# docker compose up -d
#----------------------------------------------------------------------------------
# ==== OPTIONAL: DEDICATED DOCKER USER ====
# 1) Optionally create a dedicated user for Wekan, for example:
# sudo useradd -d /home/wekan -m -s /bin/bash wekan
# 2) Add this user to the docker group, then logout+login or reboot:
# sudo usermod -aG docker wekan
# 3) Then login as user wekan.
# 4) Create this file /home/wekan/docker-compose.yml with your modifications.
#----------------------------------------------------------------------------------
# ==== RUN DOCKER AS SERVICE ====
# 1a) Running Docker as service, on Systemd like Debian 9, Ubuntu 16.04, CentOS 7:
# sudo systemctl enable docker
# sudo systemctl start docker
# 1b) Running Docker as service, on init.d like Debian 8, Ubuntu 14.04, CentOS 6:
# sudo update-rc.d docker defaults
# sudo service docker start
# ----------------------------------------------------------------------------------
# ==== USAGE OF THIS docker-compose-mongodb-v7.yml ====
# 1) For seeing does Wekan work, try this and check with your web browser:
# docker compose up
# 2) Stop Wekan and start Wekan in background:
# docker compose stop
# docker compose up -d
# 3) See running Docker containers:
# docker ps
# 4) Stop Docker containers:
# docker compose stop
# ----------------------------------------------------------------------------------
# ===== INSIDE DOCKER CONTAINERS, AND BACKUP/RESTORE ====
# https://github.com/wekan/wekan/tree/main/docs/Backup
# If really necessary, repair MongoDB: https://github.com/wekan/wekan-mongodb/issues/6#issuecomment-424004116
# 1) Going inside containers:
# a) Wekan app, does not contain data
# docker exec -it wekan-app bash
# b) MongoDB, contains all data
# docker exec -it wekan-db bash
# 2) Copying database to outside of container:
# docker exec -it wekan-db bash
# cd /data
# mongodump
# exit
# docker cp wekan-db:/data/dump .
# 3) Restoring database
# # 1) Stop wekan
# docker stop wekan-app
# # 2) Go inside database container
# docker exec -it wekan-db bash
# # 3) and data directory
# cd /data
# # 4) Remove previous dump
# rm -rf dump
# # 5) Exit db container
# exit
# # 6) Copy dump to inside docker container
# docker cp dump wekan-db:/data/
# # 7) Go inside database container
# docker exec -it wekan-db bash
# # 8) and data directory
# cd /data
# # 9) Restore
# mongorestore --drop
# # 10) Exit db container
# exit
# # 11) Start wekan
# docker start wekan-app
#-------------------------------------------------------------------------
services:
#-------------------------------------------------------------------------------------
# ==== DATABASE: FerretDB 2 + PostgreSQL 16 ====
# FerretDB is a MongoDB-compatible proxy that stores data in PostgreSQL.
# It supports the full MongoDB wire protocol used by Meteor/WeKan,
# including OpLog via replication-set emulation (--replication-set-name=rs0).
#
# Upgrade path from MongoDB:
# The wekan-migrate service below runs ONCE before wekan starts.
# It copies all data from an existing MongoDB instance (if reachable at
# SOURCE_MONGO_URL) to FerretDB, upgrades the schema to v8.43, and
# moves GridFS / CollectionFS binary files to the filesystem.
# Progress is visible in a browser while migration runs.
#
# If you are upgrading from a MongoDB-based install:
# 1. Keep your old MongoDB container running (or start it separately).
# 2. Set SOURCE_MONGO_URL in the wekan-migrate environment below.
# 3. Run: docker compose up -d
# 4. Watch migration at http://localhost:8080/ until "completed".
# 5. Shut down old MongoDB once satisfied.
#
# If this is a fresh install, wekan-migrate exits instantly (nothing to migrate).
#-------------------------------------------------------------------------------------
#
#wekan-postgres:
# image: postgres:16-alpine
# container_name: wekan-postgres
# restart: always
# networks:
# - wekan-tier
# expose:
# - 5432
# environment:
# - POSTGRES_DB=wekan
# - POSTGRES_USER=wekan
# - POSTGRES_PASSWORD=wekan
# # Tune for a kanban workload (low connection count, moderate write rate)
# - POSTGRES_INITDB_ARGS=--encoding=UTF8 --locale=C
# volumes:
# - /etc/localtime:/etc/localtime:ro
# - wekan-postgres:/var/lib/postgresql/data
# healthcheck:
# test: ["CMD-SHELL", "pg_isready -U wekan -d wekan"]
# interval: 5s
# timeout: 5s
# retries: 10
#
#wekan-ferretdb:
# image: ghcr.io/ferretdb/ferretdb:2
# container_name: wekan-ferretdb
# restart: always
# networks:
# - wekan-tier
# expose:
# - 27017
# environment:
# # FerretDB stores everything in PostgreSQL
# - FERRETDB_POSTGRESQL_URL=postgresql://wekan:wekan@wekan-postgres:5432/wekan
# # CVE-2026-98432: no MPTCP listener (Go's default since 1.24)
# - GODEBUG=multipathtcp=0
# # Emulate MongoDB replica-set for Meteor OpLog (real-time updates)
# - FERRETDB_REPLICATION_SET_NAME=rs0
# # Suppress verbose debug output
# - FERRETDB_LOG_LEVEL=warn
# depends_on:
# wekan-postgres:
# condition: service_healthy
# healthcheck:
# test: ["CMD", "ferretdb", "--version"]
# interval: 5s
# timeout: 5s
# retries: 10
#
#-------------------------------------------------------------------------------------
# ==== MIGRATION SERVICE ====
# Runs once, before WeKan starts. Exits 0 on success, 1 on fatal error.
# WeKan only starts after this service exits successfully
# (depends_on condition: service_completed_successfully).
#
# On a FRESH install (no SOURCE_MONGO_URL or source unreachable) it exits
# immediately — no penalty for new deployments.
#
# SOURCE_MONGO_URL: point to your old MongoDB container/host.
# e.g. mongodb://wekandb:27017/wekan
# mongodb://192.168.1.10:27017/wekan
# Leave it unset or empty to skip migration.
#-------------------------------------------------------------------------------------
#wekan-migrate:
# image: node:24.17.0-slim
# container_name: wekan-migrate
# restart: "no"
# networks:
# - wekan-tier
# working_dir: /migrate
# # Install the mongodb driver then run the migration script.
# # npm ci is used if package-lock.json exists; npm install otherwise.
# command: >
# sh -c "
# cd /migrate &&
# npm install --omit=dev --prefer-offline 2>/dev/null || npm install --omit=dev &&
# node migrate-mongodb-to-ferretdb.mjs
# "
# environment:
# # ---- Source (old MongoDB) ----
# # Set to your old MongoDB URL to trigger data migration.
# # Leave empty for a fresh install (migration is skipped automatically).
# - SOURCE_MONGO_URL=
# #- SOURCE_MONGO_URL=mongodb://wekandb:27017/wekan
#
# # ---- Target (FerretDB) ----
# - TARGET_MONGO_URL=mongodb://wekan-ferretdb:27017/wekan
#
# # ---- File storage ----
# # Must match the WRITABLE_PATH used by the wekan service.
# - WRITABLE_PATH=/data
#
# # ---- Progress dashboard ----
# # Browse to http://localhost:8080/ while migration runs.
# - MIGRATION_PORT=8080
#
# # ---- Tuning (optional) ----
# #- BATCH_SIZE=200
# #- DRY_RUN=true # Log only, no writes — useful for testing
# #- FORCE_MIGRATE=true # Re-run even if already marked complete
# ports:
# - 8080:8080
# depends_on:
# wekan-ferretdb:
# condition: service_healthy
# volumes:
# - /etc/localtime:/etc/localtime:ro
# - wekan-files:/data:rw
# - ./releases:/migrate:ro
#-------------------------------------------------------------------------------------
# ==== LEGACY MONGODB (commented out) ====
# Uncomment to keep old MongoDB running alongside FerretDB during migration.
# After migration is verified, remove this block entirely.
#-------------------------------------------------------------------------------------
wekandb:
image: mongo:7
container_name: wekan-db
restart: always
#command: mongod --logpath /dev/null --storageEngine wiredTiger --wiredTigerCacheSizeGB 32 --timeZoneInfo /usr/share/zoneinfo --setParameter logicalSessionRefreshMillis=900000 --setParameter localLogicalSessionTimeoutMinutes=45 --oplogSize 20480 --replSet rs0 --quiet
#command: mongod --storageEngine wiredTiger --wiredTigerCacheSizeGB 32 --timeZoneInfo /usr/share/zoneinfo --setParameter logicalSessionRefreshMillis=900000 --setParameter localLogicalSessionTimeoutMinutes=45 --oplogSize 20480 --replSet rs0 --quiet
command: >
sh -c '
mongod --storageEngine wiredTiger --wiredTigerCacheSizeGB 32 --timeZoneInfo /usr/share/zoneinfo --setParameter logicalSessionRefreshMillis=900000 --setParameter localLogicalSessionTimeoutMinutes=45 --oplogSize 20480 --replSet rs0 --bind_ip_all --quiet &
until mongosh --host 127.0.0.1 --quiet --eval "
try {
const status = rs.status();
quit(status.ok === 1 ? 0 : 1);
} catch (e) {
if (
e.codeName === \"NotYetInitialized\" ||
e.message.includes(\"no replset config has been received\") ||
e.message.includes(\"not yet initialized\")
) {
rs.initiate({
_id: \"rs0\",
members: [{ _id: 0, host: \"wekandb:27017\" }]
});
quit(1);
}
quit(1);
}
" >/dev/null 2>&1; do
sleep 2
done
wait
'
networks:
- wekan-tier
expose:
- 27017
# Healthcheck: report healthy only once the replica set has an elected
# primary, so the wekan app (depends_on: condition: service_healthy) does
# not start before MongoDB is ready and crash with "Topology is closed".
# start_period gives a large database time to replay its journal after an
# upgrade before failures are counted.
healthcheck:
test: ["CMD", "mongosh", "--host", "127.0.0.1", "--port", "27017", "--quiet", "--eval", "try { quit(rs.status().ok === 1 && db.hello().isWritablePrimary ? 0 : 1) } catch (e) { quit(1) }"]
interval: 10s
timeout: 10s
retries: 30
start_period: 60s
volumes:
- /etc/localtime:/etc/localtime:ro
- wekan-db:/data/db
- wekan-db-dump:/dump
wekan:
#-------------------------------------------------------------------------------------
# ==== WEKAN FROM GITHUB/QUAY/DOCKER HUB ====
# All of GitHub, Quay and Docker Hub have latest, but because
# latest tag changes when is newest release,
# when upgrading would be better to use version tag.
# a) Using specific version tag is better:
# image: ghcr.io/wekan/wekan:v6.89
# image: quay.io/wekan/wekan:v6.89
# image: wekanteam/wekan:v6.89
# b) GitHub Container registry.
# b1) Latest release tag:
image: ghcr.io/wekan/wekan:latest
# b2) Newest git commit automatic build:
#image: ghcr.io/wekan/wekan:main
# c) Quay:
#image: quay.io/wekan/wekan:latest
# d) Docker Hub:
#image: wekanteam/wekan:latest
#-------------------------------------------------------------------------------------
container_name: wekan-app
# On CentOS 7 there is seccomp issue with glibc 6,
# so CentOS 7 users shoud use these security_opt seccomp:unconfined
# settings to get WeKan working. See:
# - https://github.com/wekan/wekan/issues/4585
# - https://github.com/wekan/wekan/issues/4587
#security_opt:
# - seccomp:unconfined
restart: always
networks:
- wekan-tier
#-------------------------------------------------------------------------------------
# ==== BUILD wekan-app DOCKER CONTAINER FROM SOURCE, if you uncomment these ====
# ==== and use commands: docker compose up -d --build
#build:
# context: .
# dockerfile: Dockerfile
#-------------------------------------------------------------------------------------
ports:
# Docker outsideport:insideport. Do not add anything extra here.
# For example, if you want to have wekan on port 3001,
# use 3001:8080 . Do not add any extra address etc here, that way it does not work.
# remove port mapping if you use nginx reverse proxy, port 8080 is already exposed to wekan-tier network
- 80:8080
environment:
#-------------------- USING MONGODB CHANGE STREAMS WITH REPLICA SETS AT CURRENT DATABASE --------------------
# If you would not like to use Change Streams and replica set for improving speed, change to use polling:
#- METEOR_REACTIVITY_ORDER=polling
# https://forums.meteor.com/t/meteor-3-5-beta-change-streams-performance-improvements/64461#change-streams-setup-3
# https://github.com/meteor/meteor/blob/release-3.5/v3-docs/docs/performance/change-streams-observer-driver.md#choosing-the-reactivity-driver-order
# Keep oplog/polling fallback available for deployments that cannot use Change Streams:
# https://github.com/wekan/wekan/issues/6307#issuecomment-4299349231
- METEOR_REACTIVITY_ORDER=changeStreams,oplog,polling
# sockjs is the only transport WeKan ships: no bundle or image carries
# uWebSockets.js, and DDP_TRANSPORT=uws is coerced to sockjs at startup.
- DDP_TRANSPORT=sockjs
#-----------------------------------------------------------------
# ==== WRITEABLE PATH FOR FILE UPLOADS ====
- WRITABLE_PATH=/data
#-----------------------------------------------------------------
# ==== AWS S3 FOR FILES ====
# Any region. For example:
# us-standard,us-west-1,us-west-2,
# eu-west-1,eu-central-1,
# ap-southeast-1,ap-northeast-1,sa-east-1
#
#- S3='{"s3":{"key": "xxx", "secret": "xxx", "bucket": "xxx", "region": "xxx"}}'
#- S3_SECRET_KEY_FILE=/run/secrets/s3_secret_key
#-----------------------------------------------------------------
# ==== MONGO_URL — points to FerretDB (MongoDB-compatible) ====
#- MONGO_URL=mongodb://wekan-ferretdb:27017/wekan
- MONGO_URL=mongodb://wekandb:27017/wekan?replicaSet=rs0
#- MONGO_URL_FILE=/run/secrets/mongo_url
#---------------------------------------------------------------
# ==== ROOT_URL SETTING ====
# Change ROOT_URL to your real Wekan URL, for example:
# If you have Caddy/Nginx/Apache providing SSL
# - https://example.com
# - https://boards.example.com
# This can be problematic with avatars https://github.com/wekan/wekan/issues/1776
# - https://example.com/wekan
# If without https, can be only wekan node, no need for Caddy/Nginx/Apache if you don't need them
# - http://example.com
# - http://boards.example.com
# - http://192.168.1.100 <=== using at local LAN
- ROOT_URL=http://localhost # <=== using only at same laptop/desktop where Wekan is installed
#---------------------------------------------------------------
# ==== EMAIL SETTINGS ====
# In Admin Panel / People / Email, enable "Enable below email settings"
# to reveal additional email sending options below the checkbox.
# see https://github.com/wekan/wekan/blob/main/docs/Email/Troubleshooting-Mail.md
# For SSL in email, change smtp:// to smtps://
# NOTE: Special characters need to be url-encoded in MAIL_URL.
# You can encode those characters for example at: https://www.urlencoder.org
#- MAIL_URL=smtp://user:pass@mailserver.example.com:25/
- MAIL_URL=smtp://<mail_url>:25/?ignoreTLS=true&tls={rejectUnauthorized:false}
- MAIL_FROM=Wekan Notifications <noreply.wekan@mydomain.com>
# Currently MAIL_SERVICE is not in use.
#- MAIL_SERVICE=Outlook365
#- MAIL_SERVICE_USER=firstname.lastname@hotmail.com
#- MAIL_SERVICE_PASSWORD=SecretPassword
#- MAIL_URL_FILE=/run/secrets/mail_url
#---------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap, this is done by default at Dockerfile:
# - NODE_OPTIONS="--max_old_space_size=4096"
# Add more stack, this is done at Dockerfile:
# bash -c "ulimit -s 65500; exec node --stack-size=65500 main.js"
#---------------------------------------------------------------
# ==== OPTIONAL: MONGO OPLOG SETTINGS =====
# https://github.com/wekan/wekan-mongodb/issues/2#issuecomment-378343587
# HIGHLY RECOMMENDED for pub/sub performance!
# MongoDB oplog is used by Meteor for real-time data synchronization.
# Without oplog, Meteor falls back to polling which increases:
# - CPU usage by 3-5x
# - Network traffic significantly
# - Latency from 50ms to 2000ms
# Must configure MongoDB replica set first
# See: https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908
# FerretDB emulates OpLog via --replication-set-name=rs0.
# HIGHLY RECOMMENDED — enables real-time DDP updates (sub-100ms latency).
#- MONGO_OPLOG_URL=mongodb://wekan-ferretdb:27017/local?replicaSet=rs0
- MONGO_OPLOG_URL=mongodb://wekandb:27017/local?replicaSet=rs0
#---------------------------------------------------------------
# ==== OPTIONAL: KADIRA PERFORMANCE MONITORING FOR METEOR ====
# https://github.com/edemaine/kadira-compose
# https://github.com/meteor/meteor-apm-agent
# https://blog.meteor.com/kadira-apm-is-now-open-source-490469ffc85f
#- APM_OPTIONS_ENDPOINT=http://<kadira-ip>:11011
#- APM_APP_ID=
#- APM_APP_SECRET=
#---------------------------------------------------------------
# ==== OPTIONAL: LOGS AND STATS ====
# https://github.com/wekan/wekan/blob/main/docs/Features/Logs.md
#
# Daily export of Wekan changes as JSON to Logstash and ElasticSearch / Kibana (ELK)
# https://github.com/wekan/wekan-logstash
#
# Statistics Python script for Wekan Dashboard
# https://github.com/wekan/wekan-stats
#
# Console, file, and zulip logger on database changes https://github.com/wekan/wekan/pull/1010
# with fix to replace console.log by winston logger https://github.com/wekan/wekan/pull/1033
# but there could be bug https://github.com/wekan/wekan/issues/1094
#
# There is Feature Request: Logging date and time of all activity with summary reports,
# and requesting reason for changing card to other column https://github.com/wekan/wekan/issues/1598
#---------------------------------------------------------------
# ==== NUMBER OF SEARCH RESULTS PER PAGE BY DEFAULT ====
#- RESULTS_PER_PAGE=20
#---------------------------------------------------------------
# ==== AFTER OIDC LOGIN, ADD USERS AUTOMATICALLY TO THIS BOARD ID ====
# https://github.com/wekan/wekan/pull/5098
#- DEFAULT_BOARD_ID=abcd1234
#---------------------------------------------------------------
# ==== WEKAN API AND EXPORT BOARD ====
# Wekan Export Board works when WITH_API=true.
# https://github.com/wekan/wekan/blob/main/docs/API/REST-API.md
# https://github.com/wekan/wekan-gogs
# If you disable Wekan API with false, Export Board does not work.
- WITH_API=true
#---------------------------------------------------------------
# ==== PASSWORD BRUTE FORCE PROTECTION ====
#https://atmospherejs.com/lucasantoniassi/accounts-lockout
#Defaults below. Uncomment to change. wekan/server/accounts-lockout.js
#- 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
#---------------------------------------------------------------
# ==== ACCOUNT OPTIONS ====
# https://docs.meteor.com/api/accounts-multi.html#AccountsCommon-config
# Defaults below. Uncomment to change. wekan/server/accounts-common.js
# - ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90
#---------------------------------------------------------------
#---------------------------------------------------------------
# ==== CARD LOADING: all (default) or lazy ====
# 'all' = load every card of a board into the browser (default).
# 'lazy' = each list loads only the cards currently visible
# (infinite scroll) plus a live count, so boards with
# thousands of cards use less memory/bandwidth.
# Also changeable at runtime in Admin Panel / Features.
- CARDS_LOADING=all
#---------------------------------------------------------------
# ==== CARD OPENED, SEND WEBHOOK MESSAGE ====
# https://github.com/wekan/wekan/issues/2518
- CARD_OPENED_WEBHOOK_ENABLED=false
#---------------------------------------------------------------
# ==== Allow configuration to validate uploaded attachments ====
#-ATTACHMENTS_UPLOAD_EXTERNAL_PROGRAM=/usr/local/bin/avscan {file}
#-ATTACHMENTS_UPLOAD_MIME_TYPES=image/*,text/*
#-ATTACHMENTS_UPLOAD_MAX_SIZE=5000000
#---------------------------------------------------------------
# ==== Allow configuration to validate uploaded avatars ====
#-AVATARS_UPLOAD_EXTERNAL_PROGRAM=/usr/local/bin/avscan {file}
#-AVATARS_UPLOAD_MIME_TYPES=image/*
#-AVATARS_UPLOAD_MAX_SIZE=500000
# DEFAULT_AVATAR_URL : avatar of users who have not set one, a URL with {username},
# {userId}, {emailMd5} or {emailSha256} replaced. Example: http://192.168.1.200/avatars/{username}.png
#- DEFAULT_AVATAR_URL=
#---------------------------------------------------------------
# ==== Allow to shrink attached/pasted image ====
# https://github.com/wekan/wekan/pull/2544
#- MAX_IMAGE_PIXEL=1024
#- IMAGE_COMPRESS_RATIO=80
#---------------------------------------------------------------
# ==== NOTIFICATION TRAY AFTER READ DAYS BEFORE REMOVE =====
# Number of days after a notification is read before we remove it.
# Default: 2
#- NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE=2
#---------------------------------------------------------------
# ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
# https://github.com/wekan/wekan/pull/2541
# Introduced a system env var BIGEVENTS_PATTERN default as "NONE",
# so any activityType matches the pattern, system will send out
# notifications to all board members no matter they are watching
# or tracking the board or not. Owner of the wekan server can
# disable the feature by setting this variable to "NONE" or
# change the pattern to any valid regex. i.e. '|' delimited
# activityType names.
# a) Example
#- BIGEVENTS_PATTERN=due
# b) All
#- BIGEVENTS_PATTERN=received|start|due|end
# c) Disabled
- BIGEVENTS_PATTERN=NONE
#---------------------------------------------------------------
# ==== NOTIFY ON ASSIGN =====
# Notify the user directly when they are added as a card member or
# assignee. Set false to disable.
#- NOTIFY_ON_ASSIGN=true
#---------------------------------------------------------------
# ==== EMAIL DUE DATE NOTIFICATION =====
# https://github.com/wekan/wekan/pull/2536
# System timelines will be showing any user modification for
# dueat startat endat receivedat, also notification to
# the watchers and if any card is due, about due or past due.
#
# Notify due days, default is None, 2 days before and on the event day
#- NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=2,0
#
# Notify due at hour of day. Default every morning at 8am. Can be 0-23.
# If env variable has parsing error, use default. Notification sent to watchers.
#- NOTIFY_DUE_AT_HOUR_OF_DAY=8
#-----------------------------------------------------------------
# ==== EMAIL NOTIFICATION TIMEOUT, ms =====
# Default: 30000 ms = 30s
#- EMAIL_NOTIFICATION_TIMEOUT=30000
#-----------------------------------------------------------------
# ==== CORS =====
# CORS: Set Access-Control-Allow-Origin header.
#- CORS=*
# CORS_ALLOW_HEADERS: Set Access-Control-Allow-Headers header. "Authorization,Content-Type" is required for cross-origin use of the API.
#- CORS_ALLOW_HEADERS=Authorization,Content-Type
# CORS_EXPOSE_HEADERS: Set Access-Control-Expose-Headers header. This is not needed for typical CORS situations
#- CORS_EXPOSE_HEADERS=*
#-----------------------------------------------------------------
# ==== MATOMO INTEGRATION ====
# Optional: Integration with Matomo https://matomo.org that is installed to your server
# The address of the server where Matomo is hosted.
#- MATOMO_ADDRESS=https://example.com/matomo
# The value of the site ID given in Matomo server for Wekan
#- MATOMO_SITE_ID=1
# The option do not track which enables users to not be tracked by matomo
#- MATOMO_DO_NOT_TRACK=true
# The option that allows matomo to retrieve the username:
#- MATOMO_WITH_USERNAME=true
#-----------------------------------------------------------------
# ==== BROWSER POLICY AND TRUSTED IFRAME URL ====
# Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside.
# Setting this to false is not recommended, it also disables all other browser policy protections
# and allows all iframing etc. See wekan/server/policy.js
- BROWSER_POLICY_ENABLED=true
# When browser policy is enabled, HTML code at this Trusted URL can have iframe that embeds Wekan inside.
#- TRUSTED_URL=https://intra.example.com
#-----------------------------------------------------------------
# ==== METRICS ALLOWED IP ADDRESSES ====
# https://github.com/wekan/wekan/blob/main/docs/Features/Metrics.md
#- METRICS_ALLOWED_IP_ADDRESSES=192.168.0.100,192.168.0.200
#-----------------------------------------------------------------
# ==== OUTGOING WEBHOOKS ====
# What to send to Outgoing Webhook, or leave out. If commented out the default values will be: cardId,listId,oldListId,boardId,comment,user,card,commentId,swimlaneId,customerField,customFieldValue
#- WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,board,list,swimlane,commentId
#-----------------------------------------------------------------
# ==== Debug OIDC OAuth2 etc ====
#- DEBUG=true
#---------------------------------------------
# ==== AUTOLOGIN WITH OIDC/OAUTH2 ====
# https://github.com/wekan/wekan/blob/main/docs/Login/autologin.md
#- OIDC_REDIRECTION_ENABLED=true
# OIDC RP-initiated logout endpoint (end_session_endpoint). When set, the
# "Log Out" menu redirects to this endpoint so the identity provider session
# is also ended and the user is returned to Wekan (ROOT_URL) via
# post_logout_redirect_uri, instead of landing on the provider home page
# (which errors for non-admin users). See https://github.com/wekan/wekan/issues/6158
# Keycloak example:
#- OAUTH2_LOGOUT_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/logout
#-----------------------------------------------------------------
# ==== OAUTH2 ORACLE on premise identity manager OIM ====
#- ORACLE_OIM_ENABLED=true
#-----------------------------------------------------------------
# ==== OAUTH2 AZURE ====
# https://github.com/wekan/wekan/blob/main/docs/Login/Azure/Azure.md
# 1) Register the application with Azure. Make sure you capture
# the application ID as well as generate a secret key.
# 2) Configure the environment variables. This differs slightly
# by installation type, but make sure you have the following:
#- OAUTH2_ENABLED=true
# Optional OAuth2 CA Cert, see https://github.com/wekan/wekan/issues/3299
#- OAUTH2_CA_CERT=ABCD1234
# Use OAuth2 ADFS additional changes. Also needs OAUTH2_ENABLED=true setting.
#- OAUTH2_ADFS_ENABLED=false
# Azure AD B2C. https://github.com/wekan/wekan/issues/5242
#- OAUTH2_B2C_ENABLED=false
# SECURITY (GHSA-mp7g-hj5q-gxhq): Link an OIDC login to a pre-existing
# Wekan account (password/LDAP) with the same email. OFF by default; when
# false an OIDC login whose email already exists is rejected instead of
# merged, preventing account takeover via spoofed email claims. Only
# enable if you fully trust your OIDC provider's email claims, and even
# then the provider must send email_verified=true for the merge to happen.
#- OAUTH2_MERGE_EXISTING_USERS=false
# When false, OAuth2/OIDC login is refused for users that do not already
# have a Wekan account (matched by verified email).
#- OAUTH2_AUTO_REGISTRATION=true
# Comma/space separated OAuth2/OIDC group names whose members become Wekan
# admins. Empty = off.
#- OAUTH2_ADMIN_GROUPS=
# OAuth2 login style: redirect (default) or popup.
#- OAUTH2_LOGIN_STYLE=redirect
# Application GUID captured during app registration:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://login.microsoftonline.com/
#- OAUTH2_AUTH_ENDPOINT=/oauth2/v2.0/authorize
#- OAUTH2_USERINFO_ENDPOINT=https://graph.microsoft.com/oidc/userinfo
#- OAUTH2_TOKEN_ENDPOINT=/oauth2/v2.0/token
# The claim name you want to map to the unique ID field:
#- OAUTH2_ID_MAP=email
# The claim name you want to map to the username field:
#- OAUTH2_USERNAME_MAP=email
# The claim name you want to map to the full name field:
#- OAUTH2_FULLNAME_MAP=name
# The claim name you want to map to the email field:
#- OAUTH2_EMAIL_MAP=email
# Optional exact email domains for generic OAuth2/OIDC login (on-premise supported).
#- OAUTH2_ALLOWED_EMAIL_DOMAINS=example.internal,other.internal
# OAUTH2_DEFAULT_ORGANIZATION : an existing organization that every account
# created by an OAuth2/OIDC login joins (short name, display name or id).
#- OAUTH2_DEFAULT_ORGANIZATION=Nextcloud users
#-----------------------------------------------------------------
# ==== OAUTH2 Nextcloud ====
# 1) Register the application with Nextcloud: https://your.nextcloud/index.php/settings/admin/security
# Make sure you capture the application ID as well as generate a secret key.
# Use https://your.wekan/_oauth/oidc for the redirect URI.
# 2) Configure the environment variables. This differs slightly
# by installation type, but make sure you have the following:
#- OAUTH2_ENABLED=true
# OAuth2 login style: redirect (default) or popup.
#- OAUTH2_LOGIN_STYLE=redirect
# Application GUID captured during app registration:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://your-nextcloud.tld
#- OAUTH2_AUTH_ENDPOINT=/index.php/apps/oauth2/authorize
#- OAUTH2_USERINFO_ENDPOINT=/ocs/v2.php/cloud/user?format=json
#- OAUTH2_TOKEN_ENDPOINT=/index.php/apps/oauth2/api/v1/token
# The claim name you want to map to the unique ID field:
#- OAUTH2_ID_MAP=id
# The claim name you want to map to the username field:
#- OAUTH2_USERNAME_MAP=id
# The claim name you want to map to the full name field:
#- OAUTH2_FULLNAME_MAP=display-name
# The claim name you want to map to the email field:
#- OAUTH2_EMAIL_MAP=email
#-----------------------------------------------------------------
# ==== OAUTH2 KEYCLOAK ====
# https://github.com/wekan/wekan/blob/main/docs/Login/Keycloak/Keycloak.md <== MAPPING INFO, REQUIRED
#- OAUTH2_ENABLED=true
# OAuth2 login style: redirect (default) or popup.
#- OAUTH2_LOGIN_STYLE=redirect
#- OAUTH2_CLIENT_ID=<Keycloak create Client ID>
#- OAUTH2_SERVER_URL=<Keycloak server url - https://keycloak.example.com>
#- OAUTH2_AUTH_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/auth
#- OAUTH2_USERINFO_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/userinfo
#- OAUTH2_TOKEN_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/token
#- OAUTH2_SECRET=<keycloak client secret>
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_ID_MAP=sub
#- OAUTH2_USERNAME_MAP=preferred_username
#- OAUTH2_EMAIL_MAP=email
#- OAUTH2_FULLNAME_MAP=name
#-----------------------------------------------------------------
# ==== OAUTH2 AUTHELIA ====
# https://github.com/wekan/wekan/blob/main/docs/Features/Login-Page/Authelia.md <== MAPPING INFO, REQUIRED
# https://www.authelia.com/integration/openid-connect/introduction/
#- OAUTH2_ENABLED=true
# OAuth2 login style: redirect (default) or popup.
#- OAUTH2_LOGIN_STYLE=redirect
#- OAUTH2_CLIENT_ID=<Authelia client id>
#- OAUTH2_SERVER_URL=https://auth.yourserver.com
#- OAUTH2_AUTH_ENDPOINT=/api/oidc/authorization
#- OAUTH2_USERINFO_ENDPOINT=/api/oidc/userinfo
#- OAUTH2_TOKEN_ENDPOINT=/api/oidc/token
#- OAUTH2_SECRET=<Authelia client secret>
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_ID_MAP=sub
#- OAUTH2_USERNAME_MAP=preferred_username
#- OAUTH2_EMAIL_MAP=email
#- OAUTH2_FULLNAME_MAP=name
#- OAUTH2_REQUEST_PERMISSIONS=openid profile email
#-----------------------------------------------------------------
# ==== OAUTH2 DOORKEEPER ====
# https://github.com/wekan/wekan/issues/1874
# https://github.com/wekan/wekan/blob/main/docs/Login/OAuth2.md2
# Enable the OAuth2 connection
#- OAUTH2_ENABLED=true
# OAuth2 docs: https://github.com/wekan/wekan/blob/main/docs/Login/OAuth2.md
# OAuth2 login style: redirect (default) or popup.
#- OAUTH2_LOGIN_STYLE=redirect
# OAuth2 Client ID.
#- OAUTH2_CLIENT_ID=abcde12345
# OAuth2 Secret.
#- OAUTH2_SECRET=54321abcde
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
# OAuth2 Server URL.
#- OAUTH2_SERVER_URL=https://chat.example.com
# OAuth2 Authorization Endpoint.
#- OAUTH2_AUTH_ENDPOINT=/oauth/authorize
# OAuth2 Userinfo Endpoint.
#- OAUTH2_USERINFO_ENDPOINT=/oauth/userinfo
# OAuth2 Token Endpoint.
#- OAUTH2_TOKEN_ENDPOINT=/oauth/token
# OAUTH2 ID Token Whitelist Fields.
#- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=""
# OAUTH2 Request Permissions.
#- OAUTH2_REQUEST_PERMISSIONS=openid profile email
# OAuth2 ID Mapping
#- OAUTH2_ID_MAP=
# OAuth2 Username Mapping
#- OAUTH2_USERNAME_MAP=
# OAuth2 Fullname Mapping
#- OAUTH2_FULLNAME_MAP=
# OAuth2 Email Mapping
#- OAUTH2_EMAIL_MAP=
#-----------------------------------------------------------------
# ==== LDAP: UNCOMMENT ALL TO ENABLE LDAP ====
# https://github.com/wekan/wekan/blob/main/docs/Login/LDAP.md
# For Snap settings see https://github.com/wekan/wekan/blob/main/docs/Platforms/FOSS/Container/Snap/Supported-settings-keys.md
# Most settings work both on Snap and Docker below.
# Note: Do not add single quotes '' to variables. Having spaces still works without quotes where required.
#
# The default authentication method used if a user does not exist to create and authenticate. Can be set as ldap.
# (this is set properly in the Admin Panel, changing this item does not remove Password login option)
#- DEFAULT_AUTHENTICATION_METHOD=ldap
#
# Enable or not the connection by the LDAP
#- LDAP_ENABLE=true
#
# The port of the LDAP server
#- LDAP_PORT=389
#
# The host server for the LDAP server
#- LDAP_HOST=localhost
#
#-----------------------------------------------------------------
# ==== LDAP AD Simple Auth ====
#
# Set to true, if you want to connect with Active Directory by Simple Authentication.
# When using AD Simple Auth, LDAP_BASEDN is not needed.
#
# Example:
#- LDAP_AD_SIMPLE_AUTH=true
#
# === LDAP User Authentication ===
#
# a) Option to login to the LDAP server with the user's own username and password, instead of
# an administrator key. Default: false (use administrator key).
#
# b) When using AD Simple Auth, set to true, when login user is used for binding,
# and LDAP_BASEDN is not needed.
#
# Example:
#- LDAP_USER_AUTHENTICATION=true
#
# Which field is used to find the user for the user authentication. Default: uid.
#- LDAP_USER_AUTHENTICATION_FIELD=uid
#
# === LDAP Default Domain ===
#
# a) In case AD SimpleAuth is configured, the default domain is appended to the given
# loginname for creating the correct username for the bind request to AD.
#
# b) The default domain of the ldap it is used to create email if the field is not map
# correctly with the LDAP_SYNC_USER_DATA_FIELDMAP
#
# Example :
#- LDAP_DEFAULT_DOMAIN=mydomain.com
#
#-----------------------------------------------------------------
# ==== LDAP BASEDN Auth ====
#
# The base DN for the LDAP Tree
#- LDAP_BASEDN=ou=user,dc=example,dc=org
#
#-----------------------------------------------------------------
# Fallback on the default authentication method
#- LDAP_LOGIN_FALLBACK=false
#
# Reconnect to the server if the connection is lost
#- LDAP_RECONNECT=true
#
# Overall timeout, in milliseconds
#- LDAP_TIMEOUT=10000
#
# Specifies the timeout for idle LDAP connections in milliseconds
#- LDAP_IDLE_TIMEOUT=10000
#
# Connection timeout, in milliseconds
#- LDAP_CONNECT_TIMEOUT=10000
#
# If the LDAP needs a user account to search
#- LDAP_AUTHENTIFICATION=true
#
# The search user DN - You need quotes when you have spaces in parameters
# 2 examples:
#- LDAP_AUTHENTIFICATION_USERDN=CN=ldap admin,CN=users,DC=domainmatter,DC=lan
#- LDAP_AUTHENTIFICATION_USERDN=CN=wekan_adm,OU=serviceaccounts,OU=admin,OU=prod,DC=mydomain,DC=com
#
# The password for the search user
#- LDAP_AUTHENTIFICATION_PASSWORD=pwd
#- LDAP_AUTHENTIFICATION_PASSWORD_FILE=/run/secrets/ldap_auth_password
#
# Enable logs for the module
#- LDAP_LOG_ENABLED=true
#
# If the sync of the users should be done in the background
#- LDAP_BACKGROUND_SYNC=false
#
# LDAP_BACKGROUND_SYNC_INTERVAL : How often the background task syncs: milliseconds (3600000 = hourly) or text
# Text is later.js text, quotes allowed, as specified in:
# https://bunkat.github.io/later/parsers.html#text
#- LDAP_BACKGROUND_SYNC_INTERVAL=every 1 hours
# Unset or empty uses the default (hourly). A value it cannot read is logged
# and the default is used; it no longer stops WeKan (#2354).
# https://github.com/wekan/wekan/issues/2354#issuecomment-515305722
- 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 : When true, the LDAP
# background sync disables users no longer present in LDAP (and re-enables
# them when they reappear).
#- LDAP_BACKGROUND_SYNC_DISABLE_NONEXISTANT_USERS=false
#
# If using LDAPS: LDAP_ENCRYPTION=ssl
#- LDAP_ENCRYPTION=false
#
# The certification for the LDAPS server. Certificate needs to be included in this docker compose.yml file.
#- LDAP_CA_CERT=-----BEGIN CERTIFICATE-----MIIE+G2FIdAgIC...-----END CERTIFICATE-----
#
# Reject Unauthorized Certificate
#- LDAP_REJECT_UNAUTHORIZED=false
#
# Optional extra LDAP filters. Don't forget the outmost enclosing parentheses if needed
#- LDAP_USER_SEARCH_FILTER=
#
# base (search only in the provided DN), one (search only in the provided DN and one level deep), or sub (search the whole subtree)
#- LDAP_USER_SEARCH_SCOPE=one
#
# Which field is used to find the user, like uid / sAMAccountName
#- LDAP_USER_SEARCH_FIELD=sAMAccountName
#
# Used for pagination (0=unlimited)
#- LDAP_SEARCH_PAGE_SIZE=0
#
# The limit number of entries (0=unlimited)
#- LDAP_SEARCH_SIZE_LIMIT=0
#
# Enable the login restriction group filter. Note the authenticated ldap user must be able to query all relevant group data with own login data from ldap.
# When true, only members of LDAP_GROUP_FILTER_GROUP_NAME are allowed to log in.
# NOTE: This flag ONLY controls the login restriction. Admin status sync
# (LDAP_SYNC_ADMIN_STATUS / LDAP_SYNC_ADMIN_GROUPS) and group->role sync
# (LDAP_SYNC_GROUP_ROLES) query LDAP groups independently and do NOT require
# this flag to be true. The group filter metadata below
# (LDAP_GROUP_FILTER_OBJECTCLASS, LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE,
# LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT, LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE)
# must still be configured for any group search to work.
#- LDAP_GROUP_FILTER_ENABLE=false
#
# Where the GROUPS are, when they are not under LDAP_BASEDN. Leave this
# unset when users and groups share one subtree: the group searches then
# use LDAP_BASEDN, exactly as they always have. Set it when the directory
# keeps them apart - ou=groups beside ou=people is a common layout - or
# every group search runs under the USER base, finds nothing, and
# LDAP_GROUP_FILTER_ENABLE=true refuses every login (wekan/wekan#5539).
#- LDAP_GROUP_BASEDN=ou=groups,dc=example,dc=org
#
# The object class for filtering. Example: group
#- LDAP_GROUP_FILTER_OBJECTCLASS=
#
# The attribute of a group identifying it. Example: cn
#- LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE=
#
# The attribute inside a group object listing its members. Example: member
#- LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE=
#
# The format of the value of LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE. Example: 'dn' if the users dn is saved as value into the attribute.
#- LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=
#
# Active Directory nested groups (#6744). When true, a user who is a member of
# LDAP_GROUP_FILTER_GROUP_NAME through another group (team group -> access
# group) is a member too: the group searches use AD's
# LDAP_MATCHING_RULE_IN_CHAIN (1.2.840.113556.1.4.1941). Needs a DN-valued
# member attribute (member, with LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=dn).
# Also applies to admin status, group->role and org/team sync. Default: false.
#- LDAP_GROUP_FILTER_NESTED=true
#
# Let users moved from local password login to LDAP still log in with their old local password (true). Default: false
#- LDAP_MIGRATION_ALLOW_PASSWORD_LOGIN=
#
# Comma separated LDAP attributes to read for a user. Empty: all attributes. Example: uid,cn,mail
#- LDAP_USER_ATTRIBUTES=
#
# The OIDC user info claim that holds the avatar URL. Default: picture
#- OAUTH2_AVATAR_MAP=
#
# Update groups, admin status, e-mail, full name and username from the OIDC provider at every login (true). Default: false
#- PROPAGATE_OIDC_DATA=
#
# Sign in with Apple: path to the private key (.p8) that signs the client secret JWT. Empty: OAUTH2_SECRET is used
#- OAUTH2_SECRET_JWT_KEY_PATH=
#
# Sign in with Apple: the Team ID, issuer of the client secret JWT
#- OAUTH2_SECRET_JWT_ISSUER=
#
# Sign in with Apple: the Key ID of the private key
#- OAUTH2_SECRET_JWT_KEY_ID=
#
# Audience of the client secret JWT. Default: https://appleid.apple.com
#- OAUTH2_SECRET_JWT_AUDIENCE=
#
# Subject of the client secret JWT. Default: OAUTH2_CLIENT_ID
#- OAUTH2_SECRET_JWT_SUBJECT=
#
# Lifetime of the client secret JWT in seconds. Default: 300
#- OAUTH2_SECRET_JWT_EXPIRES_IN=
#
# Let a CAS login take over an existing local account with the same username (true). Default: false
#- CAS_MERGE_EXISTING_USERS=
#
# The group name (id) that matches all users.
#- LDAP_GROUP_FILTER_GROUP_NAME=
#
# LDAP_UNIQUE_IDENTIFIER_FIELD : This field is sometimes class GUID (Globally Unique Identifier). Example: guid
#- LDAP_UNIQUE_IDENTIFIER_FIELD=
#
# LDAP_UTF8_NAMES_SLUGIFY : Convert the username to utf8
#- LDAP_UTF8_NAMES_SLUGIFY=true
#
# LDAP_USERNAME_FIELD : Which field contains the ldap username. username / sAMAccountName
#- LDAP_USERNAME_FIELD=sAMAccountName
#
# LDAP_FULLNAME_FIELD : Which field contains the ldap fullname. fullname / sAMAccountName
#- LDAP_FULLNAME_FIELD=fullname
#
#- LDAP_MERGE_EXISTING_USERS=false
#
# Allow existing account matching by e-mail address when username does not match
#- LDAP_EMAIL_MATCH_ENABLE=true
#
# LDAP_EMAIL_MATCH_REQUIRE : require existing account matching by e-mail address when username does match
#- LDAP_EMAIL_MATCH_REQUIRE=true
#
# LDAP_EMAIL_MATCH_VERIFIED : require existing account email address to be verified for matching
#- LDAP_EMAIL_MATCH_VERIFIED=true
#
# LDAP_EMAIL_FIELD : which field contains the LDAP e-mail address
#- LDAP_EMAIL_FIELD=mail
#-----------------------------------------------------------------
#- LDAP_SYNC_USER_DATA=false
#
#- LDAP_SYNC_USER_DATA_FIELDMAP={"cn":"name", "mail":"email"}
#
#- LDAP_SYNC_GROUP_ROLES=
#
# The default domain of the ldap it is used to create email if the field is not map correctly
# with the LDAP_SYNC_USER_DATA_FIELDMAP is defined in setting LDAP_DEFAULT_DOMAIN above.
#
# Enable/Disable syncing of admin status based on ldap groups:
# NOTE: Admin status sync and group->role sync (LDAP_SYNC_GROUP_ROLES) query
# LDAP groups on their own. They no longer require LDAP_GROUP_FILTER_ENABLE=true,
# which only controls the login restriction filter. The group filter metadata
# (LDAP_GROUP_FILTER_OBJECTCLASS, LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE,
# LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT, LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE)
# must still be configured for the group search to work.
#- LDAP_SYNC_ADMIN_STATUS=true
#
# Comma separated list of admin group names to sync.
#- LDAP_SYNC_ADMIN_GROUPS=group1,group2
#
# When true, sync a user's LDAP groups as Wekan Organizations.
#- LDAP_SYNC_ORGANIZATIONS=false
#
# Comma separated allowlist of LDAP group names/patterns to sync as Organizations.
# Wildcards supported: * (any chars), ? (single char). Empty = all of the user's groups.
#- LDAP_SYNC_ORGANIZATIONS_GROUPS=
#
# When true, sync a user's LDAP groups as Wekan Teams.
#- LDAP_SYNC_TEAMS=false
#
# Comma separated allowlist of LDAP group names/patterns to sync as Teams.
# Wildcards supported: * (any chars), ? (single char). Empty = all of the user's groups.
#- LDAP_SYNC_TEAMS_GROUPS=
#---------------------------------------------------------------------
# Login to LDAP automatically with HTTP header.
# In below example for siteminder, at right side of = is header name.
#- HEADER_LOGIN_ID=HEADERUID
#- HEADER_LOGIN_FIRSTNAME=HEADERFIRSTNAME
#- HEADER_LOGIN_LASTNAME=HEADERLASTNAME
#- HEADER_LOGIN_EMAIL=HEADEREMAILADDRESS
# SECURITY (GHSA-jggc-qvfc-jr6x): comma-separated allowlist of source IPs
# permitted to use header login. The source IP is the real TCP peer of the
# connection (your reverse proxy), NOT the spoofable X-Forwarded-For header.
# REQUIRED when header login is enabled: if empty/unset, header login fails
# CLOSED and authenticates no one.
#- HEADER_LOGIN_TRUSTED_IPS=127.0.0.1,10.0.0.2
# Optional: if WeKan sits behind MULTIPLE proxy hops, list the intermediate
# proxy IPs here. X-Forwarded-For is then honored ONLY when the immediate
# TCP peer is one of these trusted proxies, and the right-most hop that is
# not itself a trusted proxy (the real client) is matched against
# HEADER_LOGIN_TRUSTED_IPS above.
#- HEADER_LOGIN_TRUSTED_PROXIES=10.0.0.1,10.0.0.2
#---------------------------------------------------------------------
# ==== LOGOUT TIMER, probably does not work yet ====
# LOGOUT_WITH_TIMER : Enables or not the option logout with timer
# example : LOGOUT_WITH_TIMER=true
#- LOGOUT_WITH_TIMER=
#
# LOGOUT_IN : The number of days
# example : LOGOUT_IN=1
#- LOGOUT_IN=
#
# LOGOUT_ON_HOURS : The number of hours
# example : LOGOUT_ON_HOURS=9
#- LOGOUT_ON_HOURS=
#
# LOGOUT_ON_MINUTES : The number of minutes
# example : LOGOUT_ON_MINUTES=55
#- LOGOUT_ON_MINUTES=
#---------------------------------------------------------------
# USERS_DISABLE_INACTIVE_AFTER_DAYS : once a night, disable accounts that
# have not used WeKan for this many days (Admin Panel > People > Last
# active). Admins are never disabled. Accounts with no recorded activity
# yet are counted from the first run. Re-enabling an account restarts its
# count. Unset or 0 = off (default). Admin Panel / People / Login can set
# it too, and its value there wins.
#- USERS_DISABLE_INACTIVE_AFTER_DAYS=180
#---------------------------------------------------------------
# LOGOUT_IDLE_MINUTES : Sign a browser session out after this many minutes without a key press, click,
# touch or scroll. Empty or 0 = off (default). REST API tokens are not affected.
#- LOGOUT_IDLE_MINUTES=30
#---------------------------------------------------------------
# REQUIRE_2FA : Compulsory two-factor authentication for accounts that sign in with a WeKan password:
# off (default), admins or all. They must set it up right after signing in.
#- REQUIRE_2FA=admins
#---------------------------------------------------------------
# PASSWORD_MIN_LENGTH : Minimum password length, in characters. Default 8. A sign-in with a shorter
# password is listed in Admin Panel / Problems / Password length; nothing is refused unless enforced:
#- PASSWORD_MIN_LENGTH=12
# PASSWORD_MIN_LENGTH_ENFORCE : true = refuse a shorter new password, and make an account that
# signs in with a shorter one change it; the change signs every session out. Off by default.
#- PASSWORD_MIN_LENGTH_ENFORCE=true
#---------------------------------------------------------------
# PASSWORD_CHECK_PWNED : true = refuse a new password found in a known data breach. Off by default.
# Only 5 hex digits of its SHA-1 are sent to api.pwnedpasswords.com.
#- PASSWORD_CHECK_PWNED=true
#---------------------------------------------------------------
# HSTS_MAX_AGE : Strict-Transport-Security max-age in seconds, sent only when ROOT_URL is https.
# Default 15552000 (180 days). 0 = do not send it.
#- HSTS_MAX_AGE=31536000
#---------------------------------------------------------------
# HSTS_INCLUDE_SUBDOMAINS : true = HSTS covers every subdomain too. Only when ALL of them have HTTPS.
#- HSTS_INCLUDE_SUBDOMAINS=false
#---------------------------------------------------------------
# HSTS_PRELOAD : true = add the preload token (needs includeSubDomains and max-age >= 31536000).
#- HSTS_PRELOAD=false
#---------------------------------------------------------------
# BACKUP_KEEP_DAYS : after each successful Admin Panel backup, delete
# local (filesystem) backups older than this many days; the newest is
# always kept. Unset or 0 = keep all (default). Admin Panel / Attachments
# / Backup can set it too, and its value there wins. docs/Backup/Backup.md
#- BACKUP_KEEP_DAYS=7
#---------------------------------------------------------------
# ACCOUNTS_COOKIE_REFRESH_RATE_LIMIT : Login-cookie refreshes allowed per
# 10 seconds from one address (Meteor default 30); raise it behind a
# reverse proxy that is not trusted for the client address. Admin Panel /
# People / Login overrides it; applies from the next start.
#- ACCOUNTS_COOKIE_REFRESH_RATE_LIMIT=100
# INBOUND_IMAP_POLL_SECONDS : Email to card: how often IMAP mailboxes are
# read, in seconds (default 60, at least 15).
#- INBOUND_IMAP_POLL_SECONDS=60
# INBOUND_EMAIL_PER_ADDRESS_PER_HOUR : Email to card: cards one sender
# address can make per hour (default 60).
#- INBOUND_EMAIL_PER_ADDRESS_PER_HOUR=60
# INBOUND_EMAIL_WEBHOOK_SECRET : the secret the mail provider must send
# with each webhook POST, if not set in the Admin Panel.
#- INBOUND_EMAIL_WEBHOOK_SECRET=long-random-value
# INBOUND_EMAIL_MAX_BYTES : Email to card: largest message in bytes
# (default 31457280, 30 MB).
#- INBOUND_EMAIL_MAX_BYTES=31457280
# INBOUND_EMAIL_MAX_ATTACHMENT_BYTES : Email to card: largest attachment
# in bytes (default 26214400, 25 MB).
#- INBOUND_EMAIL_MAX_ATTACHMENT_BYTES=26214400
# EMAIL_VIEW_SENDS_PER_HOUR : Emails one user can send from the email view
# per hour (default 50).
#- EMAIL_VIEW_SENDS_PER_HOUR=50
# Admin Panel / People / Notification Settings / Email to card overrides the email ones.
#---------------------------------------------------------------
# Per server process, environment only:
# INBOUND_IMAP_DISABLED : true stops THIS server process from reading IMAP
# mailboxes - for a multi-pod deployment where one pod should read them.
# Environment only: an Admin Panel value would be shared by every pod.
#- INBOUND_IMAP_DISABLED=true
# WEKAN_DISK_MONITOR : false turns off the disk-usage monitor of this
# server (Admin Panel / Problems / Disk usage). Default on.
#- WEKAN_DISK_MONITOR=false
# WEKAN_DISK_WATCH_PATHS : Comma-separated paths on this server whose disk
# usage is watched, instead of the data and files directories.
#- WEKAN_DISK_WATCH_PATHS=/data,/var/lib/wekan
# WEKAN_RAM_MONITOR : false turns off the memory monitor of this server
# (Admin Panel / Problems / Memory usage). Default on.
#- WEKAN_RAM_MONITOR=false
# WEKAN_IMPORT_RUN_STALE_MS : Milliseconds after which an import with no
# progress counts as interrupted and can be resumed or discarded (at least
# 60000).
#- WEKAN_IMPORT_RUN_STALE_MS=600000
#---------------------------------------------------------------
# ATTACHMENT RETENTION (models/lib/attachmentRetention.js). Off unless set.
# ATTACHMENTS_RETENTION_DAYS : once a night, delete card attachments older
# than this many days. A normal delete: restorable from the card history.
#- ATTACHMENTS_RETENTION_DAYS=730
# ATTACHMENTS_RETENTION_MODE : uploaded (default) = by upload date;
# card-inactive = also only when the card has had no activity for as long.
#- ATTACHMENTS_RETENTION_MODE=uploaded
# ATTACHMENTS_PURGE_DELETED_AFTER_DAYS : remove for good, file included,
# attachments deleted (by retention or by anyone) this many days ago.
# Only this frees storage.
#- ATTACHMENTS_PURGE_DELETED_AFTER_DAYS=30
# ATTACHMENTS_RETENTION_DRY_RUN=true : only log what would happen.
#- ATTACHMENTS_RETENTION_DRY_RUN=true
# ATTACHMENTS_RETENTION_MAX_PER_RUN : per step per night (default 1000).
#- ATTACHMENTS_RETENTION_MAX_PER_RUN=1000
#-------------------------------------------------------------------
# Hide password login form
# - PASSWORD_LOGIN_ENABLED=true
#-------------------------------------------------------------------
#- CAS_ENABLED=true
#- CAS_BASE_URL=https://cas.example.com/cas
#- CAS_LOGIN_URL=https://cas.example.com/login
#- CAS_VALIDATE_URL=https://cas.example.com/cas/p3/serviceValidate
#---------------------------------------------------------------------
#- SAML_ENABLED=true
#- 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 : assertion attribute whose value becomes
# the WeKan username (e.g. username). Empty = the email / NameID. With
# SAML_MERGE_EXISTING_USERS=true an existing account is found by that
# username, or - when the value is the assertion's email - by a verified
# email, so an LDAP account with its own short username can be linked.
# Linking an existing account ALSO requires the assertion to carry the
# attribute email_verified=true (SAML has no standard one: add it at the
# IdP only if the IdP verifies addresses) and that email to be verified on
# the local account. A refused link logs its reason in the server log.
# docs/Features/Login-Page/SAML.md
#- SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE=
# SAML_ATTRIBUTES : not used by login at the moment; attributes are read
# from the validated assertion as named (email, username, displayName).
#- SAML_ATTRIBUTES=
#- SAML_MERGE_EXISTING_USERS=false
#- SAML_IDP_PROFILE=standard
#- SAML_WANT_RESPONSE_SIGNED=
#- SAML_WANT_ASSERTIONS_SIGNED=
#- SAML_LOGIN_FLOW=
#---------------------------------------------------------------------
# Login with Meteor accounts providers, see docs/Features/Login-Page/OAuth-Providers.md
# and docs/Features/Login-Page/Passwordless.md. Every one of these can be overridden
# in Admin Panel / People / Login; a value set there wins over the environment
# variable. Register this callback URL at the provider:
# <ROOT_URL>/_oauth/<service> where service is google, github, facebook,
# twitter, meteor-developer, weibo or meetup.
# ==== Google ==== create the app at https://console.cloud.google.com/apis/credentials
# callback URL: <ROOT_URL>/_oauth/google
#- OAUTH_GOOGLE_ENABLED=true
#- OAUTH_GOOGLE_CLIENT_ID=
#- OAUTH_GOOGLE_SECRET=
# OAUTH_GOOGLE_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_GOOGLE_SECRET_FILE=/run/secrets/oauth_google_secret
# ==== GitHub ==== create the app at https://github.com/settings/developers
# callback URL: <ROOT_URL>/_oauth/github
#- OAUTH_GITHUB_ENABLED=true
#- OAUTH_GITHUB_CLIENT_ID=
#- OAUTH_GITHUB_SECRET=
# OAUTH_GITHUB_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_GITHUB_SECRET_FILE=/run/secrets/oauth_github_secret
# ==== Facebook ==== create the app at https://developers.facebook.com/apps/
# callback URL: <ROOT_URL>/_oauth/facebook
#- OAUTH_FACEBOOK_ENABLED=true
#- OAUTH_FACEBOOK_APP_ID=
#- OAUTH_FACEBOOK_SECRET=
# OAUTH_FACEBOOK_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_FACEBOOK_SECRET_FILE=/run/secrets/oauth_facebook_secret
# ==== Twitter / X ==== create the app at https://developer.x.com/en/portal/dashboard
# callback URL: <ROOT_URL>/_oauth/twitter
#- OAUTH_TWITTER_ENABLED=true
#- OAUTH_TWITTER_CONSUMER_KEY=
#- OAUTH_TWITTER_SECRET=
# OAUTH_TWITTER_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_TWITTER_SECRET_FILE=/run/secrets/oauth_twitter_secret
# ==== Meteor Developer ==== create the app at https://www.meteor.com/
# callback URL: <ROOT_URL>/_oauth/meteor-developer
#- OAUTH_METEOR_DEVELOPER_ENABLED=true
#- OAUTH_METEOR_DEVELOPER_CLIENT_ID=
#- OAUTH_METEOR_DEVELOPER_SECRET=
# OAUTH_METEOR_DEVELOPER_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_METEOR_DEVELOPER_SECRET_FILE=/run/secrets/oauth_meteor_developer_secret
# ==== Weibo ==== create the app at https://open.weibo.com/
# callback URL: <ROOT_URL>/_oauth/weibo
#- OAUTH_WEIBO_ENABLED=true
#- OAUTH_WEIBO_CLIENT_ID=
#- OAUTH_WEIBO_SECRET=
# OAUTH_WEIBO_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_WEIBO_SECRET_FILE=/run/secrets/oauth_weibo_secret
# ==== Meetup ==== create the app at https://www.meetup.com/api/oauth/list/
# callback URL: <ROOT_URL>/_oauth/meetup
#- OAUTH_MEETUP_ENABLED=true
#- OAUTH_MEETUP_CLIENT_ID=
#- OAUTH_MEETUP_SECRET=
# OAUTH_MEETUP_SECRET_FILE : read the secret from a file (Docker secrets) instead
#- OAUTH_MEETUP_SECRET_FILE=/run/secrets/oauth_meetup_secret
# OAUTH_PROVIDERS_LOGIN_STYLE : redirect or popup, for all providers above. Default: redirect
#- OAUTH_PROVIDERS_LOGIN_STYLE=redirect
# OAUTH_PROVIDERS_MERGE_EXISTING_USERS : link a provider login to an existing WeKan
# account with the same email. Default: false = the login is refused, not merged,
# like OAUTH2_MERGE_EXISTING_USERS. Enable only if you trust the provider's emails.
#- OAUTH_PROVIDERS_MERGE_EXISTING_USERS=false
# OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS : only these email domains may sign in with
# the providers above, comma separated, like OAUTH2_ALLOWED_EMAIL_DOMAINS. Empty: all.
#- OAUTH_PROVIDERS_ALLOWED_EMAIL_DOMAINS=example.com
# PASSWORDLESS_ENABLED : email a one-time sign-in code instead of asking a
# password. Needs MAIL_URL. Also switchable in Admin Panel / People / Login.
#- PASSWORDLESS_ENABLED=true
#---------------------------------------------------------------------
# Wait spinner to use
# - WAIT_SPINNER=Bounce
#---------------------------------------------------------------------
# Wait for MongoDB to be healthy (replica-set primary elected) before
# starting WeKan, so index creation does not crash with "Topology is closed".
# If you use FerretDB instead, comment out the wekandb block below and
# uncomment the wekan-ferretdb block.
depends_on:
wekandb:
condition: service_healthy
# wekan-migrate:
# condition: service_completed_successfully
# wekan-ferretdb:
# condition: service_healthy
volumes:
- /etc/localtime:/etc/localtime:ro
- wekan-files:/data:rw
# Secrets are optional. Uncomment below and ensure files exist to use them.
#secrets:
# - ldap_auth_password
# - oauth2_secret
# - mail_url
# - mongo_url
# - s3_secret_key
#---------------------------------------------------------------------------------
# ==== OPTIONAL: SHARE DATABASE TO OFFICE LAN AND REMOTE VPN ====
# When using Wekan both at office LAN and remote VPN:
# 1) Have above Wekan docker container config with LAN IP address
# 2) Copy all of above wekan container config below, look above of this part above and all config below it,
# before above depends_on: part:
#
# wekan:
# #-------------------------------------------------------------------------------------
# # ==== MONGODB AND METEOR VERSION ====
# # a) For Wekan Meteor 1.8.x version at meteor-1.8 branch, .....
#
#
# and change name to different name like wekan2 or wekanvpn, and change ROOT_URL to server VPN IP
# address.
# 3) This way both Wekan containers can use same MongoDB database
# and see the same Wekan boards.
# 4) You could also add 3rd Wekan container for 3rd network etc.
# EXAMPLE:
# wekan2:
# ....COPY CONFIG FROM ABOVE TO HERE...
# environment:
# - ROOT_URL='http://10.10.10.10'
# ...COPY CONFIG FROM ABOVE TO HERE...
#---------------------------------------------------------------------------------
# OPTIONAL NGINX CONFIG FOR REVERSE PROXY
# nginx:
# image: nginx
# container_name: nginx
# restart: always
# networks:
# - wekan-tier
# depends_on:
# - wekan
# ports:
# - 80:80
# - 443:443
# volumes:
# - ./nginx/ssl:/etc/nginx/ssl/:ro
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
## Alternative volume config:
## volumes:
## - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
## - ./nginx/ssl/ssl.conf:/etc/nginx/conf.d/ssl/ssl.conf:ro
## - ./nginx/ssl/testvm-ehu.crt:/etc/nginx/conf.d/ssl/certs/mycert.crt:ro
## - ./nginx/ssl/testvm-ehu.key:/etc/nginx/conf.d/ssl/certs/mykey.key:ro
## - ./nginx/ssl/pphrase:/etc/nginx/conf.d/ssl/pphrase:ro
volumes:
wekan-files:
driver: local
#wekan-postgres:
# driver: local
# Legacy MongoDB volumes — kept so existing data survives until migration is done.
# Remove once migration is verified and old MongoDB is decommissioned.
wekan-db:
driver: local
wekan-db-dump:
driver: local
networks:
wekan-tier:
driver: bridge
# Docker Compose Secrets
# Create secret files on the host system before running docker-compose up
# Example: echo "your_password_here" > ldap_auth_password.txt
# Then use: docker-compose up -d
# Secrets are optional. Uncomment to enable and ensure files exist at provided paths.
#secrets:
# ldap_auth_password:
# file: ./secrets/ldap_auth_password.txt
# oauth2_secret:
# file: ./secrets/oauth2_secret.txt
# mail_url:
# file: ./secrets/mail_url.txt
# mongo_url:
# file: ./secrets/mongo_url.txt
# s3_secret_key:
# file: ./secrets/s3_secret_key.txt