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:
Container starts
Rails boots
Plugins inside /plugins are discovered
As soon as Redmine starts, plugin initialization code, hooks and model extensions begin loading from the /plugins directory.
Plugin code may query the database
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:
Initialize Redmine core schema first
Only then expose plugins
Run plugin migrations separately
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:
Automated deployments
CI/CD pipelines
Kubernetes orchestration
Automated customer provisioning
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.
Try All RedmineX Plugins
entire solution & plugins | totally FREE
How Does The Demo Work?
Login credentials
After submitting the form, you will be redirected to a page with login credentials.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.Ask anything
Michael is ready to help you with any request so you can squeeze maximum from your Redmine.





