- 投稿日:2021-03-02T23:44:20+09:00
【Docker】 よく使う基本的なコマンド
はじめに
1ヶ月半ほど前にDockerの勉強を始めたものの、この約1ヶ月間をポートフォリオ制作や他の課題に時間を費やし、久しぶりに勉強を始めたところです。Docker独自の初見のコマンドも多く、覚えることが大変だと感じたため、自身のメモ用として今回もQiitaに記録を残しておきたいと思います。
コマンド集
# ホストの中にあるDocker imageを確認 $ docker images # コンテナを作成し、docker imageのデフォルトコマンドを実行する $ docker run <image名> # コンテナを表示 $ docker ps # 起動しているコンテナのみ表示 $ docker ps -a # 全てのコンテナを表示(起動していない物も含む) # コンテナを作成し、デフォルトコマンドを実行する(コンテナ内に入る) $ docker run -it <image名> <デフォルトコマンド> 例)$ docker run -it ubuntu bash # 既に作成されているコンテナを指定し、デフォルトコマンドを実行する(コンテナ内に入る) $ docker exec -it <コンテナ名> <デフォルトコマンド> 例)$ docker exec -it ubuntu bash # コンテナから抜ける (プロセスを切る = status: Exited) $ exit # コンテナから抜ける (プロセスを切らない = status: Up) $ detach # status: Exitedの状態をUpに変更する $ docker restart <コンテナ名> # コンテナから新しいイメージを作成し、名前をつける $ docker commit <コンテナ名> <新しいimage名> # Docker imageの元のリポジトリ名同じ名前に変更してpushする #source: 一度任意で設定したimage名 #target: username/リポジトリ名 $ docker tag <source> <target> # Docker imageをDocker Hubへpushする $ docker push <image名> # Docker HubからDocker imageをpullする $ docker pull <image名>● tag
Docker imageのバージョン
(latest: デフォルト)終わり
今回は以上になります。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になればと思っています。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
- 投稿日:2021-03-02T23:01:17+09:00
dockerでgemを追加したときにbundle installではなくbuildする
備忘録的な感じです
題名にある通りDockerでrails開発をしていてgemを追加した後
$ docker-compose run --rm (コンテナ名) bundle installを試したらgemが更新されずエラーになる
$ docker-compose buildでエラーも出ず解決した。
色々調べていたらdockerfileの
DokerfileFROM ruby:2.6.6 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client RUN mkdir /rails-qanda WORKDIR /rails-qanda COPY Gemfile /rails-qanda/Gemfile COPY Gemfile.lock /rails-qanda/Gemfile.lock RUN bundle install COPY . /rails-qandaのCOPY Gemfile /rails-qanda/Gemfileが
[COPY] ローカルのファイルをコンテナへコピー
という意味らしいのでgemを追加したらここの部分やり直すためにbuildし直すということなのかな。また理解が深まり次第追記予定
docker難しい、、
- 投稿日:2021-03-02T23:01:16+09:00
docker-composeでGPUが使えるコンテナを立てる
概要
- docker-composeでコンテナの管理をしたい
- docker-composeでGPUを利用するのにちょっと詰まったので、手順をメモしておきます
先人が丁寧に記事化してくれていたり、公式ドキュメントでも言及されているので、そっちを見てね。
環境
実験した環境です。
- OS:
Ubuntu 20.04 LTS
- docker:
Docker version 19.03.12, build 48a66213fe
- docker-compose:
version 1.26.0, build d4451659
nVidiaドライバがインストールされており、ローカル環境でnvidia-smiなどのコマンドが使えることを前提とします。
手順
nvidia-container-runtime
をインストール/etc/docker/daemon.json
にruntimeの追加- dockerの再起動
docker-compose.yml
を書く
nvidia-container-runtime
のインストールまずは公式ドキュメントに書かれている通り、
NVIDIA-CONTAINER-RUNTIME
をインストールします。
これはドキュメントに書かれている通りです。インストール手順については、公式にこちらで案内があります。まずはapt-getするためにリポジトリを追加します。
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \ sudo apt-key add - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) $ curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \ sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list $ sudo apt-get updateapt-getする
$ apt-get install nvidia-container-runtimeパスを確認する
$ which nvidia-container-runtime /usr/bin/nvidia-container-runtimeここまでで、GPUを利用できるコンテナを立てるだけなら、docker runのオプションで
--gpus all
などを指定すれば良いはずです。
ちなみに私の環境では、nvidia-container-runtime
を明示的にインストールしてなかったのですが、なぜか--gpus
オプションでコンテナを立てることができてました。なぜかは記憶がありません。
(nvidiaドライバとCUDA toolkitはインストールした記憶があるので、たぶんこれだと思いますが、仕組みが理解できていませんです)
/etc/docker/daemon.json
にruntimeの追加docker-composeを使ってコンテナを立てたいのですが、docker-composeには現状で
--gpus
オプションみたいなものは無いようです。
そこで、runtimeパラメータを指定しますが、nvidiaランタイムを手動で追加します。
(daemon.json
に自動で追加されるみたいに書いている方もいましたが、僕の環境では手動で書かないとダメでした)$ cat /etc/docker/daemon.json { "data-root": "/mnt/reservoir/docker", "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } } }こんな感じです。
dockerの再起動
言わずもがなですが
$ sudo systemctl restart docker
docker-compose.yml
を書いてコンテナを確認こんな感じで
runtime
パラメータと環境変数を指定します。version: '2.3' services: chainer_test: build: context: . dockerfile: ./docker/Dockerfile image: test_gpu:0.1 runtime: nvidia environment: NVIDIA_VISIBLE_DEVICES: all NVIDIA_DRIVER_CAPABILITIES: all container_name: test_gpu.1 volumes: - $PWD:/workspace tty: trueあとは通常通りにbuildとupすればGPUが利用できるコンテナが立ち上がります。
$ docker-compose build $ docker-compose upこんな感じ
# nvidia-smi Tue Mar 2 13:47:04 2021 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 450.102.04 Driver Version: 450.102.04 CUDA Version: 11.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 GeForce GTX 1070 Off | 00000000:01:00.0 Off | N/A | | 0% 36C P8 9W / 230W | 792MiB / 8118MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| +-----------------------------------------------------------------------------+(補足)docker-composeのversion 3を使う場合
version3では
runtime
パラメータが利用できないようです。
version3を使いたい場合には、dockerのdefault-runtimeをnvidiaにすれば良いみたいです。$ cat /etc/docker/daemon.json { "default-runtime": "nvidia", ~~以下略~~ }これで、次のようruntimeを指定しなくてもGPUが利用できるコンテナを立てることができます。
version: '3' services: chainer_test: build: context: . dockerfile: ./docker/Dockerfile image: test_gpu:0.2 environment: NVIDIA_VISIBLE_DEVICES: all NVIDIA_DRIVER_CAPABILITIES: all container_name: test_gpu.2 volumes: - $PWD:/workspace tty: true(余談)詰まってたところ
公式ドキュメントでは、
nvidia-container-runtime-hook
のパスを確認しとけと書かれています。
で、上記の通り、僕の環境ではnvidia-container-runtime
を明示的にインストールしてなかったのに--gpus
オプションが有効だったのと、nvidia-container-runtime-hook
が存在していたので、nvidia-container-runtime
はインストール済みだったのだろうと思い込んでました。
なので、インストールから先の手順を試行錯誤してしまってました。ほんと恥ずかしい。
- 投稿日:2021-03-02T22:56:09+09:00
Dockerコンテナ上でUSBモジュールを使う方法
Dockerコンテナ上でBWT901CL(IMUセンサ)を使おうとして,調べたことをまとめる.
やらないといけないことは以下の2点.
1.docker run
でホストとコンテナ間でUSBデバイスのフォルダを共有する.
2.chmod
で実行権限を与える.1. ホストとコンテナ間でUSBデバイスの共有
そのときの
docker run
用のシェルスクリプトは以下のとおりrun.shUSER_NAME=dorebom WORKSPACE=workspace/ros2docker/ros2_ws docker run --rm -it --privileged \ --gpus all \ --device=/dev/ttyUSB0:/dev/ttyUSB0 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v /etc/localtime:/etc/localtime \ -v /home/$USER_NAME/$WORKSPACE:/home/developer/ros2_ws \ -e DISPLAY=$DISPLAY \ --name ros2test \ ros2docker:foxyここで,今回のUSBデバイスのアドレスは
/dev/ttyUSB0
であったので,--device
オプションで共有.[NOTE]その他のオプションは,Dockerコンテナ上でGPUを使うためと,ROSのGazeboなどのGUIをホスト側で利用するためのものであり,また後日解説する.
2. 実行権限を与える
このままでは,コンテナ内でUSBデバイスを認識できても実行できないので権限を与える.
$ sudo chmod 777 /dev/ttyUSB0ここで,私の環境ではDockerコンテナ内でユーザアカウントを利用しているため,
sudo
を使用している.参考にしたページ
- 投稿日:2021-03-02T22:28:58+09:00
ROS2環境のDockerコンテナでのVSCode Remote開発
VSCodeでリモート開発しようとすると,インテリセンスが機能せず不便だったので調べてみた.
インテリセンスを有効にする方法
コンテナ上の開発フォルダの直下に以下のフォルダとファイルを書き込む.
.vscode/ └ setting.json
setting.json
ファイルに,以下の内容を書き込む.{ "python.autoComplete.extraPaths": [ "/opt/ros/foxy/lib/python3.8/site-packages/" ] }ここで,
foxy
の部分はROSのディストリビューションに応じて変更し,python3.8
の部分もPythonのバージョンに応じて変更する.これで,ROSに関するライブラリに対してパスが通り,インテリセンスが機能するようになる.
記事を書くのに参考にしたページ
- 投稿日:2021-03-02T21:38:24+09:00
【Nuxt.js × golang】ゴミ出しの通知をしてくれるラインbotを作った
経緯
起きてすぐにゴミ出しに行かないと間に合わないので寝起きでもすぐに判断できるように通知botを作成しました。
概要
管理画面にラインでログインし、各曜日のゴミ出しの内容を設定します。
朝の6時に設定した内容がログインしたラインアカウントに通知されます。
処理の流れは次の通りです。管理画面のリンク
ログインしなくてもサンプル用画面でモーダルの操作などは行えます。
使用技術
言語はTypescriptとgolangで書いています。
詳細は以下の通りです。管理画面
- Nuxt.js
- Typescript
- liff
- Line Login SDK
- firestore
API
- golang
- echo
- firestore
その他
- Docker
- heroku
- cron job
- APIを毎朝6時に叩く用
画面説明
ログイン後の画面
- 通知を停止するかどうかと各曜日の通知内容を編集できます
- 曜日ごとに設定した内容が表示されます
- 複数選択した場合は
・
区切りで表示されます通知内容編集モーダル
- 通知する内容をチェックして更新するとその曜日の朝に通知されるようになります
詰まった点
デプロイ失敗
- portを固定してデプロイしようとしていた
- portを環境変数にすることで解決
- Dockerfileに
ENTRYPOINT yarn run start
と記載していた
- dockerで立ち上げるのは問題なかったがデプロイできなかった
CMD ["yarn", "run", "start"]
に修正して解決
window is not defined
が出るpluginsで次のようにファイルを作成した
import liff from '@line/liff' if (!liff.id) { const liffId: string = process.env.liffId as string // liffの初期化 liff.init({ liffId }) } export default liffページ内で呼び出そうとしたら
window is not defined
が出た
importで呼び出すのではなく次のように書き換えてみたところ解決したlet liff: any = null if (process.browser) { liff = require('@/plugins/liff') }storeの呼び出し方法
this.$store
でエラーが出る
次のような書き方で解決した(this as any).$store.getters['users/getGarbageList']できれば
this.$store
に直したいおわりに
今回初めてTypescriptで個人開発してみたが、storeの定義や呼び出しがjavascriptと結構違い大変でした。
その分引数や変数に型がついてると全体的にコードが読みやすくなる気がしました。
最後に今回書いたコードを載せておきます。github(UI): https://github.com/d-yamagishi522/garbage-removal-notification-ui
github(API): https://github.com/d-yamagishi522/garbage-removal-notification-api
- 投稿日:2021-03-02T16:27:45+09:00
【Docker】「If you encounter this issue regularly because of slow network conditions」というエラー
- 投稿日:2021-03-02T15:50:17+09:00
Dockerでphpmyadmin+Wordpress+MySQLの環境構築[Windows 10 home]
※自分も初心者なので責任は一切負いません。参考程度にしてください。
使用するもの
- Docker
- Docker-compose
- Ubuntu
- WSL2
※各自インストールするなりしてください手順
1:任意の場所にディレクトリ(フォルダ)を作成
どこに作ってもいいですがCドライブから遠すぎるとめんどくなりがちです。
名前も自由です。
今回は例として「Test」という名前にします。
更に「Test」フォルダに入って「wp-content」フォルダを作り、更にその中に入って「wp-themes」フォルダと「wp-plugins」フォルダを作りましょう。2:docker-compose.ymlを作成
先程作成した「Test」フォルダの中に作ってください。開いたら中身を編集します。
中身はこう書いてください↓version: '3.1' services: wordpress: image: wordpress restart: always ports: - 8080:80 #ポート番号は自由に設定していいがこだわりがないならこの番号でいい environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER:hogehoge # (任意) mysqlへログインする際のユーザー名と合わせる WORDPRESS_DB_PASSWORD:hogehoge # (任意) mysqlへログインする際のパスワード と合わせる WORDPRESS_DB_NAME: wordpress_db volumes: - wordpress:/var/www/html - ./wp-content/themes:/var/www/html/wp-content/themes - ./wp-content/plugins:/var/www/html/wp-content/plugins db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: wordpress_db MYSQL_USER:hogehoge # (任意) mysqlへログインする際のユーザー名 MYSQL_PASSWORD:hogehoge # (任意) mysqlへログインする際のパスワード MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql phpmyadmin: image: phpmyadmin/phpmyadmin:latest restart: always depends_on: - db ports: - "8888:80" #ポート番号は自由に設定していいがこだわりがないならこの番号でいい volumes: wordpress: db:※最後の
volumes: wordpress: db:を書き忘れたがためにデータの永続化ができず5時間ほど無駄にしました!気をつけてください。
3:docker-compose up -d を実行
Ubuntuで「docker-compose up -d」を実行しましょう。
(失敗したらちゃんと~/Test$という表示になってるか確認!)
こうなったら成功です。4:成功したか確認
http://localhost:8080/
と
http://localhost:8888/
にアクセス。
Wordpressの画面とphpmyadminの画面が出るはず。
「docker-compose.yml」に書いたユーザー名とパスワードでログイン。ここで、Volume一覧を表示して見ましょう。
docker volume lsとコマンド実行。
おそらく
Test_db
Test_wordpress
が入っているはずです。データの永続化ができてるかを確認するため、適当に新規投稿をしてみてから一回dockerのコンテナを削除します(docker-compose down)。永続化できていない場合はこの時点でデータがリセットされるので新規投稿データも消えます。
逆に永続化に成功していた場合はデータがまだ残っているはずです。コンテナ削除後もう一度「docker volume ls」を実行。まだTest_dbとTest_wordpressが残っていたら多分問題ありません。
再度「docker-compose up -d」を実行し、phpmyadminやWordpress編集画面でコンテナ削除前の新規投稿が残っているか確認しましょう。
- 投稿日:2021-03-02T15:43:25+09:00
docker npmインストールメモ
忘れないようにメモです。
laravel用に作成したdockerのコンテナ内で
npm: command not found
をいただいたので、
インストールするための手順をまとめる。環境
使ったimage: php:7.4-fpm-buster
もともとを探るとdebian:buster-slimが使われており、$ uname -aを走らせると、
Linux ae39fa4a710d 4.19.121-linuxkit #1 SMP Tue Dec 1 17:50:32 UTC 2020 x86_64 GNU/Linux
と表示される。コマンド
$ apt update$ apt install nodejs npmこれだけ!
インストールされたか確認
$ node -v v10.24.0 $ npm -v 5.8.0バッチリです!
インストールコマンド
yum
だのapt
だの色々あって混乱するので一度整理する。yum
ディストリビューションが
Red Hat Enterprise Linux, CentOs
であればyum系を使う。
Red Hat形式(.rpm)である。apt
ディストリビューションが
Debian GNU, Ubuntu
であればapt系を使う。
Debian形式(.deb)である。おまけ:homebrew
Macだと homebrewを介して色々インストールすることが多いかも。
参考
・https://qiita.com/hal-bo/items/1e0568120c545bf723c6
・https://qiita.com/nanbuwks/items/ed8adb2d4324c939a349
- 投稿日:2021-03-02T15:33:49+09:00
初学者がCircleCI/CDを実装する上で感じた注意点
前提
・以下の記事に書かれていることを理解している
いまさらだけどCircleCIに入門したので分かりやすくまとめてみた・Laravelを用いたアプリケーションに対してCI/CDを実行する
CI・・・Githubプッシュ時にPHPUnitが自動で実行される(テスト用データベースにSQLiteのインメモリ機能を使用)
CD・・・Dockerfileより自前のイメージを作成し、そのイメージをOrbsを利用しECRへ自動プッシュし、そしてそれをECSへ自動デプロイする環境
PHP Laravel PHPUnit SQLite Docker 7.4.5 7.28.4 8.5 3.28.0 19.03.13 .circleci/config.yml
version: 2.1 orbs: aws-ecr: circleci/aws-ecr@6.5.0 aws-ecs: circleci/aws-ecs@1.2.0 jobs: test: docker: - image: circleci/php:7.4.5-node-browsers working_directory: ~/intro-app steps: - checkout - run: name: Update apt-get command: sudo apt-get update - restore_cache: keys: - v1-dependencies-{{ checksum "composer.json" }} - v1-dependencies- - run: name: Install PHP libraries command: composer install -n --prefer-dist - save_cache: paths: - ./vendor key: v1-dependencies-{{ checksum "composer.json" }} - run: name: Install three libraries related to GD command: sudo apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev - run: name: Support Freetype2 and jpeg command: sudo docker-php-ext-configure gd --with-freetype --with-jpeg - run: name: Install GD library command: sudo docker-php-ext-install -j$(nproc) gd - run: name: Generate php artisan key command: php artisan key:generate --env=testing - run: name: Run PHPUnit command: vendor/bin/phpunit workflows: test_and_deploy: jobs: - test - aws-ecr/build-and-push-image: requires: - test context: AWS_ECR_ECS repo: intro-app_circleci tag: '${CIRCLE_SHA1}' filters: branches: only: master - aws-ecs/deploy-service-update: requires: - aws-ecr/build-and-push-image context: AWS_ECR_ECS family: 'intro-app' cluster-name: 'intro-app' service-name: 'intro-app' container-image-name-updates: 'container=intro-app,image-and-tag=${AWS_ECR_ACCOUNT_URL}/intro-app_circleci:${CIRCLE_SHA1}' filters: branches: only: masterCIに関するエラー
ダミーファイルを生成できない
CircleCIのテスト時に、ダミーファイルを使用した箇所全てにエラーが表示された。
UploadedFile::fake()->image('photo.jpg'),Tests\Feature\InformationControllerTest::testStore Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor()このメソッドが定義されているIlluminate\Http\UploadedFileクラスをコンテナ内で使うには、PHP GDというPHPのライブラリが必要なので、CircleCI環境下にもインストールしてあげる。
PHP GDのインストールは以下の記事を参考にするとうまくいく(他の記事ではなかなかうまくいかないので要注意)
Docker上でPHP拡張モジュール『GD』を有効化する.circleci/config.ymlでのインストール箇所
- run: name: Install three libraries related to GD command: sudo apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev - run: name: Support Freetype2 and jpeg command: sudo docker-php-ext-configure gd --with-freetype --with-jpeg - run: name: Install GD library command: sudo docker-php-ext-install -j$(nproc) gdCDに関するエラー
1 Orbsはワークフロー内で使用しなければならない
一度、Orbsを以下のようにjobsの中に書いてみたことがある。
jobs: test: // 省略 deploy: steps: - aws-ecr/build-and-push-image: requires: - test context: AWS_ECR_ECS repo: intro-app_circleci tag: '${CIRCLE_SHA1}' filters: branches: only: master - aws-ecs/deploy-service-update: requires: - aws-ecr/build-and-push-image context: AWS_ECR_ECS family: 'intro-app' cluster-name: 'intro-app' service-name: 'intro-app' container-image-name-updates: 'container=intro-app,image-and-tag=${AWS_ECR_ACCOUNT_URL}/intro-app_circleci:${CIRCLE_SHA1}' filters: branches: only: master workflows: test_and_deploy: jobs: - test - deploy: requires: testこのように設定すると、「aws-ecr/build-and-push-image」や「aws-ecs/deploy-service-update」はコマンドではない!と怒られる(stepsにはCI環境上で行うコマンドなどを記述する。jobsの下にstepsを配置するのはマスト)。
よってOrbsはworkflow内に記述する。
2 Orbsのパラメータに注意を払う
Orbsのパラメータはいろいろ存在する。
aws-ecr/build-and-push-imageのパラメータ
パラメータ 説明 必須 デフォルト aws-access-key-id アクセスキー NO AWS_ACCESS_KEY_ID aws-secret-access-key シークレットアクセスキー NO AWS_SECRET_ACCESS_KEY account-url ECRアカウントURL NO AWS_ECR_ACCOUNT_URL repo ECRレポジトリ名 YES なし region リージョン NO AWS_REGION tag タグ NO latest dockerfile ECRへプッシュするイメージを作成するためのDockerfileの指定 NO Dockerfile context コンテキスト no なし aws-ecs/deploy-service-updateのパラメータ
パラメータ 説明 必須 デフォルト aws-access-key-id アクセスキー NO AWS_ACCESS_KEY_ID aws-secret-access-key シークレットアクセスキー NO AWS_SECRET_ACCESS_KEY family タスク定義名 YES なし cluster-name クラスター名 YES なし service-name サービス名 NO 空文字列 container-image-name-updates デプロイ先のコンテナ名とデプロイするイメージ名 NO 空文字列 context コンテキスト no なし 注意するポイントは以下の2つ。
パラメータにはデフォルト値が設定されている
デフォルト値とCirclCIの環境変数が一致している場合、パラメータの記述を省略しても、そのパラメータに設定したCircleCIの環境変数が適用される。
contextを設定しなければCircleCIの環境変数を参照できない
ここはかなり詰まってしまったところだ。
contextの中に環境変数を設定した場合、パラメータにcontextを設定しなければ、そのcontext内の環境変数を参照できない。3 vendorディレクトリの不足
デプロイには成功したが、コンテナが落ちてしまった。CloudWatchでコンテナ内で起きたエラーをチェックしてみると以下のエラーメッセージが検出された。
Warning: require(/workdir/vendor/autoload.php): failed to open stream: No such file or directory in /workdir/artisan on line 18このエラーは、「vendorディレクトリが存在しない」ために起きたもの。
リモートリポジトリにプッシュする際、vendorディレクトリは含まれない設定になっているため(.gitignoreに記述してある)、本番環境にデプロイしたLaravelのコード群の中にもvendorディレクトリは存在しない。ではどうするか?
vendorディレクトリは「composer install」でインストールできるので、Dockerfileに以下のように記述する。RUN composer install補足
「composer install」をDockerfile内のどこにどうやって書けばいいのか悩んでしまったので、その経緯を一応細かく書いておきます。(めちゃくちゃ基礎的なことを理解できていませんでした)
悩んだ原因は、Dockerfileの「RUN」コマンドと「CMD」コマンドを誤って解釈していたからでした。
僕の間違った解釈
RUN・・・イメージを生成するためだけのコマンド
CMD・・・コンテナ内で実行するコマンド正しい意味
RUN・・・コンテナ内で実行するコマンド
CMD・・・コンテナ起動時一度だけ実行されるコマンド上記のように解釈していたので、もうCMDコマンドはサーバーを立ち上げるために一度使っているから、どうやって「composer install」を実行すればいいのか?と悩みました。。。
以下の記事が大変参考になりました。
僕はイメージのbuildを間違って捉えていました。。。
DockerのRUNとCMDの違い
- 投稿日:2021-03-02T14:37:12+09:00
Docker Composeのvolumesについてわかったことをまとめる
docker-compose.ymlにおける
volumes:
部分の記述の意味や、そもそもの「ボリューム(Volume)」の意味が理解できずに混乱したので、調べて分かったことを本記事にまとめておきます✍️ちなみに、自分の場合はボリュームをDocker側のリソースとしてでしか捉えられていなかったのが混乱の元になっていました…。
(※注1)本記事ではDockerコマンド(
$ docker volume create
など)を用いた説明は行なっていません。
(※注2)初学者の為、用語や概念の理解が間違っていることがあります。その場合は遠慮なくご指摘いただけるとありがたいです。対象読者
- docker-compose.ymlの記述が理解できない人
- ↑特に
volumes:
の部分が理解できない人- そもそもDockerのボリューム(Volume)の概念がよく分からない人
Dockerにおけるデータ永続化プロセス
まず初めに、Dockerのデータ永続化プロセスにおいて、主要なアクターは3人いることを押さえておきたい(参考記事)。
- Host(ホストPC)上の永続化させたいディレクトリ or 単一ファイル
- Docker内のコンテナ
- Docker内のボリューム
ここで重要なのが、1と3のどちらも(広義的には)ボリュームと呼ぶことができるということ。
ボリューム(Volume)とは何か
「ボリューム(Volume)」とは、「永続化できるデータ」又は「データを永続化できる場所」のことを指している…と考えるのがわかりやすいと思う。
この意味で考えると、
・ホスト側で(特に永続化させたい部分の)ディレクトリ(=ls
で可視化できる)
や
・Docker側のリソースのボリューム(=docker volume ls
で可視化できる)
は、共にボリュームであると言える。
ちなみに、後者のことは「データボリューム(Data Volume)」と呼ぶらしい。したがって、docker-compose.yml内の
volumes:
部分の記述は「これらのボリュームをコンテナにマウントさせますよ!」ということを表している。
…もし「マウント」の意味が分からなければ、「接ぎ木」のイメージで捉えるといいかもしれない。Dockerにおけるデータ永続化の2つの手段
繰り返しになるが、Dockerにおけるデータ永続化の手段は2つある。
- ホストPC側のディレクトリを、Dockerのコンテナにマウントさせる
- Dockerリソースのボリュームを、Dockerのコンテナにマウントさせる
ではそれぞれの場合、docker-compose.ymlの
volumes:
にはどのように記述すれば良いのだろうか。
次の「docker-compose.ymlのvolumes:
部分の書き方」で説明する。docker-compose.ymlの
volumes:
部分の書き方そもそもvolumesフィールドの書き方にはルールがあり、簡略形では
[SOURCE:]TARGET[:MODE]
のように書く。
SOURCE
:コンテナにマウントさせたいホスト上のディレクトリorファイル、またはデータボリューム名。TARGET
:SOURSE
のマウント対象となるコンテナのディレクトリ。それぞれの関係性のイメージとしては、SOURCE
が外付けHDDで、それをTARGET
に挿し込む感じ。MODE
:SOURCE
のファイルのアクセス権限。roとかrwとか。volumesの書き方(簡略形)
参考:公式ドキュメント
1. ホストPC側のディレクトリを、Docker内コンテナにマウントさせる
→ホストディレクトリ:コンテナディレクトリ
のように書く。docker-compose.yml# ホストディレクトリが「./api」で、コンテナディレクトリが「/app」 web: volumes: - ./api:/app2. DockerリソースのボリュームをDocker内コンテナにマウントさせる
→データボリューム名:コンテナディレクトリ
、またはコンテナディレクトリ
のように書く。
- 前者は「名前付きボリューム」と呼ばれ、docker-compose.ymlの最下部にその旨の記述をする必要がある。
- 後者は「匿名ボリューム(anonymous volume)」と呼ばれ、この場合は最下部の記述は必要ない。ただしこの場合のボリュームの名称はハッシュ値(ランダムなアルファベットと数字の羅列)になるため、外部から参照する際に分かりづらくなることに注意。
docker-compose.yml# データボリューム名が「mysql_data」、コンテナディレクトリが「/var/lib/mysql」 db: volumes: - mysql_data:/var/lib/mysql/ # (中略) volumes: mysql_data:volumesの書き方(簡略化しない場合)
参考:公式ドキュメント
簡略化せずに記述することもできるとのこと。docker-compose.yml# 公式ドキュメントより引用 services: web: image: nginx:alpine ports: - "80:80" volumes: - type: volume # マウントタイプ source: mydata # 簡略形のSOURCE target: /data # 簡略形のTARGET volume: # 追加のオプション nocopy: true - type: bind source: ./static target: /opt/app/static主な参考文献
https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
https://nishinatoshiharu.com/docker-volume-tutorial/
https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes
https://docs.docker.jp/compose/compose-file.html#volumes-volume-driver参考文献 プラスα
https://qiita.com/onokatio/items/fcc9f8f94f8533bb030a
https://pc.atsuhiro-me.net/entry/2020/03/19/105714
https://namazu-tech.hatenablog.com/entry/2018/02/23/233104
https://katuo-ai.com/docker-volume
- 投稿日:2021-03-02T10:12:03+09:00
Docker 全てのコンテナを再ビルドして起動する
- 投稿日:2021-03-02T00:37:01+09:00
VSCode + Docker で Vue.js の開発環境構築
ことの発端
これまで VSCode で C++ の開発環境構築を進めていたのですが、フロントエンドの方々も vue の開発環境を Docker で行う方針にしたので、その導入のメモ書きです。
手順
1. Dockerfile と docker-compose.yml を作成
今回は、Dockerコンテナでサーバを起動するので、
docker-compose.yml
を作成します。
作業用のディレクトリを作成して、Dockerfile
とdocker-compose.yml
を作成します。1DockerfileFROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y nodejs npm build-essential git python3 curl \ && npm i n -g \ && n stable \ && apt-get purge -y nodejs npmdocker-compose.ymlversion: "3" services: ubuntu: build: . ports: - "58080:8080" - "56006:6006"
8080
は vue のnpm run serve
のデフォルトポート、6006
はnpm run storybook
のデフォルトポートで、それぞれ、ローカルポートの58080
と56006
に割り当てます。
他に必要であれば追記しましょう。22. VSCodeからコンテナ内へリモート接続する
拡張機能 Remote - Containers : ms-vscode-remote.remote-containers をインストールします。
コマンドパレットが表示されるので
Remote-Containers: Open Folder in Containers...
を選びます。
フォルダ選択画面が表示されるので、Dockerファイルが存在するフォルダを選択します。
この手順で、コンテナビルド→設定→起動→ログインが行われます。
3. 開発用の拡張機能をインストール3
- 拡張機能 Vetur : octref.vetur をインストールします。
- 必須じゃないけど Prettier - Code formatter : esbenp.prettier-vscode なんかもオススメです。
これにて、開発環境の構築は終了です。
ガシガシコードを書きましょう。おまけ
以降は、取り敢えず、vueの知識が無いけど、とりあえず動作確認をやってみたい場合に、やってみると良いかもしれません。
1. ショボいサンプルプロジェクトをクローンする
ショボくて申し訳ない。
git clone https://github.com/codianz/templ.storybook cd templ.storybook
2. パッケージのインストール
大概のパッケージマネージャでお約束ですのヤツです。
npm i3. vue開発サーバの起動
vueアプリを開発する際に起動しておくサーバです。
npm startブラウザで
http://localhost:58080/
で起動確認します。4. パッケージのインストール
storybook で開発を進める際に起動しておくサーバです。
npm run storybookブラウザで
http://localhost:56006/
で起動確認します。
- 投稿日:2021-03-02T00:37:01+09:00
VSCode + Docker でフロントエンドの開発環境構築
ことの発端
これまで VSCode で C++ の開発環境構築を進めていたのですが、フロントエンドの方々も vue の開発環境を Docker で行う方針にしたので、その導入のメモ書きです。
フロントエンドというか Node.js を使う開発環境って感じなので、vue だけじゃなくて electron なんかでも使えると思います。手順
1. Dockerfile を作成
作業用のディレクトリを作成して、
Dockerfile
を作成します。1DockerfileFROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y nodejs npm build-essential git python3 curl \ && npm i n -g \ && n stable \ && apt-get purge -y nodejs npm通常コンテナ内でポートリスニングしていてもインバウンドが遮断されているんですが、VSCodeのターミナルで起動すると自動的にポートフォワードしてくれるので特に何も指定する必要がありません。2
2. VSCodeからコンテナ内へリモート接続する
拡張機能 Remote - Containers : ms-vscode-remote.remote-containers をインストールします。
コマンドパレットが表示されるので
Remote-Containers: Open Folder in Containers...
を選びます。
フォルダ選択画面が表示されるので、
Dockerfile
が存在するフォルダを選択します。この手順で、コンテナビルド→設定→起動→ログインが行われます。
3. 開発用の拡張機能をインストール3
- 拡張機能 Vetur : octref.vetur をインストールします。
- 必須じゃないけど Prettier - Code formatter : esbenp.prettier-vscode なんかもオススメです。
これにて、開発環境の構築は終了です。
ガシガシコードを書きましょう。おまけ
以降は、取り敢えず、vueの知識が無いけど、とりあえず動作確認をやってみたい場合に、やってみると良いかもしれません。
1. ショボいサンプルプロジェクトをクローンする
ショボくて申し訳ない。
git clone https://github.com/codianz/templ.storybook cd templ.storybook
2. パッケージのインストール
大概のパッケージマネージャでお約束ですのヤツです。
npm i3. vue開発サーバの起動
vueアプリを開発する際に起動しておくサーバです。
npm startブラウザで
http://localhost:8080/
で起動確認します。4. パッケージのインストール
storybook で開発を進める際に起動しておくサーバです。
npm run storybookブラウザで
http://localhost:6006/
で起動確認します。VSCode のポートフォワーディング(2021/03/02追記)
当初、
docker-compose.yml
を作成していたんだけど、実行してみたら、コンテナのポートがそのままフォワードされとるやんという事態に 「 ??? 」 だったのですが、VSCodeの親心というヤツでした。
この機能のお陰で、
npm start
(npm run serve
)とかやると、右下にこんなポップアップが表示されます。
そして、左側のペインにフォワーディング状況を確認することができます。
す。。。凄すぎる。。。
- 投稿日:2021-03-02T00:20:27+09:00
Prometheusをはじめから丁寧に解説してみた[ハンズオン]
概要
PrometheusはSoundCloudというサービスのエンジニアによって開発されたオープンソースのシステム監視及びアラートツールキットです。内部に時系列のデータベースを持っていて、かつPull型のデータモデルを持っています。
詳細については、https://prometheus.ioをご覧ください。
特徴
Prometheusの主な機能は次のとおりです。
柔軟なクエリ言語であるPromQLを持つ
Pull型(over HTTP)の監視サービスで時系列の収集
独自のデータストア
グラフ化とダッシュボードのサポートの複数のモード(ただしGrafanaを使うことが多いです)
エコシステム
Prometheusエコシステムは非常に優秀なものがいくつかあります。
- 時系列データをスクレイプして保存するメインのPrometheusサーバー
- アプリケーションコードを計測するためのクライアントライブラリ
- 短命の仕事をサポートするためのプッシュゲートウェイ
- HAProxy、StatsD、Graphiteなどのサービス用の専用エクスポーター
- アラートを処理するalertmanager
アーキテクチャ
一見アーキテクチャを見ると複雑ですが導入は非常に簡単です。
上の図の流れの一例として、まず、左下のJobExporters(Prometheus Target)からメトリクスを真ん中のPrometheus ServerがPullをします。その後収集したデータからAlertmanagerでエラー検知してSlackに送ったり、PromQLでログの可視化、解析を行います。
登場人物
この部分は10分で理解する Prometheusの引用となってしまいますが、とてもわかりやすかったため、掲載させていただきます。
上のアーキテクチャ図にも複数コンポーネントが登場しますが、はじめのところは以下の二つだけ知っておけばとりあえずなんとかなります。
名称 説明 exporter 監視対象サーバー上で動かすプログラム
テキスト形式でリソース情報を公開するWeb API のようなもの
監視対象のリソース毎に exporter が用意されているprometheus 監視サーバーのプログラム
定期的に全ての exporter をポーリングしてリソース情報を収集する
監視したデータは prometheus 内の DB に保持されるExporter ⇨ アーキテクチャ図の左下
prometheus ⇨ アーキテクチャ図の真ん中
Prometheusのメリット
Prometheusを導入するメリットをいくつか紹介します。総合監視ツールZABBIX等と比較していきます。
- 時系列DBにデータを格納するのでI/Oが速く、画面表示が軽快(ただしGrafana経由が多い) ⇦ ZABBIXはRDBMSのため、重くなって画面表示が遅くなることがある。
- 分散管理が容易で、Diskやメモリの追加でスケールアップできる。 ⇦ ZABBIXはRDBMSのレプリケーションやDBのメモリチューニングが必要
- APIを介してホストの自動検出、削除が標準機能で可能であり、環境変更への対応が容易。
- エンドポイントを登録すればホストに紐づかなくても監視可能、柔軟性が高い。 ⇦ ZABBIXでもWEBを使えばできるが設定が必要
- Grafanaの機能だが、グラフやダッシュボードUIの作成が綺麗で容易
Prometheusのデメリット
デメリットもいくつかあります。
- データの長期保存を前提としていないので、別途に長期保存用のサーバが必要 ⇦ RDBMSなら問題ない
- デフォルトの設定だとID/PassなしのWEBアクセスでデータの閲覧や監視の無効化などができてしまうので、接続制限やBasic認証が必要
- ストレージ問題 ⇦ 一つ目と被りますが、Prometheusは、デフォルトではTSDB(Time Series Database)というローカルのストレージを利用するのですが、これは冗長化や可用性が考慮されていません。対策として、Metricsの容量設計やRemoteStorageという機能を用い、外部のDBに保存する必要があります。
一長一短だとは思いますが、差し引いてもかなり優秀なソフトウェアだと思います。
GUI(概観)
簡単に実際のダッシュボードの画面を貼り付けていきます。
グラフとか
なんとなくの動きは可視化されてますね。
Target全体
正常系
アラート
インスタンスが止まっていますね。。AlertManagerを使えばSlackに通知することもできます。⬇︎
たくさんアラートが飛んできています。
Grafana
ログデータ可視化ツールGrafanaを使うとかっこよく可視化できます。(大事)
また、ダッシュボードを作成したり、独自のUIパーツでカスタマイズすることもできます。
いい感じのデザインですね。
なんとなく知れたからいいやという方はここまでお疲れ様でした。
実際に触ってみたいという方はもう一踏ん張りしましょう!
ハンズオン
目標
- Prometheusなんとなく触れるようになる
- 環境が構築できる
- 起動できる
- targetとかなんとなくわかるようになる
前提知識
今回はDocker-composeを使うので前提知識とします。
- Docker-compose
環境のセットアップ
ローカル環境にインストールすることも可能ですが、コンテナを使うことが多いのでdockerを使ってセットアップしていきます。
フォルダ構成
tree . ├── docker-compose.yaml └── prometheus └── prometheus.yaml 1 directory, 2 files
docker-compose.yamlとprometheus.yamlを使います。実際の開発現場ではalert manager,grafana.envやalertrulesなども作成してカスタマイズしていきます。
docker-compose.yamlの作成
version: "3" services: prometheus: image: prom/prometheus container_name: prometheus volumes: - ./prometheus:/etc/prometheus/ ports: - 127.0.0.1:9090:9090 grafana: image: grafana/grafana container_name: grafana ports: - 3000:30009090番ポートでprometheusサーバーを立て、3000番ポートでgrafanaサーバーを立てます。volumes: でローカルのprometheus設定ファイルをコンテナ内にマウントさせます。
prometheus.yamlの作成
global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. external_labels: monitor: "codelab-monitor" rule_files: scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"]こちらはprometheusの詳細設定を記述するファイルです。static_configsの場所に計測したいエンドポイントを設定します。また、監視の間隔や異常検知の定義(alert_rulesなど)もこのファイルに記述します。
起動
docker-compose up -d
これでprometheusサーバー、grafanaサーバーが起動したかと思います。
http://localhost:9090 に移動するとprometheusにアクセスできます。
また、statusタブからtargetを押すとhttp://localhost:9090/metricsが正常に動作していることがわかります。
それではgrafanaにもアクセスしましょう!
http://localhost:3000 に移動するとgrafanaにアクセスできます。初回起動時にユーザー名、パスワードを聞かれますがどちらもadminでログインできます。
prometheusと連携するためにはDataSourceからprometheusを追加する必要があります。
Save&Testを押して、Prometheus Statusボタンを押し、グラフが描画されるかどうか確認してください!
完成です
最後に
今回のハンズオンではプロメテウスサーバーの監視というあまり意味のないことをしましたが、APIサーバー、cacheサーバー、インフラなどprometheusでは様々を監視可能です。
不明点などございましたらお気軽にコメントをお願いします参考文献
公式サイト
prometheus のデータを grafana でグラフ表示してみた
10分で理解する Prometheus
次世代監視の大本命! Prometheus を実運用してみた
10分で理解するGrafana
Observabilityをはじめよう!(後編) 〜Metrics/Logs/Tracesチュートリアル〜