Project

General

Profile

Actions

Task #244

open

Task Group #243: [DevOps] DevOps related task management

[DevOps] Install the bitnami package for Redmine and configure Redmine to use as an external issue tracker for GitLab

Added by Sanghoon Lee 10 days ago. Updated 4 days ago.

Status:
Resolved
Priority:
Normal
Assignee:
Start date:
03/24/2026
Due date:
% Done:

90%

Estimated time:
Product Code:
uAi SW:

Description

Install the bitname package for Redmine and configure Redmine to use as an external issue tracker for GitLab

[GitLab] ──→ External Issue Tracker Setting ──→ [Bitnami Redmine:3000]
                                                                │
                                                        [MariaDB Container]

Redmine Installation & GitLab Integration Procedures


1. System Architecture Overview

                        ┌─────────────────────────────────────────────────────────┐
                        │                       GitLab                            │
                        │                                                         │
                        │   Repository   │   Issues   │   Commit Messages         │
                        └───────┬────────┴─────┬──────┴───────────┬───────────────┘
                                │              │                  │
          [1] Webhook           │              │ [2] Integration  │ [3] Commit message
          push event triggered  │              │ issue URL link   │ XCP-#42 (refs #42)
                                │              │                  │
                                v              v                  │
                        ┌───────────────────────────────┐         │
                        │           Redmine             │         │
                        │                               │ <───────┘
                        │  redmine_gitlab_hook plugin   │    refs #42 → issue link
                        │            │                  │
                        │            v                  │
                        │   git fetch --all -p          │
                        │   (update mirror repository)  │
                        │            │                  │
                        │            v                  │
                        │   fetch_changesets            │
                        │   (sync commits to DB)        │
                        │                               │
                        │  Issues  │  Repository  │ DB  │
                        └───────────────────────────────┘

 [1] Webhook    : GitLab push → automatically syncs commits to Redmine repository
 [2] Integration: GitLab Settings → Integrations → Redmine issue tracker URL linking
 [3] Commit ref : "XCP-#42 (refs #42)" → creates issue links in both GitLab and Redmine
Component Version / Details
Redmine 6.1 (redmine:6.1-trixie)
Database MySQL 8.0
Plugin redmine_gitlab_hook v4.0.0 (phlegx/redmine_gitlab_hook)
Host IP 192.168.1.102
Redmine Port 3000
GitLab URL http://git.xela.com:8888

2. Prerequisites

2-1. Verify Docker & Docker Compose Installation

docker --version
docker compose version

2-2. Create Required Directories

mkdir -p /home/xela/redmine/redmine_data
mkdir -p /home/xela/redmine/mysql_data
mkdir -p /home/xela/redmine/redmine_repos
mkdir -p /home/xela/redmine/plugins

2-3. Generate a GitLab Access Token

A token is required for authentication during git fetch operations.

  1. Go to GitLab → User Settings → Access Tokens (or project Settings → Repository → Deploy tokens)
  2. Select scope: read_repository
  3. Note down the generated username and token value

Deploy Token recommended: Grants read-only access scoped to a specific project, and is not affected by account password changes.


3. Directory Structure & File Configuration

/home/xela/redmine/
├── docker-compose.yml          # Container orchestration
├── Dockerfile                  # Custom image with plugins included
├── SETUP.md                    # Korean setup guide
├── SETUP_EN.md                 # Markdown version
├── SETUP_EN.textile            # This document (Redmine wiki format)
├── plugins/
│   └── redmine_gitlab_hook/    # GitLab webhook integration plugin
├── redmine_data/               # Persistent Redmine data (file attachments, etc.)
├── redmine_repos/              # Git mirror repositories (host path)
│   └── XCP.git/                # Example bare mirror repository
└── mysql_data/                 # Persistent MySQL data

Key docker-compose.yml Settings

services:
  redmine_db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: <change this>
      MYSQL_USER: redmine
      MYSQL_PASSWORD: <change this>
      MYSQL_DATABASE: redmine
    volumes:
      - /home/xela/redmine/mysql_data:/var/lib/mysql

  redmine:
    build: .                          # Custom build from Dockerfile
    ports:
      - "192.168.1.102:3000:3000"     # Bind to specific IP only
    volumes:
      - /home/xela/redmine/redmine_data:/usr/src/redmine/files
      - /home/xela/redmine/redmine_repos:/var/lib/redmine/repositories:rw

