Help us understand the problem. What is going on with this article?

Docker ComposeでConfluenceを構築する

More than 3 years have passed since last update.

この記事は Docker2 Advent Calendar 2016 の7日目です。(空いていたので滑り込みました。)

全国のConfluence好きの皆さんこんにちは。
転職先の会社にConfluenceがなかった...そんなことありませんか?

私も転職先にConfluenceがなかったので、早速稟議を出しつつ折角なのでDocker環境でConfluenceを構築しました。

要件

以下の環境を想定。

  • Docker Compose
  • Confluence 5.10.8 (6系はまだ6.0.1なので見送り)
  • nginx
  • PostgreSQL (RDS利用予定なので、docker-compose.ymlには含めない)

全体の構成

これから構築するファイル構成。

.
├── docker-compose.yml
├── data
│   └── confluence-home
├── confluence
│   ├── Dockerfile
│   ├── server.xml
│   └── setenv.sh
├── nginx
│   ├── Dockerfile
│   ├── conf.d
│   │   └── default.conf
│   └── nginx.conf
└── postgres
    └── Dockerfile

ConfluenceのDockerfileを作成する

まずConfluenceのDockerfileを作成する。
今回は5.10系をインストールするので公式の Dockerfile — Bitbucket の5.10ブランチのDockerfileをベースにする。

しかし、このままConfluenceのコンテナ内にMySQLドライバをダウンロードしてしまうので書き換える。

MySQLドライバダウンロード箇所を取り除く

MySQLドライバをダウンロードしている箇所を取り除く。
PostgreSQLを利用する場合には、特に追加で何もする必要はないので削除のみ。

confluence/Dockerfile
@@ -10,9 +10,6 @@ LABEL Description="This image is used to start Atlassian Confluence" Vendor="Atl

 ENV CONFLUENCE_DOWNLOAD_URL http://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-${CONF_VERSION}.tar.gz

-ENV MYSQL_VERSION 5.1.38
-ENV MYSQL_DRIVER_DOWNLOAD_URL http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-${MYSQL_VERSION}.tar.gz
-
 # Use the default unprivileged account. This could be considered bad practice
 # on systems where multiple processes end up being executed by 'daemon' but
 # here we only ever run one process anyway.
@@ -31,7 +28,6 @@ RUN set -x \
     && chown ${RUN_USER}:${RUN_GROUP}     "${CONFLUENCE_HOME}" \
     && mkdir -p                           "${CONFLUENCE_INSTALL}/conf" \
     && curl -Ls                           "${CONFLUENCE_DOWNLOAD_URL}" | tar -xz --directory "${CONFLUENCE_INSTALL}" --strip-components=1 --no-same-owner \
-    && curl -Ls                           "${MYSQL_DRIVER_DOWNLOAD_URL}" | tar -xz --directory "${CONFLUENCE_INSTALL}/confluence/WEB-INF/lib" --strip-components=1 --no-same-own
     && chmod -R 700                       "${CONFLUENCE_INSTALL}/conf" \
     && chmod -R 700                       "${CONFLUENCE_INSTALL}/temp" \
     && chmod -R 700                       "${CONFLUENCE_INSTALL}/logs" \

メモリを可変にする

さて、Confluenceを環境構築して改めて実感したが、メモリが大量に必要となる。2GBでは全然足りない。

How to fix out of memory errors by increasing available memory - Atlassian Documentation を参考に、setenv.shを書き換えてTomcatのメモリ使用量を増やす必要があるが、今後のことを考えて環境変数にする。

setenv.shを下記のように書き換え、

confluence/setenv.sh
CATALINA_OPTS="-XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution ${CATALINA_OPTS}"
CATALINA_OPTS="-Xloggc:$LOGBASEABS/logs/gc-`date +%F_%H-%M-%S`.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M ${CATALINA_OPTS}"
CATALINA_OPTS="-XX:G1ReservePercent=20 ${CATALINA_OPTS}"
CATALINA_OPTS="-Djava.awt.headless=true ${CATALINA_OPTS}"
CATALINA_OPTS="-Datlassian.plugins.enable.wait=300 ${CATALINA_OPTS}"
+CATALINA_OPTS="-Xms${CONFLUENCE_CATALINA_MEM}m -Xmx${CONFLUENCE_CATALINA_MEM}m -XX:+UseG1GC ${CATALINA_OPTS}"


