2020年6月1日月曜日

AWS + Docker + Redmine の簡単な構築手順(pluginを使いたい場合)

AWS/EC2(Amazon Linux 2)でDockerを使ってRedmineの環境構築をした際のメモです。公式のredmineのDockerイメージを使い、尚且プラグインを使いたい場合、多分これが一番簡単だと思います。

(0) スワップ領域確保

EC2の弱いサーバ(t2.micro)で動かす場合、redmineを動かすと割とカジュアルに「メモリ不足」で落ちます。スワップ領域を1GBほど確保すれば、t2.microでも問題なく動きます。(t2.microのお値段は30日あたり$4.176)

dd if=/dev/zero of=/tmp/swap.img bs=1M count=1024

chmod 600 /tmp/swap.img

mkswap /tmp/swap.img

swapon /tmp/swap.img

free


(1) docker / docker-composeをインストール

sudo yum install -y docker
sudo systemctl enable docker
sudo systemctl start docker

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

(2) redmineのDockerfileを作成

sudo mkdir ~/redmine
sudo mkdir ~/redmine/work
sudo mkdir ~/redmine/redmine
sudo vi ~/redmine/redmine/Dockerfile

以下、Dockerfileの内容:
FROM redmine:4.1-passenger
RUN apt-get update && apt-get install build-essential
WORKDIR /home/ec2-user/redmine/work
RUN bundle install
RUN rake redmine:plugins:migrate RAILS_ENV=production

メモ: 当初docker-compose.ymlだけで「image: redmine:4.1-passenger」を指定して構築したのですが、それだとプラグインをビルド(bundle install)時に「make not found」でビルド失敗してしまいます。公式dockerイメージにはbuild-essentialが入っていないので、公式dockerイメージは(そのままでは)pluginを導入することができません。なので、redmine用のDockerfileを個別に作成して、RUNスクリプトでbuild-essentialをインストールしつつ、ついでにbundle install + DBマイグレーションを実行しておくことが必須です...
今どきredmineを使う所も稀かもしれないけど、その中でもpluginを使わない人なんて居るのだろうか?なので、(Dockerポリスからは怒られるかもしれないが)公式のdockerイメージにbuild-essentialを入れておくべきではなかろうか。

(3) docker-compose.ymlを作成

sudo mkdir /var/lib/redmine
sudo mkdir /var/lib/redmine/config
sudo touch /var/lib/redmine/config/configuration.yml
sudo vi ~/redmine/docker-compose.yml

以下、docker-compose.ymlの内容:
version: '3.5'

services:
  redmine:
    build: ./redmine
    container_name: redmine
    ports:
      - 3000:3000
    environment:
      TZ: Asia/Tokyo
      REDMINE_DB_MYSQL: mysql
      REDMINE_DB_DATABASE: redmine
      REDMINE_DB_USERNAME: redmine
      REDMINE_DB_PASSWORD: redmine
      REDMINE_DB_ENCODING: utf8
    depends_on:
      - mysql
    restart: always
    volumes:
      - /var/lib/redmine/files:/usr/src/redmine/files
      - /var/lib/redmine/log:/usr/src/redmine/log
      - /var/lib/redmine/plugins:/usr/src/redmine/plugins
      - /var/lib/redmine/public/themes:/usr/src/redmine/public/themes
      - /var/lib/redmine/config/configuration.yml:/usr/src/redmine/config/configuration.yml

  mysql:
     image: mysql:5.7
     container_name: mysql
     restart: always
     environment:
       TZ: Asia/Tokyo
       MYSQL_ROOT_PASSWORD: devops
       MYSQL_DATABASE: redmine
       MYSQL_USER: redmine
       MYSQL_PASSWORD: redmine
     volumes:
       - mysql-data:/var/lib/redmine/mysql
     command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci

volumes:
  mysql-data:
    name: mysql-redmine

(4) プラグインの追加方法

  1. /var/lib/redmine/plugins以下にgit cloneなりコピーなりして配置
  2. docker-compose restart
起動が上手く行かない場合、ログを見るなりdocker-compose upとかで起動するなりして失敗原因を確認。多分、何かしらのサードパーティーツールが足りていない筈なので、必要なやつをDockerfileのapt-get installに追加してイメージ再作成すればOK。(build-essentialだけあればほぼ問題無いと思いますが念の為)

