どうも建築業界向けの機能も対応するにはもっとビルドを頑張らないといけないようである。
※COLLADA2GLTFとかIFCconvertとか。やりたいひとは頑張れ...一応ビルドはできたぞ。長いから書かないけれど。
背景
いまさらながら Redmine で GTD をやってみようと 2 週間ほど運用してきた。
しかし、使いやすいようにしようと思うと 10 個近くのプラグインが必要であったり、かゆいところに手が届かない感じが多いように思った。
簡単に調べてみると、やっぱり必要な機能は openproject の方がデフォルトで揃っているように感じた。そのため、一念発起して公式ではサポートされていない arm64 上の docker での実行を試みた。
結果は一応うまくいったので、世界の誰かのためになればと思い、この記事を投稿します。
環境構築
ざっくりとした構築方法は以下の通り
- 公式の Dockerfile を元に arm64 で動くように変更を加える
- All in One コンテナではなく、docker-compose を使用するバージョンの arm64 版を目指す
- https を有効にするために letsencrypt を利用する自作の proxy を立てる
まずは All in One コンテナが動くことを目標とする
公式の GitHub リポジトリをクローンする
git clone https://github.com/opf/openproject.git
# 真面目な人はこの後、タグをチェックアウトしてね。私は面倒なのでデフォルトブランチで作業します。
docker/prod/Dockerfile を変更
gosu を arm64 版を使用するように 変更する。
# clone してきた中身を変えても良い (COPY . . が途中にある)
# ホストでダウンロードしても良いけど、やり直すことになった時にやり忘れそう
FROM ruby:2.7.2-buster
MAINTAINER operations@openproject.com
# Allow platform-specific additions. Valid values are: on-prem,saas,bahn
ARG PLATFORM=on-prem
# Use OAuth token in case private gems need to be fetched
ARG GITHUB_OAUTH_TOKEN
ARG DEBIAN_FRONTEND=noninteractive
ARG PGLOADER_BINARY_DOWNLOAD_URL=https://openproject-docker-public.s3-eu-west-1.amazonaws.com/pgloader/bin/pgloader-ccl
ENV NODE_VERSION="12.18.3"
ENV BUNDLER_VERSION="2.1.4"
ENV BUNDLE_PATH__SYSTEM=false
ENV APP_USER=app
ENV APP_PATH=/app
ENV APP_DATA_PATH=/var/openproject/assets
ENV APP_DATA_PATH_LEGACY=/var/db/openproject
ENV PGDATA=/var/openproject/pgdata
ENV PGDATA_LEGACY=/var/lib/postgresql/9.6/main
ENV DATABASE_URL=postgres://openproject:openproject@127.0.0.1/openproject
ENV RAILS_ENV=production
ENV RAILS_CACHE_STORE=memcache
ENV RAILS_GROUPS=production
ENV RAILS_LOG_TO_STDOUT=1
ENV RAILS_SERVE_STATIC_FILES=1
ENV OPENPROJECT_INSTALLATION__TYPE=docker
# Valid values are: standard,bim
ENV OPENPROJECT_EDITION=standard
ENV NEW_RELIC_AGENT_ENABLED=false
ENV ATTACHMENTS_STORAGE_PATH=$APP_DATA_PATH/files
# Set a default key base, ensure to provide a secure value in production environments!
ENV SECRET_KEY_BASE=OVERWRITE_ME
RUN curl ${PGLOADER_BINARY_DOWNLOAD_URL} > /usr/local/bin/pgloader-ccl && chmod +x /usr/local/bin/pgloader-ccl
WORKDIR $APP_PATH
COPY docker/prod/setup ./docker/prod/setup
RUN ./docker/prod/setup/preinstall.sh
COPY Gemfile ./Gemfile
COPY Gemfile.* ./
COPY modules ./modules
COPY vendor ./vendor
# some gemspec files of plugins require files in there, notably OpenProject::Version
COPY lib ./lib
RUN bundle install --quiet --deployment --path vendor/bundle --no-cache \
--with="$RAILS_GROUPS" --without="test development" --jobs=8 --retry=3 && \
rm -rf vendor/bundle/ruby/*/cache && rm -rf vendor/bundle/ruby/*/gems/*/spec && rm -rf vendor/bundle/ruby/*/gems/*/test
# Finally, copy over the whole thing
COPY . .
# Replace gosu with gosu-arm64
RUN wget -O ./docker/prod/gosu https://github.com/tianon/gosu/releases/download/1.12/gosu-arm64
RUN ./docker/prod/setup/postinstall.sh
# Expose ports for apache and postgres
EXPOSE 8080 5432
# Expose the postgres data directory and OpenProject data directory as volumes
VOLUME ["$PGDATA", "$APP_DATA_PATH"]
# Set a custom entrypoint to allow for privilege dropping and one-off commands
ENTRYPOINT ["./docker/prod/entrypoint.sh"]
# Set default command to launch the all-in-one configuration supervised by supervisord
CMD ["./docker/prod/supervisord"]
docker/prod/setup/preinstall-common.sh を変更
x64 版のバイナリを指定している箇所を arm64 版を使うように変更する。
#!/bin/bash
set -e
set -o pipefail
# install node + npm
curl -s https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-arm64.tar.gz | tar xzf - -C /usr/local --strip-components=1
wget --quiet -O- https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
echo "deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list
apt-get update -qq
apt-get install -y \
apt-transport-https \
pandoc \
poppler-utils \
unrtf \
tesseract-ocr \
catdoc \
postgresql-9.6 \
postgresql-client-9.6 \
imagemagick
rm -rf "$PGDATA_LEGACY"
# Specifics for BIM edition
curl -SL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/master/dotnet-runtime-latest-linux-arm64.tar.gz
mkdir -p /usr/share/dotnet
tar -zxf dotnet.tar.gz -C /usr/share/dotnet
ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
tmpdir=$(mktemp -d)
cd $tmpdir
# Install XKT converter
npm install @xeokit/xeokit-gltf-to-xkt@0.0.3 -g
# Install COLLADA2GLTF
wget --quiet https://github.com/KhronosGroup/COLLADA2GLTF/releases/download/v2.1.5/COLLADA2GLTF-v2.1.5-linux.zip
unzip -q COLLADA2GLTF-v2.1.5-linux.zip
mv COLLADA2GLTF-bin "/usr/local/bin/COLLADA2GLTF"
# IFCconvert
wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.6.0-9bcd932-linux64.zip
unzip -q IfcConvert-v0.6.0-9bcd932-linux64.zip
mv IfcConvert "/usr/local/bin/IfcConvert"
wget --quiet https://github.com/bimspot/xeokit-metadata/releases/download/1.0.0/xeokit-metadata-linux-arm.tar.gz
tar -zxvf xeokit-metadata-linux-arm.tar.gz
chmod +x xeokit-metadata-linux-arm/xeokit-metadata
cp -r xeokit-metadata-linux-arm/ "/usr/lib/xeokit-metadata"
ln -s /usr/lib/xeokit-metadata/xeokit-metadata /usr/local/bin/xeokit-metadata
cd /
rm -rf $tmpdir
gem install bundler --version "$BUNDLER_VERSION" --no-document
useradd -d /home/$APP_USER -m $APP_USER
build する (20 分ほど掛かる)
docker build -t openproject/community:11-arm64 -f docker/prod/Dockerfile ./
疎通 (スモーク) テストを行う
docker run --rm -it -p 8080:80 -e SECRET_KEY_BASE=secret openproject/community:11-arm64
docker-compose で動かす
公式の docker-compose.yml
を取得する
git clone https://github.com/opf/openproject-deploy --depth=1 --branch=stable/11 openproject
cd openproject/compose
nano docker-compose.yml
docker-compose.yml
を変更する
- コンテナネーム
app
のイメージを自作のイメージに変更する -
volumes
のホスト側のマウントポイントをカレントディレクトリにする
version: "3.7"
networks:
frontend:
backend:
volumes:
pgdata:
opdata:
x-op-restart-policy: &restart_policy
restart: unless-stopped
x-op-image: &image
image: openproject/community:11-arm64
x-op-app: &app
<<: *image
<<: *restart_policy
environment:
RAILS_CACHE_STORE: "memcache"
OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211"
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
DATABASE_URL: "postgres://postgres:p4ssw0rd@db/openproject"
USE_PUMA: "true"
# set to true to enable the email receiving feature. See ./docker/cron for more options
IMAP_ENABLED: "${IMAP_ENABLED:-false}"
volumes:
- "./opdata:/var/openproject/assets"
services:
db:
image: postgres:10
<<: *restart_policy
stop_grace_period: "3s"
volumes:
- "./pgdata:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: p4ssw0rd
POSTGRES_DB: openproject
networks:
- backend
cache:
image: memcached
<<: *restart_policy
networks:
- backend
proxy:
<<: *image
<<: *restart_policy
command: "./docker/prod/proxy"
ports:
- "${PORT:-8080}:80"
environment:
APP_HOST: web
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
depends_on:
- web
networks:
- frontend
web:
<<: *app
command: "./docker/prod/web"
networks:
- frontend
- backend
depends_on:
- db
- cache
- seeder
worker:
<<: *app
command: "./docker/prod/worker"
networks:
- backend
depends_on:
- db
- cache
- seeder
cron:
<<: *app
command: "./docker/prod/cron"
networks:
- backend
depends_on:
- db
- cache
- seeder
seeder:
<<: *app
command: "./docker/prod/seeder"
restart: on-failure
networks:
- backend
疎通 (スモーク) テスト
docker-compose up
HTTPS を有効にする
ディレクトリ構造
compose/
├── docker-compose.yml #変更する
└── proxy #作成する
├── Dockerfile #作成する
└── default.conf.template #作成する
proxy を自作のものに変更する
FROM nginx:latest
ARG CERTBOT_EMAIL=default@default.com
ARG DOMAIN_LIST
# Expose ports.
EXPOSE 80
EXPOSE 443
RUN apt-get update \
&& apt-get install -y cron certbot \
&& certbot certonly --dry-run --standalone --agree-tos -m "${CERTBOT_EMAIL}" -n -d ${DOMAIN_LIST} \
&& certbot certonly --standalone --agree-tos -m "${CERTBOT_EMAIL}" -n -d ${DOMAIN_LIST} \
&& rm -rf /var/lib/apt/lists/* \
&& echo "@monthly /usr/bin/certbot renew --nginx >> /var/log/cron.log 2>&1" >/etc/cron.d/certbot-renew \
&& crontab /etc/cron.d/certbot-renew
VOLUME /etc/letsencrypt
CMD [ "sh", "-c", "cron && ./docker-entrypoint.sh nginx -g 'daemon off;'" ]
docker-compose.yml
を変更する
version: "3.7"
networks:
frontend:
backend:
volumes:
pgdata:
opdata:
x-op-restart-policy: &restart_policy
restart: unless-stopped
x-op-image: &image
image: openproject/community:11-arm64
x-op-app: &app
<<: *image
<<: *restart_policy
container_name: app
environment:
RAILS_CACHE_STORE: "memcache"
OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211"
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
DATABASE_URL: "postgres://postgres:p4ssw0rd@db/openproject"
USE_PUMA: "true"
# set to true to enable the email receiving feature. See ./docker/cron for more options
IMAP_ENABLED: "${IMAP_ENABLED:-false}"
volumes:
- "./opdata:/var/openproject/assets"
services:
db:
container_name: db
image: postgres:10
<<: *restart_policy
stop_grace_period: "3s"
volumes:
- "./pgdata:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: p4ssw0rd
POSTGRES_DB: openproject
networks:
- backend
cache:
container_name: cache
image: memcached
<<: *restart_policy
networks:
- backend
# proxy:
# <<: *image
# <<: *restart_policy
# command: "./docker/prod/proxy"
# ports:
# - "${PORT:-8080}:80"
# environment:
# APP_HOST: web
# OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
proxy:
<<: *restart_policy
container_name: proxy
build:
context: ./proxy
network: host
args:
- CERTBOT_EMAIL=your-email@mail.com #replace with your own email
- DOMAIN_LIST=your.hostname.com #replace with your own domains
ports:
- "80:80"
- "443:443"
volumes:
- ./proxy/default.conf.template:/etc/nginx/templates/default.conf.template
environment:
MY_DOMAIN_NAME: your.hostname.com #replace with your own domains
depends_on:
- web
networks:
- frontend
web:
<<: *app
container_name: web
command: "./docker/prod/web"
networks:
- frontend
- backend
depends_on:
- db
- cache
- seeder
worker:
<<: *app
container_name: worker
command: "./docker/prod/worker"
networks:
- backend
depends_on:
- db
- cache
- seeder
cron:
<<: *app
container_name: cron
command: "./docker/prod/cron"
networks:
- backend
depends_on:
- db
- cache
- seeder
seeder:
<<: *app
container_name: seeder
command: "./docker/prod/seeder"
restart: on-failure
networks:
- backend
proxy/default.conf.template
を変更する
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/letsencrypt/live/${MY_DOMAIN_NAME}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${MY_DOMAIN_NAME}/privkey.pem;
location / {
proxy_pass http://web:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect http:// https://;
}
# --- For CertBot ---
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html/;
}
location = /.well-known/acme-challenge/ {
return 404;
}
}
疎通 (スモーク) テスト
docker-compose up