export CATALINA_OPTS

ENVに 環境変数としてデフォルトのメモリ使用量を記述する。

confluence/Dockerfile
@@ -4,6 +4,7 @@ MAINTAINER Atlassian Confluence
 # Setup useful environment variables
 ENV CONFLUENCE_HOME     /var/atlassian/application-data/confluence
 ENV CONFLUENCE_INSTALL  /opt/atlassian/confluence
+ENV CONFLUENCE_CATALINA_MEM  2048
 ENV CONF_VERSION  5.10.8

 LABEL Description="This image is used to start Atlassian Confluence" Vendor="Atlassian" Version="${CONF_VERSION}"
@@ -54,6 +55,7 @@ RUN set -x \
 # here we only ever run one process anyway.
 USER ${RUN_USER}:${RUN_GROUP}

+COPY ./setenv.sh  ${CONFLUENCE_INSTALL}/bin/
 COPY ./server.xml ${CONFLUENCE_INSTALL}/conf/

プロキシ実行用にserver.xmlを書き換える

次にプロキシ実行用の設定を行う。
How to use NGINX to proxy requests for Confluence - Atlassian Documentation に従い、プロキシ実行用に書き換えたserver.xmlを用意する。

confluence/server.xml
- <Connector port="8090" connectionTimeout="20000" redirectPort="8443" maxThreads="48" minSpareThreads="10" enableLookups="false" acceptCount="10" debug="0" URIEncoding="UTF-8" protocol="org.apache.coyote.http11.Http11NioProtocol"/>
+ <Connector port="8090" connectionTimeout="20000" redirectPort="8443" maxThreads="48" minSpareThreads="10" enableLookups="false" acceptCount="10" debug="0" URIEncoding="UTF-8" protocol="org.apache.coyote.http11.Http11NioProtocol" proxyName="localhost" proxyPort="80"/>
     <Engine name="Standalone" defaultHost="localhost">
       <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false">
-        <Context path="" docBase="../confluence" reloadable="false" useHttpOnly="true">
+        <Context path="/confluence" docBase="../confluence" reloadable="false" useHttpOnly="true">

併せて、Dockerfile側にもCOPYを追記する。

confluence/Dockerfile
--- a/confluence/Dockerfile
+++ b/confluence/Dockerfile
@@ -54,6 +54,8 @@ RUN set -x \
 # here we only ever run one process anyway.
 USER ${RUN_USER}:${RUN_GROUP}

+COPY ./server.xml ${CONFLUENCE_INSTALL}/conf/
+
 # Expose default HTTP connector port.
 EXPOSE 8090

ただし、このままではproxyNameはlocalhost固定となってしまう。ここは環境変数ではどうしようもないので、Dockerfile側でARGsedを使いbuild時に置換を行う。

confluence/Dockerfile
@@ -8,7 +8,7 @@
 ENV CONF_VERSION  5.10.8
 ENV JAVA_HOME           /usr/lib/jvm/java-8-openjdk-amd64/jre

+ARG CONFLUENCE_HOSTNAME="localhost"


 LABEL Description="This image is used to start Atlassian Confluence" Vendor="Atlassian" Version="${CONF_VERSION}"
@@ -64,7 +64,7 @@

 COPY ./server.xml ${CONFLUENCE_INSTALL}/conf/
+RUN sed -i -e "4s/localhost/${CONFLUENCE_HOSTNAME}/" ${CONFLUENCE_INSTALL}/conf/server.xml

リバースプロキシとしてnginxを利用する

