Skip to content

Instantly share code, notes, and snippets.

@markasoftware
Last active January 18, 2026 04:57
Show Gist options
  • Select an option

  • Save markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 to your computer and use it in GitHub Desktop.

Select an option

Save markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 to your computer and use it in GitHub Desktop.
OpenProject Enterprise mode for free
############ If you are using DOCKER all-in-one image, create Dockerfile like: ################
############ FROM openproject/openproject:16 ################
############ COPY ./enterprise_token.rb app/models/enterprise_token.rb ################
############ If you are runing a manual installation: ################
############ REPLACE app/models/enterprise_token.rb in the source code with this file! ################
############ also be sure to RESTART OpenProject after replacing the file. ################
############ If using some other set up (eg docker-compose), read the comments on ################
############ https://gist.github.com/markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 ################
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class EnterpriseToken < ApplicationRecord
class << self
# On the backend, features are checked only using `allows_to?`, which we can hardcode to return `true`.
# On the frontend, however, it instead checks if particular strings are included in the `available_features`
# Unfortunately there is no canonical variable with all the features, so we have to hardcode.
# Use `rg --pcre2 -INo "(?<=allows_to\?[^:*]:|allowsTo\(')[a-z_]*" | sort -u` to generate this list:
TRUE_FEATURES = %i[
allowed_action
baseline_comparison
board_view
calculated_values
conditional_highlighting
custom_actions
custom_field_hierarchies
customize_life_cycle
date_alerts
define_custom_style
edit_attribute_groups
forbidden_action
gantt_pdf_export
internal_comments
ldap_groups
nextcloud_sso
one_drive_sharepoint_file_storage
placeholder_users
readonly_work_packages
scim_api
sso_auth_providers
team_planner_view
time_entry_time_restrictions
virus_scanning
work_package_query_relation_columns
work_package_sharing
work_package_subject_generation
].freeze
# Not all the methods here are ever actually called outside the enterprise_token.rb file itself
# in upstream openproject, but I'll include all of them that can be reasonably implemented here,
# just in case openproject changes in the future to start using the extra methods.
def current
self.new
end
def all_tokens
[self.new]
end
def active_tokens
[self.new]
end
def active_non_trial_tokens
[self.new]
end
def active_trial_tokens
[]
end
def active_trial_token
nil
end
def allows_to?(feature)
true
end
def active?
true
end
def trial_only?
false
end
def available_features
TRUE_FEATURES
end
def non_trialling_features
TRUE_FEATURES
end
def trialling_features
[]
end
def trialling?(feature)
false
end
def hide_banners?
true
end
def show_banners?
false
end
def user_limit
nil
end
def non_trial_user_limit
nil
end
def trial_user_limit
nil
end
def banner_type_for(feature:)
nil
end
def get_user_limit_of(tokens)
nil
end
end
FAR_FUTURE_DATE = Date.new(9999, 1, 1)
def token_object
Class.new do
def id
"lmao"
end
def has_feature?(feature)
true
end
def will_expire?
false
end
def mail
"[email protected]"
end
def subscriber
"markasoftware-free-enterprise-mode"
end
def company
"markasoftware"
end
def domain
"markasoftware.com"
end
def issued_at
Time.zone.today - 1
end
def starts_at
Time.zone.today - 1
end
def expires_at
Time.zone.today + 1
end
def reprieve_days
nil
end
def reprieve_days_left
69
end
def restrictions
nil
end
def available_features
EnterpriseToken.TRUE_FEATURES
end
def plan
"markasoftware_free_enterprise_mode"
end
def features
EnterpriseToken.TRUE_FEATURES
end
def version
69
end
def started?
true
end
def trial?
false
end
def active?
true
end
end.new
end
def id
"lmao"
end
def encoded_token
"oaml"
end
def will_expire?
false
end
def mail
"[email protected]"
end
def subscriber
"markasoftware-free-enterprise-mode"
end
def company
"markasoftware"
end
def domain
"markasoftware.com"
end
def issued_at
Time.zone.today - 1
end
def starts_at
Time.zone.today - 1
end
def expires_at
Time.zone.today + 1
end
def reprieve_days
nil
end
def reprieve_days_left
69
end
def restrictions
nil
end
def available_features
EnterpriseToken.TRUE_FEATURES
end
def plan
"markasoftware_free_enterprise_mode"
end
def features
EnterpriseToken.TRUE_FEATURES
end
def version
69
end
def started?
true
end
def trial?
false
end
def active?
true
end
def allows_to?(action)
true
end
def expiring_soon?
false
end
def in_grace_period?
false
end
def expired?(reprieve: true)
false
end
def statuses
[]
end
def invalid_domain?
false
end
def unlimited_users?
true
end
def max_active_users
nil
end
def sort_key
[FAR_FUTURE_DATE, FAR_FUTURE_DATE]
end
def days_left
69
end
end
@maximbeliveau
Copy link

