Content

How to create your custom Redmine Docker image

Redmine is one of the most popular tools for project management and issue tracking. If you tried it or had to install it in a production environment, you probably also know there is an official docker image that greatly simplifies installation and scaling for high demand environments.

Redmine before customization

If you are like me and prefer to directly see the code for building a custom Redmine Docker image, you can go to github.com/lcofre/redmine and check the Dockerfile.

The Redmine Docker image is a good starting point, although you probably would want to customize it with plugins and themes of your liking. In this how-to, we will build a Docker image based on the official one, add some themes and plugins, and upload it to the docker registry.

For simplicity's sake, we won't use an external database but an internal database in the Redmine container itself. For a production environment though, it is advisable to set up a dedicated storage container.

Plugins and Themes

We chose a few plugins and themes to illustrate varied ways of adding them to Redmine:

  • Hide sidebar, a plugin to allow for more screen space, especially when writing issues
  • Paste clipboard, to attach screenshots pasting from the clipboard instead of selecting a file
  • A1 and Gitmike, two themes to change the look of the UI

We are excluding plugins that require a database migration, as you need a pre-existing database. Please comment below if you need to install a plugin that needs migrations, as we have good ideas for you.

Writing the Dockerfile

A Dockerfile is a recipe on how to build a Docker image. The first fact we will learn here is that we have to base our image on some other image, so we'll use the official one for Redmine

FROM Redmine

This first line of the Dockerfile will base or image on the latest and greatest image, 4.1.0 at the time of writing. As this will grab whatever version is latest, you may prefer to use a specific version to avoid unexpected new versions that may break the build of this image

FROM Redmine:4.1.0

Using Git to get the components

In most cases, themes and plugins have git repositories where we can download the latest code. This is the case for the following three components.

The base Redmine image comes without git, but we can add it to the image this way

RUN apt install -y git

This will be executed when the image is built and will allow you to use git in the following instructions.

Gitmike theme: they recommend to clone their repo directly

RUN git clone https://github.com/makotokw/redmine-theme-gitmike.git public/themes/gitmike

The line will save the cloned project in the appropriate folder public/themes

Hide Sidebar: The same procedure can be applied to plugins. This one requires nothing more than placing the cloned folder in the plugins folder

RUN git clone https://gitlab.com/bdemirkir/sidebar_hide.git plugins/sidebar_hide

Clipboard Image paste: This also seems the typical procedure, clone the repo and you are good to go

RUN git clone https://github.com/RubyClickAP/clipboard_image_paste.git plugins/clipboard_image_paste

But if you read a bit more you'll see that "it’s recommended to install RMagick gem, otherwise attached images will not show in exported PDF files". So how do we do this? It should be as easy as

RUN gem install rmagick

but you probably know that the gem needs to be built before it can be installed, so you need to install some packages before installing the gem. The line you really need is

RUN apt install -y build-essential imagemagick libmagickcore-dev libmagickwand-dev ruby-dev \

       && gem install rmagick

All in one command, separated in two lines for readability.

The original author of this plugin does not provide a version for Redmine 4, but a search of the plugin name in GitHub landed me on a project that does: RubyClickAP/clipboard_image_paste.

Adding a plugin or theme from a downloaded source

The A1 theme is a good example to illustrate the cases where you have the source, but not a URL to download during the build process. One option in cases like this is to provide the source to the building process. That way the content is added to the image without downloading it

COPY a1 public/themes/a1

This requires the a1 folder to be in the same place the Dockerfile is.

Now you are ready to build your image, so open a terminal where your Dockerfile is and execute

docker build -t my-redmine .

Once built you'll be able to run your image with

docker run -it -p 3000:3000 --name my-redmine my-redmine

Go ahead and open http://localhost:3000 to see your custom Redmine!

Redmine after customization

Some tips to add more plugins

In order to try out new plugins, it’s always better to use a fresh Redmine container. That is how I realized rmagick requires some packages to be installed. First, run a discardable instance of Redmine with

docker run --rm -d -p 3000:3000 --name test-redmine redmine

and then enter the instance with

docker exec -it test-redmine bash

There you can install OS packages, gems or run migrations. Just remember the steps so you can add them to your Dockerfile!

Uploading your custom image to Docker Hub

The image you just built is available to your local environment only. What if you want to make it available to others, let's say to everyone? Of course, you can upload the Dockerfile and related files to a git repo, and the ones interested can build the image themselves. But Docker also allows you to upload the built image to their registry. For that, create an account in hub.docker.com and also create a repository for your image. Then login in the terminal like this

docker login

Tag your image so it can be uploaded to your repo

docker tag my-redmine:latest lcofre/redmine:latest

and push it like this

docker push lcofre/redmine:latest

The Docker image in the Docker registry

Now anyone can try out your image by doing

docker run -it -p 3000:3000 --name my-redmine lcofre/redmine

That's it! This is how you go from a standard Redmine installation to a personalized version accessible in the Docker registry. Please share your comments or questions below.

Trimming the Docker image size

You'll find that the Dockerfile in the repo joined many lines into one. This is a Docker recommendation to make smaller images. You can find that advice and others in https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Another recommendation to reduce the final size of the image is to use the alpine version of Redmine

FROM Redmine:alpine

Alpine is a different linux distribution. Instead of using apt to install packages you need to use apk.

One last tip: the packages we installed with apt in the Dockerfile are not needed anymore after the image is built. You can follow the best practice of using multi-stage builds: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds

The practice of keeping a small size Docker image helps especially when scaling up the number of instances, but also reduces the attack surface on your image.

 

Author: Leandro CofreLukáš Beňa

Additional information
Free Trial

Easy Redmine 10 upgrade
Top plugins & features
New & mobile design
Server upgrades
Global cloud

Start Free Trial

Try Easy Redmine in a 30-day free trial

Full-featured, 30 Days, SSL protected, Daily Backups, In your Geo Location

or