Share

Redmine: setting up a user friendly project management tool & ticketing system

Why Redmine ?

 

When starting a new project, it's alway useful to have a way of taking notes, keeping track of tasks to be done and having of way of prioritising them. In that respect, Redmine is an ideal tool in that it is :

    1. Very user friendly: I've already deployed it in multiple organisations and users have been able to start using it with litteraly no training.
    2. Easily customised: Redmine allows each project to have it's own workflows, types of tasks or data fields to be filled in
    3. A full set of tools: out of the box, Redmine allows tasks & files management, Wiki pages & GANTT setup, time tracking and repository integration on a per project basis
    4. Plugins: having existed for so long, many usefull plugins exist in the "Official plugin directory"
    5. Interconnectivity: API allow users to set up their own automation or use existing plugins available from other tools such as Zabbix for monitoring or Gitlab. Check the official supported "Third party Tools" page for more information.

 

  • Official website: https://redmine.org/
  • Repositories: https://www.redmine.org/projects/redmine/repository
  • Docker images: https://hub.docker.com/_/redmine/

 

We've got the pros, what are the cons?

It's a Ruby on Rails based application with makes it very flexible but also very tricky to customise using plugins since each plugin will have it's own requirements in Ruby, Rails or GEM versions.  

 


Story time!

When setting up Redmine 4.1.1 in late 2020, the latest Ruby version was 3.1.3 but the default version packaged for Ubuntu was 3.0.5 and neither were properly supported by Redmine in my configuration, forcing me to downgrade to Ruby 2.7.X.

Fair enough: Ruby 2.7.7 had been release along 3.0.5 and 3.1.3 so no issue, right ?

Wrong : 2.7.7 had bugs, making it unusable and forcing an extra downgrade to 2.7.6. and   adding an extra day of work


 

This also makes the version upgrade process delicate seeing as upgrading 1 brick of the system might require upgrading the others or not.   And once setup and in use, it is quite likely plugins will be used and you will find that there are errors due to plugins requiring different versions of the same GEM. Most issues can be sorted pretty simply but it does make for longer maintenance.

 

Setup Redmine in 5 minutes using Docker

 

Why use Docker ?

  Using pre-built Docker images is the easiest way to avoid some of the Ruby on Rails version issues: Docker images are provided having been tested and provide a working Redmine solution. This means that you only have to deal with Plugin compatibility issues, which can be sorted out simply by changing the Docker deployement script to use a different Redmine image.

 

Pre-requisites:

  • A server with Docker installed with the docker-compose package
  • Optional: access to a dedicated database & database user if the database is hosted separately

 

Files and folders configuration

 

For this demonstration, a sub-directory "redminedocker" has been created in /opt containing:

File docker-compose.yml

File at the root of the directory containing our running image configuration (see below)

Folder

files

Where the files uploaded to the platform will be stored.

We want to keep the files on the host so that they are not lost if we need to delete the container.

Folder

plugins

Directory where we will "git pull" the plugins we want to try.

We want to keep the files on the host so that they are not lost if we need to delete the container.

Folder

public/themes

Directory and sub-directory where custom/alternative Redmine themes will be installed

We want to keep the files on the host so that they are not lost if we need to delete the container.

Folder configs

Contains the files used when building our custom container image

Optional: to be used if you want to customize the Docker image 

File

Dockerfile

Lists the instructions used to build the custom image

Optional: to be used if you want to customize the Docker image 

File

entrypoint.sh

File that allows us to set up scripts to be run when launching the container or once it's running

Optional: to be used if you want to customize the Docker image 

 

docker-compose.yml

 