There was one new feature called calculated_values which got added recently and I just added to this script, but I doubt that is the problem. Can someone else confirm the behavior @maximbeliveau is seeing and that this behavior is unexpected?

i tried this weekend on my Dev at home and its working, i will run more test at work tomorow.

@n3b0r
Copy link

n3b0r commented Nov 15, 2025

Where is the rg binary located in the docker container to get the list of functions?

@maximbeliveau
Copy link

Where is the rg binary located in the docker container to get the list of functions?

/app/app/models

@markasoftware
Copy link
Author

markasoftware commented Nov 15, 2025 via email

@yegorov-p
Copy link

works for 16.6.1

@vedaj
Copy link

vedaj commented Dec 1, 2025

works for 16.6.1

How did you get it to work? Could you please elaborate?

@FlichB
Copy link

FlichB commented Dec 2, 2025

works for 16.6.2
added it using the method for docker-install suggested by @javito1081

for those that dont want to read the comments i'll paste it here

Step 1:

Downloaded the file using curl to the openproject folder, i have a folder called openproject and inside its my docker compose file and now the enterprise_token.rb, along with my assets and data folder

curl "https://gist.githubusercontent.com/markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45/raw/25f33dd28753c908455ac9e8969955795a865fb0/enterprise_token.rb

  • link may change with edits to this page - check link on top of this page

Step 2:

Once downloaded i added this line - ./enterprise_token.rb:/app/app/models/enterprise_token.rb to my docker compose file in the volumes

services:
openproject:
image: openproject/openproject:15
container_name: openproject
ports:
- "8200:80"
restart: unless-stopped
environment:
- OPENPROJECT_SECRET_KEY_BASE=secret
- OPENPROJECT_HOST__NAME=openproject.something.com
- OPENPROJECT_HTTPS=true
- OPENPROJECT_DEFAULT__LANGUAGE=es
- OPENPROJECT_USER__DEFAULT__TIMEZONE=America/Mexico_City
volumes:
- ./pgdata:/var/openproject/pgdata
- ./assets:/var/openproject/assets
- ./enterprise_token.rb:/app/app/models/enterprise_token.rb

Step 3:

after that, i saved the file and ran my docker compose like this:

docker-compose -f openproject/openproject.yml up -d

thats it, no restarts or any extra steps

@Tofandel
Copy link

Tofandel commented Dec 5, 2025

I'll just say this, but the proper way to have a crack survive updates is to make a patch file of only the minimal changes required and apply the patch file everytime an update is installed. Works for docker, works for DPKG

@Thari0
Copy link

Thari0 commented Dec 14, 2025

I tried to use this docker compose, but no matter how i pass the token file i'm getting the error below.
I linked the file in the compose, i copied it into the container, i pasted content directly into the original file. Tried https and http, the error is always the same. Any ideas what might be wrong?

services:
openproject:
ports:
- 8999:80
environment:
- SECRET_KEY_BASE=secret
- OPENPROJECT_HOST__NAME=project.XXX.eu
- OPENPROJECT_HTTPS=true
- OPENPROJECT_DEFAULT__LANGUAGE=en
image: openproject/openproject:16.6.2
container_name: openproject
restart: unless-stopped
volumes:
- ./enterprise_token.rb:/app/app/models/enterprise_token.rb:ro
- ./assets:/var/openproject/assets
- ./pgdata:/var/openproject/pgdata
networks: {}
volumes:
assets: null
pgdata: null

500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.

@1itt1eB0y
Copy link

1itt1eB0y commented Dec 15, 2025

I tried to use this docker compose, but no matter how i pass the token file i'm getting the error below. I linked the file in the compose, i copied it into the container, i pasted content directly into the original file. Tried https and http, the error is always the same. Any ideas what might be wrong?

services:
openproject:
ports:

  • 8999:80
    environment:
  • SECRET_KEY_BASE=secret
  • OPENPROJECT_HOST__NAME=project.XXX.eu
  • OPENPROJECT_HTTPS=true
  • OPENPROJECT_DEFAULT__LANGUAGE=en
    image: openproject/openproject:16.6.2
    container_name: openproject
    restart: unless-stopped
    volumes:
  • ./enterprise_token.rb:/app/app/models/enterprise_token.rb:ro
  • ./assets:/var/openproject/assets
  • ./pgdata:/var/openproject/pgdata
    networks: {}
    volumes:
    assets: null
    pgdata: null

