OpenLogs

All tools

Leantime

Project management system for teams that do not have a dedicated project manager.

Replaces

Paid project management services, such as Asana and Jira.

All open-source alternatives to Asana, Jira

Difficulty

Difficulty: Hard

3 services (2 database or broker: mysql), 5 volume mounts, 1 env value to set, host access: cap_add. Heuristic score 7 of 11: hard.

Stack

PHP (language), MySQL (database)

Deployment

docker_compose

Requirements

Not stated.

License

AGPL-3.0 (OSI-approved open source)

Read from github.com/Leantime/leantime/blob/8464a2e/LICENSE

Business model

Unknown

The README at the pinned commit does not state a business model, so it stays unknown.

Source: github.com/Leantime/leantime/blob/8464a2e/README.md, read on .

Repository

Leantime/leantime

GitHub stats

Stars
11,882
Forks
1,156
Open issues and pull requests
236
Last push
2026-10-21
Latest release
v3.12.0
Released
2026-10-15

From the GitHub API on . These numbers are a snapshot, not live. GitHub detected the license as AGPL-3.0.

Compose file

Config check passed docker compose config exited 0 on this exact file on 2026-10-22.
docker-compose.yml Version 1
version: '3.3'

services:
  leantime_db:
    image: mysql:8.4
    container_name: mysql_leantime
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped
    env_file: ./.env                                        # Environment file with settings
    networks:
      - leantime-net
    command: --character-set-server=UTF8MB4 --collation-server=UTF8MB4_unicode_ci
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

  leantime:
    image: leantime/leantime:${LEAN_VERSION:-latest}
    restart: unless-stopped
    env_file: ./.env                                        # Environment file with settings
    # Add security options
    security_opt:
      - no-new-privileges:true
    # Add capabilities
    cap_add:
      # - CAP_NET_BIND_SERVICE
      - CAP_CHOWN
      - CAP_SETGID
      - CAP_SETUID
    ports:
      - "${LEAN_PORT:-8080}:8080"
    networks:
      - leantime-net
    volumes:
      - public_userfiles:/var/www/html/public/userfiles     # Volume to store public files, logo etc
      - userfiles:/var/www/html/userfiles                   # Original volume name for compatibility
      - plugins:/var/www/html/app/Plugins                   # Plugin storage
      - logs:/var/www/html/storage/logs                     # Log storage
    depends_on:
      leantime_db:
        condition: service_healthy

  # Add a helper container for volume permissions
  # Run via docker compose --profile mysql_helper up -d
  mysql_helper:
    image: mysql:8.4
    command: chown -R mysql:mysql /var/lib/mysql
    volumes:
      - db_data:/var/lib/mysql
    user: root
    profiles: [ "helper" ]

volumes:
  db_data:
  userfiles:                                               # New volume for public files
  public_userfiles:
  plugins:
  logs:

networks:
  leantime-net:

From a separate packaging repository: github.com/Leantime/docker-leantime/blob/8718fac/docker-compose.yml.

Compose file from Leantime/docker-leantime, the project's own packaging repository.

