- 投稿日:2020-07-10T23:12:53+09:00
DockerのVolumeについて
EC2(AmazonLinux2)環境にてDockerと戯れているのですが、
気がついたらホストOS上にマウントポイントが増殖していました。。。
そこでVolumeの理解を深める為に色々と試しました。DockerにおけるVOLUMEについて
Dockerリファレンスのdockerfile-VOLUMEの説明より抜粋
VOLUME 命令は指定した名前でマウントポイントを作成し、他のホストやコンテナから外部マウント可能なボリュームにします。
docker run
コマンドは、ベース・イメージから指定した場所に、データを保存する場所として新規作成したボリュームを初期化します。これを読んで「コンテナ内にVOLUMEで指定したディレクトリが作成されるんだな」と理解はしましたが、"他のホストやコンテナから外部マウント可能なボリュームにします"という部分は、
コンテナ起動時(run)に-v
でホストOS上のディレクトリとの紐付けを可能にするディレクトリを定義するという認識でした。(-vを指定しないと結局のところ永続化はされずデータは破棄される認識)で、色々とVolumeの動作検証をしました。
検証環境
- EC2 (Amazon Linux2)
動作検証
- VOLUME指定の無いイメージ(CentOS)からコンテナ起動してみる(-v, --mount指定なし)
#Volumeは存在しない(コンテナ起動前) [~]docker volume ls DRIVER VOLUME NAME #CentOSイメージからコンテナ起動 [~]docker run --name test_container -dt centos #Volumeは存在しない(コンテナ起動後) docker volume ls DRIVER VOLUME NAME
- VOLUME指定のあるイメージからコンテナ起動してみる(-v, --mount指定なし)
下記dockerfileを使用してCentOSイメージをベースにVolume指定されたイメージを作成して起動してみる#dockerfile(CentOSイメージをベースにVolume=/test_volumeを定義) ARG baseimagetag=latest FROM centos:${baseimagetag} AS baseimage VOLUME /test_volume #dockerイメージ作成 [~]docker build -t centos_mod . #Volumeは存在しない(コンテナ起動前) [~]docker volume ls DRIVER VOLUME NAME #CentOS(改変)イメージからコンテナ起動 [~]docker run --name test_container -dt centos_mod #Volumeが作成される(コンテナ起動後) docker volume ls DRIVER VOLUME NAME local ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b #VolumeのホストOS上のマウントポイントを確認 #自動的に/var/lib/docker/volumes/配下にマウントポイントが作成されていることがわかる [~]docker inspect ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b [ { "CreatedAt": "2020-07-10T08:30:00+09:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b/_data", "Name": "ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b", "Options": null, "Scope": "local" } ] #コンテナ停止、削除 [~]docker stop test_container [~]docker rm test_container #Volumeが確認(コンテナ削除後) #ホストOS上のマウントポイントは存在している docker volume ls DRIVER VOLUME NAME local ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b
- VOLUME指定のあるイメージからコンテナ起動してみる(-v にてVolume名を指定)
#CentOS(改変)イメージからコンテナ起動(ホストOSのマウントポイントを名称(host_mount)で指定 [~]docker run --name test_container -v host_mount:/test_volume -dt centos_mod baf6954e9dbce1dd9ad3ae5c8286e63c01fd39689d79053725ae1800b70ea752 #Volumeが作成される(コンテナ起動後) [~]docker volume ls DRIVER VOLUME NAME local host_mount #VolumeのホストOS上のマウントポイントを確認 #自動的に/var/lib/docker/volumes/配下に-vで指定した名前/_dataでマウントポイントが作成されていることがわかる docker inspect host_mount [ { "CreatedAt": "2020-07-10T22:22:49+09:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/host_mount/_data", "Name": "host_mount", "Options": null, "Scope": "local" } ]
- VOLUME指定のあるイメージからコンテナ起動してみる(-v にてホストOS上のディレクトリを指定)
#CentOS(改変)イメージからコンテナ起動(ホストOSのマウントポイントをディレクトリ(/test_mount)で指定 [~]docker run --name test_container -v /test_mount:/test_volume -dt centos_mod e5e70d6235dbfe54950e2053f61236c1450d43c0b3aacfa38341e37cfacecaaa #Volumeの確認(コンテナ起動後) #下記コマンドではマウントポイントは表示されない [~]docker volume ls DRIVER VOLUME NAME #コンテナ情報からマウントポイントを確認 [~]docker inspect test_container ##一部抜粋 "Mounts": [ { "Type": "bind", "Source": "/test_mount", "Destination": "/test_volume", "Mode": "", "RW": true, "Propagation": "rprivate" } ],動作検証をして理解したこと
- VOLUMEが定義されたDockerイメージを使用してコンテナ起動すると、 VOLUMEで指定されたディレクトリが永続化領域としてコンテナ内に作成される
- Dockerコンテナ起動時(run)にVOLUMEで指定されたディレクトリに対応するホストOS上のマウントポイント(ディレクトリ)を指定しない場合、ホストOS上のDockerのVolume領域(上記検証では/var/lib/docker/volumes)にマウントポイントが自動で作成される
- 起動時にVOLUMEで指定されたディレクトリに対応するホストOS上のマウントポイント(名称)を指定した場合、無指定時と同様、ホストOS上のDockerのVolume領域にマウントポイントが指定した名称/_dataで作成される
docker volume ls
で表示されるマウントポイントはホストOS上のDockerのVolume領域(/var/lib/docker/volumes)に作成されたディレクトリを表示している
※Volume領域以外のディレクトリをマウントポイントに指定した場合は表示されない- ホストOS上に作成されたマウントポイントはコンテナを停止、破棄しても削除されない(永続化領域なんだから当たり前)
※VOLUME指定されたイメージ(MySQLなど)からのコンテナ起動を繰り返していると認識していないディレクトリが山のように発生している可能性も。。)(おまけ)Volume指定されているイメージかを確認する方法
docker inspect <イメージ名>
でイメージの情報を表示し、"Volumes": の部分にディレクトリが指定されてるかを確認する例)MySQLコンテナの場合
永続化領域としてコンテナ内に/var/lib/mysqlが定義されている"Volumes": { "/var/lib/mysql": {} },
- 投稿日:2020-07-10T23:12:14+09:00
DockerでNuxt.jsプロジェクト新規作成セット
概要
- nuxt.jsのセットアップ、新規プロジェクト作成、サーバー起動までをかんたん手順で行えます。
- Dockerコンテナとして構築するので、お手元のPCを汚しません。
- 複製、破棄、構築し直しも、手軽に行えます。
github(一式ダウンロード)
https://github.com/yagrush/docker-nuxtjs
必要なもの
- Docker
- docker-compose
- makeコマンド
がインストールされている Mac / Linux。
(WindowsではnodeのDockerコンテナが起動しませんでした。要調査。)使い方
https://github.com/yagrush/docker-nuxtjs のリポジトリをcloneまたはダウンロード&解凍する。
以下の2つのファイルを編集する。
.env
PROJECT_NAMEの値をご自分の希望に合わせて編集してください。
この値は、nuxt.jsプロジェクトのディレクトリ名にもなります。PROJECT_NAME=my_projectMakefile
Makefileは、makeコマンド用の設定ファイルです。
これを使うと、複数のコマンド操作に名前を付けて、ショートカットのように簡単に呼び出せます。さて、最近のバージョンでは、
create-nuxt-app
(nuxt.jsプロジェクト作成コマンド)実行時、途中でカスタム内容の指定を求められます。
本一式ではその入力を自動化するために create-nuxt-app実行時のオプション --answers で予めカスタム内容を指定するようにしています。カスタム項目一覧はこちらの公式ソースコードからご確認いただけます。
nuxt.js公式リポジトリ内、prompts.js
--answers のパラメータをJSON形式で指定して、ご自分のご希望に合わせて下さい。... ... create-nuxt-app: docker-compose exec dev bash -c 'create-nuxt-app $$PROJECT_NAME --answers "{ \ \"name\": \"$$PROJECT_NAME\", \ \"language\": \"js\", \ \"pm\": \"yarn\", \ \"ui\": \"vuetify\", \ \"features\": [\"axios\"], \ \"linter\": [\"eslint\"], \ \"test\" : \"jest\", \ \"mode\" : \"universal\", \ \"target\" : \"static\", \ \"devTools\": [\"jsconfig.json\"] }" \ ' ... ...※ エスケープが若干複雑ですみません。
Makefile
>docker-compose
>bash -c
と入れ子になっているので…
基本的にサンプルをコピペ&編集して頂ければ大丈夫かとは思います。
(サンプルの設定は、単なる私の好みです。)コマンドインターフェースを起動する。
ダウンロードしたフォルダの中に移動する。
# git cloneした場合 cd docker-nuxtjs # ZIPをダウンロードして解凍した場合 cd docker-nuxtjs-master以下のコマンドを実行する。
make init成功すると、このようなコマンドログになります。↓
... ... yarn run v1.22.4 $ eslint --ext .js,.vue --ignore-path .gitignore . --fix Done in 24.57s. ? Successfully created project my_project To get started: cd my_project yarn dev To build & start for production: cd my_project yarn build yarn start To test: cd my_project yarn test docker-compose exec dev bash -c 'sed -i -e "s@export default {@export default {\n telemetry: false,\n@g" $PROJECT_NAME/nuxt.config.js' docker-compose exec -d dev bash -c 'cd $PROJECT_NAME && npm run dev' $ちょっぴり解説コーナー
docker-compose exec dev bash -c 'sed -i -e "s@export default {@export default {\n telemetry: false,\n@g" $PROJECT_NAME/nuxt.config.js'nuxt.config.jsのexport default節に
telemetry: false
を追記します。
これにより、最近npm run dev
実行時に「サービス向上のため情報送信に協力するか?」の回答入力を要求されてしまうのを自動的に回避(falseだと拒否)します。Nuxt.jsサンプルページが起動しているはずなのでアクセスしてみる。
↑ こんなページ、見れましたでしょうか?
見れたら成功です。本リポジトリ内の
app/
(make initすれば生成されます)とdockerコンテナ内の/work/app
が同期(ボリュームマウント)しているので、例えばapp/$PROJECT_NAME/pages/index.vue
を編集すれば、即座に↑のサンプルページに反映されます。Dockerコンテナを停止する
make stopDockerコンテナを起動する
make upDockerコンテナを再ビルドする
make remake※ Nuxt.jsプロジェクトの再作成はしません。Dockerコンテナとしての再ビルドです。
本一式を完全廃棄する
make destroy※ このコマンドだけではapp/や本一式の内容物をいきなり削除はしないのでご安心ください。
そのあと、ご自身の手で本一式のディレクトリを削除してください。
あとがき
js界隈は変化が速過ぎて、WEB文献そのままでは全然動かず苦労します。
これを流用して少しでもショートカットして、みなさんのコーディング時間確保などに役立てれば幸いです。また、nginxで動かすproduction版など改善の余地がまだまだあるので、時間あるときにまた更新していきます。
- 投稿日:2020-07-10T17:36:55+09:00
CircleCIを使ってGitのコミットごとにGCPにDockerイメージを作る
はじめに
コミットごとにDokerのイメージを作るようにしました。
それぞれのコミットごとに完全動作するコンテナが出来上がります。
こうしておくと
- CIの一つとしてイメージのビルドが通る、イメージを使ってテストを実行できる、といったことが可能になる
- それぞれのイメージでデプロイができる
- 検証をする場合にイメージのビルドを行わず、プルすることができる
といったメリットがあります。
Dockerfileの準備
テスト用に
Dockerfile
を作成しておきます。DockerfileFROM golang:latestテスト用なのでどういったDockerfileでも構いません。
設定
CircleCIの設定
CircleCIでGCPを使う場合の参考ページです
https://circleci.com/docs/2.0/google-auth/基本的にこのページに沿っていけば実現できるのですが、うまく動かないポイントも多いため注意が必要です。
まずCircleCIで
Add Project
し、GitHub(やGitLab, Bitbucket)と連携しておきます。
(GitHubとCircleCIの連携は済ませているとします)GCPでのサービスアカウントの登録
GCP上でサービスアカウントを登録します。
作成したサービスアカウントからキーをJSONでダウンロードしておきます。
次に「IAM」から作成したサービスアカウントに対して権限を付与します。
権限 Cloud Build サービス アカウント Storage オブジェクト管理者 Storage オブジェクト作成者 Storage オブジェクト閲覧者 閲覧者 Cloud Buildを実行するための権限、CGRにイメージをアップロードするためのCloud Storage関連の権限、プロジェクトを参照するための閲覧権限が必要でした。
思った以上に権限が必要で、足りないと途中でエラーが出るためその対処は大変です。
CircleCIによるGCPの参考ページにもGCRの場合には追加の権限が必要になる、との記載があります。If you are having issues pushing container images to GCR you may need more granular permissions than the default service account provides. You can grant permission changes in the Cloud Storage IAM Console
https://circleci.com/docs/2.0/google-auth/「プロジェクトの編集者」といった権限を与えるとなんでもできてしまうため権限が足りなエラーは解消しますが、自動化する場合には万が一の漏洩を考えて最小限の権限とすることが必要です。
ローカルでの試験
CircleCIでの手順に進む前にローカル環境から正しく動くか、権限が足りているか、ということを確認しておきます。
こうすることでCircleCI、GCPといった複数のサービスをまたがって行う作業に対してトラブルを早めに見つけられるようにしておきます。まずプロジェクトIDとリージョン(ゾーン)を設定しておきます。(プロジェクト名をexampleとしていますが適宜読み替えてください)
$ export GOOGLE_PROJECT_ID=example $ export GOOGLE_COMPUTE_ZONE=ap-northeast1先ほどダウンロードしたCircleCI用のキーで
gcloud
コマンドで認証を掛けます。$ echo <ダウンロードしたキーの場所> | gcloud auth activate-service-account --key-file=- Activated service account credentials for: [circleci@example.iam.gserviceaccount.com]プロジェクトとリージョンの設定を行います。
$ gcloud --quiet config set project ${GOOGLE_PROJECT_ID} $ gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}アカウントが切り替わっていることを確認しておきます。
$ gcloud config list [compute] zone = ap-northeast1 [core] account = circleci@example.iam.gserviceaccount.com disable_usage_reporting = False project = example Your active configuration is: [default]先ほど作成したDockerfileをビルドしてみます。
$ gcloud builds submit --tag gcr.io/${GOOGLE_PROJECT_ID}/test . Creating temporary tarball archive of 10 file(s) totalling 5.4 KiB before compression. Uploading tarball of [.] to [gs://example_cloudbuild/source/1594367971.xxxxxxxxxxxxxxxx.tgz] Created [https://cloudbuild.googleapis.com/v1/projects/xxxxxxxxxxxxxxxxxxxxxx]. ..... latest: digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx size: 1795 DONE ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ID CREATE_TIME DURATION SOURCE IMAGES STATUS xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx 2020-07-10T07:59:32+00:00 18S gs://example_cloudbuild/source/1594367971.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.tgz gcr.io/example/test (+1 more) SUCCESS成功しました。
確認しておきます。
$ gcloud container images list-tags gcr.io/example/test DIGEST TAGS TIMESTAMP b413792axxxx latest 2020-07-07T18:20:07正しく作成されていますね。
CircleCIへの組み込み
CircleCIでビルドが通るように設定を行います。
環境変数を設定します。
CircleCIのプロジェクトを開いた画面中にある
Project Settings
からEnvironment Variables
を選択します。それぞれの変数を設定しています。
鍵のJSONについてはpbcopy
などを利用すると便利です。$ cat ~/Download/example.json | pbcopy
環境変数名 GCLOUD_SERVICE_KEY 先の手順で作成したサービスアカウントの鍵 GOOGLE_PROJECT_ID プロジェクトID GOOGLE_COMPUTE_ZONE コンピュートゾーン (ap-northeast1 ap-northeast2 など) 下記のように3つの変数を設定します。
セットアップ
次にCircleCIの
config.yml
を設定します。CircleCIでは
google/cloud-sdk
というイメージを使うとgcloud
が一通り揃っています。circleci/config.ymlversion: 2.1 jobs: build: docker: - image: google/cloud-sdk steps: - checkout - run: | echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=- gcloud --quiet config set project ${GOOGLE_PROJECT_ID} gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} gcloud builds submit --tag gcr.io/${GOOGLE_PROJECT_ID}/test .コミット、プッシュをして動作させます。
circleci
コマンドが入っている場合、下記のようにvalidate
を掛けておくと構文エラーをへらすことができます。$ circleci config validate && git add .circleci/config.yml && git commit -m 'Add CircleCI config' && git push origin HEADCircleCIでのビルドを確認します。
問題がなければ正しくビルドされ、GCRにイメージが作成されているはずです。
費用など
GCRでは Cloud Storage としてイメージが保管されるため、月々の費用がかかります。
2020年7月現在、概算で下記の通りです。Standard のバケット料金は、1 GB あたり月額約 $0.026 です。
https://cloud.google.com/container-registry/pricing?hl=ja巨大なイメージを管理する場合には注意が必要です。
- 投稿日:2020-07-10T17:20:00+09:00
Ubuntu 16.04へのIcinga2監視ツールのインストールと設定
Ubuntu 16.04にIcinga2監視ツールをインストールして設定する方法を探り、またAlibaba CloudにDockerをインストールして、いくつかの重要なDockについて学んでいきます。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
序章
Icinga 2 はフリーでオープンソースの強力なネットワークリソース監視ソフトウェアアプリケーションで、ネットワークからのリソースの可用性をチェックし、停止をユーザーに通知し、レポート用のパフォーマンスデータを生成します。Icinga 2を使用して、ネットワークサービス(SMTP、POP3、HTTP、NNTP、ping)、ホストリソース(CPU負荷、ディスク使用量)、ネットワークコンポーネント(スイッチ、ルーター、温度・湿度センサー)を監視することができます。これはNagiosシステム監視アプリケーションに非常に似ています。Icinga 2をNagiosプラグインと簡単に統合することができます。Icinga 2には、複数の場所にまたがる大規模で複雑な環境を監視するための、美しくユーザーフレンドリーなウェブインターフェースが付属しています。
Icinga 2には様々な機能が搭載されていますが、以下にその一部をご紹介します。
- GraphiteとInfluxDBをネイティブにサポートしています。
- 問題が発生した場合、電子メールやテキストメッセージで通知を送信します。
- カスタマイズ可能なプラグインにより、独自のサービスチェックを簡単に開発することができます。
- ホストとサービスの状態、ネットワークマップ、レポート、ログなどを可視化するためのIcinga Classic UIとIcinga Webインターフェイスを提供します。
- パフォーマンスグラフ化のためのPNP4Nagios、NagiosGrapher、InGraphなどの追加アドオンをサポートします。
このチュートリアルでは、Ubuntu 16.04サーバにIcinga 2とIcinga web 2をインストールして設定する方法を学びます。また、リモートホストサービスを監視するためにicinga2を設定する方法も学びます。
前提条件
- Alibaba Cloud Instance for Icinga ServerとUbuntu 16.04がインストールされています。
- Alibaba Cloud Instance for Icinga Client with Ubuntu 16.04がインストールされています。
- 静的IPアドレス192.168.0.103がIcinga Server Instanceに設定されています。
- 静的IPアドレス192.168.0.104がIcingaクライアントインスタンスに設定されています。
- ドメイン名に適切なDNSレコードが設定されています。
- SSHサービス経由でルートアカウントにアクセスできます。
はじめに
始める前に、以下のコマンドでシステムリポジトリとソフトウェアパッケージを最新バージョンに更新してください。
apt-get update -y apt-get upgrade -y次に、システムのホスト名を設定する必要があります。これは以下のコマンドで行うことができます。
hostnamectl set-hostname icingaserver次に、以下のコマンドでシステムのホスト名を確認します。
hostnamectl次に、サーバーインスタンスを再起動して、以下のコマンドですべてのアップデートを適用します。
reboot必要なパッケージのインストール
Icinga 2はウェブサーバー上で動作するので、Apacheサーバー、MariaDB、PHP言語、必要なPHPモジュールをシステムにインストールする必要があります。以下のコマンドを実行するだけで、すべてのパッケージをインストールすることができます。
apt-get install apache2 libapache2-mod-php7.0 mariadb-server mariadb-client php7.0 php7.0-xml php7.0-pgsql php7.0-opcache php7.0-xml php7.0-ldap php7.0-cli php7.0-gd php7.0-intl php7.0-readline php7.0-mbstring php7.0-json php7.0-curl php7.0-mysql -y必要なパッケージがすべてインストールされたら、以下のコマンドを使ってApacheとMariaDBサービスを起動し、起動時に起動できるようにします。
systemctl start apache2 systemctl enable apache2 systemctl start mysql systemctl enable mysql次に、以下のコマンドを使用して、Apache rewrite モジュールを有効にして、HTTP 接続を HTTPS にリダイレクトします。
a2enmod rewrite次に、システムの地理的な位置と一致するタイムゾーンを設定する必要があります。これはphp.iniファイルを編集することによって行うことができます。
nano /etc/php/7.0/apache2/php.ini次の行を変更します。
date.timezone = Asia/Kolkata保存して終了したらファイルを閉じ、Apache サービスを再起動して変更を適用します。
systemctl restart apache2Icinga2とIcinga Web 2のインストール
デフォルトでは、Ubuntu 16.04のデフォルトリポジトリでは、最新版のIcingaは利用できません。そのため、Icinga用のソフトウェアリポジトリを追加する必要があります。
まず、以下のコマンドでIcingaのパッケージ署名キーをダウンロードして追加します。
curl -sSL https://packages.icinga.com/icinga.key | sudo apt-key add -次に、APT設定ファイルにIcingaリポジトリを追加します。
nano /etc/apt/sources.list.d/icinga.listファイルの最後に以下の行を追加します。
deb https://packages.icinga.com/ubuntu icinga-xenial main保存してファイルを閉じ、以下のコマンドでリポジトリを更新します。
apt-get update -yリポジトリが更新されたら、以下のコマンドでIcinga2とIcinga web 2をインストールします。
apt-get install icinga2 icingaweb2 icinga2-ido-mysql -yインストール中に、アプリケーションを設定するための一連の質問を受けます。以下に示すように、それぞれの質問に答えてください。
Enable Icinga 2's ido-mysql feature? YES Configure database for icinga2-ido-mysql with dbconfig-common? NO次に、Icinga 2のido-mysqlとコマンド機能を有効にする必要があります。これは以下のコマンドを使って行うことができます。
icinga2 feature enable ido-mysql icinga2 feature enable command最後に、以下のコマンドでIcinga2サービスを再起動し、起動時に起動できるようにします。
systemctl restart icinga2 systemctl enable icinga2データベースの設定
開始前に、MariaDB データベースのセキュリティを確保する必要があります。これは、mysql_secure_installationスクリプトを実行することで行うことができます。
mysql_secure_installationこのスクリプトは、以下のようにMySQLのルートパスワードの変更、匿名ユーザーの削除、リモートルートログインの無効化、テストデータベースの削除を行います。
Change the root password? [Y/n] n Remove anonymous users? [Y/n] y Disallow root login remotely? [Y/n] y Remove test database and access to it? [Y/n] y Reload privilege tables now? [Y/n] yMariaDBのセキュリティが確保されたら、MariaDBシェルにログインし、以下のコマンドでIcinga2 IDO用の強力なパスワードを持つデータベース、データベースユーザーを作成します。
mysql -u root -p MariaDB [(none)]> CREATE DATABASE icinga2; MariaDB [(none)]> GRANT ALL PRIVILEGES on icinga2.* to 'icinga2'@'localhost' identified by 'strongpassword'; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> exit;次に、データベース、Icinga web 2用の強力なパスワードを持つデータベースユーザーを作成する必要があります。 これは、以下のコマンドを使用して行うことができます。
MariaDB [(none)]> CREATE DATABASE icingaweb2db; MariaDB [(none)]> GRANT ALL PRIVILEGES on icingaweb2db.* to 'icingaweb2'@'localhost' identified by 'strongpassword'; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> exit;次に、Icinga2 IDOスキーマをIcinga2データベースにインポートする必要があります。これは以下のコマンドを使用して行うことができます。
mysql -u root icinga2 -p < /usr/share/icinga2-ido-mysql/schema/mysql.sql次に、Icinga2 MySQL IDO設定ファイルを編集して、データベースの資格情報を手動で更新する必要があります。これは、/etc/icinga2/features-enabled/ido-mysql.confファイルを編集することで行うことができます。
nano /etc/icinga2/features-enabled/ido-mysql.conf以下のようにファイルを変更します。
user = "icinga2", password = "strongpassword", host = "localhost", database = "icinga2"ファイルを保存して閉じ、変更を適用するためにIcinga2サービスを再起動します。
systemctl restart icinga2ファイアウォールを介してIcinga2を許可する
デフォルトでは、新しくインストールされたUbuntu 16.04サーバインスタンスでは、UFWファイアウォールは無効になっています。UFWファイアウォールを有効にするには、以下のコマンドを使用します。
ufw enable次に、以下のコマンドでApacheのポート80、443、5665を許可します。
ufw allow 80 ufw allow 443 ufw allow 5665 ufw reloadWebインタフェースを使ってIcinga2を設定する
Icinga Web 2は、インフラストラクチャの問題を監視したり、ホストやサービスの健全性を確認したりするために使用できるIcinga 2のWebインターフェースです。
Icinga Web 2 インターフェイスにアクセスする前に、ウェブセットアップツールの使用を許可するセットアップトークンを作成する必要があります。これは以下のコマンドで作成できます。
icingacli setup token create以下のような出力が表示されるはずです。
The newly generated setup token is: 4630c2921fca4da8上記のトークンをコピーし、ウェブブラウザを開いてURL http://your-domain.com/icingaweb2 または http://your-server-ip/icingaweb2 を入力すると、以下のようなIcinga web 2のセットアップウィザードにリダイレクトされます。
さて、先ほどコピーしたトークンをSetup Tokenフィールドに貼り付け、Nextボタンをクリックして処理を開始します。
ここでは、有効にしたいモジュールを選択する必要があります。DocとMonitoringモジュールを有効にして、次へボタンをクリックすると、次のようなページが表示されるはずです。
ここで、Icinga2はあなたのシステム要件をチェックします。必要なPHPモジュールがすべてインストールされていることを確認し、「次へ」ボタンをクリックすると、次のようなページが表示されます。
ここでは、Icinga webにアクセスするための認証メカニズムを選択する必要があります。 Authentication Type = Databaseを選択し、Nextボタンをクリックすると、以下のようなページが表示されるはずです。
ここでは、Icinga web 2のデータベース認証情報を入力して、データベース名、ユーザー名、パスワードを入力し、次へボタンをクリックすると、次のページが表示されます。
次に、データベース認証の名前を定義して「次へ」ボタンをクリックすると、以下のようなページが表示されるはずです。
ここで、管理者アカウントのクレデンシャルを入力して、Icinga2のWebインターフェースにログインし、「次へ」ボタンをクリックすると、次のようなページが表示されます。
ここで、Icinga2のアプリケーションとログ情報を提供し、次へボタンをクリックすると、次のページが表示されるはずです。
さて、すべての設定を確認して「次へ」ボタンをクリックすると、次のようなページが表示されるはずです。
ここで、[次へ]ボタンをクリックして設定処理を開始します。
ここでは、Icinga web 2 Backendの名前とBackendの種類を入力し、Nextボタンをクリックすると、次のようなページが表示されるはずです。
ここで、Icinga2 IDOデータベースの認証情報を入力し、「次へ」ボタンをクリックすると、次のようなページが表示されます。
[次へ]ボタンをクリックして、セットアッププロセスを続行します。次のようなページが表示されるはずです。
ここでは、Icinga2が提供するデフォルト値のままで、次へボタンをクリックすると、以下のようなページが表示されるはずです。
ここで、これまでに行ったすべての設定を確認し、「完了」ボタンをクリックしてインストールを完了させます。インストールが正常に設定されると、以下のページが表示されるはずです。
ここで、「Login to icinga web 2」ボタンをクリックすると、以下のようなページが表示されるはずです。
ここで、以前に作成した管理者アカウントの認証情報を入力し、ログインボタンをクリックすると、以下のようなIcinga web 2のダッシュボードが表示されます。
リモートホストの監視のためにIcinga2マスターノードを設定する
これでIcinga web 2の設定が完了したので、Icinga2サーバーノードを設定して監視用のマスターにしましょう。これは以下のコマンドを実行することで行うことができます。
icinga2 node wizardセットアップの過程で、いくつかの質問がありますので、以下に示すようにすべての質問に答えてください。
Welcome to the Icinga 2 Setup Wizard! We'll guide you through all required configuration details. Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]: n Starting the Master setup routine... Please specify the common name (CN) [icingaserver]: Checking for existing certificates for common name 'icingaserver'... Certificates not yet generated. Running 'api setup' now. information/cli: Generating new CA. information/base: Writing private key to '/var/lib/icinga2/ca/ca.key'. information/base: Writing X509 certificate to '/var/lib/icinga2/ca/ca.crt'. information/cli: Generating new CSR in '/etc/icinga2/pki/icingaserver.csr'. information/base: Writing private key to '/etc/icinga2/pki/icingaserver.key'. information/base: Writing certificate signing request to '/etc/icinga2/pki/icingaserver.csr'. information/cli: Signing CSR with CA and writing certificate to '/etc/icinga2/pki/icingaserver.crt'. information/pki: Writing certificate to file '/etc/icinga2/pki/icingaserver.crt'. information/cli: Copying CA certificate to '/etc/icinga2/pki/ca.crt'. Generating master configuration for Icinga 2. information/cli: Adding new ApiUser 'root' in '/etc/icinga2/conf.d/api-users.conf'. information/cli: Enabling the 'api' feature. Enabling feature api. Make sure to restart Icinga 2 for these changes to take effect. information/cli: Dumping config items to file '/etc/icinga2/zones.conf'. information/cli: Created backup file '/etc/icinga2/zones.conf.orig'. Please specify the API bind host/port (optional): Bind Host []: Bind Port []: information/cli: Created backup file '/etc/icinga2/features-available/api.conf.orig'. information/cli: Updating constants.conf. information/cli: Created backup file '/etc/icinga2/constants.conf.orig'. information/cli: Updating constants file '/etc/icinga2/constants.conf'. information/cli: Updating constants file '/etc/icinga2/constants.conf'. information/cli: Updating constants file '/etc/icinga2/constants.conf'. Done. Now restart your Icinga 2 daemon to finish the installation!次に、Icinga2サービスを再起動し、マスターノードの設定を適用します。
systemctl icinga2 restart次に、Icinga 2マスターノードもクライアントから有効なチケットが必要なので、Icinga 2クライアントノード用のチケットを生成する必要があります。
以下のコマンドを使って同じものを生成します。
icinga2 pki ticket --cn 'icingaclient'以下のような出力が表示されるはずです。
582f9fda5c5823440e63ea0f083d105b81237b37監視用のリモートクライアントノードを設定する
始める前に、クライアントノードにIcinga 2とNagiosプラグインをインストールする必要があります。まず、以下のコマンドを使ってIcingaパッケージ署名キーをダウンロードして追加します。
curl -sSL https://packages.icinga.com/icinga.key | sudo apt-key add -次に、APT設定ファイルにIcingaリポジトリを追加します。
nano /etc/apt/sources.listファイルの最後に以下の行を追加します。
deb https://packages.icinga.com/ubuntu icinga-xenial main保存してファイルを閉じ、以下のコマンドでリポジトリを更新します。
apt-get update -yリポジトリが更新されたら、以下のコマンドでIcinga2とNagiosプラグインをインストールします。
apt-get install icinga2 nagios-plugins -y次に、以下のコマンドでIcinga 2サービスを起動し、起動時に起動できるようにします。
systemctl start icinga2 systemctl enable icinga2次に、以下のようにクライアントノード上でIcinga 2ノードウィザードを実行します。
icinga2 node wizard以下のように、すべての質問に答えてください。
Welcome to the Icinga 2 Setup Wizard! We will guide you through all required configuration details. Please specify if this is a satellite/client setup ('n' installs a master setup) [Y/n]: Y Starting the Client/Satellite setup routine... Please specify the common name (CN) [icingaclient]: Please specify the parent endpoint(s) (master or satellite) where this node should connect to: Master/Satellite Common Name (CN from your master/satellite node): icingaserver Do you want to establish a connection to the parent node from this node? [Y/n]: Y Please specify the master/satellite connection information: Master/Satellite endpoint host (IP address or FQDN): 192.168.0.103 Master/Satellite endpoint port [5665]: 5665 Add more master/satellite endpoints? [y/N]: N Parent certificate information: Subject: CN = icingaserver Issuer: CN = Icinga CA Valid From: Dec 29 15:13:35 2017 GMT Valid Until: Dec 25 15:13:35 2032 GMT Fingerprint: 53 5A BC BE 57 D3 1B F7 D0 A4 D7 F2 F4 2A 44 2F 64 53 D7 A0 Is this information correct? [y/N]: y Please specify the request ticket generated on your Icinga 2 master (optional). (Hint: # icinga2 pki ticket --cn 'icingaclient'): 582f9fda5c5823440e63ea0f083d105b81237b37 Please specify the API bind host/port (optional): Bind Host []: Bind Port []: Accept config from parent node? [y/N]: y Accept commands from parent node? [y/N]: y Reconfiguring Icinga... Disabling feature notification. Make sure to restart Icinga 2 for these changes to take effect. Enabling feature api. Make sure to restart Icinga 2 for these changes to take effect. Done. Now restart your Icinga 2 daemon to finish the installation!ここで、すべての設定を適用するために、Icinga2サーバーを再起動します。
systemctl restart icinga2これで、Icinga 2のマスターノードとクライアントノードが接続されました。また、監視したいクライアントを定義するために、Icinga 2のマスターノードにゾーンファイルを設定する必要があります。
マスターノードに戻り、ゾーンディレクトリを作成します。
nano mkdir /etc/icinga2/zones.d/icingaclient次に、以下のコマンドでサービスファイルとホストファイルを作成します。
nano /etc/icinga2/zones.d/icingaclient/service.conf以下の行を追加します。
apply Service "load" { import "generic-service" check_command = "load" command_endpoint = host.vars.client_endpoint assign where host.vars.client_endpoint } apply Service "procs" { import "generic-service" check_command = "procs" command_endpoint = host.vars.client_endpoint assign where host.vars.client_endpoint }保存してからホストファイルを作成します。
nano /etc/icinga2/zones.d/icingaclient/icingaclient.conf以下の行を追加します。
object Zone "icingaclient" { endpoints = [ "icingaclient" ] parent = "icingaserver" } object Endpoint "icingaclient" { host = "192.168.0.104" } object Host "icingaclient" { import "generic-host" address = "192.168.0.104" vars.os = "Linux" vars.notification["mail"] = { groups = [ "icingaadmins" ] } vars.client_endpoint = name }ホスト名とIPアドレスがクライアントノードと一致していることを確認してください。ファイルを保存し、以下のコマンドでIcinga 2サービスを再起動します。
systemctl restart icinga2ここで、Icinga web 2のインターフェイスを開き、Overview > Hostsタブをクリックすると、新しく追加されたクライアントノードが表示されるはずです。
結論
おめでとうございます!これで、Ubuntu 16.04サーバーにIcinga2サーバーとIcinga web 2をインストールして設定することができました。これで、IcingaのWebインターフェースを使って、中央の場所から簡単にインフラ全体を監視することができます。詳細については、https://www.icinga.com/docs/ の Icinga ドキュメントページを参照してください。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-07-10T15:55:57+09:00
DockerでDjangoアプリケーションをデプロイする
Dockerは、コンテナを利用してアプリケーションの作成、デプロイ、実行を容易にする技術です。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
Dockerとは?
Dockerは、コンテナを利用してアプリケーションの作成、デプロイ、実行を容易にする技術です。コンテナを使うことで、開発者はアプリケーションに必要なすべてのコンポーネントをパッケージ化し、後からパッケージとして出荷することができます。また、同じサーバー上でより多くのアプリケーションを稼働させることも可能になります。
Dockerを使えば、コンテナ上で動作しているアプリケーションは互いに隔離されているため、より高いレベルのセキュリティを確保することができます。さらに、Dockerは各コンテナが独自のリソースを持っていることを保証するので、アプリケーションは割り当てられたリソースのみを使用することになります。
前提条件
このガイドを開始する前に、以下のものが必要です。
- Alibaba Cloud ECS Linuxインスタンス。まだLinuxインスタンスをセットアップしていない場合は、この記事で様々なセットアップ方法を紹介します。
- Docker
- Python 2.7
Dockerのインストール
ssh コマンドを使ってサーバにログインします。
$ ssh root@47.88.220.88
Ubuntuのパッケージを更新します。
$ sudo apt-get update
以下のコマンドで最新版のDockerをインストールします。
$ sudo apt-get install docker
Dockerが正しくインストールされていることを確認するには、以下のコマンドを実行します。
$ sudo docker run hello-world
正しく実行すれば、上記のコマンドでインスタンスがテストイメージをダウンロードしてコンテナ内で実行できるようになるはずです。
Dockerでのコンテナとイメージ
Alibaba Cloud ECSインスタンスでは、イメージを使用して同じ構成のECSクラスタを作成することができます。同様に、Dockerコンテナにもイメージがあります。概念的には、両者は非常に似ています。Dockerの公式ドキュメントに基づいています。
コンテナイメージは、軽量でスタンドアロンの実行可能なソフトウェアのパッケージであり、それを実行するために必要なすべてのものが含まれています: コード、ランタイム、システムツール、システムライブラリ、設定。
実行中のコンテナは、
$ sudo docker ps
を実行することで見ることができます。一方、イメージとは、コンテナのスナップショットのような不活性で不変なファイルのことです。イメージは build コマンドで作成され、run コマンドで起動するとコンテナを生成します。
イメージは
$ sudo docker images
を実行することで見ることができます。Djangoアプリケーションを構築する
まずはDjangoをインストールしてDjangoアプリケーションを作成してみましょう。
$ sudo pip install django==1.9 $ django-admin startproject djangoapp要件ファイル
djangoapp ディレクトリ内に要件ファイルを作成し、アプリケーションが必要とする依存関係を定義します。
$ cd djangoapp $ nano requirements.txt以下の依存関係を追加します。
#requirements.txt Django==1.9 gunicorn==19.6.0Dockerファイルの作成
Dockerには、Dockerファイルから命令を読み込んで自動的にイメージを構築する機能があります。Dockerファイルには、Dockerがイメージを構築するために使用するすべてのコマンドと命令が含まれています。
Dockerfileで使用される基本的なコマンドをいくつか定義してみましょう。
- FROM - 新しいビルドステージを初期化し、その後の命令のためのベースイメージを設定します。そのため、有効なDockerfileはFROM命令で始まらなければなりません。
- RUN - 指定されたコマンドを実行します。
- ADD - コンテナにファイルをコピーします。
- EXPOSE - 実行時にコンテナが指定されたネットワークポートをリッスンしていることをDockerに通知します。
- CMD - 実行中のコンテナにデフォルトを提供します。 では、Dockerfileというファイルを作成してみましょう。
$ nano Dockerfile
まずはDockerfileに必要なプロパティをすべて定義してみましょう。ベースイメージとメンテナ名を定義します。
# base image FROM python:2.7 # File Author / Maintainer MAINTAINER Esther次に、コンテナ内のアプリケーションフォルダをコピーし、CMDが実行されるディレクトリを定義します。
# Copy the application folder inside the container ADD . /usr/src/app # set the default directory where CMD will execute WORKDIR /usr/src/app最後にデフォルトのコマンドを設定して実行します。
CMD exec gunicorn djangoapp.wsgi:application --bind 0.0.0.0:8000 --workers 3
最終的なDockerfileは以下のようになるはずです。
# set the base image FROM python:2.7 # File Author / Maintainer MAINTAINER Esther #add project files to the usr/src/app folder ADD . /usr/src/app #set directoty where CMD will execute WORKDIR /usr/src/app COPY requirements.txt ./ # Get pip to download and install requirements: RUN pip install --no-cache-dir -r requirements.txt # Expose ports EXPOSE 8000 # default command to execute CMD exec gunicorn djangoapp.wsgi:application --bind 0.0.0.0:8000 --workers 3Dockerイメージの構築
以下のコマンドを実行して、dockerイメージを構築します。
$ sudo docker build -t django_application_image . Sending build context to Docker daemon 12.8kB Step 1/7 : FROM python:2.7 ---> 2863c80c418c Step 2/7 : ADD . /usr/src/app ---> 09b03ff8466e Step 3/7 : WORKDIR /usr/src/app Removing intermediate container a71a3bf6af90 ---> 3186c92adc85 Step 4/7 : COPY requirements.txt ./ ---> 701c0be5e039 Step 5/7 : RUN pip install --no-cache-dir -r requirements.txt ---> Running in ed034f98db74 Collecting Django==1.9 (from -r requirements.txt (line 1)) Downloading Django-1.9-py2.py3-none-any.whl (6.6MB) Collecting gunicorn==19.6.0 (from -r requirements.txt (line 2)) Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB) Installing collected packages: Django, gunicorn Successfully installed Django-1.9 gunicorn-19.6.0 Removing intermediate container ed034f98db74 ---> 1ffd08204a07 Step 6/7 : EXPOSE 8000 ---> Running in 987b48e1a4ef Removing intermediate container 987b48e1a4ef ---> ef889d6e8fcb Step 7/7 : CMD exec gunicorn djangoapp.wsgi:application --bind 0.0.0.0:8000 --workers 3 ---> Running in 4d929e361d0f Removing intermediate container 4d929e361d0f ---> c6baca437c64 Successfully built c6baca437c64 Successfully tagged django_application_image:latest構築されたイメージは、マシンのローカルのDockerイメージレジストリにあります。イメージを確認するには、
$ sudo docker images
を実行します。REPOSITORY TAG IMAGE ID CREATED SIZE django_application_image latest c6baca437c64 34 minutes ago 702MBアプリを実行する
$ sudo docker run -p 8000:8000 -i -t django_application_image [2018-03-25 12:29:08 +0000] [1] [INFO] Starting gunicorn 19.6.0 [2018-03-25 12:29:08 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 [2018-03-25 12:29:08 +0000] [1] [INFO] Using worker: sync [2018-03-25 12:29:08 +0000] [8] [INFO] Booting worker with pid: 8 [2018-03-25 12:29:08 +0000] [9] [INFO] Booting worker with pid: 9 [2018-03-25 12:29:08 +0000] [10] [INFO] Booting worker with pid: 10gunicorn がアプリにサービスを提供しているというメッセージがhttp://0.0.0.0:8000に表示されます。 サーバーの IP (ip_address:8000) に移動し、Django のウェルカムページが表示されるはずです。
実行中のコンテナを見るには
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 100695b41a0a django_application_image "/bin/sh -c 'exec gu…" 13 seconds ago Exited (0) 4 seconds ago hopeful_easley結論
Dockerを使っていると、時としていくつかの問題に直面することがあります。エラーが発生したときに最初にすべきことは、Dockerのログファイルをチェックすることです。
Dockerやその他のコンテナは、アプリケーション開発のための従来の仮想マシンの強力な代替手段です。Alibaba Cloud上でコンテナを実行する方法の詳細については、コンテナサービスのページをご覧ください。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-07-10T15:43:56+09:00
【Rails6】hamlを導入したらmissing a templateエラーが発生したときの対処法【超簡単】
hamlのメリット
- 閉じタグや
<% end %>
が必要なくなり、簡潔にかける。- インデントがきちっとしていないとエラーになるので嫌でも綺麗にかける。
上記のメリットに加えて、現場でも使われる機会が多いので、勉強がてらRailsにhamlを導入してみました。
そのときmissing a template
というエラーが発生し少し困ったのでここへメモとして残しておきます。
このページを見ているということは既にhamlを導入済身の方が多いと思うので一番下の解決方法へ飛んでください。
そうでない方のためにも、hamlの導入方法についても解説します。(環境)
- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.6
- nginx:1.15.8
hamlの導入方法
1.Gemを追記
Gemfilegem 'haml-rails'2.いつものやつ
$ docker-compose exec サービス名 bundle開発環境にDockerを使っているので
docker-compose exec サービス名
を付けてます。
これでhamlの導入は完了です。erbファイルをhamlに変換
$ docker-compose exec サービス名 rails haml:erb2hamlたったこれだけでerbファイルをhamlへ変換してくれます。
missing a templateエラーが発生
ActionController::UnknownFormat (PostsController#index is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.)localhostにアクセスしたら上記のようなエラーが出てviewが表示されなくなりました。
解決方法
解決方法はサーバーを再起動するだけ。(
rails s
)
僕の場合は開発環境にdockerを使っていたのでコンテナを再起動しました。$ docker-compose restartこれで解決すると思います。
視野が狭くなると再起動するという発想すらでなくなり迷宮入りしかけました。
エラーが起きた時は視野を広く持てるように気を付けたいです。
- 投稿日:2020-07-10T09:55:19+09:00
dockerで共有ボリュームを試してみる
複数のコンテナ間でストレージを共有したい、ということで
こちらのサイトを参考に試してみる。やること
share、mainという2つのコンテナを作成。
コンテナ起動時にそれぞれ以下のようにボリュームオプションを指定
share: -v /data/vol0001 ※共有ディレクトリ作成
main : --volumes-from share ※shareのボリュームオプションを引き継ぐ起動したら共有ボリュームにファイルを作成し
それぞれのコンテナからきちんと見えることを確認する。shareコンテナ起動
shareコンテナ起動$ docker container run -it -d -v /data/vol0001 --name share registry.access.redhat.com/ubi7/ubi:latest /bin/bash c72dff13bff397a38c70d3b45ba022ffb3f808b9124296971568396e8ec4d1e6 $ $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c72dff13bff3 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 10 seconds ago Up 9 seconds share $mainコンテナ起動
mainコンテナ起動$ docker container run -it -d --volumes-from share --name main registry.access.redhat.com/ubi7/ubi:latest /bin/bash e942908dca92c1a2f76d78bb256d4403442b5e89cd86e45a1feb7dcb957bafa6 $ $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e942908dca92 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 3 seconds ago Up 2 seconds main c72dff13bff3 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 2 minutes ago Up 2 minutes share $shareコンテナに入り、共有ボリュームにファイルを作成
shareコンテナ側からファイル作成$ docker container exec -it share /bin/bash # # cd /data/vol0001 # echo "this is share" > test.txt # cat test.txt this is share # exit exit $mainコンテナに入り、共有ボリュームを確認し追記
mainコンテナ側から追記$ docker container exec -it main /bin/bash # cd /data/vol0001 # ls -l total 4 -rw-r--r-- 1 root root 14 Jun 28 12:44 test.txt # # cat test.txt this is share # # echo "this is main" >> test.txt # # cat test.txt this is share this is main # # exit exit $shareコンテナで追記内容を確認
shareコンテナ側で確認$ docker container exec share cat /data/vol0001/test.txt this is share this is main $shareコンテナを停止してもmainから共有ボリュームが見れるか
shareコンテナ停止$ docker container stop share share $ $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e942908dca92 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 13 minutes ago Up 8 minutes main c72dff13bff3 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 15 minutes ago Exited (137) 13 seconds ago share $ $ docker container exec main cat /data/vol0001/test.txt this is share this is main $問題なく見える
shareコンテナを削除してもmainから共有ボリュームが見れるか
shareコンテナ削除$ docker container rm share share $ $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e942908dca92 registry.access.redhat.com/ubi7/ubi:latest "/bin/bash" 14 minutes ago Up 9 minutes main $ $ docker container exec main cat /data/vol0001/test.txt this is share this is main $問題なく見える
後片付け
後片付け$ docker container rm -f main main $ $ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $気になったことを調べてみる
run時に -v /data/vol0001 でdockerボリュームを作成したが
このボリュームはどこに存在するのか。下記サイトのおかげで疑問は解消。
https://karuta-kayituka.hatenablog.com/entry/2019/05/04/114056ファイル内のVOLUMEが指すものは、どこに存在するものなのか?(ホストのどこか?)
⇒ホストに存在するが特定のディレクトリと共有してるわけではなく、
docker volumeとして作成された新たなボリュームを指しているdocker runのvオプションとはVOLUMEは別物なのか?
⇒同じである。 名前付きかどうかという違いがあるぐらいだまた、共有ボリュームは docker volume ls で確認できるが
名前がハッシュ値になっているためどれがどれだか分からなかった。
これはdocker volume createで事前にボリュームを作成せず
docker run -vで自動で新規作成してしまったため(自動作成だと名前がハッシュになる)。docker volume create v1
のように明示的に名前を指定してボリュームを作成し
docker container run -v v1:/data/vol0001 …
のようにコンテナ起動するべきだった。ということで、きちんと後片付けしたつもりだったが
共有ボリュームが残っていることが分かったので docker volume で削除。共有ボリューム削除$ docker volume rm 5e123abdf19ececb4e3791aeedafc2d7bc8c50bfaeccbdf8f4c1df7b99d4a019 5e123abdf19ececb4e3791aeedafc2d7bc8c50bfaeccbdf8f4c1df7b99d4a019 $ $ docker volume ls DRIVER VOLUME NAME $個人メモ
dockerボリュームはホスト上に存在するので
fargateだと同じことはできなそう。そのためのEFSのはず。
- 投稿日:2020-07-10T09:26:01+09:00
USBカメラをDockerから使いたい
概要
UVC対応のUSBカメラ(BUFFALO BSW200MBK)をDockerから使おうとしてつまずいたので、試したことをまとめます。
本記事ではROSを利用していますが、ROS側の問題では無いはずです。ホスト
- HP Spectre x360 2019年モデル
- intel i7-1065G7
- intel CPU内蔵グラフィック
- Ubuntu 18.04
- Docker version 19.03.12, build 48a66213fe
- 一般ユーザーは
sudo gpasswd -a $USER docker
として、sudo
なしで起動できるように設定済み試したこと
次のようなDockerfileを作成して、
FROM ubuntu:16.04 # 中略 ROS kinetic のインストール RUN apt-get update && apt-get install -y \ ros-kinetic-uvc-camera RUN useradd -m -d /home/myubuntu16 myubuntu16 -p $(perl -e 'print crypt("myubuntu16", "salt"),"\n"') && \ echo "myubuntu16 ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers RUN \ apt-get update && \ apt-get -y install libgl1-mesa-glx libgl1-mesa-dri && \ rm -rf /var/lib/apt/lists/* ENV QT_X11_NO_MITSHM 1 ENV USER myubuntu16 USER myubuntu16 CMD ["bash"]次のコマンドでコンテナを起動しました。
docker build -t myubuntu:16 . docker run -it \ --name myubuntu_test \ --volume=/tmp/.X11-unix:/tmp/.X11-unix \ --volume=$(pwd)/myubuntu16:/home/myubuntu16 \ --device=/dev/dri:/dev/dri \ --device=/dev/video0:/dev/video0 \ --env="DISPLAY=$DISPLAY" \ myubuntu:16立ち上がったコンテナで
roscore
を起動して、別のターミナルから同じコンテナに入って、カメラを起動するノードを立ち上げたところでエラーが発生。# ターミナル2 $ docker exec -it myubuntu_test bash $ rosrun uvc_camera uvc_camera_node [ INFO] [1594303093.006722031]: using default calibration URL [ INFO] [1594303093.006790555]: camera calibration URL: file:///home/myubuntu16/.ros/camera_info/camera.yaml [ INFO] [1594303093.006832237]: Unable to open camera calibration file [/home/myubuntu16/.ros/camera_info/camera.yaml] [ WARN] [1594303093.006850909]: Camera calibration file /home/myubuntu16/.ros/camera_info/camera.yaml not found. opening /dev/video0 terminate called after throwing an instance of 'std::runtime_error' what(): couldn't open /dev/video0 Abortedcouldn't open /dev/video0と出たので、カメラの状態を取得するツール(?)を実行
$ sudo apt install v4l-utils $ v4l2-ctl --list-device Failed to open /dev/video0: Permission denied権限を確認して、変更してみると
Permission denied
は解消された。$ ls -la /dev/video* crw-rw---- 1 root video 81, 0 Jul 9 13:48 /dev/video0 $ sudo chmod 777 /dev/video0 $ v4l2-ctl --list-device USB_Camera: USB_Camera (usb-0000:00:14.0-1): /dev/video0ふたたび、同じコンテナ内の3個のターミナルで以下をそれぞれ実行
$ roscore $ rosrun uvc_camera uvc_camera_node $ rosrun image_view image_view image:=/image_raw動いた
- 投稿日:2020-07-10T08:17:43+09:00
プログラムの怖いところ ライブラリのバージョンアップ
はじめに
本記事はライブラリのバージョンアップが原因でプログラムが動かなくなり、どの様に原因を調査して解決まで行き着いたかについて、システム開発の一助となるストーリーをご紹介します。
概要
とあるtoCのシステムにおけるバックエンドのプログラム(API)で軽微な修正を行い、デプロイしたときの話になります。
本番環境と開発環境が存在し、開発環境でテストした上で本番環境でリリース作業を実施。本番環境でデプロイ後、システムの一部機能で正常性が確認できない事態が発生しました。
バックエンドはDockerで開発を行っているため、デプロイ時に
docker compose build
でビルドを毎回行っています。デプロイ自体は成功しているため、ライブラリのバージョンアップが関係しているのではないかと予想していましたが、のちに調査が難航することになるとは、このときは予想していませんでした。。当該事象発生時は原因究明に至らなかったため、切り戻しを実施し、リリース作業は中断。翌日に原因調査を行いました。
原因調査
前提として本番環境と開発環境で使用していたソースは、一部機能をマージしてないなど環境差異は発生していましたが今回発生した事象に関係はありません。
調査を開始し、開発環境で事象を再現させるために確認を行いましたが、同様の事象は発生しませんでした。その後、本番環境で使用したソースを開発環境でデプロイすると事象が再現しました。
開発環境で事象再現後、デバッグするために本番環境で使用したソースの不具合が発生している箇所に
console.log(e)
でログ出力する様にしてデバッグを行いました。不具合が発生している箇所に対するAPIのリクエストを実行し、サーバ側のログを確認すると、データベースのあるテーブルのカラムが見つからないと言うエラーメッセージが出力されていました。
仮説としてプログラムで利用していたORMライブラリのバージョンが上がったため、今まで許容していたデータベースに対する接続がエラーになっているのではないかという考えに辿りつきました。
解決方法
本番環境で稼働中のコンテナで生成された
yarn.lock
ファイルと、開発環境でデプロイしたコンテナのyarn.lock
ファイルのORMライブラリのバージョンを比較すると、開発環境のコンテナのマイナーバージョンが1桁だけ上がっていることを確認しました。検証として
package-lock.json
のORMライブラリのバージョンを、本番環境で稼働中のコンテナで生成されたバージョンと同じバージョンに固定すると、事象が再現しないことが確認できました。よって暫定対応としては、ORMのライブラリのバージョンを固定しないことで一旦は解決しましたが、今後の運用として色々と課題を認識しました。
DevOps
DevOps観点で感じた課題について以下に記載します。
※本記事の内容は、あくまで考え方の一例であり、必ずしも全ての考え方がシステムに適合したり、ここに書いている内容で満たされている訳ではありません。
ライブラリのバージョン固定
保守性を高める場合はライブラリのバージョンを上げないように固定することが望ましいですが、セキュリティとトレードオフになります。また、バージョンアップする場合は確認の工数もかかります。npm outdated
コマンドを実行すると、現在インストールされているバージョン、現在のバージョン指定でインストールされる最新バージョン、リリースされている最新バージョンが表示されます。テストの再現性
当たり前ですが極力環境差異をなくしたテスト方法の考案及びテスト環境を構築し、テストを実施することが望ましいです。※参考:3.6 本番環境とテスト環境の差異に関する教訓(T6)本質的なアプローチ
今回の様な事象は技術的な手段で解決する以前に、開発や運用ポリシー等を定義していればこの様なリスクを軽減する可能性は上がります。おわりに
本事象を通して改めて学んだのは、プログラムは数字1桁が変わるだけで動かなくなるという恐ろしさと、DevOpsの重要性です。
DevOpsは文化です。DevOpsは人が作る必要があるため、言うだけは簡単ですがシステムのあるべき姿を計画し、実行して継続することは大変です。
この失敗を次に生かしてシステム開発のライフサイクルを短縮し、ソフトウェア品質の高い継続的デリバリーを実現していきたいと思いました。
- 投稿日:2020-07-10T05:43:25+09:00
ログファイルからをバッチ処理を行う旧世代アプリケーションをサイドカーパターンとService Discoveryを使ってコンテナ内ロギングをする
概要
Dockerコンテナでアプリケーション構築するメリットは皆さんご周知ではあると思いますが、EC2でアプリケーションを公開していてECSなどのコンテナ基盤に乗り換えた時に、EBSやEFS等のlinuxファイルシステムに依存している部分をコンテナ上でどうするかという問題に直面します。
今回はその問題のうち、アクセスログファイル等を集計してDBに入れたいというありがちな問題をService DiscoveryとFluentdコンテナのサイドカーパターンで解決する手法を実践します。
そもそもなぜコンテナ内のファイルシステムに保持してはいけないか
Dockerfile が定義するイメージによって生成されるコンテナは、できる限り "はかないもの"(ephemeral)と考えておくべきです。 "はかない" という語を使うのは、コンテナが停止、破棄されて、すぐに新たなものが作り出されるからです。 最小限の構成や設定があれば稼動できます。
とあり、更にGCPのコンテナ運用のベストプラクティスによると、
初めてコンテナを試している場合、従来のサーバーのようにコンテナを扱わないでください。たとえば、実行中のコンテナ内でアプリケーションを更新したり、脆弱性が発生したときに実行中のコンテナにパッチを適用したりしたくなるかもしれません。
コンテナは基本的に、このような処理に対応するように設計されていません。コンテナは、ステートレスかつ不変になるように設計されています。
コンテナは基本的に、このような処理に対応するように設計されていません。コンテナは、ステートレスかつ不変になるように設計されています。
とあり、コンテナ内では状態を持たない = ステートレス であることがかなり推奨されています。
コンテナ内で作られたファイルをコンテナ内で持ってしまうと、コンテナが破棄され次世代のコンテナが立ち上がった際に生成したファイルが無いので実質欠損するという事態が起こりえます。
これを回避するためにデータストアに格納することが推奨されていますが、今回はDockerの永続化Volumeを使ってデータを退避させます。コンテナ基盤を使って運用するときの普通のロギング
ECS、kubernetesなどのコンテナ基盤を使う場合、Dockerの標準ログドライバーを使うことが推奨されています。
主に、docker logs
やkubectl logs
で見れる標準出力のログをどこかに集約させるという手法です。
大体各種クラウドにはコンテナ基盤に付随してロギングを集約させるマネージドサービスが搭載されていると思うのでそれを使ってデータストアに入れるパターが王道だと思います。
ただ、これらはアプリケーション側でログ出力の整備を行わなければ成立しません。今回はその整備にコストがかかる場合、既存のロギングシステムを残しつつ、コンテナ環境でどう再現するかの手法です。構成図
コンポーネント
- ECS
- サービス検出(Service Discovery)
- nginx, app, batch
- Fluentd公式イメージ
- RDBやその他データストア
App Serviceの構築
メインのアプリケーションコンテナは複数コンテナ存在し、Fluentdのログコンテナは単一コンテナとしてログを集約させます。
App Serviceは通常通りnginx containerからunix socketsを介してapp containerに接続します。これに関してはこちらの記事を参照して構築していきます。
https://qiita.com/na-o-ys/items/1a863419e1f6c3063ace
App Serviceに関してはもう構築できている前提で話を進めていきます。Log Serviceの構築
Log Serviceですがこちらは別サービスになっているのでscalingはせず、単一サービスとして構築します。
まず、Log Service用のタスクはport mappingは指定せず、Dockerfileでコンテナ側でのみportを開いてください。"portMappings": [], "networkMode": "awsvpc",単一サービスですのでタスクの数は1、最小ヘルス率は0、最大率は100としてタスクの重複を許さないようにします。
それと、今回はタスクのnetworkmodeはawsvpc
に設定してください。続いてサービス検出の設定ですが、名前空間名は好みで変えても良いですが、慣習として
xxx.local
xxx.internal
という名前空間が使われやすいです。
サービスの検出名も好みで良いですが、分かりやすくfluentdのコンテナ名にします。
private DNSレコードは今回はAレコードを作成してください。
注意点としてタスクのnetworkmodeがawsvpc
じゃない場合Aレコードが作成できないと思います。
代替としてSRVレコードが用意されていますがこちらは動的ポートマッピングを使用する為、既存のログプラグインで対応できない可能性があります。
awsvpc
はENIをアタッチされてるのでAレコードからportを指定して接続ができるようになります。
ENIをアタッチする関係上インスタンスを制限されるデメリットもありますが、ネットワークパフォーマンスの観点からもECS全体でawsvpc
が推奨されます。以上でサービスを構築するとService Discoveryによるprivate DNSでのコンテナアクセスが可能になります。
タスク上でport mappingせずともdnsとportを指定して通信ができるようになったかと思います
root@21454022290b:/# dig fluentd.local ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.amzn2.0.4 <<>> fluentd.local ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;fluentd.local. IN A ;; ANSWER SECTION: fluentd.local. 10 IN A 172.31.0.54 ;; Query time: 1 msec ;; SERVER: 172.31.0.2#53(172.31.0.2) ;; WHEN: 木 7月 09 20:15:59 UTC 2020 ;; MSG SIZE rcvd: 60ログプラグインでもportを指定して接続ができるようになっているかと思います。
host: fluentd.local port: 24224これでログ集約サーバーの出来上がりです。
サイドカーパターンでログファイルを処理する
fluentdにより生成されたログファイルを用いてbatch containerで処理したい場合、サイドカーパターンでvolumeを共有して永続化する必要があります。
まずfluentdのDockerfileでvolumeのpathを指定してあげます。
VOLUME /fluentd/log/xxx注意点はコンテナ内の実行ユーザーによってはvolumeディレクトリに書き込めない場合があるので、適宜書き込み権限を追加してください。
続いて、batchをサイドカーパターンでvolume共有したタスクを用意します。
[ { "name": "fluentd", "image": "xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx-fluentd:e6767fd9", "cpu": 400, "memoryReservation": 400, "essential": true }, { "name": "batch", "image": "xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx-batch:e6767fd9", "cpu": 400, "memoryReservation": 400, "essential": true, "volumesFrom": [ { "readOnly": false, "sourceContainer": "fluentd" } ], "dependsOn": [ { "containerName": "fluentd", "condition": "START" } ] } ]ポイントは
volumesFrom
を指定してあげて書き込み処理をしたい場合はreadOnly: false
にすることです。
念のため、もしfluentd containerの起動が遅れた状態でにバッチ処理が走らないようにdependsOn
で起動を待つ指定もしておきます。
また、batchコンテナ内のユーザーにも書き込み権限を追加するようにしてください。今回自分が実践したbatchはcronで回すタイプだったので
cron -f
で定期実行していますが、何かしらのトリガーで無事ログファイルのbatch処理が正常に走れば完成です。
- 投稿日:2020-07-10T04:35:45+09:00
docker-compose.ymlのbuild設定はとりあえずcontextもdockerfileも埋めとけって話
docker-composeを使った開発では以下の2つのディレクトリ構成になっていることが多いです。
サービスディレクトリ直下にDockerfile. ├ app │ ├ Dockerfile │ └ ...その他ファイル群 ├ api │ ├ Dockerfile │ └ ...その他ファイル群 ├ nginx │ ├ Dockerfile │ └ ...その他ファイル群 └ docker-compose.ymldockerディレクトリ下にサービス毎にDockerfile. ├ app/ ├ api/ ├ nginx/ ├ docker │ ├ app │ │ └ Dockerfile │ ├ api │ │ └ Dockerfile │ └ nginx │ └ Dockerfile └ docker-compose.ymlDockerの コンテキスト という概念を知っていないと、ディレクトリ構成が違うだけで何度もコンテキスト周りのエラーで悩まされることがあります(1敗)。
なので自分的結論を出してみました。TL;DR
docker-compose を使った開発では
docker-compose.ymlversion: "3" services: nginx: build: ./docker/nginx/のようにDockerfileがあるディレクトリを指定するだけでなく
docker-compose.ymlservices: nginx: build: context: . dockerfile: ./docker/nginx/Dockerfileのようにコンテキストをルートディレクトリに指定して、Dockerfileの場所も直接指定しておけばおk
Dockerの「コンテキスト」とは?
docker build コマンドを実行したときの、カレントなワーキングディレクトリのことを ビルドコンテキスト(build context)と呼びます。 デフォルトで Dockerfile は、カレントなワーキングディレクトリにあるものとみなされます。 ただしファイルフラグ(-f)を使って別のディレクトリとすることもできます。 Dockerfile が実際にどこにあったとしても、カレントディレクトリ配下にあるファイルやディレクトリの内容がすべて、ビルドコンテキストとして Docker デーモンに送られることになります。
これをさらに要約すれば 「docker buildコマンドを実行した場所」ってことですね。
docker build
コマンドを実行した場所ってことなので、docker build
コマンドはDockerfileがあるディレクトリで実行すれば問題なさそうですね。しかし、
docker-compose
コマンドを使って開発している場合はどうでしょうか?
Dockerfileがあるディレクトリでコマンドを実行することってほとんど無いと思います。その場合はコンテキストについてどう考えればいいのでしょうか?サービス直下にDockerfileを置く場合
例として「Laravel, Nginx」というよくあるプロジェクトの構成で考えてみます。
ディレクトリ構成は以下の様になります。. ├ api │ ├ Dockerfile │ ├ app │ ├ bootstrap │ └ ...その他のLaravelファイル ├ nginx │ ├ Dockerfile │ └ default.conf └ docker-compose.ymlこのディレクトリ構成の場合、
api/Dockerfile
とnginx/Dockerfile
のコンテキストはそれぞれどこになるか分かりますか?
docker build
コマンドを実行するapi/
、nginx/
ディレクトリ?
nginx/
ディレクトリがコンテキストだとするとnginx/Dockerfile
は以下のようになります。nginx/DockerfileFROM nginx:1.18-alpine ADD ./default.conf /etc/nginx/conf.d/default.conf RUN mkdir -p /var/www/public ADD ../api/public /var/www/public以下の1文に注目してください。コンテキストが
nginx/
なのに、../api/public
で分かる通り、コンテキストのディレクトリから外れたファイルを参照していますね。nginx/DockerfileADD ../api/public /var/www/publicこのまま実行すると
ERROR: Service 'php' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder115741816/api: no such file or directoryのようなエラーが出ます。
Dockerはコンテキスト(カレントディレクトリ)の外のファイルにはアクセスできない仕様なのです。そこら辺に関しては以下の記事で詳しく説明されています。
https://qiita.com/toshihirock/items/c85f3eb5f4752b15ca3d
ではどうやって
nginx/
のコンテキストからapi/
のファイルにアクセスすればいいのでしょうか?
答えは簡単です。コンテキストをルートディレクトリにすればいいのです
docker-compose.yml
で「コンテキスト」と「Dockerfileのある場所」を直接指定してみましょう。docker-compose.ym;version: "3" services: nginx: build: context: . dockerfile: ./nginx/Dockerfile ports: - 8080:80 depends_on: - php php: build: context: . dockerfile: ./api/Dockerfile ports: - 9000:9000コンテキストはどちらのサービスも
build: context: .で
docker-compose.yml
があるルートディレクトリに設定。Dockerfileの場所は
dockerfile: ./nginx/Dockerfile dockerfile: ./api/Dockerfileでそれぞれ指定。
dockerディレクトリにDockerfileをまとめた場合
では次に
docker
というディレクトリを作って、その中に各サービスのDockerfileをまとめた構成を考えてみます。. ├ api │ └ Laravelのファイル群 ├ nginx │ └ default.conf ├ docker │ ├ php │ │ └ Dockerfile │ └ nginx │ └ Dockerfile └ docker-compose.yml先ほどと同様にコンテキストを
docker/php
やdocker/nginx
と考えた場合、どうやってもうまくいきません。
このディレクトリ構成の場合は、そもそもDockerfileからコンテキスト外のサービスのファイル群が入っているapi/
とnginx/
に一切アクセスできません。ここでも同様
docker-compose.yml
でコンテキストをルートディレクトリに、Dockerfileの位置も直接指定する必要がありそうです。docker-commpose.ymlversion: "3" services: nginx: build: context: . dockerfile: ./docker/nginx/Dockerfile ports: - 8080:80 depends_on: - php php: build: context: . dockerfile: ./docker/api/Dockerfile ports: - 9000:9000注意点
ルートディレクトリをDockerのコンテキストにすることで、Dockerfileはどんなファイルにもアクセスできるようになりました。
一方で、build
時はその分Dockerデーモンという奴にそれだけ多くのファイルを送ることになるので遅くなることがあるようです。
- 投稿日:2020-07-10T01:56:39+09:00
Visual Studio Code で Nuxt.js を使った Docker コンテナ内での開発
はじめに
以前、環境を汚さず(選ばず)Nuxtプロジェクトを作成しGitHub Pagesで公開するまでの一部始終 という記事を書きました。
その後、より簡単にNuxtの開発環境を作れないかと何回かやっているうちに、
Visual Studio Code をうまく使えばよりシンプルにできることがわかってきたので、再度まとめました。
Nuxtのバージョンが上がってプロジェクト作成時の設定が若干変わっています。
事前準備
Docker, Visual Studio Codeをインストールしておきます。
これからインストールする方は以下を参考にしてください。
Windows 10 Home に Docker for Desktop をインストールする手順
Visual Studio Code のインストール手順(Windows)
※今回は Windows 10 Home 環境で作業していますが、Docker, Visual Studio Code が入っていればどのOSでも同じようにできるはずです。
今回の Nuxt.js のバージョンは 2.13.3 です。
Visual Studio Code の起動
Visual Studio Code を起動します。
プロジェクトフォルダの作成
メニュー File / Open Foder... を選択し、プロジェクト用フォルダを作成して開きます。
今回は C:\dev\nuxt_in_docker というフォルダを作成しました。
Welcome ページは不要ですので × ボタンで消します。
Dockerファイルの作成
ファイル作成ボタンを押し、 Dockerfile を作成します。
Dockerfile に以下の内容を入力して保存します。
DockerfileFROM node:alpine ENV CHOKIDAR_USEPOLLING=true NUXT_TELEMETRY_DISABLED=1 RUN apk update && apk add git1行目では、apline OS上に node がインストールされた公式の Docker イメージを使うよう指定しています。
2行目では、Nuxt で開発する際の自動リロードと、統計情報参加の応答を環境変数で指定しています。
3行目では、Docker コンテナ内で Git を使えるようインストールしています。
Remote Development 拡張機能をインストール
Extensions に切り替えて、Remote Development を検索してインストールします。
(インストール済みなら何もしなくてOKです。)
コンテナ開発モードに切り替える
左下の Open a remote window ボタンを押して Remote-Containers: Reopen in Container を選択します。
つづけて、From 'Dockerfile' を選択します。
しばらく待つと左下の表示が に変わります。
これで、Docker コンテナ内で開発する準備が整いました。Vue開発用拡張機能をインストール
devcontainer.json が表示されるので、extentions に Vuter を追加し上書き保存します。
※Vuter は vue ファイルや js ファイル、スタイルシートのコードハイライトや、自動補完、構文チェックを行ってくれる拡張機能です。
devcontainer.json(変更前)"extensions": []devcontainer.json(変更後)"extensions": ["octref.vetur"]
変更を反映させるために、左下の Open a remote window ボタンを押して Remote-Containers: Rebuild Container を選択します。
拡張機能を見ると、vuter がインストールされているのが確認できます。
Nuxtプロジェクト作成
メニュー Terminal / New Terminal を選択します。
Docker コンテナ内でターミナルを開いたことになるので、コマンドプロンプトではなくシェルになります。
ターミナル内で、Nuxtプロジェクトを作成コマンドを実行します。
TERMINALyarn create nuxt-app実行途中で、プロジェクト作成時の各種設定を入力していきます。
プロジェクト名入力? Project name: nuxt_in_dockerプロジェクト名を聞いてきますが、デフォルトでフォルダ名と同じに設定されていてそのままでいいので Enter を押します。
開発言語選択? Programming language: JavaScriptJavaScript か TypeScript を選択できます。今回は JavaScript にしますので、そのまま Enter を押します。
パッケージ管理選択? Package manager: Yarnyarn か npm を選択できます。今回は yarn にしますので、そのまま Enter を押します。
sh:UI フレームワーク選択
? UI framework: (Use arrow keys)
下記11種類から選択できますが、今回は使用しない(None)ので、そのまま Enter を押します。
- Ant Design Vue
- Bootstrap Vue
- Buefy
- Bulma
- Element
- Framevuerk
- iView
- Tachyons
- Tailwind CSS
- Vuesax
- Vuetify.js
導入モジュール選択? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)下記3つを選択できますが、後からでも追加できるので、そのまま Enter を押します。
- ◯ Axios
- ◯ Progressive Web App (PWA)
- ◯ Content
構文チェックツール選択? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)下記4つを選択できますが、Vuter である程度カバーできるので今回はそのまま Enter を押します。
- ◯ ESLint
- ◯ Prettier
- ◯ Lint staged files
- ◯ StyleLint
テストフレームワーク選択? Testing framework: Jest下記3つから選択できます。後からも追加できますが、設定が若干面倒ですので、今回は Jest を入れておきます。
↓キーで Jest を選択して Enter キーを押します。
- Jest
- AVA
- WebdriverIO
レンダリング方式? Rendering mode: Universal (SSR / SSG)Universal (SSR / SSG) か Single Page App (SPA) を選択できます。
今回は最終的に静的な html, js, css を生成するので、 Universal を選びます。そのまま Enter を押します。
※後から設定を変更することも可能です。
デプロイ方式選択? Deployment target: Static (Static/JAMStack hosting)作成したものをどのようにに動作させるかを選択します。
Server (Node.js hosting) は、Node.js のサーバで動作させます。
Static (Static/JAMStack hosting) は、JAM(JavaScript, API, Markup)=通常のWebサーバで動作させます。
今回は Static を選択し、Enter を押します。
開発ツール選択? Development tools: jsconfig.json (Recommended for VS Code)下記2つを選択できます。 Visual Studio Code 用におすすめされているので、
jsconfig.json を選択し、Enter キーを押します。
- ◯ jsconfig.json (Recommended for VS Code)
- ◯ Semantic Pull Requests
作成完了になるまでしばらく待ちましょう。
作成完了? Successfully created project nuxt_in_docker To get started: yarn dev To build & start for production: yarn build yarn start To test: yarn test Done in 186.42s.
Git管理開始
gitを初期化し、ユーザ名とメールアドレスを登録します。
※ユーザ名、メールアドレスは自分のものに置き換えて入力してください。TERMINALgit init git config user.name ユーザ名 git config user.email メールアドレス
初回コミット
Source Control に切り替えて、コミットします。
コミットコメント欄に first と入力し、コミットボタンを押します。ステージングに入れてないと確認が出ますが、全ファイルをコミットするのでYesを選択します。
以下の表示が出る場合は、ユーザ名、メールアドレスが正しく登録されていませんので、再度登録コマンドを実行してください。
開発サーバを起動
開発サーバを起動します。
Exploer に切り替え、下のほうにある NPM SCRIPTS を開き、dev の右側の三角ボタンを押します。
しばらく待つと、 Listening on: http://localhost:3000/ と表示されます。
これで開発サーバが起動しました。ポート設定
ブラウザで表示できるようにするために、Docker 内のポートとローカルポートを接続します。
3000番ポートが表示されているので、右の追加ボタンを押します。
以下の画面が出た場合は「アクセスを許可する」ボタンを押します。
これで Docker 内の 3000 番ポートと、ローカルの 3000 番ポートが接続され、
ブラウザで動作確認ができます。
ブラウザで画面を確認
タイトルを変更
pages/index.vue を開きます。
nuxt_in_docker の文字を Nuxtはじめました に書き換えて上書き保存します。
保存するとブラウザの表示が自動的に切り替わります。
テストを実行
NPM SCRIPTS 内の test の右の三角ボンタンを押します。
テストを追加
index.vue のテストを追加してみます。
test/Logo.spec.js をCtrlドラッグでコピーします。
Logo の部分を index に書き換えて上書き保存します。
再度テストを実行します。
すると以下のように Logo コンポーネントが正しく登録されていないと出ます。
警告が出ないうように修正
警告を消すために、index.vue の <script>タグ内を記述します。
変更前<script> export default {} </script>変更後<script> import Logo from "@/components/Logo.vue"; export default { components: { Logo } }; </script>再度テストを実行します。
警告が消えてきれいに実行できました。
- 投稿日:2020-07-10T01:56:39+09:00
VisualStudioCodeでNuxt.jsを使ったDockerコンテナ内での開発
はじめに
以前、環境を汚さず(選ばず)Nuxtプロジェクトを作成しGitHub Pagesで公開するまでの一部始終 という記事を書きました。
その後、より簡単にNuxtの開発環境を作れないかと何回かやっているうちに、
VisualStudioCodeをうまく使えばよりシンプルにできることがわかってきたので、再度まとめました。
Nuxtのバージョンが上がってプロジェクト作成時の設定が若干変わっています。事前準備
Docker, Visual Studio Codeをインストールしておきます。
これからインストールする方は以下を参考にしてください。
Windows 10 Home に Docker for Desktop をインストールする手順
VisualStudioCodeのインストール手順(Windows)
※今回は Windows 10 Home 環境で作業していますが、Docker, VisualStudioCode が入っていればどのOSでも同じようにできるはずです。
今回の Nuxt.js のバージョンは 2.13.3 です。
VisualStudioCodeを起動します。
メニュー File / Open Foder... を選択し、プロジェクト用フォルダを作成して開きます。
今回は C:\dev\nuxt_in_docker というフォルダを作成しました。
Welcome ページは不要ですので × ボタンで消します。
ファイル作成ボタンを押し、 Dockerfile を作成します。
Dockerfile に以下の内容を入力して保存します。
FROM node:alpine ENV CHOKIDAR_USEPOLLING=true NUXT_TELEMETRY_DISABLED=1 RUN apk update && apk add git1行目では、apline OS上に node がインストールされた公式の Docker イメージを使うよう指定しています。
2行目では、Nuxt で開発する際の自動リロードと、統計情報参加の応答を環境変数で指定しています。
3行目では、Docker コンテナ内で Git を使えるようインストールしています。Extensions に切り替えて、Remote Development を検索してインストールします。
(インストール済みなら何もしなくてOKです。)
左下の Open a remote window ボタンを押して Reopen in Container を選択します。
つづけて、From Dockerfile を選択します。
しばらく待つと左下の表示が に変わります。
これで、Dockerコンテナ内で開発する準備が整いました。devcontainer.json が表示されるので、extentions に vuter を追加し上書き保存します。
※Vuter は vue ファイルや js ファイル、スタイルシートのコードハイライトや、自動補完、構文チェックを行ってくれる拡張機能です。
変更前"extensions": []変更後"extensions": ["octref.vetur"]変更を反映させるために、左下の Open a remote window ボタンを押して Rebuild Container を選択します。
拡張機能を見ると、vuter がインストールされているのが確認できます。
メニュー Terminal / New Terminal を選択します。
Docker コンテナ内でターミナルを開いたことになるので、コマンドプロンプトではなくシェルになります。
ターミナル内で、Nuxtプロジェクトを作成コマンドを実行します。
yarn create nuxt-app実行途中で、プロジェクト作成時の各種設定を入力していきます。
プロジェクト名入力? Project name: nuxt_in_dockerプロジェクト名を聞いてきますが、デフォルトでフォルダ名と同じに設定されていてそのままでいいので Enter を押します。
開発言語選択? Programming language: JavaScriptJavaScript か TypeScript を選択できます。今回は JavaScript にしますので、そのまま Enter を押します。
パッケージ管理選択? Package manager: Yarnyarn か npm を選択できます。今回は yarn にしますので、そのまま Enter を押します。
:UI フレームワーク選択
? UI framework: (Use arrow keys)
下記11種類から選択できますが、今回は使用しない(None)ので、そのまま Enter を押します。
- Ant Design Vue
- Bootstrap Vue
- Buefy
- Bulma
- Element
- Framevuerk
- iView
- Tachyons
- Tailwind CSS
- Vuesax
- Vuetify.js
導入モジュール選択? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)下記3つを選択できますが、後からでも追加できるので、そのまま Enter を押します。
- ◯ Axios
- ◯ Progressive Web App (PWA)
- ◯ Content
構文チェックツール選択? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)下記4つを選択できますが、Vuter である程度カバーできるので今回はそのまま Enter を押します。
- ◯ ESLint
- ◯ Prettier
- ◯ Lint staged files
- ◯ StyleLint
テストフレームワーク選択? Testing framework: Jest下記3つから選択できます。後からも追加できますが、設定が若干面倒ですので、今回は Jest を入れておきます。
↓キーで Jest を選択して Enter キーを押します。
- Jest
- AVA
- WebdriverIO
レンダリング方式? Rendering mode: Universal (SSR / SSG)Universal (SSR / SSG) か Single Page App (SPA) を選択できます。
今回は最終的に静的な html, js, css を生成するので、 Universal を選びます。そのまま Enter を押します。
※後から設定を変更することも可能です。
デプロイ方式選択? Deployment target: Static (Static/JAMStack hosting)作成したものをどのようにに動作させるかを選択します。
Server (Node.js hosting) は、Node.js のサーバで動作させます。
Static (Static/JAMStack hosting) は、JAM(JavaScript, API, Markup)=通常のWebサーバで動作させます。
今回は Static を選択し、Enter を押します。
開発ツール選択? Development tools: jsconfig.json (Recommended for VS Code)下記2つを選択できます。 Visual Studio Code 用におすすめされているので、
jsconfig.json を選択し、Enter キーを押します。
- ◯ jsconfig.json (Recommended for VS Code)
- ◯ Semantic Pull Requests
作成完了になるまでしばらく待ちましょう。
作成完了? Successfully created project nuxt_in_docker To get started: yarn dev To build & start for production: yarn build yarn start To test: yarn test Done in 186.42s.
gitを初期化し、ユーザ名とメールアドレスを登録します。
※ユーザ名、メールアドレスは自分のものに置き換えて入力してください。
git init git config user.name ユーザ名 git config user.email メールアドレスSource Control に切り替えて、コミットします。
コミットコメント欄に first と入力し、コミットボタンを押します。ステージングに入れてないと確認が出ますが、全ファイルをコミットするのでYesを選択します。
以下の表示が出る場合は、ユーザ名、メールアドレスが正しく登録されていませんので、再度登録コマンドを実行してください。
開発サーバ起動を起動します。
Exploer に切り替え、下のほうにある NPM SCRIPTS を開き、dev の右側の三角ボタンを押します。
しばらく待つと、 Listening on: http://localhost:3000/ と表示されます。
これで開発サーバが起動しました。Docker内のポートとローカルポートを接続します。
3000番ポートが表示されているので、右の追加ボタンを押します。
以下の画面が出た場合は「アクセスを許可する」ボタンを押します。
これで Docker 内の 3000 番ポートと、ローカルの 3000 番ポートが接続され、
ブラウザで動作確認ができます。Open in Brower ボタンを押します。
タイトルを変更してみる
pages/index.vue を開きます。
nuxt_in_docker の文字を Nuxtはじめました に書き換えて上書き保存します。
保存するとブラウザの表示が自動的に切り替わります。
テストを実行する
NPM SCRIPTS 内の test の右の三角ボンタンを押します。
テストを追加する
index.vue のテストを追加してみます。
test/Logo.spec.js をCtrlドラッグでコピーします。
Logo の部分を index に書き換えて上書き保存します。
再度テストを実行します。
すると以下のように Logo コンポーネントが正しく登録されていないと出ます。
警告を消すために、index.vue の <script>タグ内を記述します。
変更前<script> export default {} </script>変更後<script> import Logo from "@/components/Logo.vue"; export default { components: { Logo } }; </script>再度テストを実行します。
警告が消えてきれいに実行できました。