前職のConfluence管理者から、nginxを通してキャッシュしないとConfluenceは重過ぎるとの話をもらっていたのでnginxと併用する。実際かなり重い。

nginx/Dockerfile
FROM nginx:1.11.5-alpine

COPY ./nginx.conf /etc/nginx/

nginx.confは docker版nginxのnginx.conf を参考に書き換える。

nginx/nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    client_max_body_size 30m;

    gzip  on;
    gzip_types text/css text/javascript
               application/x-javascript application/javascript
               application/json;
    gzip_min_length 1k;
    gzip_disable "msie6";

    server {
      listen       80;

      location = / {
        return 302 /confluence;
      }

      location / {
        proxy_set_header X-Forwarded-Host   $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_pass       http://confluence:8090;
      }
    }
}

gzip周りはnginx実践入門を参考にした。

docker-compose.yml を作成する

nginxイメージを作りはじめたのでdocker-compose.ymlも作り始める。

docker-compose.yml
version: '2'
services:
  nginx:
    build: ./nginx
    links:
      - confluence
    ports:
      - '80:80'
  confluence:
    build:
      context: ./confluence
      args:
        CONFLUENCE_HOSTNAME: 'localhost'
    environment:
      CONFLUENCE_CATALINA_MEM: 2048
    ports:
      - '8090:8090'
    volumes:
      - ./data/confluence-home:/var/atlassian/application-data/confluence

$ docker-compose 利用時には、Dockerfileに書いたARGENVは、docker-compose.yml に書いたargsenvironmentでオーバーライドされる。
つまり可変部分は docker-compose.yml だけ書き換ればOK。便利。

設定ファイルをホストOSにマウントする

Confluenceは初回ブラウザアクセス時に行う設定の際に /var/atlassian/application-data/confluence 以下にファイル群が生成される。

このファイル群を削除した状態でConfluenceを再起動しアクセスすると、また初期設定画面になる。

その為、Dockerコンテナを破棄しても情報が引き継がれるように、このディレクトリをホストOSにマウントする。先程のdocker-compose.ymlの末尾がその設定に該当する。

docker-compose.yml
    volumes:
      - ./data/confluence-home:/var/atlassian/application-data/confluence

起動してみる

$ docker-compose build && docker-compose up して localhostにアクセスしてみる。

Screen Shot 2016-12-06 at 00.26.20.png

後はライセンスキーを入れたりDB設定をしたりすればConfluenceが使えるようになる!やったね!!

オマケ

PostgreSQL も Docker で動かす

ConfluenceとPostgreSQLをリンクさせつつ、環境変数を渡すだけで簡単にDockerで動かすことができる。

docker-compose.yml
19a20,21
+     links:
+       - postgres
23a26,34
+   postgres:
+     build: ./postgres
+     environment:
+       POSTGRES_USER: postgres
+       POSTGRES_PASSWORD: postgres
+     ports:
+       - '5432:5432'
+     volumes:
+       - ./data/postgres:/var/lib/postgresql/data

Timezoneも可変にする

Confluenceの編集履歴の相対時刻表示はOSのタイムゾーンに依存するのでTimezoneをAsia/Tokyoに変更する。

confluence/Dockerfile
@@ -8,6 +8,9 @@ ENV CONFLUENCE_CATALINA_MEM  1024
 ENV CONF_VERSION  5.10.8
 ENV JAVA_HOME           /usr/lib/jvm/java-8-openjdk-amd64/jre

 ARG CONFLUENCE_HOSTNAME="localhost"
+ARG TIMEZONE="Asia/Tokyo"

 LABEL Description="This image is used to start Atlassian Confluence" Vendor="Atlassian" Version="${CONF_VERSION}"

 ENV CONFLUENCE_DOWNLOAD_URL http://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-${CONF_VERSION}.tar.gz
@@ -51,6 +54,9 @@ RUN set -x \
                                           "${CONFLUENCE_INSTALL}/conf/server.xml" \
     && touch -d "@0"                      "${CONFLUENCE_INSTALL}/conf/server.xml"