Ubuntu
Redhat
version: "3.9"
services:
  redmine:
    container_name: redmine
    image: redmine:5.0.5
    #build: /opt/redminedocker/configs
    restart: always
    ports:
      - "80:3000"
    environment:
      - "REDMINE_PLUGINS_MIGRATE=true"
      - "REDMINE_HTTPS=true"
      - "REDMINE_DB_POSTGRES=db"
      - "REDMINE_DB_DATABASE=redmine"
      - "REDMINE_DB_USERNAME=redadmin"
      - "REDMINE_DB_PASSWORD=tB6mcmsC"
      - "REDMINE_DB_PORT=5432"
    extra_hosts:
      - "db:172.10.11.201"
    volumes:
      - /opt/redminedocker/plugins:/usr/src/redmine/plugins
      - /opt/redminedocker/public/themes:/usr/src/redmine/public/themes
      - /opt/redminedocker/files:/usr/src/redmine/files
version: "3.3"
services:
  redmine:
    container_name: redmine
    image: redmine:5.0.5
    #build: /opt/redminedocker/configs
    restart: always
    ports:
      - "80:3000"
    environment:
      - "REDMINE_PLUGINS_MIGRATE=true"
      - "REDMINE_HTTPS=true"
      - "REDMINE_DB_POSTGRES=db"
      - "REDMINE_DB_DATABASE=redhatmine"
      - "REDMINE_DB_USERNAME=redhatadmin"
      - "REDMINE_DB_PASSWORD=PG8gb5Ts"
      - "REDMINE_DB_PORT=5432"
    extra_hosts:
      - "db:172.10.11.201"
    volumes:
      - /opt/redminedocker/plugins:/usr/src/redmine/plugins
      - /opt/redminedocker/public/themes:/usr/src/redmine/public/themes
      - /opt/redminedocker/files:/usr/src/redmine/files

 

As you can see, there is no major changes: I wanted both images to have their own database in order to run separately database so credentials are different.

 

The only significant change: the version  value.

It depends on the docker engine version available on your platform. You can use a compose version/engine compatibility matrix to select what version to use although it is more likely that the version will be selected based on the options you want/need to use so better read the release notes.

 

 

Our application will be exposed not on the Redmine default port 3000 but on port 80 meaning we only need to connect to the server's public IP once application is up and running.

Leaving defaut value "3000:3000" would only force us to connect by typing:

XXX.XXX.XXX.XXX:3000 

 

  1. Launching the application

If you haven't installed docker and docker-compose packages:

 

Ubuntu
Redhat
sudo apt update -y
sudo apt upgrade -y
sudo apt install docker-compose -y                

sudo dnf upgrade
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf repolist -v
sudo dnf install --nobest docker-ce
sudo dnf install docker-ce -y
sudo systemctl enable --now docker
systemctl is-active docker
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose
sudo mv docker-compose /usr/local/bin && sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

Simply running an update & upgrade will add Docker packages to APT cache.

Installing docker-compose will automatically install all dependencies.

Docker is enabled by default.

We need to add the proper repository and then install the packages.

Docker is disabled by default, so we need to enable it.

And then Docker-compose package must be installed.

 

 

Once your docker-compose.yml file is ready, simply go to the directory in which it's stored  (/opt/redminedocker in our example) and execute:

sudo docker-compose up -d

 

The service will then pull the image listed and deploy it with the parameters listed in the docker-compose.yml file:

 

Once deployed, you can check that the container is running by executing:

sudo docker ps -a

It will list all the running containers.

 

 

If you only want to check one particular container:

sudo docker ps -a container_name

Which would be for our example:

sudo docker ps -a redmine

 

At this point, you should be able to log into your Redmine application:

 

You can now connect using the default credentials and setup your Redmine platform.

 

Going further: Docker options, debugging and customizing Redmine

  1. "image" vs "build" tags

 

Using the "image" tag you will be using pre-existing images from official repositories such as DockerHub or your own repository as the images are.

 

The "build" tag allows you to take the same images but adapt them to your needs for that particular project.

This is useful when:

  • adapting official images that are almost prefect for your use but not quite
  • using the same image in different environments without having to store multiple versions of the same image in your repository. The built image will be stored on the host running the image.

 

It will re-run the docker-compose process and execute any changes detected in the docker-compose.yml file.

To build your customized image in this instance:

  1. comment out

image: redmine:5.0.5

  1. uncomment