500 Internal Server Error
If you are the administrator of this website, then please read this web application's log file and/or the web server's log file to find out what went wrong.

Did you try to remove :ro for - ./enterprise_token.rb:/app/app/models/enterprise_token.rb:ro ? I didn't use :ro and it stated as expected.
Here is my json.

version: '3.3'
services:
  community:
    ports:
      - '8884:80'
    environment:
      - OPENPROJECT_SECRET_KEY_BASE=****************
      - OPENPROJECT_HOST__NAME=**********
      - OPENPROJECT_HTTPS=false
      - OPENPROJECT_LANGUAGE_DEFAULT=zh-CN
    image: 'openproject/openproject:16'
    network_mode: bridge
    volumes:
      - ./enterprise_token.rb:/app/app/models/enterprise_token.rb
      - ./data:/var/openproject

@Thari0
Copy link

Thari0 commented Dec 18, 2025

All right, i tried everything and it seemed impossible.
Turned out i used link provided by FlichB, as it was quite recent, but it is different then the file here.

So for future reference for all, use fresh download link 🤦‍♂️

@FlichB
Copy link

FlichB commented Dec 18, 2025

All right, i tried everything and it seemed impossible. Turned out i used link provided by FlichB, as it was quite recent, but it is different then the file here.

So for future reference for all, use fresh download link 🤦‍♂️

Thank you - i edited the link and added a disclaimer that the link may change

@guilherme-demarchi
Copy link

Working for OpenProject 16.6.3. I'm using the setup where docker compose have separated services (db, web, worker, etc). I added the volume ./enterprise_token.rb:/app/app/models/enterprise_token.rb to the services web and worker, and it worked right away

@markasoftware
Copy link
Author

markasoftware commented Jan 3, 2026 via email

@SchBSA-collab
Copy link

I tried with the version 16.6.3 with a Dockerfile to discover this solution (I pulled the image from Docker Hub, but on OpenProject it says version 16.6.2) but it does not works for me, I still don"t have access to "Team planners" (it says "Available starting with the Basic enterprise plan").

@supaeasy
Copy link

Has anyone tested 17.0.0 yet?

@SchBSA-collab
Copy link

I'm on it with a dockerfile

@maximbeliveau
Copy link

maximbeliveau commented Jan 14, 2026

I tried with the version 16.6.3 with a Dockerfile to discover this solution (I pulled the image from Docker Hub, but on OpenProject it says version 16.6.2) but it does not works for me, I still don"t have access to "Team planners" (it says "Available starting with the Basic enterprise plan").

You can push the token directly when you build an image with a dockerfile like this :

############## STAGE 1 #############
FROM openproject/openproject:16 AS plugin

COPY /token/enterprise_token.rb /app/app/models/enterprise_token.rb

COPY Gemfile.plugins /app/

RUN bundle config unset deployment
&& bundle install
&& bundle config set deployment 'true'
RUN ./docker/prod/setup/precompile-assets.sh

############## STAGE 2 #############
FROM openproject/openproject:16.6.4-slim

COPY --from=plugin /app/app/models/enterprise_token.rb /app/app/models

COPY --from=plugin /usr/bin/git /usr/bin/git
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/bundle /app/vendor/bundle
COPY --chown=$APP_USER:$APP_USER --from=plugin /usr/local/bundle /usr/local/bundle
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/public/assets /app/public/assets
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/config/frontend_assets.manifest.json /app/config/frontend_assets.manifest.json
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/Gemfile.* /app/
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/plugins /app/vendor/plugins

@SchBSA-collab
Copy link

I tried with the version 16.6.3 with a Dockerfile to discover this solution (I pulled the image from Docker Hub, but on OpenProject it says version 16.6.2) but it does not works for me, I still don"t have access to "Team planners" (it says "Available starting with the Basic enterprise plan").

You can push the token directly when you build an image with a dockerfile like this :

############## STAGE 1 ############# FROM openproject/openproject:16 AS plugin

COPY /token/enterprise_token.rb /app/app/models/enterprise_token.rb

COPY Gemfile.plugins /app/

RUN bundle config unset deployment && bundle install && bundle config set deployment 'true' RUN ./docker/prod/setup/precompile-assets.sh

############## STAGE 2 ############# FROM openproject/openproject:16.6.4-slim

COPY --from=plugin /app/app/models/enterprise_token.rb /app/app/models