+# set timezone
+RUN sed -i -e "s|Etc/UTC|${TIMEZONE}|" /etc/timezone

IPAゴシックをマクロタイトルに適用する

順調に動作していたかに思われたConfluenceだが、編集画面のマクロのタイトル部分が文字化けしていた。

image

ここはIPAゴシックをインストールしてjreからも参照できるようにする。

confluence/Dockerfile
@@ -22,7 +23,7 @@ ENV RUN_GROUP           daemon
 # directory structure.
 RUN set -x \
     && apt-get update --quiet \
-    && apt-get install --quiet --yes --no-install-recommends libtcnative-1 xmlstarlet \
+    && apt-get install --quiet --yes --no-install-recommends libtcnative-1 xmlstarlet fonts-ipafont-gothic\
     && apt-get clean \
     && mkdir -p                           "${CONFLUENCE_HOME}" \
     && chmod -R 700                       "${CONFLUENCE_HOME}" \


+# add font for macro title
+RUN mkdir -p "${JAVA_HOME}/lib/fonts/fallback"
+RUN ln -s /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf "${JAVA_HOME}/lib/fonts/fallback/ipag.ttf"
confluence/setenv.sh
@@ -44,6 +44,9 @@ CATALINA_OPTS="-Djava.awt.headless=true ${CATALINA_OPTS}"
 CATALINA_OPTS="-Datlassian.plugins.enable.wait=300 ${CATALINA_OPTS}"
 CATALINA_OPTS="-Xms${CONFLUENCE_CATALINA_MEM}m -Xmx${CONFLUENCE_CATALINA_MEM}m -XX:+UseG1GC ${CATALINA_OPTS}"

+# For macro titles
+CATALINA_OPTS="-Dconfluence.document.conversion.fontpath=${JAVA_HOME}/lib/fonts/fallback ${CATALINA_OPTS}"
+CATALINA_OPTS="-Dconfluence.document.conversion.slides.defaultfontname.regular=IPAGothic -Dconfluence.document.conversion.slides.defaultfontname.asian=IPAGothic -Dconfluence.do

 export CATALINA_OPTS

PDFエクスポートが遅い問題を解決する

Confluence 5.10.8ではPDFエクスポートが遅くなる現象があるが、恐らくローカルの一時ファイルとして出力したPDFファイルをリクエスト元に返す際に上手くいってない。 /etc/hosts に自身のホスト名を書くと解消するのでこちらもdocker-compose.ymlから対応する。

docker-compose.yml
@@ -12,7 +12,10 @@ services:
   confluence:
     build: ./confluence
     environment:
       CONFLUENCE_HOSTNAME: "www.example.com"
       CONFLUENCE_CATALINA_MEM: 2048
+    extra_hosts:
+      - "www.example.com:127.0.0.1"
     ports:
       - '8090:8090'
     volumes:

このようにしておいて、各自の環境で :%s/www\.example\.com/<任意のドメイン>/に置換すればconfluenceコンテナの /etc/hosts/ にextra_hostsに書いた内容が追記される。

Compose file reference - Docker

注意事項

atlassian/confluence-server - Docker Hub

にも記載されているが、OpenJDKはConfluenceのサポート対象外となっている。

サポートされるJava環境はOracle JDKだが、ライセンス上再配布不可となっているので、Oracle JDK環境で動作させるには、各自でOracle JDKのDockerイメージを構築し、そのイメージを参照してConfluenceイメージを構築する必要がある。
Update the Confluence Docker image to use Oracle JDK - Atlassian Documentation

諸々躓く所があったが、無事にDocker ComposeでConfluenceを構築することができました。

上記のDocker環境はGitHubにも公開しております(OpenJDKです)。
shinespark/docker-confluence: GitHub

好みの環境にあわせてdocker-compose.ymlのホスト名だけ書き換えて $ docker-compose up すればほぼ問題なく利用可能です。PR歓迎しています。

shinespark
ホクサイウデマエX
http://shinespark.hatenablog.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした