環境
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
$ uname -srvmo
Linux 4.4.0-45-generic #66~14.04.1-Ubuntu SMP Wed Oct 19 15:05:38 UTC 2016 x86_64 GNU/Linux
$ cat /proc/meminfo | grep ^Mem
MemTotal: 16306348 kB
MemFree: 4981548 kB
MemAvailable: 12620380 kB
参考
- galexrt/zulip - Docker Hub
- galexrt/docker-zulip: Zulip Server as a Docker Image
- Installation on Ubuntu - Docker
- Install Docker Compose - Docker
準備
dockerインストール
リポジトリ設定
$ sudo aptitude update
$ sudo aptitude install apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list
インストール
$ sudo aptitude update
$ apt-cache policy docker-engine
$ sudo aptitutde install docker-engine
サービス起動
$ sudo service docker start
ユーザをdockerグループに追加
$ sudo gpasswd -a $USER docker
docker-composeインストール
docker-composeを使用するのでインストールする。
※ホームディレクトリをコピーするだけでサーバの引越しができるように、バイナリを置くだけで使えるようなツールはホームディレクトリに置くようにしています。
$ curl -L https://github.com/docker/compose/releases/download/1.8.1/docker-compose-`uname -s`-`uname -m` > ~/bin/docker-compose
$ chmod +x ~/bin/docker-compose
$ docker-compose -v
docker-compose version 1.8.1, build 878cff1
インストール
docker-zulipコード取得
$ cd ~/git
$ git clone https://github.com/galexrt/docker-zulip.git
docker-zulip設定変更
SETTING_NOREPLY_EMAIL_ADDRESS が noreply@example.com
のままだとインストールスクリプトが中断されるけど、他は何もチェックされないようです。
試しに使ってみるだけなので example.com を home.local に置き換えるのとポート番号の変更だけにしました。
$ cd docker-zulip
$ sed -i 's/example\.com/home.local/g' docker-compose.yml
$ sed -i 's/80:80/10080:80/g' docker-compose.yml
$ sed -i 's/443:443/10443:443/g' docker-compose.yml
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -23,8 +23,8 @@ redis:
zulip:
image: "quay.io/galexrt/zulip:1.4.2"
ports:
- - "80:80"
- - "443:443"
+ - "10080:80"
+ - "10443:443"
links:
- database
- memcached
@@ -41,17 +41,17 @@ zulip:
SECRETS_email_password: "123456789"
SECRETS_rabbitmq_password: "zulip"
SECRETS_secret_key: "REPLCAE_WITH_SECURE_SECRET_KEY"
- SETTING_EXTERNAL_HOST: "example.com"
- SETTING_ZULIP_ADMINISTRATOR: "admin@example.com"
- SETTING_ADMIN_DOMAIN: "example.com"
- SETTING_NOREPLY_EMAIL_ADDRESS: "noreply@example.com"
- SETTING_DEFAULT_FROM_EMAIL: "Zulip <noreply@example.com>"
- SETTING_EMAIL_HOST: "smtp.example.com"
- SETTING_EMAIL_HOST_USER: "noreply@example.com"
+ SETTING_EXTERNAL_HOST: "home.local"
+ SETTING_ZULIP_ADMINISTRATOR: "admin@home.local"
+ SETTING_ADMIN_DOMAIN: "home.local"
+ SETTING_NOREPLY_EMAIL_ADDRESS: "noreply@home.local"
+ SETTING_DEFAULT_FROM_EMAIL: "Zulip <noreply@home.local>"
+ SETTING_EMAIL_HOST: "smtp.home.local"
+ SETTING_EMAIL_HOST_USER: "noreply@home.local"
SETTING_ALLOWED_HOSTS: "[ '*', '127.0.0.2' ]"
ZULIP_AUTH_BACKENDS: "EmailAuthBackend"
- ZULIP_USER_EMAIL: "example@example.com"
+ ZULIP_USER_EMAIL: "example@home.local"
ZULIP_USER_PASS: "zulip"
- ZULIP_USER_DOMAIN: "example.com"
+ ZULIP_USER_DOMAIN: "home.local"
volumes:
- "/opt/docker/zulip/zulip:/data:rw"
docker-zulip実行
$ docker-compose up
Creating dockerzulip_redis_1
Creating dockerzulip_memcached_1
Creating dockerzulip_rabbitmq_1
Creating dockerzulip_database_1
Creating dockerzulip_zulip_1
Attaching to dockerzulip_redis_1, dockerzulip_memcached_1, dockerzulip_rabbitmq_1, dockerzulip_database_1, dockerzulip_zulip_1
≪省略≫
rabbitmq_1 |
rabbitmq_1 | =INFO REPORT==== 6-Nov-2016::01:46:20 ===
rabbitmq_1 | accepting AMQP connection <0.513.0> (172.17.0.5:40066 -> 172.17.0.4:5672)
rabbitmq_1 |
rabbitmq_1 | =INFO REPORT==== 6-Nov-2016::01:46:20 ===
rabbitmq_1 | accepting AMQP connection <0.522.0> (172.17.0.5:40068 -> 172.17.0.4:5672)
zulip_1 | 2016-11-06 01:46:21,104 INFO exited: zulip-deliver-enqueued-emails (exit status 1; not expected)
zulip_1 | 2016-11-06 01:46:21,151 INFO spawned: 'zulip-deliver-enqueued-emails' with pid 306
zulip_1 | 2016-11-06 01:46:21,481 INFO exited: zulip-postsetup-create_user (exit status 0; expected)
zulip_1 | 2016-11-06 01:46:21,903 INFO exited: zulip-deliver-enqueued-emails (exit status 1; not expected)
zulip_1 | 2016-11-06 01:46:22,906 INFO spawned: 'zulip-deliver-enqueued-emails' with pid 311
zulip_1 | 2016-11-06 01:46:23,872 INFO exited: zulip-deliver-enqueued-emails (exit status 1; not expected)
zulip_1 | 2016-11-06 01:46:26,644 INFO spawned: 'zulip-deliver-enqueued-emails' with pid 316
zulip_1 | 2016-11-06 01:46:27,639 INFO exited: zulip-deliver-enqueued-emails (exit status 1; not expected)
zulip_1 | 2016-11-06 01:46:31,643 INFO spawned: 'zulip-deliver-enqueued-emails' with pid 321
zulip_1 | 2016-11-06 01:46:32,626 INFO exited: zulip-deliver-enqueued-emails (exit status 1; not expected)
zulip_1 | 2016-11-06 01:46:33,628 INFO gave up: zulip-deliver-enqueued-emails entered FATAL state, too many start retries too quickly
FATALが出ているのが気になるが、とりあえず動きました。
https://192.168.0.200:10443/
docker-compose.ymlで設定したZULIP_USER_EMAIL、ZULIP_USER_PASSでユーザ登録されているはずですが、ログインできませんでした。
少し調べてみたところ、どうやら設定ファイルに記述したユーザは作成されていないよう。レルムを作成しておかないとユーザ作成が失敗するのですが、レルムを作成している処理がどこにも見当たりませんでした。
レルムの作成と管理者ユーザの登録は手動で行う必要があります。
レルムの作成と管理者ユーザの登録
# zulipコンテナに接続
$ docker exec -it dockerzulip_zulip_1 /bin/bash
root# su - zulip
$ cd deployments/current
# レルム作成
$ ./manage.py create_realm --domain=home.local --name='home'
# ユーザ作成
$ ./manage.py create_user --this-user-has-accepted-the-tos --domain home.local zulip@home.local 'Zulip'
# パスワード設定
$ ./manage.py changepassword zulip@home.local
# 管理者権限付与
$ ./manage.py knight -f zulip@home.local
作成した管理者ユーザでログインすることができました。
docker-zulip削除
docker-composeは管理対象の複数のコンテナの停止から削除までをコマンド一発で行ってくれるので便利です。データはホスト側に保管するようになっているため、これの削除も行います。
$ docker-compose down
$ sudo rm -rf /opt/docker/zulip
感想
データをホスト上に保管するようにしてあるため、zulipをアップデートする場合はコンテナを入れ替えるだけで済み、運用がとても楽になると思います。
インターネットに接続できないネットワーク環境でzulipを使用する場合はこれしかないといった感じ。
おまけ
zulipにログインできない原因を調べたときのメモとか。
データベース内容確認
# データベース接続
$ docker exec -it dockerzulip_zulip_1 /bin/bash
root# psql -h database -U zulip
# テーブル一覧
zulip=> \d
WARNING: terminal is not fully functional
List of relations
Schema | Name | Type | Owner
--------+--------------------------------------------+----------+-------
zulip | auth_group | table | zulip
zulip | auth_group_id_seq | sequence | zulip
zulip | auth_group_permissions | table | zulip
zulip | auth_group_permissions_id_seq | sequence | zulip
zulip | auth_permission | table | zulip
zulip | auth_permission_id_seq | sequence | zulip
zulip | confirmation_confirmation | table | zulip
zulip | confirmation_confirmation_id_seq | sequence | zulip
zulip | confirmation_realmcreationkey | table | zulip
zulip | confirmation_realmcreationkey_id_seq | sequence | zulip
zulip | django_content_type | table | zulip
zulip | django_content_type_id_seq | sequence | zulip
zulip | django_migrations | table | zulip
zulip | django_migrations_id_seq | sequence | zulip
zulip | django_session | table | zulip
zulip | django_site | table | zulip
zulip | django_site_id_seq | sequence | zulip
zulip | fts_update_log | table | zulip
zulip | fts_update_log_id_seq | sequence | zulip
zulip | guardian_groupobjectpermission | table | zulip
zulip | guardian_groupobjectpermission_id_seq | sequence | zulip
zulip | guardian_userobjectpermission | table | zulip
zulip | guardian_userobjectpermission_id_seq | sequence | zulip
zulip | third_party_api_results | table | zulip
zulip | zerver_attachment | table | zulip
zulip | zerver_attachment_id_seq | sequence | zulip
zulip | zerver_attachment_messages | table | zulip
zulip | zerver_attachment_messages_id_seq | sequence | zulip
zulip | zerver_client | table | zulip
zulip | zerver_client_id_seq | sequence | zulip
zulip | zerver_defaultstream | table | zulip
zulip | zerver_defaultstream_id_seq | sequence | zulip
zulip | zerver_huddle | table | zulip
zulip | zerver_huddle_id_seq | sequence | zulip
zulip | zerver_message | table | zulip
zulip | zerver_message_id_seq | sequence | zulip
zulip | zerver_preregistrationuser | table | zulip
zulip | zerver_preregistrationuser_id_seq | sequence | zulip
zulip | zerver_preregistrationuser_streams | table | zulip
zulip | zerver_preregistrationuser_streams_id_seq | sequence | zulip
zulip | zerver_pushdevicetoken | table | zulip
zulip | zerver_pushdevicetoken_id_seq | sequence | zulip
zulip | zerver_realm | table | zulip
zulip | zerver_realm_id_seq | sequence | zulip
zulip | zerver_realmalias | table | zulip
zulip | zerver_realmalias_id_seq | sequence | zulip
zulip | zerver_realmemoji | table | zulip
zulip | zerver_realmemoji_id_seq | sequence | zulip
zulip | zerver_realmfilter | table | zulip
zulip | zerver_realmfilter_id_seq | sequence | zulip
zulip | zerver_recipient | table | zulip
zulip | zerver_recipient_id_seq | sequence | zulip
zulip | zerver_referral | table | zulip
zulip | zerver_referral_id_seq | sequence | zulip
zulip | zerver_scheduledjob | table | zulip
zulip | zerver_scheduledjob_id_seq | sequence | zulip
zulip | zerver_stream | table | zulip
zulip | zerver_stream_id_seq | sequence | zulip
zulip | zerver_subscription | table | zulip
zulip | zerver_subscription_id_seq | sequence | zulip
zulip | zerver_useractivity | table | zulip
zulip | zerver_useractivity_id_seq | sequence | zulip
zulip | zerver_useractivityinterval | table | zulip
zulip | zerver_useractivityinterval_id_seq | sequence | zulip
zulip | zerver_usermessage | table | zulip
zulip | zerver_usermessage_id_seq | sequence | zulip
zulip | zerver_userpresence | table | zulip
zulip | zerver_userpresence_id_seq | sequence | zulip
zulip | zerver_userprofile | table | zulip
zulip | zerver_userprofile_groups | table | zulip
zulip | zerver_userprofile_groups_id_seq | sequence | zulip
zulip | zerver_userprofile_id_seq | sequence | zulip
zulip | zerver_userprofile_user_permissions | table | zulip
zulip | zerver_userprofile_user_permissions_id_seq | sequence | zulip
(74 rows)
ユーザ情報を管理していると思われるテーブルの内容を確認する。(フィールドは \d zerver_userprofile
で調べた)
# ユーザ一覧
zulip=> select email,domain from zerver_userprofile,zerver_realm where zerver_userprofile.realm_id=zerver_realm.id;
email | domain
------------------------------+------------
emailgateway@zulip.com | zulip.com
welcome-bot@zulip.com | zulip.com
notification-bot@zulip.com | zulip.com
nagios-send-bot@zulip.com | zulip.com
nagios-receive-bot@zulip.com | zulip.com
feedback@zulip.com | zulip.com
(6 rows)
レルムの一覧を確認する。
zulip=> select domain,name from zerver_realm;
domain | name
------------+------
zulip.com |
(1 rows)
docker-compose.ymlで設定したZULIP_USER_DOMAIN、ZULIP_USER_EMAILがデータベースに登録されていないことが分かった。
docker-zulipのリポジトリ内でZULIP_USER_DOMAIN、ZULIP_USER_EMAILを使用している箇所を調べる。
$ grep -R '\(ZULIP_USER_DOMAIN\|ZULIP_USER_EMAIL\)' .
./includes/createZulipAdmin.sh:if [ ! -z "$ZULIP_USER_CREATION_ENABLED" ] && ([ -z "$ZULIP_USER_DOMAIN" ] || [ -z "$ZULIP_USER_EMAIL" ]); then
./includes/createZulipAdmin.sh: realm = get_realm('$ZULIP_USER_DOMAIN')
./includes/createZulipAdmin.sh: create_user('$ZULIP_USER_EMAIL', '$ZULIP_USER_PASS', realm, '$ZULIP_USER_FULLNAME', email_to_username('$ZULIP_USER_EMAIL'))
./includes/createZulipAdmin.sh:User = get_user_profile_by_email(email='$ZULIP_USER_EMAIL')
./kubernetes/zulip-rc.yml: - name: ZULIP_USER_EMAIL
./kubernetes/zulip-rc.yml: - name: ZULIP_USER_DOMAIN
./docker-entrypoint.sh:export ZULIP_USER_DOMAIN="${ZULIP_USER_DOMAIN:-$(echo $SETTING_EXTERNAL_HOST)}"
./docker-entrypoint.sh:export ZULIP_USER_EMAIL="${ZULIP_USER_EMAIL:-}"
./docker-compose.yml: ZULIP_USER_EMAIL: "example@home.local"
./docker-compose.yml: ZULIP_USER_DOMAIN: "home.local"
./includes/createZulipAdmin.sh
でユーザ作成を行っていることが分かる。
manager.py
でユーザ作成する際に--domain
を指定しないとエラーになることから、ユーザ作成の前にドメイン(realm)を作成しておく必要があるはずだが、realm = get_realm('$ZULIP_USER_DOMAIN')
でドメインを参照している処理があるだけで、ドメインを作成している個所がない。
ドメイン取得に失敗したらドメインを作成するという処理が必要と思われる。