(5) メール配信をしたい場合

  1. /var/lib/redmine/config/configuration.yml に必要な設定を追加
  2. docker-compose restart
SESを使う場合はこんな感じ:
production:
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "SMTP settingsに書かれているホスト名"
      port: 587
      domain: "ドメイン(※ドメイン認証は無くても大丈夫かも)"
      user_name: "取得したSMTPクレデンシャルのユーザ名"
      password: "取得したSMTPクレデンシャルのパスワード"

(6) Redmineのバージョンを変更したい場合

DockerfileのFROMを修正した後、

docker-compose stop
docker-compose up -d

とかでイケるはず。

(7) クラウド環境で動かしたりとか

ここまでで記載した内容でとりあえずオンプレミスでは正常に動きます。
クラウド環境というかインターネット上で動かす場合に必要な設定を記載しておきます。
  • Route53やお名前.comなどで独自ドメインを確保
  • ACM(Certification Manager)で、確保したドメイン(ex: example.com) or そのサブドメイン(ex: redmine.example.com)の証明書を作成
  • ELB(ロードバランサ)を作成(リスナーはhttps※ポート番号はウェルノウンポートを避ける、ターゲットは作成したインスタンスのhttpポート3000/tcpへオーバロード & ACMで作成した証明を割り当て)
  • Route53の確保したドメインのホストゾーンにCNAMEレコード追加してELBのホスト名に繋ぐようにする(Elastic IPを割り当てているのであればAレコードでもOKだけどElastic IPは有限なのでCNAMEの方が多分都合が良い筈)
  • Redmine自体の設定でユーザ作成は無効化(管理者が対応)、認証を必須、パスワードログインは基本的にせず自社のGsuiteアカウントを使ってGoogleアカウント認証(それができるプラグインがあり自社ドメインに限定等が出来る)でログインして貰うようにする。
  • adminの無効化方法は分からなかった(私はRedmineにはまだ詳しくない)ので、とりあえずクソ長くて解読しにくいパスワードにして対処
上記のような感じで設定すれば、多分、セキュリティレベルとしては普通のクラウド版Redmineサービス(MyRedmineとか)よりも高い筈。

月額コストはだいたい850円〜900円ぐらい。
※とりあえず、EC2はt2.microでEBSに全部載せという雑な構成で動かす場合
※EC2の無料分に収まれば多分月50円(データ転送やSESのコスト分のみ)ぐらいかな(使用頻度による...)
多分、クラウドサービス版RedmineではMyRedmineが一番安い筈ですが、それでも月8,000円掛かります。Redmine自体割と枯れたシステム(※褒め言葉)なので、社内運用とかであれば保守の人員コストもそんなに掛からないことを勘案すると、自社で構築してしまった方が多分コスパが良いです。((1)〜(7)までの構築に掛かる人件費ですが、AWSに慣れた人なら0.5人日以下でサクッとできてしまいます)
自社で何らかのWebサービスを構築する or 運用しているのであれば、その練習台(インフラエンジニアの新人研修ネタ?)としても丁度良いかも。DBをAurora、EBSに乗せているfilesディレクトリ(添付ファイルデータ)をEFSに変えればAutoScalingを用いてスケールアウトさせることも出来るので、スケーラビリティ設計の練習台にもできそう。

リモートワーク(テレワーク)対応で、今までオンプレで使っていたRedmineをクラウドサービスに移行しようとして、MyRedmineを使う予算承認が降りたのですが、MyRedmineを試食してみたところ「これなら自分で作った方が早いし安い」と思い自前構築した時のメモでした。(今更Redmine...と思いつつ、こういうケースって多いかも?)

実のところ、構築するのが面倒だった(0.5人日で済むとはいえ一応工数が掛かる)のでMyRedmineで良いじゃん(安いし)と思っていたのですが、MyRedmineの場合、契約書に決済者(※私は決済者ではない)の手書きサイン or 会社名が入った社印が必要とのことだった(※要するにWeb申し込みで完結しない契約タイプだった)ので、いわゆる「ハンコ打ちに会社行かなければいけないヤツ」だったことが自前構築の決断要因でした。
会社に行くと往復2時間(0.25人日)無駄にするし、決済者を捕まえるためのスケジュール調整にも無駄に工数が掛かるので、0.5人日掛けて自前構築した方がお得な筈。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...