研究室に Crowi を導入してみたのでメモ。
経緯
- 研究室の情報共有を行いたい
- フロー的な情報管理ツールに手を出してみたものの、なんだかんだでストック情報が多いので wiki が良い
- puki-wiki 使っているものの、
- ユーザー管理が微妙
- 編集しながら完成物が見たい
- ディレクトリ構造を変えるとリンクが切れる
どんな事がしたいか
- wiki で階層的に情報を整理したい
- でも、階層構造は途中で変えたくなる事が多いから、階層構造変えてもリンク切れて欲しくない
- 気軽に編集したい
- 完成品を見ながら編集したい
- でも、本文は使いまわしたり、Google Document みんなで同時に編集した結果を貼りつけたり、ツールから吐き出させた整形済みテキストを貼り付けたりさせたいので、WYSIWYG 的なエディタより、プレーンテキストで管理したい
- できれば、markdown
- 編集に対する貢献を見やすくして、編集に対するモチベーションを上げたい
- たくさんページを編集している人が目立つ
- 作ったページへのレスポンスが分かる
Crowi
- 良いところ
- 上記のしたい事が全て実装されている
- イマイチなところ
- 本文検索できない (ver 1.5 から対応された)
- 画像以外のファイルを添付できない
参考
構成
- Core OS / Docker を使って、セットアップをできるだけ自動化させる。
- 複数の crowi (や、他のサーバー類) を同居させるために、proxy サーバーを立てる
- HTTPS 通信させる
- データのバックアップを実施する
セットアップ内容
- docker-compose のインストール
- スクリプトを
/opt/docker/install-docker-compose.sh
に配置 - systemd で起動時に実行 (
install-docker-compose.service
)
- スクリプトを
- docker コンテナの起動
- コンテナ起動スクリプトを
/opt/docker/{container}/start.sh
に配置 - systemd でサービス登録 (
docker-{container}.service
) - 設定ファイルなどは
/opt/docker/{container}
に配置 - コンテナ内のボリュームは
/opt/docker/{container}/data
などにマッピング
- コンテナ起動スクリプトを
- バックアップ
- 起動スクリプトを
/opt/backup/run_backup.sh
に配置-
/opt/backup/backup.d
以下の.sh
ファイルを実行
-
- コンテナごとにバックアップスクリプトを作成し、
/opt/backup/backup.d
に配置 - 起動スクリプトは、systemd timer で定時実施 (
backup.timer
) - 外部ストレージは、
/media/backup
へマウント
- 起動スクリプトを
使用している docker コンテナ
-
nginx
- proxy サーバーに使用
-
bakudankun/crowi
- crowi のコンテナ
-
mongo, redis
- crowi の DB に使用
-
ars096/mongo-backup
- 定期的に mongo-db にアクセスして mongodump する cron が走っているコンテナ
手順
1. インストールメディアの準備
- Core OS の ISO image をダウンロード
- CD-R に焼く
2. cloud-config.yml の準備
cloud-config.yml
#cloud-config
# ===============
# Common settings
# ===============
# -----------------
# OS Configurations
# -----------------
# User Configurations
# - - - - - - - - - -
users:
-
name: core # << 運用するユーザー名に変更する
passwd: **** # << `openssl passwd -1` で生成されるハッシュを書き込む
groups:
- sudo
- docker
# System Configurations
# - - - - - - - - - - -
hostname: core # << 運用するホスト名に変更する
coreos:
update:
reboot-strategy: off
units:
-
name: coreos-setup-environment.service
command: restart
-
name: systemd-networkd.service
command: restart
-
name: docker.service
command: start
- # << ネットワーク設定を適切に変更する
name: 10-static.network
runtime: no
content: |
[Match]
Name=eno1
[Network]
Address=192.168.0.2/24
Gateway=192.168.0.1
DNS=192.168.0.1
# ----------------------
# Install docker-compose
# ----------------------
coreos:
units:
-
name: install-docker-compose.service
command: start
content: |
[Unit]
Description=Install docker-compose command
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/sh /opt/docker/install-docker-compose.sh
write_files:
- # << 最新の docker-compose のバージョンを確認後、修正する
path: "/opt/docker/install-docker-compose.sh"
permissions: "0755"
owner: "root:root"
content: |
if [ ! -e /opt/bin/docker-compose || ! -s /opt/bin/docker-compose ]; then
mkdir -p /opt/bin
curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /opt/bin/docker-compose
chmod +x /opt/bin/docker-compose
fi
# ---------------------
# Backup Configurations
# ---------------------
coreos:
units:
- # << バックアップ先を外付けメディアにしない場合、不要
name: media-backup.mount
command: start
content: |
[Mount]
What=/dev/sdb1
Where=/media/backup
Type=ext4
- # << バックアップを定期実行しない場合、不要
name: backup.service
content: |
[Unit]
Description=Run backup script /opt/backup/run_backup.sh
[Service]
Type=oneshot
ExecStart=/opt/backup/run_backup.sh
- # << バックアップを定期実行しない場合、不要
# << バックアップ時刻を適切に変更 : default UTC 19:00 (JST 04:00)
name: backup.timer
command: start
content: |
[Unit]
Description=Run backup.service every day
[Timer]
OnCalendar=*-*-* 19:00:00
write_files:
- # << バックアップを定期実行しない場合、不要
path: "/opt/backup/run_backup.sh"
permissions: "0755"
owner: "root:root"
content: |
for file in `\find /opt/backup/backup.d -name '*.sh'`; do
echo "$(date --utc '+%Y-%m-%d %H:%M:%S'), /usr/bin/sh $file" >> /var/log/backup.log 2>&1
/usr/bin/sh $file
done
# =================
# Docker Containers
# =================
# ------------
# proxy server
# ------------
# Systemd Configurations
# - - - - - - - - - - - -
coreos:
units:
-
name: docker-proxy.service
command: start
content: |
[Unit]
Description=Start proxy container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/sh /opt/docker/proxy/start.sh
ExecStop=/usr/bin/sh /opt/docker/proxy/stop.sh
write_files:
- # << HTTPS 接続させない場合、ssl.key, ssl.cer の docker cp をコメントアウトする
path: "/opt/docker/proxy/start.sh"
permissions: "0755"
owner: "root:root"
content: |
/usr/bin/docker rm -f proxy
/usr/bin/docker run -d --name proxy -v /opt/docker/proxy/log:/var/log/nginx -p 80:80 -p 443:443 nginx:alpine
/usr/bin/docker exec -d proxy rm /etc/nginx/conf.d/default.conf
/usr/bin/docker cp /opt/docker/proxy/nginx.conf proxy:/etc/nginx
/usr/bin/docker cp /opt/docker/proxy/ssl.key proxy:/etc/nginx
/usr/bin/docker cp /opt/docker/proxy/ssl.cer proxy:/etc/nginx
/usr/bin/docker cp /opt/docker/proxy/proxy-crowi.conf proxy:/etc/nginx/conf.d
/usr/bin/docker restart proxy
/usr/bin/docker attach proxy
-
path: "/opt/docker/proxy/stop.sh"
permissions: "0755"
owner: "root:root"
content: |
/usr/bin/docker stop proxy
/usr/bin/docker rm proxy
# Backup Configurations
# - - - - - - - - - - - -
write_files:
- # << バックアップを定期実行しない場合、不要
path: "/opt/backup/backup.d/backup_proxy.sh"
permissions: "0755"
owner: "root:root"
content: |
rsync -av /opt/docker/proxy /media/backup/proxy > /media/backup/proxy.log 2>&1
# nginx conf file
# - - - - - - - -
write_files:
-
path: "/opt/docker/proxy/nginx.conf"
permissions: "0755"
owner: "root:root"
content: |
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;
server_tokens off;
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;
include /etc/nginx/conf.d/*.conf;
}
-
path: "/opt/docker/proxy/proxy-crowi.conf"
permissions: "0755"
owner: "root:root"
content: |
server { # << HTTPS で運用しない場合、削除
listen 80;
server_name crowi.example.jp; # << 運用するホスト名に変更する
return 301 https://$host$request_uri;
}
server {
listen 443 ssl; # << HTTPS で運用しない場合、listen 80; に変更
server_name crowi.example.jp; # << 運用するホスト名に変更する
ssl_certificate ssl.cer; # << HTTPS で運用しない場合、削除
ssl_certificate_key ssl.key; # << HTTPS で運用しない場合、削除
access_log /var/log/nginx/crowi.access.log main;
error_log /var/log/nginx/crowi.error.log warn;
location / {
proxy_pass http://crowi.example.jp:8000/; # 運用するホスト名、crowi ポートに変更
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
client_max_body_size 1g; # アップロードできるファイルサイズの最大値
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# ------------
# crowi server
# ------------
# Systemd Configurations
# - - - - - - - - - - - -
coreos:
units:
-
name: docker-crowi.service
command: start
content: |
[Unit]
Description=Start crowi container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/sh /opt/docker/crowi/start.sh
ExecStop=/usr/bin/sh /opt/docker/crowi/stop.sh
write_files:
-
path: "/opt/docker/crowi/start.sh"
permissions: "0755"
owner: "root:root"
content: |
/opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml stop
/opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml rm -f
/opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml up
-
path: "/opt/docker/crowi/stop.sh"
permissions: "0755"
owner: "root:root"
content: |
/opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml stop
/opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml rm -f
# Backup Configurations
# - - - - - - - - - - - -
write_files:
- # << バックアップを定期実行しない場合、不要
path: "/opt/backup/backup.d/backup_crowi.sh"
permissions: "0755"
owner: "root:root"
content: |
FROM_DIR="/opt/docker/crowi"
TO_DIR="/media/backup/crowi"
YEAR=$(date --utc '+%Y')
MONTH=$(date --utc '+%m')
DAY=$(date --utc '+%d')
NEW_DIR=$TO_DIR/$YEAR/$MONTH/$DAY
mkdir -p $NEW_DIR
rsync -av $FROM_DIR $NEW_DIR > $TO_DIR.log 2>&1
## remove old month daily backup
if [ $DAY -eq "01" ]; then
RM_YEAR=$(date --utc '+%Y' --date '2 months ago')
RM_MONTH=$(date --utc '+%m' --date '2 months ago')
for i in {2..31}; do
RM_PATH=$TO_DIR/$RM_YEAR/$RM_MONTH/$(printf "%02d" i)
if [ -e $RM_PATH ]; then
echo "rm -rf --preserve-root $RM_PATH" >> $TO_DIR.log 2>&1
rm -rf --preserve-root $RM_PATH
fi
done
fi
# docker-compose file
# - - - - - - - - - -
write_files:
-
path: "/opt/docker/crowi/docker-compose.yml"
permissions: "0755"
owner: "root:root"
content: |
version: '2'
services:
crowi:
container_name: crowi
image: bakudankun/crowi:1.4.0
links:
- mongo:db
- redis:redis
ports:
- 8000:8000 # << 外部からアクセスさせる port を設定
volumes:
- /opt/docker/crowi/data/crowi:/data
environment:
- PASSWORD_SEED=**** # << 内緒の文字列を設定する
- SECRET_TOKEN=**** # << 内緒の文字列を設定する
- PORT=8000
- FILE_UPLOAD=local
mongo:
container_name: crowi-mongo
image: mongo
volumes:
- /opt/docker/crowi/data/db:/data/db
redis:
container_name: crowi-redis
image: redis:alpine
mongo-backup:
container_name: crowi-dbbackup
image: ars096/mongo-backup
links:
- mongo:db
volumes:
- /opt/docker/crowi/data/backup:/data/backup
- /opt/docker/crowi/log/mongo-backup:/var/log
3. Core OS のインストール
3.1. インストール用に Core OS を起動
- 手順 1. で作成した CD-R を使い Core OS で PC を起動
- 自動的に core ユーザーでログインされる
3.2. cloud-config.yml をコピー
- 手順 2. で作成した
cloud-config.yml
を USB メモリに保存し、PC に接続 - デバイス名を確認し、マウントしてからファイルをコピー
デバイス名を確認。/dev/sdb1 として認識されていた。
$ ls /dev/sd*
/dev/sda /dev/sda2 /dev/sda4 /dev/sda7 /dev/sdb /dev/sdc
/dev/sda1 /dev/sda3 /dev/sda6 /dev/sda9 /dev/sdb1
適当なディレクトリを作ってマウント
$ sudo mkdir /media/data
$ sudo mount /dev/sdb1 /media/data
ファイルをコピー
$ cp /media/data/cloud-config.yml ~/
3.3. インストールを実行
- DHCP のネットワークに接続しておく
- coreos-install コマンドを実行
$ sudo coreos-install -d /dev/sda -C stable -c cloud-config.yml -v
...
...
Success! CoreOS stable 899.13.0 is installed on /dev/sda
- 再起動
- CD は取り出しておく
$ sudo reboot
- OS と Docker を最新に更新
$ sudo update_engine_client -update
$ sudo reboot
再起動後
$ cat /etc/os-release
NAME=CoreOS
ID=coreos
VERSION=1122.2.0
VERSION_ID=1122.2.0
BUILD_ID=2016-09-06-1449
PRETTY_NAME="CoreOS 1122.2.0 (MoreOS)"
ANSI_COLOR="1;32"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://github.com/coreos/bugs/issues"
$ docker -v
Docker version 1.10.3, build 1f8f545
$ docker-compose -v
docker-compose version 1.8.0, build f3628c7
4. HTTPS 設定
- サーバー証明書を取得する
- docker を自動実行させるために、秘密鍵のパスフレーズは解除しておく
- サーバー証明書 (ssl.cer) と秘密鍵 (ssl.key) を、
/opt/docker/proxy
に設置- 無いと、docker cp が失敗し、nginx コンテナの起動に失敗する
5. 動作確認
PC 起動後に、自動で各種 docker コンテナと、バックアップ timer が起動しているはずなので確認する。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a183c7c2d5ba bakudankun/crowi:1.4.0 "/entrypoint.sh npm s" 22 minutes ago Up 22 minutes 0.0.0.0:8000->8000/tcp crowi
c007eb75a3b8 ars096/mongo-backup "/entrypoint.sh /bin/" 22 minutes ago Up 22 minutes 27017/tcp crowi-dbbackup
e4f2cded4aa2 mongo "/entrypoint.sh mongo" 22 minutes ago Up 22 minutes 27017/tcp crowi-mongo
42d1309e9010 redis:alpine "docker-entrypoint.sh" 22 minutes ago Up 22 minutes 6379/tcp crowi-redis
410d52e95a3e nginx:alpine "nginx -g 'daemon off" 26 minutes ago Up 26 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp proxy
$ systemctl status docker-proxy
● docker-proxy.service - Start proxy container
Loaded: loaded (/etc/systemd/system/docker-proxy.service; static; vendor preset: disabled)
Active: active (running) since Thu 2016-09-15 02:02:15 UTC; 28min ago
Main PID: 1479 (sh)
Tasks: 9
Memory: 11.0M
CPU: 735ms
CGroup: /system.slice/docker-proxy.service
├─1479 /usr/bin/sh /opt/docker/proxy/start.sh
└─1770 /usr/bin/docker attach proxy
$ systemctl status docker-crowi
● docker-crowi.service - Start crowi container
Loaded: loaded (/etc/systemd/system/docker-crowi.service; static; vendor preset: disabled)
Active: active (running) since Thu 2016-09-15 02:06:33 UTC; 24min ago
Main PID: 2882 (sh)
Tasks: 8
Memory: 41.5M
CPU: 2.115s
CGroup: /system.slice/docker-crowi.service
├─2882 /usr/bin/sh /opt/docker/crowi/start.sh
├─2907 /opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml up
└─2908 /opt/bin/docker-compose -f /opt/docker/crowi/docker-compose.yml up
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Thu 2016-09-15 14:02:08 UTC 11h left Thu 2016-09-15 02:02:08 UTC 29min ago rkt-gc.timer rkt-gc.service
Thu 2016-09-15 19:00:00 UTC 16h left n/a n/a backup.timer backup.service
Fri 2016-09-16 00:00:00 UTC 21h left Thu 2016-09-15 01:11:56 UTC 1h 19min ago logrotate.timer logrotate.service
Fri 2016-09-16 02:17:15 UTC 23h left Thu 2016-09-15 02:17:15 UTC 14min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
4 timers listed.
Pass --all to see loaded but inactive timers, too.
バックアップスクリプトを試しに流してみる
$ sudo sh /opt/backup/run_backup.sh
$ cat /var/log/backup.log
2016-09-15 02:42:31, /usr/bin/sh /opt/backup/backup.d/backup_proxy.sh
2016-09-15 02:42:31, /usr/bin/sh /opt/backup/backup.d/backup_crowi.sh
$ ls /media/backup/
crowi crowi.log lost+found proxy proxy.log
$ cat /media/backup/crowi.log
sending incremental file list
crowi/
crowi/docker-compose.yml
crowi/start.sh
crowi/stop.sh
crowi/data/
crowi/data/backup/
...
crowi/log/
crowi/log/mongo-backup/
sent 430,666,128 bytes received 3,591 bytes 287,113,146.00 bytes/sec
total size is 430,546,946 speedup is 1.00
ブラウザからアクセスすれば、Crowi の install 画面が見えるはず。
6. Shipyard を使ってコンテナ管理
そのうち試したい。