課題
モバイルアプリ(Android/iOS)にプッシュをなげるための Push Provider として稼働しているサーバーがある。今回、新しいモバイルアプリを作成したがサーバーは共有したいので、異なる2つ目のモバイルアプリにもプッシュを投げれるようにしたい。
nginx をフロントにして、要求を受けたサーバーアプリが同じサーバー上の Gaurun を利用し FCM/APNS にPushリクエストを投げる仕組みを利用しているが、Gaurun は Android/iOS それぞれ一つしか処理できないため2つ目のアプリへの対応ができない。
やりたいこと
Gaurun を複数プロセス動かすことで、2つ目のアプリも処理できるようにしたい。
回答 ⇒ Docker を使おう!
Docker を使って、2つのコンテナで Gaurun を動かすことで対応する。
それぞれのコンテナ上の Gaurun は異なるポートで動作するようにして、サーバーアプリはモバイルアプリを判断して対応する Gaurun にリクエストを投げるようにする。
環境
- Server : Azure VM
- ホストOS : Ubuntu 18.04.2 LTS (Bionic Beaver)
- Web Server : nginx + Lumen
- Push Provider : Gaurun 0.10.0
Docker のインストール
###1.古い Docker をアンインストールする
$ sudo apt-get remove docker docker-engine docker.io containerd runc
###2.リポジトリを設定する
パッケージインデックスを更新
$ sudo apt-get update
HTTPS経由でリポジトリを使用できるようにするためのパッケージをインストール
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-commo
Dockerの公式GPGキーを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
フィンガープリントを持つキーが手元にあることを確認
$ sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) docker@docker.com
sub rsa4096 2017-02-22 [S]
atp リポジトリの設定
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
###3.Docker (Community Edition) のインストール
$ sudo apt-get update
$ sudo apt-get install -y docker-ce
インストール確認
$ sudo docker run hello-world
Version 確認
$ docker version
###4.ブート時に自動起動
Docker がOS起動時に自動起動するように設定する。
$ sudo systemctl enable docker
Gaurun の2重化
アプリ1用を gaurun1、アプリ2用を gaurun2 とする。
###1.Gaurun をコピーする
$ cd /home/sunskysoft/go/src/github.com/mercari
$ sudo cp -r gaurun gaurun2
###2.Gaurun2 の設定変更
Gaurun2 の設定ファイルを開く
$ sudo vi gaurun2/conf/gaurun.toml
・ポートを変更する(1056 -> 1059)
・Android 用 apikey を変更する
[core]
port = "1056"
:
[android]
apikey = "FCM のAPI Key" # アプリ1用
:
[ios]
pem_cert_path = "/root/src/conf/key_cert.pem" # アプリ1用
pem_key_path = "/root/src/conf/key_dev.pem" # アプリ1用
:
[core]
port = "1059"
:
[android]
apikey = "FCM のAPI Key" # アプリ2用
:
[ios]
pem_cert_path = "/root/src/conf/key_cert.pem" # アプリ2用
pem_key_path = "/root/src/conf/key_dev.pem" # アプリ2用
:
###3.アプリ2用の証明書(iOS用)をコピーする
以下のフォルダにアプリ2用の証明書を置く
/home/sunskysoft/go/src/github.com/mercari/gaurun2/conf
・key_cert.pem
・key_dev.pem
Docker コンテナ作成と実行
###1.コンテナを作成して Gaurun を実行する
コンテナ名はそれぞれ gaurun1, gaurun2 とし、それぞれのフォルダをコンテナの /root/src に割り当てる。
ポートはgaurun.toml で指定した gaurun1:1056、gaurun2:1059 にポートフォワードする設定とする。
$ sudo docker run -d --name gaurun1 \
-p 1056:1056 \
-v /home/sunskysoft/go/src/github.com/mercari/gaurun:/root/src \
-it ubuntu \
/root/src/bin/gaurun -c /root/src/conf/gaurun.toml&
$ sudo docker run -d --name gaurun2 \
-p 1059:1059 \
-v /home/sunskysoft/go/src/github.com/mercari/gaurun2:/root/src \
-it ubuntu \
/root/src/bin/gaurun -c /root/src/conf/gaurun.toml&
###2.コンテナ内に証明書をインストールして、コンテナをリスタートする
この状態では Gaurun からのPush要求がエラー(x509 certificate signed by unknown authority)となるため、コンテナに証明書をインストールする。
コンテナ gaurun1 に入る
$ sudo docker exec -it gaurun1 /bin/bash
root@xxx:/# apt-get update
root@xxx:/# apt-get install ca-certificates
root@xxx:/# rm -rf /var/cache/apt/*
root@xxx:/# exit
コンテナ gaurun1 をリスタート
$ sudo docker restart gaurun1
同様にコンテナ gaurun2 に入る
$ sudo docker exec -it gaurun2 /bin/bash
root@xxx:/# apt-get update
root@xxx:/# apt-get install ca-certificates
root@xxx:/# rm -rf /var/cache/apt/*
root@xxx:/# exit
コンテナ gaurun2 をリスタート
$ sudo docker restart gaurun2
サーバーアプリの修正
サーバーアプリは条件判断などを行い、
アプリ1向けであれば "http://localhost:1056/push" に、
アプリ2向けであれば "http://localhost:1059/push" に、
リクエストを送るようにする。
サーバー負荷に関しては別途考慮する必要はあるが、これで1つのサーバーで2つのアプリに対して Push リクエストを投げれるようになった。
参考
Docker docs (公式)
https://docs.docker.com/install/linux/docker-ce/ubuntu/
[Qiita] Ubuntuにdockerをインストールする
https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d
Vagrant環境に複数のDockerのコンテナを構築して複数のプッシュ通知(gauran)する
http://morototo.hatenablog.com/entry/2017/05/29/200738
[teratail]1台のサーバーで2つの Gaurun を動かすことは可能?
https://teratail.com/questions/178281