---
title: BESTNET 클라우드에서 Redmine 구축하기
description: "BESTNET Tech Blog # 베스트넷 클라우드에 Redmine 구축하는 절차 Ubuntu 24.04 / Apache + Passenger / PostgreSQL / HTTPS 환경에서 Redmine 6.1 계열을 구동하는 서버 구축 편 본 문서에서는 베스트넷 클라우드에 준비한 Ubuntu 24.04 LTS 가상 머신에 Redmine을 구축하고, 브라우저에서…"
url: "https://bestnetllc.co.jp/ko/docs/bestnet-%ed%81%b4%eb%9d%bc%ec%9a%b0%eb%93%9c%ec%97%90%ec%84%9c-redmine-%ea%b5%ac%ec%b6%95%ed%95%98%ea%b8%b0/"
updated: "2026-10-19"
category: Tech Blog
---

# BESTNET 클라우드에서 Redmine 구축하기

BESTNET Tech Blog

# 베스트넷 클라우드에 Redmine 구축하는 절차

Ubuntu 24.04 / Apache + Passenger / PostgreSQL / HTTPS 환경에서
Redmine 6.1 계열을 구동하는 서버 구축 편

본 문서에서는 베스트넷 클라우드에 준비한 Ubuntu 24.04 LTS 가상 머신에
Redmine을 구축하고, 브라우저에서 초기 로그인이 가능한 상태까지 순서대로 정리합니다.

LDAP/LDAPS 연계나 외부 SMTP, Zabbix 연계는 이후 연재되는 별도 문서에서 다룰 예정이며,
이번에는 먼저 “안정적으로 로그인 화면을 표시할 수 있는 Redmine 서버”를 완성하는 것까지를 목표로 합니다.

## 이번 목표

### 도달점

HTTPS로 Redmine 로그인 화면이 표시되고, 관리자로 초기 로그인할 수 있는 상태로 만듭니다.

### 이번 범위

OS 초기 설정, Redmine 배치, DB 초기화, Apache + Passenger, 자체 서명 SSL까지.

### 다음 회 이후

AD / LDAPS, 외부 SMTP, Zabbix 에이전트 도입, 모니터링 연계 등을 나누어 다룹니다.

## 구성 개요

| OS | Ubuntu Server 24.04 LTS |
| --- | --- |
| Web/AP | Apache + Passenger |
| DB | PostgreSQL |
| Redmine | 6.1.1 |
| Ruby | Ubuntu 24.04 동봉 Ruby 3.2 계열 |
| 공개 방식 | 80 → 443 리다이렉트, 443은 자체 서명 인증서로 대기 |
| 배치 경로 | /opt/redmine/releases/redmine-6.1.1 |

 **주의:**
이 문서에서는 검증 용이성을 우선하여 자체 서명 인증서를 사용합니다.
공개 환경에서는 상용 인증서 또는 사내 CA 인증서로 교체하실 것을 권장합니다.

## Step 1. OS 업데이트 및 필요 패키지 설치

먼저 OS를 최신화하고, Redmine 빌드 및 PostgreSQL 연결에 필요한 패키지를 일괄 설치합니다.
`libyaml-dev`를 설치해 두는 것이 포인트입니다.

```
sudo apt update
sudo apt full-upgrade -y

sudo apt install -y 
  build-essential 
  ruby-full ruby-dev bundler 
  zlib1g-dev libpq-dev libyaml-dev pkg-config 
  postgresql postgresql-contrib 
  apache2 apache2-dev 
  imagemagick ghostscript 
  curl ca-certificates gnupg dirmngr apt-transport-https 
  ldap-utils tar
```

## Step 2. Passenger 설치

Passenger 공식 리포지토리를 추가하고, Apache 모듈로 설치합니다.

```
curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key-2025.txt 
  | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null

echo "deb https://oss-binaries.phusionpassenger.com/apt/passenger noble main" 
  | sudo tee /etc/apt/sources.list.d/passenger.list

sudo apt update
sudo apt install -y passenger libapache2-mod-passenger

sudo a2enmod passenger
sudo a2enconf servername
echo "ServerName rdm.bestnetllc.co.jp" | sudo tee /etc/apache2/conf-available/servername.conf

sudo apache2ctl configtest
sudo systemctl reload apache2
```

동작 확인은 다음과 같이 진행합니다.

```
sudo /usr/bin/passenger-config validate-install
sudo /usr/sbin/passenger-memory-stats
```

## Step 3. Redmine 용 사용자 및 배치 디렉터리 준비

