最近仕事でAsteriskというOSSのPBXサーバーを触っています。 普段はAsteriskをEC2上で動かしていますが、気軽に作れて気軽に壊せる環境が欲しかったのでDockerイメージを作ってみました。
ここではAsteriskが何かの解説はしません。 また、現時点ではレジは取れるが、音声が聞こえないという状況です。 こちらはボチボチ調査を進める予定。
Asterisk on Docker
作成したものはrhoboro/asterisk-dockerリポジトリのasterisk-base/Dockerfileに置いています。 また、 asterisk-base/ でビルドしたDockerイメージをrhoboro/asterisk-base:16.8.0という名前でDocker Hubにも登録しています。
今回はベースイメージに ubuntu:20.04 を選択し、 Asterisk 16.8.0 をインストールしています。 基本的にはAsteriskのインストールに必要なものを入れているだけなので、特筆するところは少ないです。
国際番号の入力をスクリプトで実行する設定
下記の行がないと、Asteriskのインストール中に国際番号の入力画面が表示されます。 docker build の最中ではそういったインタラクティブな対応が行えないため、事前に値をセットしています。
&& echo "libvpb1 libvpb1/countrycode string ${country_code}" | debconf-set-selections \
Asteriskの設定ファイルとONBUILD命令
Asteriskには多様なconfファイルがあり、実際にAsteriskを動かす際にはこれらの変更が不可欠です。 しかし、実際にAsteriskを動かすときにどのような設定ファイルが使われるかはビルド時には特定できません。 そこでDockerfileの命令の一つであるONBUILDを下記のように使いました。
ONBUILD COPY conf/* /usr/local/asterisk/etc/asterisk/
ONBUILDを使うと、ONBUILDが含まれるDockerイメージをベースイメージとしてビルドを行った際にONBUILDに渡しておいたコマンドを実行できます。 つまり、リポジトリトップにおいているもうひとつのDockerfileのビルドを実行したときに、ベースイメージに conf/* がコピーされます。
こちらのDockerfileの中身はこれだけです。
FROM rhoboro/asterisk-base:16.8.0
なお、ONBUILDは直接ベースイメージに指定された時のみ動くため、孫イメージからは利用できません。
Asteriskの起動コマンド
Dockerはメインとなるプロセスをフォアグラウンドで起動する必要があります。 通常、Asteriskはデーモンとして動かすことが多いですが、下記のようにフォアグラウンドで起動できました。
asterisk -vvvvvgc
Asteriskの起動
このリポジトリのDockerイメージを使うと、下記のようにAsteriskを起動できます。
ただし、現時点ではレジは取れるが音声が聞こえない状況です。
$ git clone https://github.com/rhoboro/asterisk-docker.git
$ git checkout 0.1
# conf/ 以下に利用したいAsteriskのconfファイルを配置
$ docker build -t myasterisk:0.1 .
# リポジトリ内にあるconfをそのまま使う場合
$ docker run --rm -it -p 5060:5060 -p 5060:5060/udp -p 10000-10010:10000-10010/udp myasterisk:0.1
下記のように Asterisk Ready と表示されたら起動しています。
この状態になれば、ZoiperなどのSIPクライアントで 6001@localhost/unsecurepassword でアカウントを追加するとレジが取れると思います。
docker run のオプションについて
Asteriskが使うSIPと呼ばれるプロトコルは、デフォルトでUDPの5060ポートを利用します。
Dockerのポートフォワーディングの設定では /udp
をつけることでUDPであることを指定できます。
無指定ではTCPになるので注意が必要です。
また、(いまはまだ動いてないですが)RTPで音声データを扱う場合は複数のポート開放が必要になります。
Dockerのポートフォワーディングの設定では、-p HOSTSTART-HOSTEND:CONTAINERSTART-CONTAINEREND
のように連番のポートを指定できます。
ただし、指定するポート数が多過ぎるとエラーとなるため注意が必要です。
今後
まだ音声の通信ができていないのでここを解決したいです。 Asteriskの設定、SIP、NAT超え、Dockerのネットワーク設定などいろいろと知識が足りていないので時間がかかるかもしれません。 とはいえ、これを自力で解決できるとSIPのネットワーク周りに強くなってるはずなので頑張りたいところ。