前回のあらすじ

  • Material-UIでブログのデザインを改善した

この記事ですること

  • 環境説明
  • 本番環境の構築
  • デプロイの為の準備

概要

ついにブログを公開する段階まで来た。
今回は自宅のIntel NUCのUbuntu上にMinikubeをインストールし、そこにデプロイしていく。
何使おうが大して変わらないのでVPSでもEC2でも好きなところですればいいと思うよ。

簡単な構成図

Nginxを前に置いて特定のアクセスをStrapi側に送っている。(画像のURLは参考)
Minikubeでポート30000で待ち受けて、3台に分かれたStrapiに対してリクエストを流している。
StrapiはMongoのStatefulSetのどれかに対して読み込みや書き込みを行う。
ストレージは3台とも共通。
MongoDBは3台構成でMongoDBのReplicaSetによってデータがレプリケーションされている。

こんな感じで冗長性をもたせた構成にしている。
Nginxが止まった場合?ハードから壊れた場合?そこまで考えるとハード増やさないといけないのでしてません。
本格的にクラスタ組むならGKE使うかなぁ…。

Intel NUCって?

https://www.intel.co.jp/content/www/jp/ja/products/boards-kits/nuc.html
ちっちゃいパソコン。
24時間稼働させたいので使ってます。

Ubuntu

https://www.ubuntulinux.jp/

Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-42-generic x86_64)

入れ方はいくらでも記事あるので割愛。

Minikubeって?

https://kubernetes.io/ja/docs/setup/learning-environment/minikube/
Kubernetesをローカルでお手軽に動かす環境。

インストール

https://qiita.com/Esfahan/items/f5c846088281c39f73a4

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
$ sudo snap install kubectl

設定を記載。

$ sudo nano /etc/profile
export MINIKUBE_WANTUPDATENOTIFICATION=false
export MINIKUBE_WANTREPORTERRORPROMPT=false
export MINIKUBE_HOME=/root
export CHANGE_MINIKUBE_NONE_USER=true
export KUBECONFIG=/root/.kube/config
$ sudo mkdir -p /root/.kube || true
$ sudo touch /root/.kube/config

これでrootでMinikubeが使える。
そして起動。

$ sudo /usr/local/bin/minikube start --vm-driver=none

$ sudo minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

$ sudo ufw allow 8443/tcp

ここまででMinikubeの準備は完了。

最初はmicrok8sっていうUbuntuが推してるやつを使ったんだけど、コンテナが複数個立ち上がらい事象に出くわして断念。
半日以上時間を無駄にしたのでもう触らないと思う。
MacのDockerのk8sでもMinikubeでも問題なく動くマニフェストなのでmicrok8sが悪いということにしておこう。

k8sって?

Kubernetesで調べれば分かる。
k8s=kubernetes。
https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/
分からない?初見でわかる人いないだろこれ…

Kubernetesは、宣言的な構成管理と自動化を促進し、
コンテナ化されたワークロードやサービスを管理するための、
ポータブルで拡張性のあるオープンソースのプラットフォームです。

大雑把に言うと、DockerImageを元にしてコンテナ作ってその状態を落ちないように維持管理してくれるツールだ。
複数のコンテナを簡単に作れていい感じにしてくれる。
コンテナ内ネットワークとか外部への公開どうすんねんとかハードウェア的な冗長性とかimageアップデートしたいんだけどとかその他諸々にも対応してるけど多すぎるし今回意識しない部分は飛ばす。
とりあえずはDocker-composeより公開向けに色々してくれるものってくらいの認識でいいと思う。
正しい理解がしたい場合は説明出来る自信はないんで幾らでも調べて。

DockerImageの作成

さて環境も整ったところでk8sで使うDockerImageを作っていく。
今までのDockerfileはローカルからファイルコピーする形だった。
開発時はいいけど本番はGithub上のファイルからクローンする。
こうすることでリポジトリへのpushをトリガーに最新のImageを作る形を構築する。
一々Image作ってDockerhubに登録してってやるのが面倒いから。
こうしとけば、NUCからimage pullする時もDockerhubのImage指定するだけでいい。
本番環境でいろいろいじくり回したく無いし、デプロイしたら放っとけるのが理想。

Dockerfile

長々と語ったがやることはdocker-compose.prod.yaml Dockerfile.prodを作るだけである。
実はcomposeの方は要らないんだけど、ローカルでDockerfileがちゃんと動くか確かめたかったんでついでに作った。

Dockerfile.prod

FROM strapi/base:12

WORKDIR /

RUN git clone https://github.com/Tim0401/dreamer-strapi.git

WORKDIR /dreamer-strapi/app
RUN yarn install

ENV NODE_ENV production

RUN yarn build

EXPOSE 1337

CMD ["yarn", "start"]

やってることは、

  • Strapiのbaseイメージを取ってくる
  • 自分のリポジトリからデータ取ってくる
  • アプリのディレクトリに移動してライブラリインストール
  • ビルド→スタート

というイメージが出来る。

docker-compose.prod.yaml

version: '3'

services:
  strapi:
    container_name: strapi
    image: tim0401/dreamer-strapi:0.1
    environment:
      - PORT=1337
      - ADMIN_JWT_SECRET=fdc557d845496da740a345a1e5dfc04e
      - DATABASE_HOST=db
      - DATABASE_PORT=27017
      - DATABASE_NAME=strapi
    ports:
      - 1337:1337
    depends_on:
      - db

  db:
    container_name: mongo
    image: mongo
    environment:
      - MONGO_INITDB_DATABASE=strapi
    ports:
      - 27017:27017
    volumes:
      - ./db:/data/db
    restart: always

こちらは上で作られる予定のイメージを使ってコンテナを作っている。
環境変数はSECRETくらいは.envに入れたほうがいい。
これは実際に使ってるわけじゃないので。
dbはdevのものと共通。

さてこの状態になったら、Githubにpushしておく。

Dockerhub

ここからはDockerhubでの作業になる。
DockerhubとはDockerImageを置いといてくれるところ。
ここに置いておけばどこからでも使えるのと、Github連携もあるので使っている。
アカウントない人は作ろう。
ここからはブラウザでの操作なので画像で紹介していく。

まずはrepositoriesをクリックして右上のCreate Repositoryを押す。

こんな画面が出てくるので名前(Image名になります)をいれてGithubアイコンをクリック。
Connectedになってない人は紐付けしてね。

そしたらリポジトリ選ぶ画面になるので、対象のリポジトリを選ぶ。

作成後、BuildsタブからConfigure Automation Buildを選んでビルド設定をする。
今はmasterにPushされた時とv0.x等のタグがつけられたPushがあった時にイメージを作ることにしている。
個人だったら前者だけでlatestイメージタグでの運用でもいいと思う。

手動でビルドをスタートしたい場合はTriggerボタンを押せばしてくれる。
初回はこれでするといいかもしれない。

これでこのImageはtim0401/dreamer-strapi:latest(私の場合)と書くだけで取得出来るようになった。
これそのまま打つと私のイメージ取得することになるんで注意。
一応ローカルから正常に取得できるか試してみる。

docker-compose -f docker-compose.prod.yaml up --build

こんな感じで上で作ったのを動かしてみる。

ローカルで動かした時と同様にアクセス出来れば成功。
表示内容がproduction仕様のものになっているはずだ。

本来はここからk8sマニフェストを作って動かすところまでやる予定だったのだが分量が大きすぎた…。
というわけで次回に回すが、今回と次回をまとめてやることをおすすめする。
ここまでだと何がなんだかわかんないしね。

次の記事: Gatsby+Strapiでブログを構築した話(8) k8sマニフェスト作成と起動