업그레이드를 쉽게 하기 위해 릴리스 디렉터리 방식으로 배치합니다.

```
sudo adduser --system --group --home /opt/redmine --shell /bin/bash redmine

sudo mkdir -p /opt/redmine/releases
sudo chown -R redmine:redmine /opt/redmine
```

## Step 4. PostgreSQL 생성

Redmine 전용 역할과 데이터베이스를 생성합니다.

```
sudo -u postgres psql
```

```
CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD '<DB_PASSWORD>' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
q
```

## Step 5. Redmine 본체 배포

여기서는 6.1.1을 예로 들겠습니다. 필요에 따라 유지보수 릴리스로 읽어주세요.

```
cd /tmp
curl -L -o redmine-6.1.1.tar.gz https://www.redmine.org/releases/redmine-6.1.1.tar.gz

sudo -u redmine tar xzf redmine-6.1.1.tar.gz -C /opt/redmine/releases
sudo ln -sfn /opt/redmine/releases/redmine-6.1.1 /opt/redmine/current
```

## Step 6. database.yml 설정

여기는 실수하기 쉬운 포인트입니다. MySQL용 샘플을 남기지 말고 PostgreSQL 정의만 작성합니다.

```
cd /opt/redmine/releases/redmine-6.1.1

sudo tee config/database.yml > /dev/null <<'EOF'
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: "<DB_PASSWORD>"
  encoding: utf8
  schema_search_path: public
EOF
```

추가로 암호화 키용 `configuration.yml`도 준비합니다.

```
sudo -u redmine cp config/configuration.yml.example config/configuration.yml
```

```
default:
  database_cipher_key: "<LONG_RANDOM_STRING>"

production:
```

## Step 7. bundle install 및 DB 초기화

Gem 설치, 시크릿 생성, DB 마이그레이션, 초기 데이터 투입을 실행합니다.

```
sudo chown -R redmine:redmine /opt/redmine

sudo -u redmine -H bash -lc '
  cd /opt/redmine/releases/redmine-6.1.1
  rm -rf vendor/bundle
  bundle config set --local path vendor/bundle
  bundle config set --local without "development test"
  bundle install
  bundle exec rake generate_secret_token
  RAILS_ENV=production bundle exec rake db:migrate
  RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data
'
```

   **보충:**
`yaml.h not found` 오류가 발생하는 경우 `libyaml-dev` 부족,
`mysql2`가 bundle 대상에 포함되는 경우 `config/database.yml`에
MySQL 설정이 남아 있을 가능성이 높습니다.

## Step 8. 자체 서명 인증서 생성

이번 예제에서는 CA:FALSE와 SAN이 포함된 자체 서명 인증서를 생성합니다.
구버전 방식으로 생성하면 브라우저나 Apache의 경고가 증가하므로, 이 형태로 만들어 두면 다루기 쉽습니다.

```
sudo mkdir -p /etc/apache2/ssl

sudo tee /tmp/rdm-openssl.cnf > /dev/null <<'EOF'
[req]
default_bits = 4096
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C  = JP
ST = Tokyo
L  = Tokyo
O  = BestNetLLC
OU = IT
CN = rdm.bestnetllc.co.jp

[v3_req]
basicConstraints = critical,CA:FALSE
keyUsage = critical,digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = rdm.bestnetllc.co.jp
EOF

sudo openssl req -x509 -nodes -newkey rsa:4096 -sha256 -days 3650 
  -keyout /etc/apache2/ssl/rdm.bestnetllc.co.jp.key 
  -out /etc/apache2/ssl/rdm.bestnetllc.co.jp.crt 
  -config /tmp/rdm-openssl.cnf

sudo chmod 600 /etc/apache2/ssl/rdm.bestnetllc.co.jp.key
sudo chmod 644 /etc/apache2/ssl/rdm.bestnetllc.co.jp.crt
```

## Step 9. Apache VirtualHost 설정

80 포트는 443으로 리디렉션하고, 443 포트는 Redmine의 `public`을 DocumentRoot로 설정합니다.
실제 경로를 직접 지정하는 이유는 심볼릭 링크로 인한 403 오류를 방지하기 위함입니다.

