こんにちは。NUTMEGでNUTMEGクラウドの開発・運用を行っているM1大浦です。
これまでNUTMEGでの開発を円滑に進めるために様々なインフラ開発を行ってきました。その中でも,最近行った「簡易的なステージング環境を構築した話」について紹介させていただきます。
ステージング環境とはシステム開発において最終的なテストを行う環境のことです。
リリースに向けて本番を想定した環境を用意し,実際に使ってみることでバグが存在しないことを確認します。ステージング環境で問題が発生しないことを確認出来たら本番環境にデプロイを行います。
簡単に言うとリハーサル会場のようなものです。
これまでのNUTMEGには,テスト環境やステージング環境がなく,開発環境とデプロイ環境の差異により,問題が起きることが多くありました。そのたびNUTMEGインフラチームは時間を削ってインシデント対応を行うというのがいつもの流れでした。
ステージング環境やテスト環境を作ることでこの問題は解決できますが,それを運用するためにインフラチームの負担が増えるのは本末転倒です。
そこで,「NUTMEGのプロダクトメンバー自身が簡単に立ち上げられるステージング環境があれば」と思い立ったのが経緯です。
ステージング環境の立ち上げにはCloudflared(旧 Cloudflare Argo Tunnel)を使用しました。
Cloudflaredは,Cloudflareのネットワークとの間にトンネルを作成するツールです。これにより,自身のサーバーのポートを開放せずに公開することが可能となっています。
NUTMEGのプロダクトはほぼすべて,Docker
,Docker Compose
を使用しており,開発者はdocker compose up
のコマンドで開発環境の立ち上げを行っています。
Cloudflaredが同時に立ち上がるdocker-compose.stage.yml
を作成することで,開発環境を立ち上げるのと同じ労力でステージング環境を立ち上げることができます。
開発者の労力はそのまま,インフラチームのインシデント対応が減ってみんなハッピーというのが思い描く新時代です。
最初の構築はすこし大変ですが,一度行ってしまえばどこの誰でもステージング環境を立ち上げることができます。
楽するために努力するは私の座右の銘です。
がんばりましょう。
NUTMEGでは開発にDocker
,Docker Compose
を使用しています。
既存のdocker-compose.yml
を参考にdocker-compose.stage.yml
を作成し,cloudflareのサービスを追加します。
設定項目は以下の通りです。
cloudflare/cloudflared:latest
コンテナを使用./cloudflare/stage
を作成/home/nonroot/.cloudflared
にマウントdocker-compose.stage.yaml
version: '3'
services:
cloudflare:
image: 'cloudflare/cloudflared:latest'
container_name: "cloudflare"
volumes: ['./cloudflare/staging:/home/nonroot/.cloudflared']
command: tunnel run
service-1:
...
service-2:
...
service-3:
...
ここで./cloudflare/stage
ディレクトリをDockerユーザーでも書き込み可能にしておきます。
chmod o+rwx ./cloudflare/stage/
あとはcloudflareの設定です。
cloudflare.com に移動しログインします。 ここではアカウント作成手順は省略します。
以下のコマンドを入力し,立ち上げるcloudflareコンテナを認証します。
docker compose -f docker-compose.stage.yml run --rm cloudflare tunnel login
コマンドを入力するとログインURLが表示されるのでログイン。
# 出力
Please open the following URL and log in with your Cloudflare account:
https://dash.cloudflare.com/argotunnel...
Leave cloudflared running to download the cert automatically.
...
URLの先に飛ぶと以下の画面に遷移し,使用したいドメインで認証。
以上でcloudflareの認証が完了します。
認証情報は./cloudflare/stage/cert.pem
に保存されます。
次にトンネルを作成します。 名前通りコンテナとClouflareをつなぐトンネルです。 これによって,外部からのアクセスを可能にします。
今回はNUTMEGで開発しているgroup-manager-2のステージング環境を作成するため,<tunnel-name>
はgm2-stg
という名前に設定しました。
docker compose -f docker-compose.stage.yml run --rm cloudflare tunnel create <tunnel-name>
以上が正常に完了すると./cloudflare/stage/<tunnel-id>.json
が保存されます。
最後にDNS・リバースプロキシの設定です。
cloudflare/staging/config.yaml
に設定ファイルを作成します。
hostname
に対して接続するサービスを指定します。
例:service-1.stg.nutfes.net にアクセスすると
docker-compose.stage.yml
のservice-1
の8080番ポートに飛ぶ。
cloudflare/staging/config.yaml
tunnel: <tunnel-id>
credentials-file: /home/nonroot/.cloudflared/<tunnel-id>.json
protocol: http2
ingress:
- hostname: service-1.stg.nutfes.net
service: http://service-1:8080
- hostname: service-2.stg.nutfes.net
service: http://service-2:8000
- hostname: service-3.stg.nutfes.net
service: http://service-3:3000
- service: http_status:404
configで設定したすべてのhostmameに対して以下のコマンドを実行し,CloudflareのDNSを設定します。
docker compose -f docker-compose.stage.yml run --rm cloudflare tunnel route dns <tunnel-name> <hostname(example.hoge.net)>
以上の設定を済ませてしまえば,今後は以下コマンドで起動するだけです。
docker compose -f docker-compose.stage.yml up
うまくできていれば以下のログが確認できるはずです。
INF Connection <tunnel-id> registered with protocol: http2
ブラウザで<hostname>
を確認してみるとちゃんと表示できますね。
以上がNUTMEGにステージング環境を導入した経緯とその方法でした。
NUTMEGのでの開発→デプロイのプロセスがスムーズになり,バグ対応も迅速化されることに期待します。
私たちNUTMEGインフラチームはNUTMEGメンバーが使いやすいインフラを構築することを目標として日々活動しています。今後も使いやすいインフラを目指して,様々な技術に挑戦していきたいと思います。