Install

  1. Docker with the Compose plugin (github.com/Leantime/docker-leantime/blob/8718fac/README.md)

    A host with Docker and the Docker Compose plugin. This entry runs from a compose file.

  2. Save the compose file as docker-compose.yml (github.com/Leantime/docker-leantime/blob/8718fac/docker-compose.yml)

    Use the compose file shown above.

  3. Save as .env next to the compose file (github.com/Leantime/docker-leantime/blob/8718fac/sample.env)
    # This is a sample configuration file with all possible configuration options.
    # If you don't want to maintain a file like this you can pass in all variables via Server Variables
    
    ## Minimum Configuration, these are required for installation
    
    # NOTE: PUID/PGID are BUILD arguments, not runtime settings. The published
    # leantime/leantime images are built with uid/gid 1000 and setting these here has
    # NO effect — they only apply if you build the image yourself and pass them with
    # --build-arg. To run the published image under a different uid, set `user:` in
    # docker-compose.yml with group 0, e.g. user: "1001:0".
    #
    # Upgrading an existing install? Docker only seeds a named volume from the image
    # when the volume is EMPTY, so userfiles/plugins/logs volumes created by an older
    # image keep their original ownership and will still throw permission errors under
    # a new uid. Fix them once from the host, e.g.
    #   docker run --rm -v leantime_userfiles:/v alpine chgrp -R 0 /v && chmod -R g=u /v
    # (repeat per volume), or recreate the volumes if you have no data to keep.
    
    LEAN_PORT = '8080'                                 # The port to expose and access Leantime
    LEAN_APP_URL = ''                                  # Base URL, needed for subfolder or proxy installs (including http:// or https://)
    LEAN_APP_DIR = ''                                  # Base of application without trailing slash (used for cookies), e.g, /leantime
    
    LEAN_DEBUG = 0                                     # Debug flag
    
    # Database - MySQL container
    MYSQL_ROOT_PASSWORD = 'changeme123'                # MySQL root password
    MYSQL_DATABASE = 'leantime'                        # Database name
    MYSQL_USER = 'lean'                                # Database username
    MYSQL_PASSWORD = 'changeme123'                     # Database password
    
    # Database - leantime container
    LEAN_DB_HOST = 'mysql_leantime'                    # Database host
    LEAN_DB_USER = 'lean'                              # Database username (needs to be the same as MYSQL_USER)
    LEAN_DB_PASSWORD = 'changeme123'                   # Database password (needs to be the same as MYSQL_PASSWORD)
    LEAN_DB_DATABASE = 'leantime'                      # Database name (needs to be the same as MYSQL_DATABASE)
    LEAN_DB_PORT = '3306'                              # Database port
    
    ## Session Management
    LEAN_SESSION_PASSWORD = '3evBlq9zdUEuzKvVJHWWx3QzsQhturBApxwcws2m'  # Salting sessions, replace with a strong password
    LEAN_SESSION_EXPIRATION = 28800                    # How many seconds after inactivity should we logout?  28800seconds = 8hours
    LEAN_SESSION_SECURE = false                        # Serve cookies via https only? Set to true when using https, set to false when using http. 
    
    
    ## Optional Configuration, you may omit these from your .env file
    
    ## Default Settings
    LEAN_SITENAME = 'Leantime'                         # Name of your site, can be changed later
    LEAN_LANGUAGE = 'en-US'                            # Default language
    LEAN_DEFAULT_TIMEZONE = 'America/Los_Angeles'      # Set default timezone
    LEAN_LOG_PATH = ''                                 # Default Log Path (including filename), if not set /logs/error.log will be used
    LEAN_DISABLE_LOGIN_FORM = false                    # If true then don't show the login form (useful only if additional auth method[s] are available)
    
    ## Look & Feel, these settings are available in the UI and can be overwritten there.
    LEAN_LOGO_PATH = '/dist/images/logo.svg'           # Default logo path, can be changed later
    LEAN_PRINT_LOGO_URL = '/dist/images/logo.png'      # Default logo URL use for printing (must be jpg or png format)
    LEAN_DEFAULT_THEME = 'default'                     # Default theme
    LEAN_PRIMARY_COLOR = '#006d9f'                     # Primary Theme color
    LEAN_SECONDARY_COLOR =' #00a886'                   # Secondary Theme Color
    
    
    ## Fileuploads
    
    # Local File Uploads
    LEAN_USER_FILE_PATH = 'userfiles/'                 # Local relative path to store uploaded files (if not using S3)
    LEAN_DB_BACKUP_PATH = 'backupdb/'                  # Local relative path to store backup files, need permission to write
    
    # S3 File Uploads
    LEAN_USE_S3 = false                                # Set to true if you want to use S3 instead of local files
    LEAN_S3_KEY = ''                                   # S3 Key
    LEAN_S3_SECRET = ''                                # S3 Secret
    LEAN_S3_BUCKET = ''                                # Your S3 bucket
    LEAN_S3_USE_PATH_STYLE_ENDPOINT = false            # Sets the endpoint style: false => https://[bucket].[endpoint] ; true => https://[endpoint]/[bucket]
    LEAN_S3_REGION = ''                                # S3 region
    LEAN_S3_FOLDER_NAME = ''                           # Foldername within S3 (can be empty)
    LEAN_S3_END_POINT = null                           # S3 EndPoint S3 Compatible (https://sfo2.digitaloceanspaces.com)
    
    ## Email
    LEAN_EMAIL_RETURN = ''                             # Return email address, needs to be valid email address format
    LEAN_EMAIL_USE_SMTP = false                        # Use SMTP? If set to false, the default php mail() function will be used
    LEAN_EMAIL_SMTP_HOSTS = ''                         # SMTP host
    LEAN_EMAIL_SMTP_AUTH = true                        # SMTP authentication required
    LEAN_EMAIL_SMTP_USERNAME = ''                      # SMTP username
    LEAN_EMAIL_SMTP_PASSWORD = ''                      # SMTP password
    LEAN_EMAIL_SMTP_AUTO_TLS = true                    # SMTP Enable TLS encryption automatically if a server supports it
    LEAN_EMAIL_SMTP_SECURE = ''                        # SMTP Security protocol (usually one of: TLS, SSL, STARTTLS)
    LEAN_EMAIL_SMTP_SSLNOVERIFY = false                # SMTP Allow insecure SSL: Don't verify certificate, accept self-signed, etc.
    LEAN_EMAIL_SMTP_PORT = ''                          # Port (usually one of 25, 465, 587, 2526)
    
    ## LDAP
    LEAN_LDAP_USE_LDAP = false                         # Set to true if you want to use LDAP
    LEAN_LDAP_LDAP_DOMAIN = ''                         # Domain name after username@ so users can login without domain definition
    LEAN_LDAP_LDAP_TYPE = 'OL'                         # Select the correct directory type. Currently Supported: OL - OpenLdap, AD - Active Directory
    LEAN_LDAP_HOST = ''                                # FQDN
    LEAN_LDAP_PORT = 389                               # Default Port
    LEAN_LDAP_URI = ''                                 # LDAP URI as alternative to hostname and port. Uses ldap://hostname:port
    LEAN_LDAP_DN = ''                                  # Location of users, example: CN=users,DC=example,DC=com
                                                       # Leantime->Ldap attribute mapping
    LEAN_LDAP_KEYS="{
            \"username\":\"uid\",
            \"groups\":\"memberOf\",
            \"email\":\"mail\",
            \"firstname\":\"displayname\",
            \"lastname\":\"\",
            \"phone\":\"telephoneNumber\",
            \"jobTitle\":\"title\"
            \"jobLevel\":\"level\"
            \"department\":\"department\"
    
    }"
    
    # For AD use these default attributes
    # LEAN_LDAP_KEYS="{
    #        \"username\":\"cn\",
    #        \"groups\":\"memberOf\",
    #        \"email\":\"mail\",
    #        \"firstname\":\"givenName\",
    #        \"lastname\":\"sn\",
    #        \"phone\":\"telephoneNumber\",
    #        \"jobTitle\":\"title\"
    #        \"jobLevel\":\"level\"
    #        \"department\":\"department\"
    #      }"
    
    LEAN_LDAP_DEFAULT_ROLE_KEY = 20;                   # Default Leantime Role on creation. (set to editor)
    
    # Default role assignments upon first login.
    # optional - Can be updated later in user settings for each user
    LEAN_LDAP_GROUP_ASSIGNMENT="{
                   \"5\": {
                     \"ltRole\":\"readonly\",
                     \"ldapRole\":\"readonly\"
                   },
                   \"10\": {
                     \"ltRole\":\"commenter\",
                      \"ldapRole\":\"commenter\"
                   },
                   \"20\": {
                     \"ltRole\":\"editor\",
                      \"ldapRole\":\"editor\"
                   },
                   \"30\": {
                     \"ltRole\":\"manager\",
                      \"ldapRole\":\"manager\"
                   },
                   \"40\": {
                     \"ltRole\":\"admin\",
                      \"ldapRole\":\"administrators\"
                   },
                   \"50\": {
                     \"ltRole\":\"owner\",
                     \"ldapRole\":\"administrators\"
                   }
    }"
    
    ## OpenID Connect
    # required
    LEAN_OIDC_ENABLE = false
    LEAN_OIDC_CLIENT_ID =
    LEAN_OIDC_CLIENT_SECRET =
    
    # required - the URL for your provider (examples down below)
    #LEAN_OIDC_PROVIDER_URL =
    
    #Create User if it doesn't exist in Leantime db, otherwise fail login
    LEAN_OIDC_CREATE_USER = false
    
    # Default role for users created via OIDC (20 is editor)
    LEAN_OIDC_DEFAULT_ROLE = 20
    
    # optional - these will be read from the well-known configuration if possible
    #LEAN_OIDC_AUTH_URL_OVERRIDE =
    #LEAN_OIDC_TOKEN_URL_OVERRIDE =
    #LEAN_OIDC_JWKS_URL_OVERRIDE =
    #LEAN_OIDC_USERINFO_URL_OVERRIDE =
    
    # optional - override the public key for RSA validation
    #LEAN_OIDC_CERTIFICATE_STRING =
    #LEAN_OIDC_CERTIFICATE_FILE =
    
    # optional - override the requested scopes
    #LEAN_OIDC_SCOPES =
    
    # optional - override the keys used for these fields
    #LEAN_OIDC_FIELD_EMAIL =
    #LEAN_OIDC_FIELD_FIRSTNAME =
    #LEAN_OIDC_FIELD_LASTNAME =
    #LEAN_OIDC_FIELD_PHONE =
    #LEAN_OIDC_FIELD_JOBTITLE =
    #LEAN_OIDC_FIELD_JOBLEVEL=
    #LEAN_OIDC_FIELD_DEPARTMENT =
    
    ## OpenID Connect setting for GitHub
    #LEAN_OIDC_PROVIDER_URL = https://token.actions.githubusercontent.com/
    #LEAN_OIDC_AUTH_URL_OVERRIDE = https://github.com/login/oauth/authorize
    #LEAN_OIDC_TOKEN_URL_OVERRIDE = https://github.com/login/oauth/access_token
    #LEAN_OIDC_USERINFO_URL_OVERRIDE = https://api.github.com/user,https://api.github.com/user/emails
    #LEAN_OIDC_SCOPES = user:email,read:user
    #LEAN_OIDC_FIELD_EMAIL = 0.email
    #LEAN_OIDC_FIELD_FIRSTNAME = name
    
    
    ## Redis (for session storage and cache)
    LEAN_USE_REDIS = false                             # Set to true to use redis as session cache
    LEAN_REDIS_URL = ''                                # Add URL path such as tcp://1.2.3.4:6379. If you are using a password, add ?auth=yourverycomplexpasswordhere to your URL
    LEAN_REDIS_HOST = ''
    LEAN_REDIS_PORT = 6379
    LEAN_REDIS_PASSWORD = ''
    LEAN_REDIS_SCHEME = ''
    
    ## Rate limiting
    LEAN_RATELIMIT_GENERAL = 1000
    LEAN_RATELIMIT_API = 10
    LEAN_RATELIMIT_AUTH = 20
    
    
    
  4. What the compose file check ran with (github.com/Leantime/docker-leantime/blob/8718fac/README.md)

    The compose file check ran together with sample.env from the same commit, saved as .env. The folder held only these files. The README of the project's docker-leantime repository tells the reader to clone it, copy sample.env to .env, edit the settings and run docker compose up -d.

  5. Start it (github.com/Leantime/docker-leantime/blob/8718fac/README.md)
    docker compose up -d
  6. Open the app (github.com/Leantime/docker-leantime/blob/8718fac/docker-compose.yml)

    Open http://localhost:8080. The compose file publishes host port 8080 for the leantime service.

Compose file check: config_ok on 2026-10-22.

Gotchas and maintenance

Gotchas

Signals

  • Open issues and pull requests: 236
  • Last push: 2026-10-21 (1 days before this page was built)
  • Latest release: v3.12.0 on 2026-10-15 (7 days before this page was built)