Running Redmine with plugins in Docker — preventing first-boot migration failures

Written by Michael Staněk

Published: May 14, 2026

in Docker is straightforward until plugins enter the picture. A common production issue appears during the very first container boot:

  • Redmine core migrations start

  • plugins are already mounted into /plugins

  • Rails discovers and initializes plugins immediately

  • plugin code executes before the core Redmine schema fully exists

  • initialization fails

  • plugin initialization fails during Rails boot, preventing the Redmine container from starting successfully

This article explains:

  • why this happens

  • why the default Docker startup sequence is insufficient

  • how to implement a deterministic and safe plugin load order

Why Redmine Docker containers fail on first startup with plugins

Most Docker examples mount plugins immediately:

volumes:
- ./plugins:/usr/src/redmine/plugins

and then rely on the stock container startup behavior.

The official Redmine Docker image automatically performs core database initialization during startup. When plugins are already present in the /plugins directory, Redmine may begin loading them during the startup process before the core database setup is fully completed.

How Redmine plugins load before core database migrations in Docker

Redmine detects and starts loading plugins as soon as the application boots.

That means:

  1. Container starts

  2. Rails boots

  3. Plugins inside /plugins are discovered

  4. As soon as Redmine starts, plugin initialization code, hooks and model extensions begin loading from the /plugins directory.

  5. Plugin code may query the database

  6. Core Redmine tables may still not exist

This creates a startup-order problem between:

  • Rails/plugin initialization

  • core database schema creation

The problem is not migration order alone. The problem is plugin load order during Rails boot.

Common Redmine plugin errors in Docker

You may observe:

  • Mysql2::Error: Table 'settings' doesn't exist

  • PG::UndefinedTable

  • plugin initialization crashes

  • Redmine container fails to start

Why Redmine plugins can break Docker startup

Many tutorials assume:

depends_on:
- db

is sufficient. It is not.

depends_on only guarantees:

  • the database container started

It does not guarantee:

  • database readiness

  • completed migrations

  • stable schema

  • safe Rails initialization

For Redmine deployments using plugins, this distinction matters.

Correct plugin load order

The safest architecture is:

  1. Initialize Redmine core schema first

  2. Only then expose plugins

  3. Run plugin migrations separately

  4. Start the application normally

This creates deterministic startup behavior.

How to start Redmine Docker containers with plugins

Step 1: Initialize Redmine Core Database Without Plugins

Create your Redmine Docker environment normally, but keep the mapped plugin directory empty during the first startup.

volumes:

- ./plugins:/usr/src/redmine/plugins

The plugins directory should exist but must be empty.
Start the containers:

docker compose up -d

or start them from Docker Desktop.
After startup, verify that Redmine is reachable and displays the login screen.

During the first startup, it is common for the database container to require additional time for initialization. In some cases, Redmine may start before the database is fully ready and fail to connect. If that happens, simply wait until the database finishes starting and restart the Redmine container.

Once the login screen is accessible, the Redmine core database schema is initialized and plugins can be installed safely.

Step 2: Copy Plugins and Run Plugin Migrations

Copy plugins into the mapped plugin directory:

<redmine_home>/plugins

Then open a shell inside the running Redmine container:

docker compose exec redmine bash

Inside the container, install plugin dependencies and run plugin migrations exactly as you would on a non-Docker Redmine installation:

bundle install

RAILS_ENV=production bundle exec rake redmine:plugins:migrate

RAILS_ENV=production bundle exec rake assets:precompile

Some plugins may depend on other plugins and need to be installed in a specific order.

When finished:

exit

Restart Redmine:

docker compose restart redmine

After the restart, Redmine should load normally with all installed plugins.

Automatically loading Redmine plugins after startup

Some teams solve this problem using custom entrypoint scripts or deployment automation that delays plugin availability until the Redmine core database has been initialized.

The exact implementation depends on the deployment environment and should be tested carefully.

For most installations, the safest and easiest approach is simply to start Redmine once without plugins, verify that the application and database are fully initialized, and only then add plugins and run plugin migrations.

Why Redmine plugins need controlled Docker startup

The stock Redmine Docker image works well for clean Redmine installations and simple setups without plugins.

However, most real-world Redmine deployments use plugins from the very beginning and mount them directly into the /plugins directory during the first container startup.

This creates a startup-order problem because Redmine may begin loading plugins before the core database schema is fully initialized.

The issue becomes especially important in environments with:

  1. Automated deployments

  2. CI/CD pipelines

  3. Kubernetes orchestration

  4. Automated customer provisioning

  5. Commercial multi-plugin Redmine stacks

Additional Docker stability recommendations

Use Healthchecks

Do not start reverse proxies or dependent services until Redmine passes a healthcheck.

healthcheck:

test: ["CMD", "curl", "-f", "http://localhost:3000"]

interval: 30s

timeout: 10s

retries: 5

Avoid automatic plugin initialization during build

Do not:

  • precompile plugin assets before the initial database setup is completed

  • run migrations during image build

  • rely on Rails autoloading before DB readiness

Important Note About Docker Volumes

This initialization procedure is only required during the first startup.

Once Redmine and the plugins are installed successfully, the containers can be stopped and started normally.

However, if Docker volumes containing the database are removed (for example using `docker compose down -v`), the database will be recreated from scratch during the next startup. In that case, the first-start procedure must be repeated.

Final thoughts on Redmine plugin initialization in Docker

The problem is not simply that plugin migrations run too early. The real issue is that Redmine starts loading plugins before the core database setup is fully completed.

The solution is to initialize Redmine first, load plugins afterwards, and run plugin migrations only after the core schema already exists.

Once the startup sequence is separated into these steps, Redmine Docker deployments become far more stable and predictable, especially for larger plugin ecosystems such as RedmineX.

Is Docker giving you a headache? RedmineX Remote Maintenance will solve it.

Share this if you liked it!

Take a look at our Youtube Channel.

Trusted By Effective Teams Worldwide

Try All RedmineX Plugins

entire solution & plugins  |  totally FREE

  • Hosted Solution
  • UX Upgrade
  • Gantt chart
  • Resources
  • Agile MyPage
  • Project templates
  • Statistics
  • Inline edit
  • Timesheet
  • All plugins
Source? *

How Does The Demo Work?

  1. Login credentials
    After submitting the form, you will be redirected to a page with login credentials.

  2. One demo to rule them all
    The demo site is shared and the database is being reset every full hour. You can do anything, but the data you enter will eventually be reset. You can ask for a dedicated demo if you‘re interested in keeping the data, or testing more thoroughly.

  3. Ask anything
    Michael is ready to help you with any request so you can squeeze maximum from your Redmine.