build: /opt/redminedocker/configs

  1. Update your container by executing command:

sudo docker-compose up -d

 

 

The build process will call the Dockerfile to get the parameters and actions to be run to create your customized image.

 

  1. Understanding the Dockerfile

 

Below will be a few examples of Dockerfile contents from running servers.

Example 1 is the file used with the docker-compose.yml above when using the "build" tag.

Example 1

 

FROM redmine:5.0.5
RUN set -ex; \
apt update;
RUN apt-get install dialog apt-utils -y
RUN apt install cron libreoffice -y
RUN apt-get install -y build-essential
RUN apt install pandoc -y
RUN apt-get clean
RUN apt-get autoclean
RUN apt-get autoremove
RUN cd /usr/src/redmine
RUN gem install json -v '2.6.1'
RUN mkdir root
CMD ["rails", "server", "-b", "0.0.0.0"]

  • FROM is to set the image used as starting point
  • RUN allows commands to be passed. You can either combine commands in a single RUN line using \ or have multiple RUN lines
  • CMD details the arguments for the ENTRYPOINT process.

This file will install a few additional packages (CRON, libreoffice, pandoc...) that are used for some of the plugins I usually install.

It also installs JSON Gem at a specific version also because of a plugin compatibility issue.

Example 2

FROM redmine:5.0.5
MAINTAINER Nicolas
RUN yum -y update && \
yum clean all
COPY ./script.sh /
RUN chmod +x /script.sh
ENTRYPOINT ["/script.sh"]
CMD ["rails", "server", "-b", "0.0.0.0"]

  • COPY will copy files from to the host in the image
  • MAINTAINER is now deprecated and replaced with LABEL but can still be found in documentation. It is used to set image metadata.
  • Yum has ben used instead of APT but file structure is the same
Example 3

FROM ruby:3.2.2-alpine
LABEL maintainer="Nicolas Author"
RUN apt-get update && apt-get install -y nodejs
WORKDIR /app
COPY Gemfile* .
RUN bundle install
COPY ..
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]

 

  • LABEL has been used instead of the deprecated MAINTAINER
  • WORKDIR sets the directory from which the application will run in the image
  • EXPOSE indicates the port to expose. In our case, this is set in our Docker-compose file.

 

 

  1. Check logs and debug

If your container restarts all the time, you can check the logs:

sudo docker logs redmine

 

It will give you the end of the logs.

To define how much of the logs to see, option --tail can be used:

sudo docker logsredmine -f --tail 1000

 

Or if you want to follow the logs as you are using the application

sudo docker logs redmine -f

This is particularly usefull when debuging a specific page loading issue.

 

To check all the log options, you can run:

docker logs --help

 

Depending on the errors observed, you will need to either:

  • correct your docker-compose.yml file
  • review your network/database connectivity
  • update/customize plugin code

 

  • Example of a database connectivity issue

 

This was because the docker-compose.yml  was calling the wrong port on the database server:

 

Here, we only need to update the docker-compose.yml file and restart the container.

 

  • Example of an issue caused by plugins installed

 

The plugin code has been pulled into the wrong directory

Redmine::PluginNotFound: Plugin not found. The directory for plugin onlyoffice_redmine should be /usr/src/redmine/plugins/onlyoffice_redmine.

 

Cheking the plugins folders:

sudo ls -l /opt/redminedocker/plugins/
total 4
drwxr-xr-x 8 root root 4096 Oct 12 19:23 onlyoffice-redmine

 

The GIT clone has copied the files to a folder differnt from the one delcared in the plugin. The quick fix is simple:

sudo mv /opt/redminedocker/plugins/onlyoffice-redmine /opt/redminedocker/plugins/onlyoffice_redminesudo docker restart redmine

 

  •  

    The plugin installed has unmet dependencies

Trying to install Redmin SAML plugin on a newly deployed Redmine instance, we get:

Redmine::PluginRequirementError: redmine_saml plugin requires the additionals plugin

 

Checking the documentation, we see that plugin Additionals is required:

cd /opt/redminedocker/plugins/
sudo git clone https://github.com/alphanodes/additionals.gitsudo docker restart redmine

 

 

  • The plugin we're trying to install isn't fully compatible due to synthax/code issues with our version of Ruby or Rail

 

Installing the plugin Issue tree to help in visual ticket/issue management, we get the error:

NameError: uninitialized constant RedmineIssuesTree::VERSION
version RedmineIssuesTree::VERSION
^^^^^^^^^
Did you mean? RedmineIssuesTree::Version
Version
/usr/src/redmine/plugins/redmine_issues_tree/init.rb:7:in block in <top (required)>'<br />/usr/src/redmine/lib/redmine/plugin.rb:96:in instance_eval'
/usr/src/redmine/lib/redmine/plugin.rb:96:in register'<br />/usr/src/redmine/plugins/redmine_issues_tree/init.rb:3:in <top (required)>'

 

Checking the init.rb file for that plugin:

sudo vi redmine_issues_tree/init.rb

 

We see:

version RedmineIssuesTree::VERSION

 

Updating to the expected format, we then get another error:

Zeitwerk::NameError: expected file /usr/src/redmine/plugins/redmine_issues_tree/lib/redmine_issues_tree/version.rb to define constant RedmineIssuesTree::Version, but didn't

 

We simply need to update file redmine_issues_tree/lib/redmine_issues_tree/version.rb to declare constant "Version" instead of "VERSION" and all works fine:

 

  • All issues have been corrected but the container still reboots non-stop

If you want to restart with a clean container, you can force-delete the running container and the re-deploy from the docker-compose file:

sudo docker rm -f redmine
sudo docker-compose up -d

 

Restarting from a new container can be useful in order to reset some of the environment parameters that can be a cause of issues.

 

  1. Update application & install themes/plugins

Updating image

Our example is set to use redmine:5.0.5 but redmine:5.0.6 has since been released.

Updating an application running from a Docker-compose file is pretty straitforward:

  1. Update the docker-compose file with the new image
  2. Run:
sudo docker-compose up -d

The new image will be pulled and a new container deployed using the same parameters.

 

Note: If you use another image source, check the documentation to make sure you are using the proper parameters.
The "environment" tags are those to be used with that image.
Other Docker images for Redmine exist and use different environment parameter names for example the Bitnami Redmine or even user maintained images such as Sameersbn Docker Redmine

 

Installing themes & plugins

There are many ways themes and plugins can be installed using docker but I'll only detail the one I most commonly use.

 

In the docker-compose.yml file, volums are set as:

    volumes:
      - /opt/redminedocker/plugins:/usr/src/redmine/plugins
      - /opt/redminedocker/public/themes:/usr/src/redmine/public/themes
      - /opt/redminedocker/files:/usr/src/redmine/files

And we have an environment parameter set:

    environment:
      - "REDMINE_PLUGINS_MIGRATE=true"

 

This means that when starting up the container, Docker will call on files from the host.

To install a theme or plugin, you simply need to download the theme/plugin code in the correct folder and restart the container.

Added themes will be available and new plugins will be installed automatically.

 

Example with the Purplemine2 theme:

cd /opt/redminedocker/public/themes
sudo git clone https://github.com/mrliptontea/PurpleMine2
sudo docker restart redmine

Installed plugins will then appear in the/settings?tab=display page.

 

Example with the Redmine Dashboard plugin:

cd /opt/redminedocker/plugins/
sudo git clone https://github.com/jgraichen/redmine_dashboard.git
sudo docker restart redmine

 

Installed plugins will then appear in the /admin/plugins page.

 

Note: usually, the application is available after 30 seconds after restart.

If it is not available or the images is always restarting, simply remove the folder containing the plugin you just added.

Even though plugins are compatible and have been tested with the different Redmine versions, when using custom Redmine images or simply multiple plugins, you can find that applications parameters set for one plugin will not be compatible with another. You then need to "debug" or adapt the plugin(s) you want to use.

 

You may also like

0
Would love your thoughts, please comment.x
()
x