ACALL 開発環境を コンテナ化したお話

ACALLワークスタイル

はじめまして。 ACALL 開発チームの 横山 です。
今回は ACALL 開発環境をコンテナ化したお話 をしようと思います。 ACALL ブログとしては、久しぶりの技術ネタの投稿になりますね。ブログを書くのも初めてなのにしょっぱなから技術ネタの紹介ということで緊張していますが、お手柔らかにお願いします。

作ったきっかけ

ACALL では、2020 年 5 月に Public API をリリースしました。この開発は同年の2月末くらいに開始されたのですが、実はこの開発は新しい技術スタックで行われています。
インフラ基盤、開発言語等様々な要素で従来の技術スタックと異なるものが採用され、アーキテクチャはマイクロサービスに移行していくこととなりました。

それまでの ACALL では開発環境は特に共通化しておらず、 それぞれのリポジトリの README.md に従って、個々の開発者が個々の環境に構築する方式でした。当然、環境差異によってエラー再現がなされなかったり、開発環境が壊れてしまって再インストールをしたりというトラブルが月 1 回くらいの頻度で発生している状態でした。

このような状態の中新しい技術スタックに移行したら、現状でさえ開発環境構築に課題がある状態なのに、更なる混乱を招くことになるだろうことは明らかでした。
このような背景の中、開発環境を コンテナ化しようという話になりました。

概要

まずは gitlab (当時。今は GitHub に移行しました。) 上にそれぞれの開発環境をコード化して保存するためのリポジトリを作りました。この環境上に Dockerfile や環境変数、docker-compose ファイルを定義していくことになります。
コマンドを実行することで開発用コンテナが複数立ち上がり、 エンジニアは VSCode Remote Container の機能を使ってコンテナ内部で作業ができるようにします。
完成イメージはコチラ<https://github.com/wakuwaku3/example.env>になります。

事前準備

ローカル環境には以下のインストールが必要になります。

  • git
  • docker, docker-compose (docker for mac, docker for windows)

Dockerfile

まずは Dockerfile を定義します。
ベースイメージはなるべく公式のものを選ぶのが良いでしょう。
コンテナ内部で GitHub のリポジトリにプッシュできるように、環境変数として GITHUB_USER_NAME, GITHUB_TOKEN, GITHUB_EMAIL を定義しています。また、リポジトリを clone する ディレクトリとして repo を作り、Docker Volume として永続化します。そして、 初期化コマンドである init.sh を実行します。

# ./golang/web/Dockerfile
FROM golang:1.14-buster

LABEL Name="example.pubsub.go"
LABEL Version="1.0.0"

ENV GITHUB_USER_NAME=GITHUB-user-name
ENV GITHUB_TOKEN=GITHUB-token
ENV GITHUB_EMAIL=GITHUB-email
ENV DB_HOST=db
ENV DB_PORT=5432
ENV DB_USER=root
ENV DB_NAME=development
ENV DB_USE_SSL=false

WORKDIR /
ADD ./init.sh init.sh

VOLUME /go
RUN mkdir -p /repo
VOLUME /repo
WORKDIR /repo

EXPOSE 8080
CMD ["bash", "/init.sh"]

init.sh を追加

次に init.sh を定義します。こいつの主な役目はリポジトリをクローンすることと、Dockerfile を終わらないようにすることです。
また、 git config --global コマンドによって、 GitHub への認証を解決しています。

# ./golang/web/init.sh
#!/bin/bash
cd /

git config --global user.name ${GITHUB_USER_NAME}
git config --global user.email ${GITHUB_EMAIL}
git config --global url."https://${GITHUB_USER_NAME}:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

if [ ! -d /repo/.git ]; then
  git clone https://github.com/wakuwaku3/{リポジトリ名}.git repo
fi

cd /repo/

sh -c "while :; do sleep 10; done"

docker-compose.yml を追加

次に、 docker-compose.yml を定義します。ここでは同時に立ち上げたいコンテナを定義します。DBのインスタンスが立ち上がるようにしておくと便利です。複数の docker-compose.yml でネットワークを共有したい場合は、予め docker network create sample-network コマンドで外部ネットワークを作ることで実現できます。
docker-compose では ${} を使うことで変数を扱うことができます。この変数は .env で定義することができます。.env ファイルには個人的な情報が含まれるので、 .gitignore でソース管理上にアップロードされないようにしています。

version: "3"

services:
  db:
    image: postgres:9-alpine
    environment:
      POSTGRES_USER: root
      POSTGRES_HOST_AUTH_METHOD: trust
    volumes:
      - "acall.data:/var/lib/postgresql/data"
    ports:
      - "5433:5432"
    tty: true
  web:
    build: ./golang/web
    environment:
      GITHUB_USER_NAME: ${GITHUB_USER_NAME}
      GITHUB_TOKEN: ${GITHUB_TOKEN}
      GITHUB_EMAIL: ${GITHUB_EMAIL}
      DB_HOST: db
      DB_PORT: 5432
      DB_USER: root
      DB_NAME: development
    tty: true
    volumes:
      - "golang.web:/root"
      - "golang.web.go1.14:/go"
volumes:
  golang.web:
  golang.web.go1.14:
networks:
  default:
    external:
      name: sample-network

実行する

ここまで準備できたらあとは docker-compose up でコンテナが立ち上がります。
立ち上がったコンテナに対して、VSCode Remote Container機能でアクセスしたり、container にアタッチして Vim を実行することで開発が可能になります。

まとめ

よかったこと

  • 開発環境の構築が容易になり、トラブルシューティングが楽になった
  • マイクロサービス化によって開発リポジトリの数が 10 → 30 個くらいに増えたが、環境の管理はかえって楽になった。
  • Dockerに不慣れな人もいたが、意外とすぐ慣れてくれた

残る課題

  • GoLand 等、一部の IDE に対応するのが難しい
    • 対応できるけど、ローカルにも別途何かを入れる必要があったりして、手順が複雑
  • cordova や elecron 等を使ったネイティブアプリ環境は コンテナ化できなかった

最後に

エンジニア募集してます

ACALLでは、バックエンド、フロントエンド、インフラ、IoTなど、各種エンジニアを募集しています。
カジュアル面談から受け付けてますので気軽に問い合わせください!