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 :
-
- Very user friendly: I've already deployed it in multiple organisations and users have been able to start using it with litteraly no training.
- Easily customised: Redmine allows each project to have it's own workflows, types of tasks or data fields to be filled in
- 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
- Plugins: having existed for so long, many usefull plugins exist in the "Official plugin directory"
- 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:
docker-compose.yml
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
If you haven't installed docker and docker-compose packages:
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
-
"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:
- comment out
image: redmine:5.0.5
- uncomment
build: /opt/redminedocker/configs
- 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.
-
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 |
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 |
|
Example 3 |
FROM ruby:3.2.2-alpine |
|
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.
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:
- Update the docker-compose file with the new image
- 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.