Volume mount note: redmine_repos (host) → /var/lib/redmine/repositories (container).
Any changes to repository files on the host are immediately reflected inside the container.

Dockerfile Overview

FROM redmine:6.1-trixie

# Install build tools
RUN apt-get install -y build-essential gcc make git default-libmysqlclient-dev

# Copy plugins and set ownership
COPY ./plugins /usr/src/redmine/plugins
RUN chown -R redmine:redmine /usr/src/redmine/plugins

# Install plugin gem dependencies
USER redmine
RUN bundle install

When adding or updating plugins, the image must be rebuilt: docker compose build --no-cache


4. Git Mirror Repository Setup

For each GitLab project to be integrated, create a local mirror repository on the Redmine server.

4-1. Create Mirror Clone

# Format: git clone --mirror http://USER:TOKEN@GITLAB_HOST/NAMESPACE/REPO.git DEST.git
git clone --mirror \
  http://invokelshn:TOKEN@git.xela.com:8888/software/XCP.git \
  /home/xela/redmine/redmine_repos/XCP.git

4-2. Verify Credentials Are Embedded in the Remote URL

cat /home/xela/redmine/redmine_repos/XCP.git/config

The url field under [remote "origin"] must include credentials in the format http://USER:TOKEN...:@

[remote "origin"]
    url = http://USERNAME:TOKEN@git.xela.com:8888/software/XCP.git
    fetch = +refs/*:refs/*
    mirror = true

Important: The Redmine container runs git fetch in a non-interactive environment — there is no TTY available to prompt for username/password.
Credentials must be embedded in the URL or configured via a credential store.

If the repository was cloned without credentials, update the URL:

git --git-dir="/home/xela/redmine/redmine_repos/XCP.git" \
  remote set-url origin \
  "http://USERNAME:TOKEN@git.xela.com:8888/software/XCP.git" 

4-3. Verify fetch Works (Test from Host)

git --git-dir="/home/xela/redmine/redmine_repos/XCP.git" fetch --all -p

Expected output:

From http://git.xela.com:8888/software/XCP
   4acdd59..1caf25e  main -> main

5. Build & Run Docker Containers

5-1. Build Image and Start Containers

cd /home/xela/redmine
docker compose build
docker compose up -d

5-2. Verify Container Status

docker compose ps
docker logs redmine --tail=30

When Puma starts successfully:

* Listening on http://0.0.0.0:3000

5-3. Rebuild After Plugin Changes

docker compose down
docker compose build --no-cache
docker compose up -d

6. Redmine Initial Configuration (Web UI)

Redmine Web UI: http://192.168.1.102:3000 (or http://redmine.xela.com:3000)

Default admin credentials: admin / adminchange immediately after first login

6-1. Retrieve API Key

The plugin uses this key to authenticate incoming webhook requests.

Administration → Settings → Repository tab → Check "Enable WS for repository management" → Copy the API key

6-2. Register a Git Repository for a Redmine Project

For each project to be integrated:

  1. Go to the project → Settings → RepositoriesNew repository
  2. Fill in the settings:
Field Value
SCM Git
Identifier xcp_mirror (must match the repository_name parameter in the webhook URL)
Path to repository /var/lib/redmine/repositories/XCP.git (path inside the container)
Is default repository Check

3. Click Create and verify the repository is recognized correctly

6-3. Configure the redmine_gitlab_hook Plugin

Administration → Plugins → Redmine GitLab Hook plugin → Configure

Setting Value Description
All Branches Yes Fetch all branches from all remotes
Prune Yes Remove stale remote-tracking references
Auto Create Yes Auto-create repository on first webhook (optional)
Fetch Updates Yes Run git fetch when webhook is received
Local Repositories Path /var/lib/redmine/repositories Required when Auto Create is enabled

7. GitLab Webhook Configuration

7-1. Webhook URL Format

http://redmine.xela.com:3000/gitlab_hook?project_id=REDMINE_PROJECT_ID&repository_name=REPO_IDENTIFIER&key=REDMINE_API_KEY
Parameter Description Example
project_id Redmine project identifier fy26_xcp-project
repository_name Redmine repository identifier xcp_mirror
key Redmine API key (from section 6-1) u67PN12c2bDK5HyaTUdC

Important: Use repository_name, not repository_id.
The plugin reads params[:repository_name] — the repository_id parameter is ignored entirely.

7-2. Register the Webhook in GitLab

  1. GitLab project → Settings → Webhooks
  2. Configure:
Field Value
URL The webhook URL from above
Trigger Check Push events
SSL verification Configure as needed

3. Click Add webhook

7-3. Example Configuration (XCP Project)

http://redmine.xela.com:3000/gitlab_hook?project_id=fy26_xcp-project&repository_name=xcp_mirror&key=u67PN12c2bDK5HyaTUdC

8. GitLab Integrations Setup (Issue Tracker Linking)

The Settings → Integrations → Redmine feature in GitLab allows issue numbers referenced in commit messages or merge requests to become clickable links that navigate directly to Redmine issues.

Webhook vs Integrations

  • Webhook (section 7): GitLab push event → automatically updates the Redmine repository mirror (commit sync)
  • Integrations (this section): Links issue references in the GitLab UI to the Redmine issue tracker

8-1. Enable the Redmine Integration in GitLab

  1. GitLab project → Settings → Integrations → select Redmine
  2. Configure the following fields:
Field Value Description
Active Checked Enable the integration
Project URL http://redmine.xela.com:3000/projects/fy26_xcp-project URL of the Redmine project
Issues URL http://redmine.xela.com:3000/issues/:id Issue URL pattern (keep :id as-is)
New issue URL http://redmine.xela.com:3000/projects/fy26_xcp-project/issues/new URL to create a new issue

3. Click Save changes

The project identifier in Project URL and New issue URL must match the Redmine project identifier exactly.
Example: if the Redmine project identifier is fy26_xcp-project, use the same value in the URLs.

8-2. Referencing Issues in Commit Messages

Once the integration is active, use the following format to create issue links in both GitLab and Redmine simultaneously:

# Format: "commit message GITLAB_PROJECT_ID-#issue_number (refs #issue_number)" 
git commit -m "Fix sensor calibration logic XCP-#42 (refs #42)" 
git push origin main
Reference format Recognized by Description
XCP-#42 GitLab GitLab project ID (XCP) + issue number → links to GitLab issue
refs #42 Redmine Redmine issue number → links to Redmine issue

GitLab Project ID: find it at GitLab project → Settings → General → Project ID
Replace XCP with the actual project ID of your GitLab project.

In the GitLab commit detail page, refs #42 will appear as a clickable link that navigates to:

http://redmine.xela.com:3000/issues/42

8-3. Verify the Integration

  • GitLab → project → Settings → Integrations → Redmine → click the Test button
  • A successful connection shows a green checkmark with a success message

9. Integration Testing Procedure

Step 1: Test git fetch Directly

Verify that git fetch works from inside the container.

docker exec redmine git \
  --git-dir="/var/lib/redmine/repositories/XCP.git" \
  fetch --all -p
  • Success: Branch update information is printed
  • Failure: See Troubleshooting section below

Step 2: Manually Trigger Webhook from GitLab UI

  1. GitLab → project → Settings → Webhooks
  2. Click Test → Push events on the registered webhook
  3. Check the response:
    • HTTP 200: Success
    • HTTP 406: git fetch failed (authentication or path issue)
    • HTTP 500: Redmine internal error (project/repository configuration issue)

Step 3: Test Webhook via curl

curl -X POST \
  "http://redmine.xela.com:3000/gitlab_hook?project_id=fy26_xcp-project&repository_name=xcp_mirror&key=u67PN12c2bDK5HyaTUdC" \
  -H "Content-Type: application/json" \
  -d '{"object_kind":"push","ref":"refs/heads/main"}'

Expected response: OK

Step 4: Monitor Logs in Real Time

# Terminal 1: watch logs
docker logs -f redmine

# Terminal 2: trigger webhook or push to GitLab

Expected log on successful processing:

Started POST "/gitlab_hook?..." for ...
Processing by GitlabHookController#index
Completed 200 OK

Step 5: Verify Commits Appear in Redmine UI

  1. Redmine → the project → Repository tab
  2. Confirm that commits pushed to GitLab are now visible

Step 6: End-to-End Test

# 1. Create a test commit (from a local development environment)
git commit --allow-empty -m "test: redmine webhook integration" 
git push origin main

# 2. After a few seconds, check Redmine
# Project → Repository → verify the commit appears in the list

10. Troubleshooting

Error 1: HTTP 500 — "has no repository or repository not found"

TypeError: Project 'XXX' has no repository or repository not found with identifier 'yyy'
Cause A: Webhook URL uses repository_id instead of repository_name
  • Fix: Replace repository_id=... with repository_name=... in the webhook URL
Cause B: No repository registered for the Redmine project
  • Fix: Register a Git repository under project Settings → Repositories (see section 6-2)
Cause C: Mismatch between repository_name parameter and the Redmine repository identifier
  • Fix: Ensure the Redmine repository identifier exactly matches the repository_name value in the webhook URL

Error 2: HTTP 406 — "Git command failed"

GitLabHook: Command 'git --git-dir="..." fetch --all -p' didn't exit properly.
fatal: could not read Username for 'http://...': No such device or address

Cause: The mirror repository's remote URL does not contain credentials

Fix:

git --git-dir="/home/xela/redmine/redmine_repos/XCP.git" \
  remote set-url origin \
  "http://USERNAME:TOKEN@git.xela.com:8888/software/XCP.git" 

Error 3: Cannot Reach GitLab Host from Inside the Container

fatal: unable to access 'http://git.xela.com:8888/...': Could not resolve host

Check:

docker exec redmine curl -I http://git.xela.com:8888

Fix: Add extra_hosts to docker-compose.yml or verify DNS configuration on the host.


How to Check Logs

# Container logs (last 100 lines)
docker logs --tail=100 redmine

# Follow logs in real time
docker logs -f redmine

# Redmine production.log (inside container)
docker exec redmine tail -100 /usr/src/redmine/log/production.log

11. Maintenance

Adding a New GitLab Project Integration

  1. Create a mirror repository (see section 4)
  2. Register the repository in the Redmine project (see section 6-2)
  3. Add a webhook in GitLab (see section 7)
  4. Run through the test procedure (see section 9)

Restart Containers

cd /home/xela/redmine
docker compose restart

Update the Plugin

cd /home/xela/redmine/plugins/redmine_gitlab_hook
git pull

cd /home/xela/redmine
docker compose down
docker compose build --no-cache
docker compose up -d

Backup

# MySQL database
docker exec redmine_db mysqldump -u redmine -pPASSWORD redmine > backup_$(date +%Y%m%d).sql

# Persistent Redmine data (file attachments, etc.)
tar -czf redmine_data_$(date +%Y%m%d).tar.gz /home/xela/redmine/redmine_data

# Git mirror repositories
tar -czf redmine_repos_$(date +%Y%m%d).tar.gz /home/xela/redmine/redmine_repos

Files

clipboard-202603241708-aqn9v.png (44.1 KB) clipboard-202603241708-aqn9v.png Sanghoon Lee, 03/24/2026 08:08 AM
Actions #2

Updated by Sanghoon Lee 10 days ago

  • Subject changed from [DevOps] Install the bitname package for Redmine and configure Redmine to use as an external issue tracker for GitLab to [DevOps] Install the bitnami package for Redmine and configure Redmine to use as an external issue tracker for GitLab
Actions #3

Updated by Sanghoon Lee 9 days ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 80
Actions #4

Updated by Sanghoon Lee 4 days ago

  • Description updated (diff)
  • Status changed from In Progress to Resolved
  • % Done changed from 80 to 90
Actions #5

Updated by Sanghoon Lee 4 days ago

  • Description updated (diff)
Actions

Also available in: Atom PDF