```
sudo a2enmod ssl rewrite headers

sudo tee /etc/apache2/sites-available/redmine.conf > /dev/null <<'EOF'
<VirtualHost *:80>
    ServerName rdm.bestnetllc.co.jp
    RewriteEngine On
    RewriteRule ^/(.*)$ https://rdm.bestnetllc.co.jp/$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName rdm.bestnetllc.co.jp
    DocumentRoot /opt/redmine/releases/redmine-6.1.1/public

    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/rdm.bestnetllc.co.jp.crt
    SSLCertificateKeyFile /etc/apache2/ssl/rdm.bestnetllc.co.jp.key

    PassengerRuby /usr/bin/ruby
    PassengerAppEnv production

    <Directory /opt/redmine/releases/redmine-6.1.1/public>
        Options FollowSymLinks
        AllowOverride all
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/redmine_ssl_error.log
    CustomLog ${APACHE_LOG_DIR}/redmine_ssl_access.log combined
</VirtualHost>
EOF

sudo a2ensite redmine
sudo a2dissite 000-default
sudo a2dissite default-ssl

sudo apache2ctl configtest
sudo systemctl reload apache2
```

## Step 10. 권한 조정 및 재시작

Apache에서 Redmine 하위 경로에 접근할 수 있도록 상위 디렉토리에도 실행 권한을 부여합니다.

```
sudo chmod 755 /opt
sudo chmod 755 /opt/redmine
sudo chmod 755 /opt/redmine/releases
sudo chmod 755 /opt/redmine/releases/redmine-6.1.1
sudo chmod 755 /opt/redmine/releases/redmine-6.1.1/public

sudo -u redmine mkdir -p /opt/redmine/releases/redmine-6.1.1/tmp/pdf
sudo -u redmine mkdir -p /opt/redmine/releases/redmine-6.1.1/public/assets

sudo touch /opt/redmine/releases/redmine-6.1.1/tmp/restart.txt
sudo systemctl restart apache2
```

## Step 11. 초기 접근 확인

먼저 로컬 통신을 확인합니다.

```
curl -kI https://127.0.0.1/
openssl s_client -connect 127.0.0.1:443 -servername rdm.bestnetllc.co.jp </dev/null
```

브라우저에서는 `https://rdm.bestnetllc.co.jp`로 접속합니다.
자체 서명 인증서이므로 브라우저 경고가 나타나지만, Redmine 로그인 화면이 표시되면 성공입니다.

 **초기 로그인:**
사용자 이름 `admin` / 비밀번호 `admin`

최초 로그인 후에는 관리자 비밀번호를 즉시 변경하고,
Redmine의 “관리 → 설정 → 일반”에서 호스트 이름과 프로토콜을 `https`에 맞춥니다.

## 구축 중 자주 발생하는 문제점

### 1. Passenger 리포지토리의 GPG 오류

오래된 키 URL을 사용하면 `NO_PUBKEY`로 실패할 수 있습니다.
공식 최신 키 파일을 사용하는 형태로 통일하면 해결하기 쉽습니다.

### 2. `yaml.h not found`로 Psych 빌드 실패

`libyaml-dev`가 부족한 경우가 많습니다.
OS 패키지를 추가한 후 `bundle install`을 다시 실행합니다.

### 3. `mysql2`가 bundle 대상에 나타남

`config/database.yml`에 MySQL 샘플 정의가 남아 있으면 발생하기 쉽습니다.
PostgreSQL용 production 정의만으로 정리하면 해결됩니다.

### 4. `ERR_SSL_PROTOCOL_ERROR` 발생

443 VirtualHost가 활성화되지 않았거나 다른 사이트가 활성화된 상태로 남아 있는 경우가 있습니다.
`apache2ctl -S`로 활성화된 vhost를 확인하면 원인을 파악하기 쉬워집니다.

### 5. 403 Forbidden 발생

`current` 심볼릭 링크 경로로 인해 권한 문제가 발생할 수 있습니다.
실제 경로를 직접 DocumentRoot에 지정하고, `/opt` 아래에 검색 권한을 부여하면 개선되기 쉽습니다.

## 정리

이상으로 베스트넷 클라우드에 Ubuntu 24.04 / Apache + Passenger / PostgreSQL 구성의
Redmine 서버를 구축하고, HTTPS를 통해 최초 로그인할 수 있는 단계까지 도달할 수 있습니다.

- Redmine 본체 배포가 완료되었습니다
- PostgreSQL에 연결할 수 있습니다
- Apache + Passenger로 애플리케이션이 시작됩니다
- 자체 서명 인증서로 443 포트를 수신할 수 있습니다
- 브라우저에서 로그인 화면이 표시됩니다

다음 글에서는 AD / LDAPS 인증, 외부 SMTP, 그리고 Zabbix를 통한 모니터링 연동으로 진행합니다.

© BestNet Tech Blog
