コンパイル型言語のデプロイ
スクリプト言語の場合はスクリプトを配信することがデプロイと同義であるが、コンパイル型の場合はビルド生成物をデプロイしなければならない。またgolangでWebアプリケーションを作成した場合、ビルド成果物自体がサーバスクリプトでもあるため実行環境上でプロセスを実行する必要がある。
Dockerコンテナとしてデプロイする
コンテナイメージとしてデプロイして立ち上げる想定なら、立ち上げと同時にプロセスを走らせることはできる。実際のところ既にサービスが立ち上がっている状態から新しいイメージのコンテナがポートを交代するとなると手動では困難だが、オーケストレーションツールに任せる場合は自然な流れになる。従ってコンテナによるデプロイ手法を取った。
コンテナとしてデプロイにあたり、以下のようなDockerfile書いてビルドした。alpineはバイナリをshellに実行させるためのライブラリが何故かshellの参照先と違うのでシンボリックリンクを張る必要があった。
FROM alpine:latest
RUN mkdir /lib64 && \
ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
COPY ./build /app
ENV APPROOT /app
CMD [ "/app/server", "||", "exit", "0" ]
ビルドしたコンテナからイメージをかき出し、イメージをDocker HubにPushする。
docker login
docker commit mingsiro71/api-stub
docker push mingsiro71/api-stub
ホストで手動デプロイの際はdocker hubからイメージをpullして立ち上げる。まず作業ディレクトリを作成してカレントディレクトリを変更。
mkdir -p ~/services/api-stub
cd ~/services/api-stub
環境変数ファイルを作成。
nano .env
# 環境変数をKEY=VALUE形式で記述
# VALUEをダブルクォーテーションで括っていた箇所があったが、そのまま読み取られてしまうので外した
ネットワークを作り、redisコンテナとセットでコンテナを起動。
docker pull mingsiro71/api-stub
docker network create api-stub
docker run -p 127.0.0.1:8081:80 --net=api-stub --name=api-stub --env-file .env -d mingsiro71/api-stub
docker run -p 6379 --net=api-stub --name=api-stub-redis -d redis
/app/serverにあるバイナリのプロセスが立ち上がり、ポート8081をapi-stubがListenする。
golangアプリケーションにおける環境変数
既に記述の中で出ているが、環境変数管理がスクリプト言語のアプリケーションと異なる。
スクリプト言語ではソースディレクトリの中に環境変数ファイル(通常.envとされる)があり、実行時にファイルから読み込まれる。
一方、golangの場合は環境変数がos.Getenv()で実行環境から呼ばれる流れが基本で、環境上にセットすることになる。そのためファイルから読み込むタイミングはイメージビルド時かコンテナ起動時になる。
今回のデプロイ方法ではイメージビルド時に環境変数を仕込んだイメージを公開のDocker HubリポジトリにPushしてしまうと内容がバレてしまうのでコンテナ起動時に読み込む必要があった。
いずれにしてもビルド時に参照しやすい位置にしたい。そこでプロジェクトルートディレクトリに配置することにした。一方で環境変数の定義自体はアプリケーションとの関連性が強いため、以下のような配置とした。
# テンプレートファイル
./src/app/env/.env.template
# 本体
./.env.dev
./.env.prd
ソースを配布された開発者は最初にsrc内部から外側へコピーする想定だ。
cp ./src/app/env/.env.template ./.env.dev
デプロイ方法と環境変数の設定タイミング
今回はDocker Hub経由でコンテナを配布する形式のデプロイであり、ホストの中で作業可能なため実行時に環境変数ファイルを読み込ませるようにした。
ただ、デプロイの方法はCI/CDパイプラインの中でビルドしてホスト環境のコンテナリポジトリにPushするのであればビルド時にパイプライン内で設定してしまった方がよい。
また、Docker Hubを経由せず、docker export, docker importコマンドを利用してtarで配信する方法もある。(この配信方法ではCMD命令が外れてしまったり少々面倒な点があり断念した。あまり実用的ではなさそうではある。)
(余談).envとDocker Compose
Docker Composeはyamlと同じ位置にある.envをyaml内で展開して利用することができる。そのためコンテナの環境変数ファイルを同じディレクトリに管理する場合、".env"ではない名前にした方がよいようである。
Back to prev page