COPY --from=plugin /usr/bin/git /usr/bin/git COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/bundle /app/vendor/bundle COPY --chown=$APP_USER:$APP_USER --from=plugin /usr/local/bundle /usr/local/bundle COPY --chown=$APP_USER:$APP_USER --from=plugin /app/public/assets /app/public/assets COPY --chown=$APP_USER:$APP_USER --from=plugin /app/config/frontend_assets.manifest.json /app/config/frontend_assets.manifest.json COPY --chown=$APP_USER:$APP_USER --from=plugin /app/Gemfile.* /app/ COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/plugins /app/vendor/plugins

Can I put this whole code in a single Dockerfile ? In stage 1 and 2, openproject versions ain't the same, is it ok ?

@maximbeliveau
Copy link

I tried with the version 16.6.3 with a Dockerfile to discover this solution (I pulled the image from Docker Hub, but on OpenProject it says version 16.6.2) but it does not works for me, I still don"t have access to "Team planners" (it says "Available starting with the Basic enterprise plan").

You can push the token directly when you build an image with a dockerfile like this :
############## STAGE 1 ############# FROM openproject/openproject:16 AS plugin
COPY /token/enterprise_token.rb /app/app/models/enterprise_token.rb
COPY Gemfile.plugins /app/
RUN bundle config unset deployment && bundle install && bundle config set deployment 'true' RUN ./docker/prod/setup/precompile-assets.sh
############## STAGE 2 ############# FROM openproject/openproject:16.6.4-slim
COPY --from=plugin /app/app/models/enterprise_token.rb /app/app/models
COPY --from=plugin /usr/bin/git /usr/bin/git COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/bundle /app/vendor/bundle COPY --chown=$APP_USER:$APP_USER --from=plugin /usr/local/bundle /usr/local/bundle COPY --chown=$APP_USER:$APP_USER --from=plugin /app/public/assets /app/public/assets COPY --chown=$APP_USER:$APP_USER --from=plugin /app/config/frontend_assets.manifest.json /app/config/frontend_assets.manifest.json COPY --chown=$APP_USER:$APP_USER --from=plugin /app/Gemfile.* /app/ COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/plugins /app/vendor/plugins

Can I put this whole code in a single Dockerfile ? In stage 1 and 2, openproject versions ain't the same, is it ok ?

Yes this is my dockerfile minus the command for my plugin which you don't need, you can just change the version of stage 2 and it will be build with this one.

@SchBSA-collab
Copy link

SchBSA-collab commented Jan 14, 2026

It worked with 16.6.3 with your script without the plugings. I'll try with 17.0.0.

############## STAGE 1 #############
FROM openproject/openproject:16 AS plugin

COPY enterprise_token.rb /app/app/models/enterprise_token.rb

RUN bundle config unset deployment
&& bundle install
&& bundle config set deployment 'true'
RUN ./docker/prod/setup/precompile-assets.sh

############## STAGE 2 #############
FROM openproject/openproject:16.6.3

COPY --from=plugin /app/app/models/enterprise_token.rb /app/app/models

COPY --from=plugin /usr/bin/git /usr/bin/git
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/vendor/bundle /app/vendor/bundle
COPY --chown=$APP_USER:$APP_USER --from=plugin /usr/local/bundle /usr/local/bundle
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/public/assets /app/public/assets
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/config/frontend_assets.manifest.json /app/config/frontend_assets.manifest.json
COPY --chown=$APP_USER:$APP_USER --from=plugin /app/Gemfile.* /app/

@ricocrivelli
Copy link

Anyone knows how to make this work on a self hosted on a ubuntu machine?

@Sn0w3y
Copy link

Sn0w3y commented Jan 14, 2026

Anyone knows how to make this work on a self hosted on a ubuntu machine?

Which installation Method?

@ricocrivelli
Copy link

Anyone knows how to make this work on a self hosted on a ubuntu machine?

Which installation Method?

Via package

@Sn0w3y
Copy link

Sn0w3y commented Jan 14, 2026

Anyone knows how to make this work on a self hosted on a ubuntu machine?

Which installation Method?

Via package

see your mail ;)

@maximbeliveau
Copy link

Working on 17.0.0 with docker compose.

@CC1119
Copy link

CC1119 commented Jan 15, 2026

Confirmed too it's working on 17.0.0 with docker compose

@lockdlock
Copy link

Anyone knows how to make this work on a self hosted on a ubuntu machine?

Which installation Method?

Via package

see your mail ;)

Could you send to me?

@SchBSA-collab
Copy link

17.0.0 also works with Dockerfile

@Koobetto
Copy link

Koobetto commented Jan 15, 2026

Anyone knows how to make this work on a self hosted on a ubuntu machine?

Which installation Method?

Via package

see your mail ;)

Can you send that to me too please? I'm running OpenProject 16.3.2 via package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment