- 投稿日:2020-11-15T21:49:36+09:00
Ruby on Railsの開発環境をDockerで構築する方法(Rails 6.x)
Docker公式手順を参考に、Rails 6系で Dockerの開発環境を構築する手順を詳解します。
各コマンドの詳しい解説は私が以前に書いた Rails5系での手順 で解説しているので、本記事では割愛します。
ファイルの準備
作業用のディレクトリを作成し、以下の 5 つのファイルを作成します。
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
- entrypoint.sh
FROM ruby:2.7.0 ## nodejsとyarnはwebpackをインストールする際に必要 # yarnパッケージ管理ツールをインストール RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn RUN apt-get update -qq && apt-get install -y nodejs yarn RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp RUN yarn install --check-files RUN bundle exec rails webpacker:compile # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"]docker-compose.ymlversion: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "3306:3306" volumes: - ./tmp/db:/var/lib/mysql web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - dbsource 'https://rubygems.org' gem 'rails', '6.0.3'Gemfile.lock(空ファイル)```entrypoint.sh #!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"Rails プロジェクトを作成
$ docker-compose run web rails new . --force --no-deps --database=mysqlコンテナをビルド
$ docker-compose buildデータベースファイルの修正
上記実行後、config/database.yml ファイルを下記の通りにまるっと修正します。
config/database.ymldefault: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: host: localhost development: <<: *default database: myapp_development host: db username: root password: password test: <<: *default database: myapp_test host: db username: root password: passwordデータベースを作成
$ docker-compose run web rails db:createWebpackerをインストール
Rails 6系から Webpacker が必要となっているため、webサーバのコンテナにwebpackerをインストールします。
$ docker-compose run web rails webpacker:installdocker-compose でコンテナを起動
$ docker-compose up -dアクセスして起動を確認
ブラウザから localhost:3000 にアクセスし、Rails の初期画面が表示されることを確認しましょう。
コンテナを停止
検証を終え、コンテナを停止させるときも docker-compose を使います。
$ docker-compose down
- 投稿日:2020-11-15T21:40:03+09:00
docker-composeでコンテナが立ち上がらない
(余談)dockerを初めて触り、導入しました。
初学者にはネットワーク基礎からの知識が必要になり、かなり苦戦しました。
まず、docker導入にあたり、学習した書籍を紹介します。
- キタミ式イラストIT塾 基本情報技術者 令和02年 Kindle版
- [試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識 Kindle版
- Docker/Kubernetes 実践コンテナ開発入門 Kindle版
- (こちらはサイト)入門 Docker https://y-ohgi.com/introduction-docker/
docker-composeでコンテナが立ち上がらない
コンテナ環境
-macOS catalina 10.15.7
-Docker version 19.03.13
-docker desktop version 2.4.0.0
rails+nginx+unicorn+mysql環境構築を試行錯誤で何度もコマンドを打っているうちにバックグラウンドに使っていないデータが溜まっていた事が原因でした。special thanks>>
環境構築はこちらの記事を参考にしました。
https://qiita.com/E6YOteYPzmFGfOD/items/509dbabeb20bf2487283
https://qiita.com/AK4747471/items/39ddacfde6a235103277打ったコマンド
docker-compose build(イメージ作成)
docker-compose up(コンテナ作成、実行)
docker-compose down --volumes(コンテナ削除、docker外で指定した保存ファイルのデータも同時に削除)
docker desktopでイメージをアイコン選択で削除解決法
以下コマンドでは、可動していないものも含め全てのDockerイメージを削除します。
docker stop $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi $(docker images -q)
https://qiita.com/suzy1031/items/1b4e1d717b6052a02307
- 投稿日:2020-11-15T20:44:44+09:00
はじめてDockerを触ってみた
こんにちは。むんです
次案件でDockerを使う事になったので、すこし触ってみました。
自分用の備忘録として書いてますが、この記事が少しでもはじめてDockerをさわる方の役に立てば嬉しいです!
記事の内容に関して間違いや、こうした方がいい等のアドバイス等ありましたら、気軽にコメントくださいでは、はじめて参りましょう!
※前提
・使用PC:Mac予備知識や関係することなど。
下記記事ご参照ください。
- 仮想化技術について(記事作成中)
- コンテナ型仮想化技術って?(記事作成中)
- よく使うDockerコマンド集(記事作成中)
早めに書きます。。11月中には書きます。目次
- Dockerって何?
- Dockerインストール
- イメージの取得、コンテナ起動
Dockerって何?
ざっくり言うと、元々あった仮想マシンの「重い」と言う問題を解決するために生まれたのがコンテナ型仮想化技術で、Dockerはコンテナ型仮想化技術の代表です。
(詳しいことはこちらの記事(記事作成中)をご参照ください)インストールから起動まで
1.Dockerをインストールする
インストール方法は公式ページに丁寧に記載されています。
お使いのOSによってインストールするものは異なるので、下記公式ページからそれぞれ適したものをインストールして下さい。
Docker公式ページ
2.バージョン確認をする
インストールが完了したら、Docker, Docker composerのバージョンを確認してみましょう。
コマンドプロンプトで、下記コマンドを打ち込みます。
docker -v
docker composer -v
※Docker composerとは、複数のコンテナを操作する際に使うツールですが、今回は使用しません。
3.ターミナルよりコンテナを起動する
コンテナの起動にはイメージが必要ですが、そのイメージは
「WEB上のDocker Hubから取得する方法」と「自分で作成する方法」があります。
今回は入門書編として、前者を説明していきます。
インストール後、Dockerを開くと下記の様な画面が表示されます。
※表示されているコマンドは、Docker Hubよりチュートリアル用のイメージを取得して、コンテナを起動する物です。
今回は、チュートリアル用のコンテナではなく、ngixを起動してみましょう。
下記コマンドをターミナルに打ち込み、Docker hubよりnginxのイメージを取得し、コンテナを起動します。
docker run --name some-nginx -d -p 8080:80 nginx
※既に起動してるプロセスのポートが被って怒られる場合は、既に起動してるプロセスを落とすか、コンテナを別のポートで起動しましょう。
Docker hubにはnginx以外にapacheなど他にも様々なイメージがあるので、試してみることをお勧めします!
4.コンテナが起動できているか、確認しましょう。
ブラウザから下記URLにアクセスします。
http://localhost:8080
※ポートは適宜読み替えて下さい。下記の様な画面が出れば、コンテナ起動成功です!
まとめ
以上、Dockerインストールからコンテナ起動までまとめてみました。
いかがでしたでしょうか。
ご参考になれば嬉しいです!
- 投稿日:2020-11-15T20:36:03+09:00
Docker Hubとコマンドの紹介 自己学習①
Dockerの学習中に、たくさんのコマンドが出てきたのでアウトプットしていきます。
Docker Hubとは
Docker imageが管理されているレジストリの名前(Git Hubみたいな感じ)。
Docker imageを管理するレジストリは他にもあるが、その一つがこのDocker Hub
である。リポジトリーの共有
Git Hub同様、Docker Hubもリポジトリーで管理することが可能。
そのリポジトリー(image)をチームなど、様々な人と共有することで簡単に開発環境を整えられる。
Git Hubでいう、リモートリポジトリをローカルにクローンするイメージ。Docker Hubを使用するには
Docker HubのWebサイトから新規登録を行う。
ターミナルを開き、ログインを行う。$ docker loginLogin Succeededと表示されれば、ログイン成功。
リポジトリー(image)をローカル(Host)へPullする
Docker Hubで管理しているリポジトリーをローカルにプルする。
$ docker pull <imageの名前>例えば、
testOS
がリポジトリ名であれば$ docker pull WindowsOSこれで、リポジトリのクローンがローカルに完成。
コンテナを作成する
WindowsOSが入ったコンテナで作業するために、
run
コマンドを実行する。$ docker run -it testOS bashこれでコンテナを作成し、コンテナの中に入ることが出来る。
ここで一旦次のパートで情報を整理する。コンテナを作成する理由は?
先ほどDocker Hubから
testOS
というリポジトリー(image)をローカルにPullしました。
しかし、この時点ではローカル環境でtestOSを使うことは出来ません。例えば、作成するアプリケーションの開発環境でtestOSが必要なので、testOSを使えるようにしたいとする。
そこで、testOSが含まれるコンテナを作成し、そのコンテナの中で作業することで、testOSが使えるようになる。コンテナから抜けるには
$ exitこのコマンドで、コンテナから抜けることが出来る。
ローカルで管理しているコンテナの確認方法
$ docker ps -a
-a
を付けないと、動いているコンテナしか表示されないので、全て表示するには-a
が必要。ローカルで管理しているイメージの確認方法
$ docker imagesexitした後に、再度コンテナの中に入る方法
run
した後にexit
コマンドでコンテナから抜けると、コンテナはexited
状態になる。
このままではコンテナが起動しておらず、中に入ることが出来ないので、再度立ち上げる。$ docker restartその後、
exec
コマンドで、再びコンテナに入るコマンドを打つ$ docker exec -it <containerの名前> bashDocker imageに変更を保存する方法
開発環境で、RubyやPHP、Javascriptが必要になったとする。
一人がコンテナの中で、Ruby、PHP,Javascriptを扱えるように設定した。他の人も同じ環境構築をするのは手間も時間もかかり大変。
→ 一人が設定したコンテナの作業環境をimage(リポジトリ)に保存し、提供すれば解決!$ docker commit <container> <image>このコマンドで、コンテナの変更内容をimageに保存する。
Docoker Hubにimageをプッシュ前に、タグで名前を一致させる
予めDocker Hubでリポジトリを新規作成しておく。(ここではnew-repoとする)
名前が一致している必要があるので、タグを付ける。$ docker tag old-repo:updated username/new-repoold-repoが変更を加えたローカルのリポジトリで、タグが更新を表すupdated。
Docker Hubで新規作成した「new-repo」にusername/new-repoで名前を一致させる。Docoker Hubにimageをプッシュする
$ docker push username/new-repoこれでDocker Hubで管理しているリポジトリにプッシュが完了
プルすることで、変更が加えられたimage(リポジトリ)をローカルで扱えるようになる。imageの削除方法
$ docker rmi <image>
- 投稿日:2020-11-15T20:36:03+09:00
【基本編】Dockerを使ってみる 自己学習①
Dockerの学習中に、たくさんのコマンドが出てきたのでアウトプットしていきます。
Docker Hubとは
Docker imageが管理されているレジストリの名前(Git Hubみたいな感じ)。
Docker imageを管理するレジストリは他にもあるが、その一つがこのDocker Hub
である。リポジトリーの共有
Git Hub同様、Docker Hubもリポジトリーで管理することが可能。
そのリポジトリー(image)をチームなど、様々な人と共有することで簡単に開発環境を整えられる。
Git Hubでいう、リモートリポジトリをローカルにクローンするイメージ。Docker Hubを使用するには
Docker HubのWebサイトから新規登録を行う。
ターミナルを開き、ログインを行う。$ docker loginLogin Succeededと表示されれば、ログイン成功。
リポジトリー(image)をローカル(Host)へPullする
Docker Hubで管理しているリポジトリーをローカルにプルする。
$ docker pull <imageの名前>例えば、
testOS
がリポジトリ名であれば$ docker pull testOSこれで、リポジトリのクローンがローカルに完成。
コンテナを作成する
testOSが入ったコンテナで作業するために、
run
コマンドを実行する。$ docker run -it testOS bashこれでコンテナを作成し、コンテナの中に入ることが出来る。
ここで一旦次のパートで情報を整理する。コンテナを作成する理由は?
先ほどDocker Hubから
testOS
というリポジトリー(image)をローカルにPullしました。
しかし、この時点ではローカル環境でtestOSを使うことは出来ません。例えば、作成するアプリケーションの開発環境でtestOSが必要なので、testOSを使えるようにしたいとする。
そこで、testOSが含まれるコンテナを作成し、そのコンテナの中で作業することで、testOSが使えるようになる。コンテナから抜けるには
$ exitこのコマンドで、コンテナから抜けることが出来る。
ローカルで管理しているコンテナの確認方法
$ docker ps -a
-a
を付けないと、動いているコンテナしか表示されないので、全て表示するには-a
が必要。ローカルで管理しているイメージの確認方法
$ docker imagesexitした後に、再度コンテナの中に入る方法
run
した後にexit
コマンドでコンテナから抜けると、コンテナはexited
状態になる。
このままではコンテナが起動しておらず、中に入ることが出来ないので、再度立ち上げる。$ docker restartその後、
exec
コマンドで、再びコンテナに入るコマンドを打つ$ docker exec -it <containerの名前> bashDocker imageに変更を保存する方法
開発環境で、RubyやPHP、Javascriptが必要になったとする。
一人がコンテナの中で、Ruby、PHP,Javascriptを扱えるように設定した。他の人も同じ環境構築をするのは手間も時間もかかり大変。
→ 一人が設定したコンテナの作業環境をimage(リポジトリ)に保存し、提供すれば解決!$ docker commit <container> <image>このコマンドで、コンテナの変更内容をimageに保存する。
Docoker Hubにimageをプッシュ前に、タグで名前を一致させる
予めDocker Hubでリポジトリを新規作成しておく。(ここではnew-repoとする)
名前が一致している必要があるので、タグを付ける。$ docker tag old-repo:updated username/new-repoold-repoが変更を加えたローカルのリポジトリで、タグが更新を表すupdated。
Docker Hubで新規作成した「new-repo」にusername/new-repoで名前を一致させる。Docoker Hubにimageをプッシュする
$ docker push username/new-repoこれでDocker Hubで管理しているリポジトリにプッシュが完了
プルすることで、変更が加えられたimage(リポジトリ)をローカルで扱えるようになる。imageの削除方法
$ docker rmi <image>
- 投稿日:2020-11-15T20:36:03+09:00
Docker自己学習①
Dockerの学習中に、たくさんのコマンドが出てきたのでアウトプットしていきます。
Docker Hubとは
Docker imageが管理されているレジストリの名前(Git Hubみたいな感じ)。
Docker imageを管理するレジストリは他にもあるが、その一つがこのDocker Hub
である。リポジトリーの共有
Git Hub同様、Docker Hubもリポジトリーで管理することが可能。
そのリポジトリー(image)をチームなど、様々な人と共有することで簡単に開発環境を整えられる。
Git Hubでいう、リモートリポジトリをローカルにクローンするイメージ。Docker Hubを使用するには
Docker HubのWebサイトから新規登録を行う。
ターミナルを開き、ログインを行う。$ docker loginLogin Succeededと表示されれば、ログイン成功。
リポジトリー(image)をローカル(Host)へPullする
Docker Hubで管理しているリポジトリーをローカルにプルする。
$ docker pull <imageの名前>例えば、
testOS
がリポジトリ名であれば$ docker pull WindowsOSこれで、リポジトリのクローンがローカルに完成。
コンテナを作成する
WindowsOSが入ったコンテナで作業するために、
run
コマンドを実行する。$ docker run -it testOS bashこれでコンテナを作成し、コンテナの中に入ることが出来る。
ここで一旦次のパートで情報を整理する。コンテナを作成する理由は?
先ほどDocker Hubから
testOS
というリポジトリー(image)をローカルにPullしました。
しかし、この時点ではローカル環境でtestOSを使うことは出来ません。例えば、作成するアプリケーションの開発環境でtestOSが必要なので、testOSを使えるようにしたいとする。
そこで、testOSが含まれるコンテナを作成し、そのコンテナの中で作業することで、testOSが使えるようになる。コンテナから抜けるには
$ exitこのコマンドで、コンテナから抜けることが出来る。
ローカルで管理しているコンテナの確認方法
$ docker ps -a
-a
を付けないと、動いているコンテナしか表示されないので、全て表示するには-a
が必要。ローカルで管理しているイメージの確認方法
$ docker imagesexitした後に、再度コンテナの中に入る方法
run
した後にexit
コマンドでコンテナから抜けると、コンテナはexited
状態になる。
このままではコンテナが起動しておらず、中に入ることが出来ないので、再度立ち上げる。$ docker restartその後、
exec
コマンドで、再びコンテナに入るコマンドを打つ$ docker exec -it <containerの名前> bashDocker imageに変更を保存する方法
開発環境で、RubyやPHP、Javascriptが必要になったとする。
一人がコンテナの中で、Ruby、PHP,Javascriptを扱えるように設定した。他の人も同じ環境構築をするのは手間も時間もかかり大変。
→ 一人が設定したコンテナの作業環境をimage(リポジトリ)に保存し、提供すれば解決!$ docker commit <container> <image>このコマンドで、コンテナの変更内容をimageに保存する。
Docoker Hubにimageをプッシュ前に、タグで名前を一致させる
予めDocker Hubでリポジトリを新規作成しておく。(ここではnew-repoとする)
名前が一致している必要があるので、タグを付ける。$ docker tag old-repo:updated username/new-repoold-repoが変更を加えたローカルのリポジトリで、タグが更新を表すupdated。
Docker Hubで新規作成した「new-repo」にusername/new-repoで名前を一致させる。Docoker Hubにimageをプッシュする
$ docker push username/new-repoこれでDocker Hubで管理しているリポジトリにプッシュが完了
プルすることで、変更が加えられたimage(リポジトリ)をローカルで扱えるようになる。imageの削除方法
$ docker rmi <image>
- 投稿日:2020-11-15T20:06:59+09:00
VSCode Remote Containers で --privileged と /sbin/init を渡したコンテナで開発する方法
はじめに
VSCode Remote Containers を使って開発する場合、Dockerfile を書いて「Reopen in Container」とすると Docker コンテナが起動しますが、この時 VSCode が
docker run
を実行します。
このため、何も気にせず公式の手順などを参考に起動すれば、--privileged
オプションを付加できず、ENTRYPOINT に/sbin/init
も渡せないため、コンテナでsystemctl
を実行できません。
※実行すると「Failed to get D-Bus connection: Operation not permitted」と表示されエラーとなります。
※このあたりの仕組みについては、既に「CentOS 7のDockerコンテナ内でsystemdを使ってサービスを起動する」などの記事で語られているため、本記事では割愛します。本記事では、題記の通り、VSCode Remote Containers で使うコンテナで、
docker run
に--privileged
と/sbin/init
を渡すための調査経緯と、実現した方法を紹介します。0. 序章: 調査編
まずは正攻法で行けないかと調査してみると、設定ファイルの devcontainer.json には「runArgs」というパラメータがあり、ここで
docker run
する時のパラメータを追加できることが分かりました。
参考: devcontainer.json reference
しかし、この方法では--privileged
を追加できても、--entrypoint
を上書きできませんでした。
VSCode Remote Containers で 「Reopen in Container」 して docker コンテナを起動すると、docker run
の引数に--entrypoint /bin/sh <各自のDocker Image> -c echo Container started ; trap "exit 0" 15; while sleep 1 & wait $!; do :; done
が付加されてしまい、devcontainer.json に書いたパラメータではこれを上書きできない仕様となっているようです。起動時にどんなコマンドが流れているかは、起動中に表示される以下ポップアップのリンクを押すことで見えるログから把握できます。
また、次のリンク先で解説されているように、Dockerfile に書いた ENTRYPOINT と CMD よりも、引数で指定された
--entrypoint
が優先されるため、Dockerfile に書いても上書きできません。
VSCode が必ずdocker run
に引数で--entrypoint
を付加するためこれが最優先されてしまいます。
参考: Dockerfileによるビルド1. 実現手順
そこで、以下の手順を辿ることにしました。
(1) まずは手順通り 「Reopen in Container」 を実行
この手順により Docker イメージがビルドされ、コンテナが起動します。
この時、先ほどのポップアップのリンクからログを開き、ログの中から以下のコマンドを探してコピーします。docker run -a STDOUT -a STDERR --mount type=bind,source=<各自の環境のパス>,target=<各自の環境のパス>,consistency=cached -l vsch.quality=stable -l vsch.remote.devPort=0 -l vsch.local.folder=<各自の環境のパス> --entrypoint /bin/sh <各自のDocker Image> -c echo Container started ; trap "exit 0" 15; while sleep 1 & wait $!; do :; done(2) VSCode でコンテナとの接続を解除
(1) で起動したコンテナは
--privileged
されていませんので、VSCode で一旦接続を解除します。(3) コピーしたコマンドを一部変更
コピーしたコマンドに
--privileged
を追記し、--entrypoint
を書き換えます。docker run -a STDOUT -a STDERR --mount type=bind,source=<各自の環境のパス>,target=<各自の環境のパス>,consistency=cached -l vsch.quality=stable -l vsch.remote.devPort=0 -l vsch.local.folder=<各自の環境のパス> --privileged --entrypoint /sbin/init <各自のDocker Image>(4) 上記コマンドをローカルのターミナルで実行
実行すると (3) のオプション通りに docker コンテナが起動します。
docker ps
で起動状態を確認できます。(5) VSCodeで「Attach to Running Container」を実行
次に、(4) で起動したコンテナを VSCode にアタッチします。
まず、以下画像のように「Attach to Running Container」を選びます。ここまでで、VSCode からコンテナに接続して、開発環境を開けます。
2. 動作確認
VSCode でコンテナのターミナルを開いて
systemctl
を打ってみます。bash-4.2# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION dev-vda1.device loaded activating tentative /dev/vda1 -.mount loaded active mounted / dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File Syste etc-hostname.mount loaded active mounted /etc/hostname etc-hosts.mount loaded active mounted /etc/hosts (以下長いので略)このようにエラーが解消され、打てるようになっています。
最後に
このように、起動したコンテナに VSCode から接続する手順を踏むことで、VSCode Remote Containers でも
systemctl
が実行できるようになります。
今回、少々面倒ですがdocker build
までは VSCode で実行して、各種オプションが含まれるdocker run
コマンドを VSCode のログから発掘する方が早いと判断しました。
(もっと良い方法があるのかもしれませんが、もし見つかったら追記します)なお
--privileged
はその名の通り特権という意味なので、ご利用は計画的に、とすべきです。参考文献
- 投稿日:2020-11-15T20:02:07+09:00
【初級編】Dockerってそもそも何?基礎からわかりやすく解説!
はじめに
今更ではありますが、Dockerについて基礎から勉強したのでまとめます。
全てのコマンドの細かいオプションとかはまとめていません。
本記事の目的はDockerというツールを知るという初歩的(だけど重要)なものです。Dockerってそもそも何?
Docker(ドッカー)とは「仮想環境の構築ツール」です。
仮想環境って何?
仮想環境というのは、コンピュータの中に疑似的に作る仮の空間(何かを実現する場)のことを指します。もう少し噛み砕くと、本来物理的に必要なものを仮想的にあるようにして動かすことのできる環境のことです。
参照:仮想マシンとは?よく聞く"仮想化" "仮想マシン"の基礎知識と特徴を解説例えば、Windows環境の中で、仮想的に作られたLinux OS環境や、別のWindows OS環境が用意できるというのが仮想環境の例です。一般的に仮想環境をつくる土台となるOSを「ホストOS」、仮想環境上のOSを「ゲストOS」と呼びます。仮想環境を構築することで、Linux用のパソコンとWindows用のパソコンをそれぞれを物理的に用意する必要がなくなり、一つのハードウェアで一元管理できるようになります。
また、メモリやハードディスク容量などを柔軟に調整ができるというメリットもあります。仮想環境を構築すれば、ハード機器の節約にもなります。仮想マシンの種類
仮想マシンには、いくつか種類があります。それぞれのメリット、デメリットについて簡単に説明します。
①ホスト型
②ハイパーバイザー型
③コンテナ型
参照:仮想環境とは?メリットやデメリット、代表的なソフトウェア「VMware」について解説①ホスト型
パソコンやサーバにホストOSをインストールし、そのOS上に仮想環境作成ソフトウェアをインストールして構築するタイプです。ホストOSの上にゲストOSが並びます。
・メリット:既存のサーバなどにインストールすればすぐに利用でき、手軽に始められる。
・デメリット:ホストOSを起動しなければならない。ハードウェアを起動した際に、ホストOSが立ち上がるまで時間がかかる場合がある。②ハイパーバイザー型
1つのハードウェアに「ハイパーバイザー」と呼ばれる仮想化ソフトウェアを直接インストールし、仮想化を構築するタイプがハイパーバイザー型です。ホストOSを起動しなくてよいので、ホストOS型と比べて早く起動できます。
・メリット:ホストOSがないため、リソースのほとんどを仮想環境に充てられる。
・デメリット:既存のパソコンやサーバを使い回せず、新しくハードウェアを購入しなくてはいけない。構築する際は、コスト面にも注意する必要がある。③コンテナ型
ホストOSに「コンテナエンジン」とよばれる仮想化ソフトウェアをインストールし、その中でコンテナと呼ばれる環境を作り、アプリケーションを実行させます。
コンテナにはゲストOSという概念はありません。ホストOSからは、一つのプロセスとして認識されます。そのため、余分なリソースが不要であり、軽快な環境を提供できるのです。実際に使用してみると、アプリケーションを短時間で起動できるでしょう。・メリット:リソース効率がよく、コストパフォーマンスにも優れている。
・デメリット:新しい技術ということもあり、構築できるベンダーが少ない。便利な管理ツールなどが不足している。ここで改めてDockerとは??
Dockerは前述した通り、「仮想環境の構築ツール」です。その中でも「コンテナ」という仮想環境を構築し、そのコンテナの中でアプリケーション、ミドルウェア、OSなどを動かすことができます。コンテナは非常に軽量で、起動や停止などを素早く完了させることができるのが魅力の一つです。
では実際にDockerがどんな仕組みで動くのか見ていきましょう。Dockerの仕組み
ここではDocker初心者なら抑えておきたい用語をもとに、Dockerの仕組みについて理解を深めていきます。
・Dockerエンジン
・Dockerコンテナ
・DockerイメージDockerエンジンとは?
Dockerエンジンは「Docker自体そのもの」という理解でいいです。Dockerイメージの作成やコンテナ起動などを行うDockerのコアな部分です。このDockerエンジンはホストOS(Windows, Mac, Linux)にDockerをインストールすることで簡単に利用できます。インストールしたらホストOS上にDockerエンジンが動き、その上で各コンテナが動いているという感じです。
画像参照:https://www.ogis-ri.co.jp/otc/hiroba/technical/docker/part1.html
Dockerコンテナとは?
DockerコンテナとはDockerエンジン上で動いている仮想環境のことです。
Dockerコンテナでは、CentOSやUbuntsuなどのOSから、NginxやMySQLなどのミドルウェア、RailsやWordpressなどのアプリケーションまで様々な環境を作ることができます。
これらのコンテナは「**ホストOSのカーネル(Linuxカーネル)を利用して動いている**」という特徴があります!
Linuxカーネルというのは、OSに必要な基本機能を集めた中心核のようなソフトウェアのことです。ここで疑問なのが、「Linuxを持たないWindowsやMac上でもDockerは立ち上がるのか?」ということです。
答えは、立ち上がります!
なぜかというと、Docker起動の裏でLinux仮想マシンが動くようになっているため、各コンテナもこの仮想マシン上で動く仕組みになっているのです。またこの仮想マシンであるLinuxはコンテナごとに独立している訳ではなく、コンテナ全てで共通したものが使われるため、ホストマシンのリソース(CPUやメモリ)を節約しながら動いているのです。そうすることでコンテナ自体は軽量化されますし、何よりDockerのコンテナの起動が早い理由なのです。
Dockerイメージとは?
DockerイメージとはDockerコンテナを作るためのマニュアルみたいなものです。
このDockerイメージをもとにコンテナが作られます。各イメージは元のイメージとなる「ベースイメージ」となるものに、「レイヤー(層)」を重ねることで新しいイメージを作成することができます!
画像参照:https://dzone.com/articles/optimizing-spring-boot-application-for-dockerまとめ
DockerについてとDockerの仕組みについて簡単にまとめました。
Dockerの概要は理解できても、Linuxの基礎知識がないとDocker環境設定で詰まってしまうと思うので、Linuxについても勉強していきたいところです。
- 投稿日:2020-11-15T17:41:02+09:00
EC2にDockerをインストールして起動してみた
はじめに
EC2 (AmazonLinux2)にDockerをインストールして使ってみた時の備忘録です。
普通はECSやElasticBeanstalkなどのコンテナ基盤を使うと思うので、あまり機会はないかもですが書いてみました。EC2でDockerをインストールしていく
EC2にログインします
$ ssh -i ~/.ssh/****.pem ec2-user@***.***.***.***git をインストール
$ sudo yum install git -yDocker をインストール
$ sudo amazon-linux-extras install docker -yDocker を起動
$ sudo service docker startおわりに
もし
ERROR: Couldn’t connect to Docker daemon at http+docker://localhost – is it running?
みたいなエラーが出ればこちら↓の記事を参考にしてみてください。
- 投稿日:2020-11-15T17:03:29+09:00
Ruby on Railsの開発環境をDockerで構築する方法
この記事では、Dockerを用いてRuby on Rails(以下、rails)の開発環境を構築する方法を紹介します。
通常、rails の初学者の方はマシンに直接インストールして開発環境を構築する人がほとんどだと思います。
しかし、環境の微妙な際(Rubyのバージョンや環境変数など)によってつまづいた場合、
そのトラブルシューティングには多くの時間を要してしまうかと思います。そこで、Dockerで仮想環境上にrailsの環境を構築してあげることで
どのマシン上の開発環境でも等しい動作を行うことができるため、環境の差異によるエラーを避けることができます。
環境をいじりすぎた時には最悪一度リセットを出来るというのもメリットですね。また、作成したアプリケーションを本番環境として外部へ公開しようとするときにも
開発環境と本番環境での違いを最小限に抑え、安定したアプリケーションとして稼働させることができます.
Dockerで仮想環境を作って公開するなんて難しそうと思うかもしれませんが、
最近ではAWSといったクラウドサービスでもDockerコンテナをそのまま実行できるECS等のサービスが整っているので
Dockerで作った環境を公開するのも楽になってきています。前提条件
マシンに Docker がインストールされていること
Docker をインストールしていない人は、公式サイトから Docker のインストーラをダウンロードしてインストールしておきましょう。
→Docker公式また、任意の作業フォルダを作成しておきます。
ここでは "rails-docker" というフォルダを作成し、その中で作業していくことにします。$ mkdir rails-docker $ cd rails-dockerDocker関連ファイルの準備
rails-docker 内に以下4つの空ファイルを準備しておきます。
VScode を利用しているなら新規ファイルの作成で作ったり、
Mac のターミナルから touch コマンドを使ってもよいです。. ├── Dockerfile # 新規作成 ├── Gemfile # 新規作成 ├── Gemfile.lock # 新規作成 └── docker-compose.yml # 新規作成Dockerファイルの解説
Dockerでは、Dockerfileというファイルに基づいてコンテナのビルドが行われ、
Docker Image(コンテナの雛形)が作成されることになります。まず Dockerfile の全文を記載します。
使用する Ruby のバージョンは 2.7.0 としています。FROM ruby:2.7.0 RUN apt-get update -qq && apt-get install -y build-essential nodejs RUN mkdir /app WORKDIR /app COPY Gemfile /app/Gemfile COPY Gemfile.lock /app/Gemfile.lock RUN bundle install COPY . /app箇条書きとはなりますが、それぞれの意味を解説します。
- FROM ruby:2.7.0
- 公開されている ruby インストール済みコンテナのうち、Rubyのバージョンが 2.7.0 であるものを引っ張ってきます。
- RUN apt-get update -qq && apt-get install -y build-essential nodejs
- Rails の実行に必要なパッケージをインストールしています
- RUN mkdir /app
- Rails のプロジェクトファイルを作成するアプリディレクトリを作成
- WORKDIR /app
- 作業用のディレクトリを指定
- COPY Gemfile /app/Gemfile
- 自分のマシン(PC)上にある Gemfile をコンテナの作業用ディレクトリに移動させ、コンテナから利用できるようにします
- Gemfile.lock も同様
- RUN bundle install
- Gemfileに記載されているgemを一括インストール
- COPY . /app
- Dockerファイルが置いてあるフォルダのファイルすべてをコンテナ内の app ディレクトリにコピー
- Rails の実行に必要なファイルをコンテナに含めるためにコピーしています
Gemfile の解説
Ruby では Gemfile というファイルで環境で使いたい gem を定義することができます。
gemとはRubyのライブラリのことをいいます。
gemはRubyGemsと呼ばれるRuby用のパッケージ管理システムで管理されており、RubyGemsが提供するgemコマンドを通じてインストール等ができます。source 'https://rubygems.org' gem 'rails', '5.2.1'また少し解説します。
- source 'https://rubygems.org'
- gem のダウンロード元を指定
- gem 'rails', '5.2.1'
- インストールする gem である rails というパッケージ名と、バージョンを指定
- 今回は rails のバージョンは 5.2.1 を指定しています
- どのバージョンを指定してもよいのですが rails 6 以降は webpacker, yarn が必要になるので注意してください
- ここでは簡単に検証するため rails 5 系を使用
Gemfile があるディレクトリで "bundle install" コマンドを実行すると、
Gemfile の定義に従って、定義した gem をインストールすることができます。先ほど解説した Docker ファイルでも、Gemfile をコンテナの作業用ディレクトリにコピーして
そのフォルダ内で bundle install を実行するように指定していましたね。Gemfile.lock の解説
実は Gemfile.lock は最初の時点では何も書き込む必要がありません。
これは直接編集するようなファイルではなく、
Gemfile に基づいて bundle install を実行した後に
インストールされた gem が Gemfile.lock に一覧として記述されるようになります。使い方としては、Gemfile.lock を参照すればインストールされている gem とバージョンが分かり、
Gemfile.lock から bundle install を実行することもできるので
完全に同じ環境をもう一度作りたいときや、多人数で開発をするときに Gemfile.lock が使われます。Gemfile だけでも良いのでは?と思った鋭い方に補足しますと、Gemfile では実はこういう書き方もできることが理由の一つになっています。
gem 'rails', '~> 5.2.1'この場合、bundle install でインストールされる rails のバージョンは 5.2.1 以上であるものの
実際にインストールできる(公開されている)バージョンはその時点によって変わってきます。しかし Gemfile.lock では Gemfile に従ってインストールしようとした時に実際にインストールされた gem 本体と具体的なバージョン、
付随して必要となるためにインストールされたパッケージまで記録されます。少し整理すると Gemfile は「アプリで必要な gem の一覧」であり、
一方の Gemfile.lock は「Gemfile に従った結果、実際にインストールした gem の情報」が記述されることになります。docker-compose.yml の解説
この yml ファイルは Docker Compose で使用されます。
Docker Composeは、複数のコンテナで構成されるアプリケーションについて
Dockerイメージのビルドや各コンテナの起動・停止といった管理を行うためのツールです。Docker Composeでは、Dockerビルドやコンテナ起動のオプションも含め、複数のコンテナのための定義を docker-compose.yml というファイルに記述し、
それを利用して Docker イメージのビルドやコンテナ起動をすることができます。開発環境のように、Rails をそれ単体で動かすならば Dockerfile だけでもよいのですが
Rails を動かすためのアプリケーションサーバに加え、
実際に公開するときにはインターネットからのアクセスを受け付けるための Web サーバや、
またデータを保存・処理するためのデータベースサーバも用意することがあります。docker-compose.ymlversion: '3' services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/app ports: - 3000:3000 depends_on: - db tty: true stdin_open: true db: image: mysql:5.7 volumes: - db-volume:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: password volumes: db-volume:rails ではデータベースも必要になるため、WebサーバだけではなくMySQLを用いたデータベースサーバのコンテナも構築します。
ここでは詳解しませんが、web という欄の中の「depends_on」で rails が連携するデータベースサーバ(コンテナ)を名前で指定しています。rails の立ち上げ
rails プロジェクトの作成 (rails new)
docker-compose.yml が置いてあるフォルダ(rails-dockerフォルダ)で以下の docker-compose コマンドを実行します。
$ docker-compose run web rails new . --force --database=mysqlコマンドについて、オプション含め少し読み方を解説します↓
- docker-compose: docker-compose というツールをつかって
- run: 以下のコマンドを実行します
- web: web コンテナで
- rails new: rails で新しいプロジェクトを作成する
- . : 現在のディレクトリに対して
- --force: 既存の file (ここでは Gemfile, Gemfile.lock) は上書きする形で
- --database=mysql: ただし rails のデータベースには MySQL を使用します
という意味を持っているのです。
この一行のコマンドを実行すると数分単位で処理に時間がかかるので、チョコレートでも食べながら気長に待ちましょう。
build の実行
Gemfile に追記された gem のインストール、
および作成されたファイルをコンテナ内に取り込むため build を実行します。$ docker-compose buildデータベース設定ファイルの編集
build が完了したら、rails で使用するデータベースファイルの設定を編集します。
config ディレクトリ内の database.yml というファイルが対象です。config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password # 追加 host: db # 変更password は docker-compose.yml で指定したパスワードと合わせる必要があります。
docker-compose.yml... environment: MYSQL_ROOT_PASSWORD: password # ここと合わせる ...また、host の欄は MySQL コンテナ名を設定しています。
コンテナの起動
コンテナを起動するため、次のコマンドを実行します。
$ docker-compose up -ddocker-compose up がコンテナをdocker-compose.yml に基づいて起動するコマンドであり、
オプションの「-d」によりバックグラウンドで起動させることができます。データベースの作成
いまはまだコンテナが起動しただけであり、データベースは作成されていないので
次のコマンドを実行してデータベースを作成します。$ docker-compose run web bundle exec rails db:createrails を実行している web コンテナで、rails db:create (=データベースの新規作成)を実行する処理となっています。
rails 開発用サーバの起動確認
これで無事に rails の開発用サーバが起動したことになります。
ブラウザのアドレスバーに localhost:3000 と入力し、起動を確認してみましょう。rails ではお馴染みの画面が表示されれば完了です。
コンテナの停止
開発用サーバを止めるため、コンテナを一括で停止するには以下のコマンドを実行します。
$ docker-compose downまた立ち上げたいときには docker-comopose up -d を実行しましょう。
最後に
これによって作られるファイルの一式は Github にあげています。
フォルダ構成が分からなくなったり、自分の環境でうまくいっているか比較して確かめたい方はご参照ください。
- 投稿日:2020-11-15T17:03:29+09:00
Ruby on Railsの開発環境をDockerで構築する方法(Rails 5.x)
この記事では、Dockerを用いてRuby on Rails(以下、rails)の 5.x 系における開発環境を構築する方法を紹介します。
※Rails 6.x 系で Docker 環境を作りたい場合は こちら をご覧ください。Docker で環境構築をするメリットとは?
通常、rails の初学者の方はマシンに直接インストールして開発環境を構築する人がほとんどだと思います。
しかし、環境の微妙な際(Rubyのバージョンや環境変数など)によってつまづいた場合、
そのトラブルシューティングには多くの時間を要してしまうかと思います。そこで、Dockerで仮想環境上にrailsの環境を構築してあげることで
どのマシン上の開発環境でも等しい動作を行うことができるため、環境の差異によるエラーを避けることができます。
環境をいじりすぎた時には最悪一度リセットを出来るというのもメリットですね。また、作成したアプリケーションを本番環境として外部へ公開しようとするときにも
開発環境と本番環境での違いを最小限に抑え、安定したアプリケーションとして稼働させることができます.
Dockerで仮想環境を作って公開するなんて難しそうと思うかもしれませんが、
最近ではAWSといったクラウドサービスでもDockerコンテナをそのまま実行できるECS等のサービスが整っているので
Dockerで作った環境を公開するのも楽になってきています。前提条件
マシンに Docker がインストールされていること
Docker をインストールしていない人は、公式サイトから Docker のインストーラをダウンロードしてインストールしておきましょう。
→Docker公式また、任意の作業フォルダを作成しておきます。
ここでは "rails-docker" というフォルダを作成し、その中で作業していくことにします。$ mkdir rails-docker $ cd rails-dockerDocker関連ファイルの準備
rails-docker 内に以下4つの空ファイルを準備しておきます。
VScode を利用しているなら新規ファイルの作成で作ったり、
Mac のターミナルから touch コマンドを使ってもよいです。. ├── Dockerfile # 新規作成 ├── Gemfile # 新規作成 ├── Gemfile.lock # 新規作成 └── docker-compose.yml # 新規作成Dockerファイルの解説
Dockerでは、Dockerfileというファイルに基づいてコンテナのビルドが行われ、
Docker Image(コンテナの雛形)が作成されることになります。まず Dockerfile の全文を記載します。
使用する Ruby のバージョンは 2.7.0 としています。FROM ruby:2.7.0 RUN apt-get update -qq && apt-get install -y build-essential nodejs RUN mkdir /app WORKDIR /app COPY Gemfile /app/Gemfile COPY Gemfile.lock /app/Gemfile.lock RUN bundle install COPY . /app箇条書きとはなりますが、それぞれの意味を解説します。
- FROM ruby:2.7.0
- 公開されている ruby インストール済みコンテナのうち、Rubyのバージョンが 2.7.0 であるものを引っ張ってきます。
- RUN apt-get update -qq && apt-get install -y build-essential nodejs
- Rails の実行に必要なパッケージをインストールしています
- RUN mkdir /app
- Rails のプロジェクトファイルを作成するアプリディレクトリを作成
- WORKDIR /app
- 作業用のディレクトリを指定
- COPY Gemfile /app/Gemfile
- 自分のマシン(PC)上にある Gemfile をコンテナの作業用ディレクトリに移動させ、コンテナから利用できるようにします
- Gemfile.lock も同様
- RUN bundle install
- Gemfileに記載されているgemを一括インストール
- COPY . /app
- Dockerファイルが置いてあるフォルダのファイルすべてをコンテナ内の app ディレクトリにコピー
- Rails の実行に必要なファイルをコンテナに含めるためにコピーしています
Gemfile の解説
Ruby では Gemfile というファイルで環境で使いたい gem を定義することができます。
gemとはRubyのライブラリのことをいいます。
gemはRubyGemsと呼ばれるRuby用のパッケージ管理システムで管理されており、RubyGemsが提供するgemコマンドを通じてインストール等ができます。source 'https://rubygems.org' gem 'rails', '5.2.1'また少し解説します。
- source 'https://rubygems.org'
- gem のダウンロード元を指定
- gem 'rails', '5.2.1'
- インストールする gem である rails というパッケージ名と、バージョンを指定
- 今回は rails のバージョンは 5.2.1 を指定しています
- どのバージョンを指定してもよいのですが rails 6 以降は webpacker, yarn が必要になるので注意してください
- ここでは簡単に検証するため rails 5 系を使用
Gemfile があるディレクトリで "bundle install" コマンドを実行すると、
Gemfile の定義に従って、定義した gem をインストールすることができます。先ほど解説した Docker ファイルでも、Gemfile をコンテナの作業用ディレクトリにコピーして
そのフォルダ内で bundle install を実行するように指定していましたね。Gemfile.lock の解説
実は Gemfile.lock は最初の時点では何も書き込む必要がありません。
これは直接編集するようなファイルではなく、
Gemfile に基づいて bundle install を実行した後に
インストールされた gem が Gemfile.lock に一覧として記述されるようになります。使い方としては、Gemfile.lock を参照すればインストールされている gem とバージョンが分かり、
Gemfile.lock から bundle install を実行することもできるので
完全に同じ環境をもう一度作りたいときや、多人数で開発をするときに Gemfile.lock が使われます。Gemfile だけでも良いのでは?と思った鋭い方に補足しますと、Gemfile では実はこういう書き方もできることが理由の一つになっています。
gem 'rails', '~> 5.2.1'この場合、bundle install でインストールされる rails のバージョンは 5.2.1 以上であるものの
実際にインストールできる(公開されている)バージョンはその時点によって変わってきます。しかし Gemfile.lock では Gemfile に従ってインストールしようとした時に実際にインストールされた gem 本体と具体的なバージョン、
付随して必要となるためにインストールされたパッケージまで記録されます。少し整理すると Gemfile は「アプリで必要な gem の一覧」であり、
一方の Gemfile.lock は「Gemfile に従った結果、実際にインストールした gem の情報」が記述されることになります。docker-compose.yml の解説
この yml ファイルは Docker Compose で使用されます。
Docker Composeは、複数のコンテナで構成されるアプリケーションについて
Dockerイメージのビルドや各コンテナの起動・停止といった管理を行うためのツールです。Docker Composeでは、Dockerビルドやコンテナ起動のオプションも含め、複数のコンテナのための定義を docker-compose.yml というファイルに記述し、
それを利用して Docker イメージのビルドやコンテナ起動をすることができます。開発環境のように、Rails をそれ単体で動かすならば Dockerfile だけでもよいのですが
Rails を動かすためのアプリケーションサーバに加え、
実際に公開するときにはインターネットからのアクセスを受け付けるための Web サーバや、
またデータを保存・処理するためのデータベースサーバも用意することがあります。docker-compose.ymlversion: '3' services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/app ports: - 3000:3000 depends_on: - db tty: true stdin_open: true db: image: mysql:5.7 volumes: - db-volume:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: password volumes: db-volume:rails ではデータベースも必要になるため、WebサーバだけではなくMySQLを用いたデータベースサーバのコンテナも構築します。
ここでは詳解しませんが、web という欄の中の「depends_on」で rails が連携するデータベースサーバ(コンテナ)を名前で指定しています。rails の立ち上げ
rails プロジェクトの作成 (rails new)
docker-compose.yml が置いてあるフォルダ(rails-dockerフォルダ)で以下の docker-compose コマンドを実行します。
$ docker-compose run web rails new . --force --database=mysqlコマンドについて、オプション含め少し読み方を解説します↓
- docker-compose: docker-compose というツールをつかって
- run: 以下のコマンドを実行します
- web: web コンテナで
- rails new: rails で新しいプロジェクトを作成する
- . : 現在のディレクトリに対して
- --force: 既存の file (ここでは Gemfile, Gemfile.lock) は上書きする形で
- --database=mysql: ただし rails のデータベースには MySQL を使用します
という意味を持っているのです。
この一行のコマンドを実行すると数分単位で処理に時間がかかるので、チョコレートでも食べながら気長に待ちましょう。
build の実行
Gemfile に追記された gem のインストール、
および作成されたファイルをコンテナ内に取り込むため build を実行します。$ docker-compose buildデータベース設定ファイルの編集
build が完了したら、rails で使用するデータベースファイルの設定を編集します。
config ディレクトリ内の database.yml というファイルが対象です。config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password # 追加 host: db # 変更password は docker-compose.yml で指定したパスワードと合わせる必要があります。
docker-compose.yml... environment: MYSQL_ROOT_PASSWORD: password # ここと合わせる ...また、host の欄は MySQL コンテナ名を設定しています。
コンテナの起動
コンテナを起動するため、次のコマンドを実行します。
$ docker-compose up -ddocker-compose up がコンテナをdocker-compose.yml に基づいて起動するコマンドであり、
オプションの「-d」によりバックグラウンドで起動させることができます。データベースの作成
いまはまだコンテナが起動しただけであり、データベースは作成されていないので
次のコマンドを実行してデータベースを作成します。$ docker-compose run web bundle exec rails db:createrails を実行している web コンテナで、rails db:create (=データベースの新規作成)を実行する処理となっています。
rails 開発用サーバの起動確認
これで無事に rails の開発用サーバが起動したことになります。
ブラウザのアドレスバーに localhost:3000 と入力し、起動を確認してみましょう。rails ではお馴染みの画面が表示されれば完了です。
コンテナの停止
開発用サーバを止めるため、コンテナを一括で停止するには以下のコマンドを実行します。
$ docker-compose downまた立ち上げたいときには docker-comopose up -d を実行しましょう。
最後に
これによって作られるファイルの一式は Github にあげています。
フォルダ構成が分からなくなったり、自分の環境でうまくいっているか比較して確かめたい方はご参照ください。
- 投稿日:2020-11-15T16:39:45+09:00
Dockerについて理解した後、実際に導入してみました。
1 本記事について
明日から新しい職場でDockerというものを使うっぽいのですが、よく(というかほぼ何も)分からないので、調べてみました。
2 Dockerとは
そもそもDockerとは何なのか分からないので調べてみました。
Dockerとは、ひとことでいうと「Linux上で動作するシンプルで使いやすい軽量コンテナ環境」です。 LinuxというOS上にコンテナという箱を用意し、そのコンテナの中に必要なソフトウェアやライブラリ(ツール)などをインストールしてひとつのまとまりとしてパッケージングすることができます。
Dockerは、インフラ関係やDevOps界隈で注目されている技術の一つで、Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのプラットフォームです。
Dockerは、Linuxのコンテナ技術を使ったもので、よく仮想マシンと比較されます。VirtualBoxなどの仮想マシンでは、ホストマシン上でハイパーバイザを利用しゲストOSを動かし、その上でミドルウェアなどを動かします。それに対し、コンテナはホストマシンのカーネルを利用し、プロセスやユーザなどを隔離することで、あたかも別のマシンが動いているかのように動かすことができます。そのため、軽量で高速に起動、停止などが可能です。Dockerというコンテナ環境で開発を行うと、その環境をパッケージング化できて何かと便利ということみたいです。
3 Dockerのインストール
公式ドキュメントに沿って、ubuntu上で、Dockerのインストールをしていきます。
3.1 念のため古いバージョンのDockerをアンインストール
古いバージョンのDockerをインストールしている可能性が微粒子レベルで存在するので削除コマンドを実行します。やらなくても良いみたいです。
$ sudo apt-get remove docker docker-engine docker.io containerd runcPackage 'XXXX' is not installed, so not removedみたいなのが出てくればOKです。
3.2 パッケージインデックスを更新・aptがリポジトリを利用できるようパッケージをインストール
Dockerをインストールするために必要なパッケージをインストールします。主にaptがHTTPSに対応していないのを補う目的があるみたいです。
$ sudo apt-get update $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common3.3 公式GPGキーを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -何をしているのかよく分からないので、ちょっと詳しく見ます。
3.3.1 curlとは
3.2でcurlをインストールしているので、curlコマンドが使えるようになっています。curlコマンドは何かというと、
引数にURLを指定すると、そのURLのファイルをダウンロードします。デフォルトの出力先は「標準出力」なので、リダイレクトで保存するか、「-O」オプションまたは「-o」オプションを指定します。
curlコマンドはダウンロードするコマンドです。(-fsSLはそのオプションです。今回は省略します。)
3.3.2 GPGとは
curlコマンドの引数のURLはDockerのGPGのURLになっています。curlコマンドはダウンロードするコマンドなので、DockerのGPGをダウンロードすることになります。GPGとはGnuPGの略で、これは何なのかというと、
公開鍵でファイルの署名を検証したり、公開鍵と秘密鍵のペアでメールの暗号化・復号化を行ったり署名を添付したりするツール。
つまり、認証に必要な鍵のことと思っておけばよさそうです。
3.3.3 apt-keyとは
DockerのGPGをapt-keyに渡しています。apt-keyとは何かというと、
「apt-key」は、「apt」が パッケージの認証に使用するキーの一覧を管理するコマンドです。Ubuntu公式以外からパッケージを取得するには、このコマンドで認証する鍵情報を取り込んでおく必要があります。
つまり、DockerをインストールするためにはDockerのGPGをローカルのapp-keyに取り込んでおく必要がある、ということみたいです。
3.4 キーの確認
GPGキーが追加されていることを確認します。DockerのGPGキーのフィンガープリントは「9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88」なので、この下8桁で以下のように検索し、結果が表示されればOKです。
$ sudo apt-key fingerprint 0EBFCD88 pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ unknown] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]3.5 stableリポジトリを設定
$sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"【Ubuntu】PPAを追加・削除する方法について | Hbk project
この記事を見ると、何のための作業なのかわかりやすいと思います。aptをつかってインストールできるパッケージは、デフォルトでは/etc/apt/source.listにあるものだけです。つまり、Dockerをインストールするためには、PPA(Personal Package Archive)を追加する必要があるということですね。
3.6 インストールの実行
アプトのパッケージインデックスを更新し、インストールを実行します。
$ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.ioこれでDockerのインストールが完了しました。
4 Dockerを使ってみる
ここからが本番です。公式ドキュメントに沿って実際にDockerを使ってみます。
4.1 オリエンテーション
まずはDockerが動くか確認します。
4.1.1 バージョンの確認
本当にDockerがインストールされているか確認します。
$ docker --version Docker version 19.03.12, build 48a66213feされていました。
4.1.2 hello-worldイメージを実行
hello-worldイメージを取得します。
$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world ca4f61b1923c: Pull complete Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. ...何をしているのかは以下のサイトを参考にするとわかりやすいです。
Docker入門(第二回)~Dockerセットアップ、コンテナ起動~ | さくらのナレッジ
Docker Hubとよばれるコンテナ共有サービスにある、公式のイメージ「hello-world」を取得し、それをもとにコンテナを起動させた形になります。
4.1.3 イメージがダウンロードされていることの確認
$ docker image lshello-worldのイメージがあるのが確認できると思います。
4.1.4 コンテナが起動していることの確認
docker runは元々イメージを取得するコマンドではなくイメージを元にコンテナを起動するコマンドですので、コンテナが起動しているはずです。
$ docker ps --all CONTAINER ID IMAGE COMMAND CREATED STATUS 54f4984ed6a8 hello-world "/hello" 20 seconds ago Exited (0) 19 seconds ago確かにコンテナが確認できました。
4.2 イメージのビルド&コンテナの実行
Dockerを動かすことができたので、次はイメージをビルド・実行していきます。
4.2.1 掲示板アプリのgit cloneを作成
テスト用の掲示板アプリのクローンを作成します。
$ git clone https://github.com/dockersamples/node-bulletin-board4.2.2 イメージのビルド
イメージをビルドします。
$ cd node-bulletin-board/bulletin-board-app $ docker build --tag bulletinboard:1.0 .4.1.2にあるように、コンテナを起動させるにはイメージが必要です。4.1.2では公式のイメージを持ってきましたが、コンテナ環境は開発環境の数だけあるため、独自のイメージが必要となります(探せば誰かがDockerHubに公開しているものが使えるかもしれませんが)。ビルドとは既にあるイメージ(ベースイメージ)を元に、新しいイメージを作成することです。ビルドは、Dockerfileがおかれている場所で実行し、Dockerfileを元に実行されます。
Dockerfileを見てみましょう。
DockerfileFROM node:current-slim WORKDIR /usr/src/app COPY package.json . RUN npm install EXPOSE 8080 CMD [ "npm", "start" ] COPY . .1行目の「FROM node:current-slim」に注目してください。「node:current-slim」というベースイメージを元に、新しいイメージをビルドするという記述です。先ほど実行したコマンドの引数に当たる「bulletinboard:1.0 .」という名前のイメージが作成されました。実際にイメージが作成されているか確認してみます。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE bulletinboard 1.0 789f62d53520 13 minutes ago 177MB node current-slim 3aaf4acbaad7 2 days ago 159MB hello-world latest bf756fb1ae65 10 months ago 13.3kBベースイメージ、およびビルドされたイメージが確認できました。
4.2.3 コンテナを起動
作成したイメージを元にコンテナを起動します。
$ docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0ブラウザでlocalhost:8000にアクセスし、掲示板アプリが動作していることが確認できます。
これについて、細かく見ていきます。4.2.3.1 --publish 8000:8080
8000がホスト側のポート番号、8080がコンテナ側のポート番号です。
4.2.3.2 --detach
コンテナをバックグラウンドで起動する際に使うオプションです。
4.2.3.3 --name bb bulletinboard:1.0
「bulletinboard:1.0」というイメージを元に「bb」という名前のコンテナを起動します。
4.2.4 コンテナを停止
コンテナを停止・削除します。
docker rm --force bbこれで無事、イメージのビルドとコンテナ化の理解ができました。
5 最後に
Dockerを利用したコンテナ環境の構築や配布のイメージがあらかたつかめたのでよかったです。
Twitterのフォローもお願いします!
- 投稿日:2020-11-15T16:20:19+09:00
まだanyenv使ってるの? Docker使ってもっと楽にいこうぜ?
Windowsなどのホストに環境を入れる際に起きる欠点
よくあるのがバージョン差異です。
そして何よりもインストールが面倒。
そしてnodeやmavenがどんどんローカル環境を圧迫していく。そして発生するMacとWindowsでの環境差異の問題。
極め付けばenvの設定ミスで違うバージョンが使われる。
devcontainerのススメ
devcontainerは、Docker上に開発環境を構築してそこで開発を全て行うための技術です。
GitHub codespaces(Visual Studio codespaces)を利用する場合のコア技術だったりもします。
簡単にいうと開発用の仮想マシンを内部にぽこじゃか作っていくことになるので、
Window AppやモバイルなどのGUIアプリの開発には若干不向きですが、
Web系は基本的にこれで事足ります。そのため、nodeやRuby、PythonといったものをVSCodeで実行するのであれば、devcontainerで済ませることができます。
必要なもの
- Docker Desktop
- Visual Stidio Code
- Remote Developmentの拡張機能
devcontainerを試しに使ってみる
今回は、例としてnodejs + Express + mongodbを使うことを前提とします。
ただし、mongoは立てるだけで実アクセスはしないことにします。devcontainerの設定
.devcontainerというディレクトリを作り、その中にdevcontainer.jsonとdockerのコンテナに関する情報を格納します。
Root Directory ├ .devcontainer │ ├ devcontainer.json │ ├ docker-compose.yml │ └ Dockerfile └ 各ソースdevcontainerを作る
コンテナとそこで動くVSCodeに関する情報を記載します。
.devcontainer/devcontainer.json{ // コンテナ名 "name": "Express Sample", // docker-composeのファイル名 "dockerComposeFile": "docker-compose.yml", // コンテナにアタッチされたプロジェクトのルートディレクトリ "workspaceFolder": "/work", // docker-composeが複数コンテナの場合、 // どのコンテナに入るのかを指定 "service": "app", // 外部から接続するポート(開放ポート)を指定 "appPort": 3000, // インストールする拡張機能を設定 "extensions": [ "VisualStudioExptTeam.vscodeintellicode", "dbaeumer.vscode-eslint", "stevencl.addDocComments", "eg2.tslint" ] }ここに記載した拡張機能はホストのVSCodeとはまた違う領域にインストールされます。
そのため、違う言語・プラットフォームに切り替えた際もVSCodeがクソ重くなるようなことは回避することができます。
Dockerの設定ファイルを作る
Dockerfileとdocker-compose.ymlを作成します。
これはdevcontainerに関係なく、開発用で使っているものをそのまま流用することも可能です。.devcontainer/DockerfileFROM node:15.2.0-alpine3.10 EXPOSE 3000.devcontainer/docker-compose.ymlversion: '3' services: app: build: . ports: - 3000:3000 volumes: - ../:/work tty: true db: image: mongo:3.6.20-xenial # 本来ならポートやボリュームアタッチが必要。開き直し
画面をリロードすると、開き直す?と聞かれるので「Reopen in Container」を選択
あとは画面がリロードされ、イメージの展開とコンテナの生成がおこなれれます。
VSCode関連のインストールも走るので、気長に待ちましょう。無事起動したら、nodeが動いていることを確認します。
この時点で、VSCodeのターミナルはdockerコンテナのターミナルを指していますので、
基本的にはVSCode内のこのターミナルを利用するようにしてください。アプリの開発
npm initしpackage.jsonを作ります。
# npm init -y # nom install -S express次に、以下のコードを作成します。
index.js'use strict' const express = require('express'); const app = express(); const port = process.env.PORT || 3000; app.get('/', (req, resp) => { resp.send('Hello, JS WORLD!'); }) app.listen(port, () =>{ console.log(`Example app listening on Port ${port}`); });実行してみます。
# node index.js node index.js Example app listening on Port 3000この状態でホストから接続してみましょう。
うまく表示されたら完成です。
あとは通常のVSCodeと同じように開発を進めることができます。
他の開発者への展開
他の開発者へ展開する場合も、devcontainerさえ作っておけば簡単に構築できます。
必要なのはVSCodeとリモート開発のための拡張機能のみです。
Node.js以外の設定
今回はnode.jsで行いましたが、PythonでもRubyでもJavaでも基本的な使い方は同じです。
次の2点についてのみ気をつけていれば、基本的に困りません。
- コンテナのベースイメージ
- インストールする拡張機能
さいごに
コンテナ単位で環境やバージョンを切り分けることができますので、
xEnvを使うよりも安全にバージョン問題を解決することができます。また、開発環境としてDockerを用いているのであれば、簡単なjsonを書くだけで済みます。
もしVSCodeを使っているのであれば、devcontainerを用いて環境構築を簡略化してはいかがでしょうか。
- 投稿日:2020-11-15T15:08:35+09:00
ローカルのdockerイメージからHerokuへデプロイする方法
デプロイする流れ
1 Heroku上にHerokuアプリを作成する。(URLが付与される) 2 Herokuのコンテナレジストリ(Heroku上のDockerイメージ置き場)にDockerイメージをプッシュする。 3 Dockerイメージをアプリへリリース 4 デプロイしたアプリへブラウザでアクセス事前にアカウントを作成し、クレジットカードを登録しておく。(クレジットカードを登録しないと公開できない。)
heroku cli のインストール(mac)
brew install heroku/brew/herokuherokuへログイン
heroku login自動起動するブラウザからログインする。
コンテナレジストリにログイン
heroku container:loginアプリに移動
※herokuはアプリのルートディレクトリ直下のdockerfileを参照する仕様。そのため、dockerfileが違う場所にある場合は、複製してルート直下にheroku用のdockerfileを配置する必要がある。
herokuでapacheを動かそうとするとエラーとなるので一部対処が必要。
エラー対処設定ファイルを作成
run-apache2.shsed -i "s/Listen 80/Listen ${PORT:-80}/g" /etc/apache2/ports.conf rm /etc/apache2/mods-enabled/mpm_event.conf rm /etc/apache2/mods-enabled/mpm_event.load apache2-foreground "$@"dockerfileでコンテナへコピーする記述と実行コマンドを追記
heroku用 dockerfile.COPY ./docker/app/run-apache2.sh /usr/local/bin/ CMD [ "run-apache2.sh" ]エラー対処設定ファイルに実行権限を付与する
chmod +x run-apache2.shherokuアプリを作成
heroku createデーターベースと連携させるためアドオンをインストールする。(ignite => 無料)
heroku addons:create cleardb:ignitecleardbの接続設定を確認する。
heroku config | grep CLEARDB_DATABASE_URL mysql:// ユーザー名 : パスワード @ ホスト名 /データーベース名 ?環境変数の設定
heroku config:add DB_USERNAME=ユーザー名 heroku config:add DB_PASSWORD=パスワード heroku config:add DB_DB_HOST='ホスト名' (.が入っているので'で括る) heroku config:add DB_DATABASE=ユーザー名確認
heroku configテーブルの作成
heroku run "テーブルの作成関数が記載されたファイル"レジストリコンテナへプッシュ
heroku container:push webレジストリコンテナへリリース
heroku container:release webブラウザ上からアクセス
heroku open※複数のアプリを登録していた場合
heroku apps:infoアプリケーション名を調べてコマンドの末尾に
--app アプリ名を付与する。
herokuアプリを削除する方法
heroku apps:destroy --app アプリ名 -confirm アプリ名heroku ログの確認(--tail で監視)
heroku logs --tail修正を反映させる。
ローカルファイルを修正。レジストリコンテナへプッシュ
heroku container:push webレジストリコンテナへリリース
heroku container:release web
- 投稿日:2020-11-15T14:40:46+09:00
Rubocopの設定を誤って地獄を見た件
Rubocopって何?
Rubocop(ルボコップ)とは、Rubyのコードレビューツールの一種です。
コードレビューツールとは、「インデントが揃っていない」 「無駄な改行・スペースがある」などの指摘を、RubyStyleGuideに基づいて、構文チェックを行います。
Rubocop自体は、デフォルトでRubyのコードの書き方についてのルールを保持しています。
1行あたりの文字数制限や、文字列はすべてシングルクォーテーションで囲まなければならない、などです。こうしたルールはすべて、文法的にはエラーにはならないもののコードの可読性を下げるという理由で設定されています。コマンドを叩けば悪しき箇所を表示してくるので、コードの保守性、可読性を保つための必須作業です。
※構文チェックは下記コマンドをターミナルで実行します。 bundle exec rubocop※下記は1行が長すぎると怒られているエラー例
1行が198文字を超えてるから、160文字以下にしなさいと怒られています。
はい、すみません((((;゚Д゚)))))))Offenses: bin/bundle:104:161: C: Layout/LineLength: Line is too long. [198/160] warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"長くなりましたが、そんなRubocopには使用準備が必要です。
現役エンジニアの方から伺った話ですが、実際の開発現場でも先輩エンジニアがコードレビューツールの使用準備を終えており、使用準備に関わらない事は普通にあるそうです。
そんなRubocopの使用準備に関わる機会に恵まれたので、その中で体験した地獄を書き記します。
- Rubocopを構築した環境
- Ruby2.7
- Docker
- Ruby on Rails6
- Vscode
RubyのLintであるonkcop/pre-commitを入れたら、個人開発が幸せになった話
Rubocopの使用準備にあたり、上記の記事を大いに参照しています。
ありがとうございました?Gemfileの記述と、rubocop.ymlファイルの作成
まずはGemfileにGemを導入します。
今回はGemfile内の:development doの部分に以下を記述します。gem 'onkcop', require: false gem 'rubocop-rails'上記のonkcopは、Rubocopの拡張版でオニクコップと読むそうです。
onkcopの公式リポジトリはこちら続いて下記コマンドをターミナルで順に実行します
①bundle install ②bundle exec onkcop initそうすると、.rubocop.ymlというファイルが作成されるので、次のように書き換えます。
rubocop.ymlrequire: - rubocop-rails inherit_from: - "config/rubocop/rubocop.yml" inherit_gem: onkcop: - "config/rails.yml" - "config/rspec.yml" AllCops: TargetRubyVersion: 2.7.1 ←※バージョンはruby -vで確認して合わせましょう。 TargetRailsVersion: 6.0.3.4 ←※バージョンはrails -vで確認して合わせましょう。 Exclude: ←※とても重要な部分 - "vendor/**/*" # rubocop config/default.yml - "db/schema*.rb" - "node_modules/**/*" - "db/migrate/**/*" ←※構文チェックが不要ファイルがあれば、この下に追記していく。使用準備はこれで終わりです。
そしたらコマンドを実行しましょう。rubocopによる構文チェック(パトロール)の実行
あとはターミナルでbundle exec rubocopコマンドを打てば、Rubocopが無駄なコードを炙り出してくれるので適宜修正していきましょう。
bundle exec rubocopコマンドを叩くと、下記のような大量出力が出てきますが、これがコード記述の規約違反です。これらがrubocopのパトロールに引っかかった構文エラーなので、適宜修正していきます。
最終的に、ターミナルでbundle exec rubocopコマンドを打ってコードに問題がなくなれば、下記のような表示に落ち着きます。Inspecting 7 files ....... 7 files inspected, no offenses detectedまた別途、重要になるのは.rubocop.ymlファイル内のExclude: の部分です。
bundle exec rubocopで構文エラーを炙り出すのですが、そもそもパトロールの必要がない部分もあります。Excludeは「除外」の意味なので、Excludeの下にパトロールの必要がないファイル名を記載する事で、Rubocopのパトロール時間が短縮できます。
パトロールの必要がない判断基準としては、Railsで自動生成されたファイルです。
加えて、人間が手を加えないファイルです。
手を加えない自動精製ファイルはパトロールさせるだけ時間の無駄です。具体的には下記のようなRailsで自動作成されるファイルたちの事です。
任意でExclude:の下に追加していきましょう。rubocop.yml※ここより上のコードは省略 AllCops: TargetRubyVersion: 2.7.1 TargetRailsVersion: 6.0.3.4 Exclude: - "vendor/**/*" # rubocop config/default.yml - "db/schema*.rb" - "node_modules/**/*" - "db/migrate/**/*" - "app/channels/**/*" - "config/**/*" - "config.ru" - "bin/**/*" - "public/**/*" - "tmp/**/*" - "log/**/*"上記のようにExclude: の下に追加したディレクトリや配下ファイルは、Rubocopによるパトロール対象外となります。以上でRubocopの設定と使い方は終わりです。
そして、最後に地獄を見た注意事項です。
bundle exec rubocopコマンドの種類に注意せよ!
※要注意コマンド bundle exec rubocop -a bundle exec rubocop -A上記のようなコマンドも存在していますが、これらは安易に使用しては危険です。
Rubocopが親切心で自動修正をしてくれるコマンドですが、使用した事で厄介な事が起きました。必要のない変更が全ファイルに適用されてしまった事です。
コマンドの効果の一つとして、文字列を囲うシングルクォーテーションを、全てのファイルでダブルクォーテーションにRubocopの親切心で自動修正されます。全てのファイルで、です!!
この時点でRubyの規約違反になりますし、英語の文脈がおかしくなる事もあります。
必要のないファイルが変換される無意味さに加え、コードの保守性を損ねるだけです。
コミットをプッシュした後だと更に泣けてきます?コミット前の状態に戻す方法
コミットしたファイルはコミット前に戻す手段は、下記コマンドでコミット前に戻せますが、手動なので修正漏れが発生する恐れがあります。
①git logでコミット番号を確認 ②git checkout {コミット番号} {コミット前に戻したいファイル名}その為、自動修正が必要ないファイルは、上記の.rubocop.ymlファイルのExclude: の下に追加しておく事を強く推奨します。除外さえしておけば、自動修正コマンドが動いてもその影響から免れます。
vscodeを使ったコードの一括修正方法
もし手動でコードを修正する場合ですが、便利な手段を知ったので記載します。
同じファイル内で同一の記述を個別、または全て文字列を任意のものに変換できます。
個別修正と一括修正のどちらも可能ですが、修正の必要不要に関してはコードをチェックした上で行ってください。英語の文法がおかしくなる恐れがあります。
以上でRubocopの構築に際して沼った部分と対策は終わりです。
プログラミングには様々なコマンドがありますが、慣れないコマンドの実行には本当に注意しましょう。((((;゚Д゚)))))))
- 投稿日:2020-11-15T14:10:12+09:00
Docker Toolboxでファイル共有する方法
はじめに
Dockerで立ち上げたコンテナに、ローカルPCの任意のフォルダをマウントすれば
docker内の閉じたNW内に自由にファイルをおけるぜー!って思い、調べた結果をまとめるなぜ今更こんな記事を上げるのか?
googleで「Docker windows ファイル 共有」で検索すれば瞬殺かと思ったらそんなことなくて
・記事の内容を見たら実はDocker for Windows向けだった(※Hyper-V クライアントが実行できないPCはDocker ToolboxでDocker環境を利用するため 参考にならない)
・virtualboxの設定(後述)はあったが、そのあとのdocker上でのコマンド方法の書式があいまいで、結局よくわからなかった
といった感じでイマイチ自分の置かれた環境とハマらなかったので苦労したので、
PCが飛んでもまたやり直せるように記事に残す。手順(概要)
ちょっと概要だけではわけわからないけど、全部で3STEPあるってところが自分の中ではポイントだったのでメモとして残す。
1.Virtualboxにて共有フォルダ設定を行う
2.Docker Machineにてコンテナ用の共有フォルダを作成し、1.の共有フォルダをマウントする
3.コンテナをコンテナ用共有フォルダとコンテナの任意のディレクトリにマウントさせて起動する手順(詳細)
1.Virtualboxにて共有フォルダ設定を行う
1.Oracle VM VirtualBoxを起動する
2.default→右クリック→設定
3.共有フォルダークリック
4.ポップアップしたウィンドウの右側にある共有フォルダ新規追加アイコンをクリック
5.下記内容を入力して「OK」
フォルダーのパス:共有フォルダとして使いたいローカルPCのフォルダパスを入力
例)C:\Users\watya\work\docker
フォルダー名:docker-machineが認識するときのフォルダー名
C:\→/C/、\→/に置き換えるところがポイント
例)/C/Users/watya/work/docker
2.Docker Machineにてコンテナ用の共有フォルダを作成し、1.の共有フォルダをマウントする
Docker Quickstart Terminal を起動し、コマンドを実行する。
以下のコマンドで /e に、1.で設定した共有フォルダー をマウントする。
これで、ローカルPC→VirtualBox→Docker machineというつながりでファイル共有がつながる。
Docker Machine 側に作成するディレクトリ名は e にしてますが、被らなければなんでもよいです。
個人的にはドライブ番号っぽくなって共有フォルダってことがわかりやすいので気に入っている。DockerToolbox$ docker-machine ssh default 'sudo mkdir -p /e' $ docker-machine ssh default 'sudo mount -t vboxsf -o uid=0,gid=0 /C/Users/watya/work/docker /e'3.コンテナをコンテナ用共有フォルダとコンテナの任意のディレクトリにマウントさせて起動する
Docker Toolboxより、コマンドを実行する。
以下のコマンドで、2.で作成した/eがnginxコンテナの/homeにマウントされる。DockerToolbox$ docker run -d -v /e:/home --name nginx nginx確認のためにログインして/homeの内容をチェックすると無事マウントされていることが確認できる
補足:Docker Machine 起動時に自動でマウントするよう設定
参考URL
今回参考にしたサイトは下記の通り。
っていうかこちらのほうが丁寧で内容の説明が深いのでよくわからなくなったら折に触れて立ち返りたい。
https://humo-life.net/memo/doku.php?id=%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2:docker:docker_toolbox%E3%81%A7%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88_%E5%85%B1%E6%9C%89%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80_%E8%A8%AD%E5%AE%9A
- 投稿日:2020-11-15T13:53:21+09:00
Error: EPERM: operation not permitted, open '/usr/src/app/src/App.vue'
npm run serve をした際に operation not permitted が出た。
Error: EPERM: operation not permitted, open '/usr/src/app/src/App.vue'vue-cliアプリをビルドしようとすると、エラーが発生します。依存関係のインストールとアプリの提供は正常に機能していました。
結論
npm install -g @vue/cli --cache /tmp/empty-cache上記コマンドで解決。
環境
- Docker
- Vue
- Vue CLI
$ npm --version $ @vue/cli 4.5.8起きた原因
Vue CLI Issue をみる限り、みなさん npm cache clean force はしているようですね。
自分が今回起きたのは 「build に時間がかかるな」 と思ったので 最近していなかった再起動をしました。
↑ 怒らないでください笑そうすると 今回のErrorが出ました。
理由は正直わかりません。もしわかる方がいらっしゃいましたら、ご教授頂けますと幸いです。
- 投稿日:2020-11-15T13:42:03+09:00
DockerでWordpress開発環境をサクッと構築
はじめに
Dockerはインストール済みとします。
Wordpressのテーマ開発を行う場合にサクッと環境構築できます。Mac 0SX
Docker 19.03.13環境構築
以下のdocker-compose.ymlを環境を作りたいディレクトリに作成してください。
docker-compose.ymlversion: "2" services: wordpress: image: wordpress:latest ports: - "3001:80" depends_on: - mysql env_file: .env volumes: - ./wp-content:/var/www/html/wp-content mysql: image: mysql:5.7 env_file: .env ports: - "3306:3306"docker-compose.ymlを作成したディレクトリに移動して、docker-composeコマンドを実行してください。
bash$ cd 作成したファイルのディレクトリ $ docker-compose build $ docker-compose upブラウザでアクセスしてセットアップ
これで環境が立ち上がったと思いますので、以下のURLでアクセスして、サイト名やDB構築などをします。
http://localhost:3001/すると以下のようなフォルダが作成されるかと思います。
├── docker-compose.yml └── wp-content ├── index.php ├── languages ├── plugins ├── themes ├── upgrade └── uploadsテーマ開発をする際はwp-content/themesの中のテーマを修正することでできます。
2回目移行の立ち上げはDockerのダッシュボードから実行ボタンをクリックして立ち上げるのが早くて便利です。
停止もダッシュボードから行えます。php.iniなどを変更したい場合は、ダッシュボードのwordpress_wordpress_1の右側に表示される「CLI」ボタンをクリックするとコンテナに接続できるので、そこからviなどを使用して編集することができます。
終わりに
なにか間違いがあればご指摘ください。
- 投稿日:2020-11-15T10:16:58+09:00
PHPのパフォーマンス調査 PHP5とPHP7の処理速度
背景
PHP5からPHP7へアップデートするだけで処理速度が大幅にアップするという話を聞いたので検証してみることにした。
※ ごめんなさい。
最もらしい建前を立ててみたけど、嘘です。
実際はQiitaへの投稿に慣れるための記事なので、
1つの例として参考にしてもらえる程度だと嬉しいな。この記事の対象者
- Dockerfileのシンプルなサンプルをみたい人
- Dockerのamazonlinux2コンテナ内でPHPをインストールしたい人
この記事で記載していない内容
- LaravelやCakePHP等、フレームワークのセットアップ方法
- NginxやApache等、ウェブサーバー用ミドルウェアのセットアップ方法
上記の内容が知りたい方は他の記事を参考にされた方が良いと思いますので、そっとページを閉じていただけると幸いです。
検証環境
Machine: Mac mini (2018)
OS: macOS Catalina バージョン 10.15.7
仮想環境: Docker AmazonLinux2イメージ
PHP5: PHP 5.6.40
PHP7: PHP 7.3.24Dockerfileの内容
PHP5もPHP7もログインしてからPHPをインストールするので、同じDockerfileを使用しています
Dockerfile# AmazonLiunx2のイメージを使うよ FROM amazonlinux:2 # ここではユーザー'bearrabi'で管理者用コマンドを使えるようにしてるだけだよ。 # PHPインストールのコマンドはここには書いてないよ RUN yum -y update && \ yum clean all && \ yum install -y sudo && \ yum install -y vim && \ yum install -y systemd && \ yum install -y yum-utils && \ useradd bearrabi && \ echo "bearrabi ALL=NOPASSWD: ALL" >> /etc/sudoers # コンテナログイン時のカレントディレクトリを指定 WORKDIR /usr/local/sbinDocker イメージのビルドからログインまで
terminal# ディレクトリを紐づけるために、ローカルにディレクトリを作成 # 途中のディレクトリが存在しないとエラーになるから注意ね % mkdir /Users/bearrabi/php_56/work # 自分の指定した名前で、Dockerfileの内容をイメージ化 % docker build . -t php_dif_img # イメージからコンテナを生成してログイン可能状態にする % docker run -d --name php_dif_con --privileged -v /Users/bearrabi/php_56/work:/usr/local/sbin:rw php_56_img /sbin/init # 生成したコンテナにログイン % docker exec -it -u bearrabi php_dif_con /bin/bash[【ユーザー】@【コンテナID】 sbin]$ となっていればログインに成功してます。
自分の環境では以下になりました。terminal[bearrabi@82461436bd6c sbin]$PHP5.6をインストール
terminal### epel(Extra Packages for Enterprise Linux)リポジトリをインストール # レポジトリは「貯蔵庫」の意味で、epelはOSに存在していないものを保管します # remiレポジトリをインストールするのに必要です $ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm ### remiレポジトリをインストール # remiレポジトリにはPHPが保管されています $ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm ### 各リポジトリのアップデート $ sudo yum -y update --disablerepo=amzn2-core --enablerepo=epel,remi,remi-php56 ### PHP5.6をインストール $ sudo yum -y install --enablerepo=remi,remi-php56 php56PHPのVersion確認
terminal$ php56 -v PHP 5.6.40 (cli) (built: Sep 29 2020 11:42:56) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend TechnologiesPHP 5.6.40がインストールされました。
処理速度検証(PHP 5.6.40)
ソースコード
test.php<?php // 速度計測の開始時刻をミリ秒で取得 $start_time = microtime(true); // この変数をループ回数の上限とする $max_loop_index = 100000000; // ループで上限値まで繰り返し $counter = 0; for($i=0; $i<$max_loop_index; $i++){ $counter += 1; } // 速度計測の終了時刻をミリ秒で取得 $end_time = microtime(true); // 処理開始から終了まで何ミリ秒必要だったかを取得 $time_defference = $end_time - $start_time; // 計測時間を出力 print "time: ".$time_defference."秒\n"; // ループ処理が最後まで完了しているか確認 print "counter: $counter 回ループ処理を行いました\n"; ?>スクリプトの実行と計測結果
terminal$ php56 test.php time: 8.2781031131744秒 counter: 100000000 回ループ処理を行いました何度やっても大体8.2秒でした。
PHP5.6をPHP7.3へアップデート
terminal# インストール済みのPHPを削除 $ sudo yum -y remove php* # インストール済みのepelレポジトリを削除 $ sudo yum -y remove epel* # 新しいepelレポジトリをインストール $ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-12.noarch.rpm # 新しいremiレポジトリをインストール $ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm # レポジトリのアップデート $ sudo yum -y update --disablerepo=amzn2-core --enablerepo=epel,remi,remi-php73 # php7.3をインストール $ sudo yum -y install --disablerepo=amzn2-core --enablerepo=remi,remi-php73 phpPHPのバージョン確認
terminal$ php -v PHP 7.3.24 (cli) (built: Oct 27 2020 11:01:59) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.24, Copyright (c) 1998-2018 Zend TechnologiesPHP 7.3.24がインストールされました
処理速度検証(PHP 7.3.24)
terminal$ php test.php time: 0.89267206192017秒 counter: 100000000 回ループ処理を行いましたあれ?
全く差がないどころか、PHP7.3の方が少し遅いじゃないか!!考察
恐らく、単純にインタプリタの処理が早くなった訳ではないのでしょう。
他の記事では、ライブラリを利用した計算時の処理速度とメモリの使用状況をモニタリングしていました。この記事では明らかにPHPのバージョンアップによって処理速度が早くなっています。
なので、一概に嘘ではないかと。最後に
今回はPHPのバージョンによる速度の処理速度の検証を行いました。
結果的には、単純な処理をさせても処理速度に差は発生しないという結果です。
パフォーマンス改善を提案する時の簡単なエビデンスとしたかったのですが、残念?とはいえ、Dockerの簡単な使い方や、amazon-extra-installを利用しないPHPのインストール方法など、最小限に記載することはできたかと思います。
どなたかのお役に立てれば幸いですね。以上です。
最後まで読んでいただき、ありがとうございます☺️
- 投稿日:2020-11-15T02:58:30+09:00
GitHub ActionでDockerのビルドキャッシュを有効にしてAmazonECSへデプロイする
やること
GitHub Actionを用いてDockerイメージをビルドし、Amazon ECRに保存し、Amazon ECSへデプロイします。
- ポイント
- 本番運用を想定し、ブランチにリリースを作成した場合にGitHub Actionが動作するようにする。
- Dockerのビルドを高速化するために、ビルドキャッシュを有効にする
準備
- 保存先のECRを作成
- デプロイ先のECRを作成
- GitHub Actionで使用するためのAWS IAMユーザーを作成(ECRとECSの権限が必要です)
これらは作成済みとして進めます。
作成するワークフロー
下記のようなワークフローを作成し、レポジトリの
.github/workflows/
へdeploy-to-ecs.yml
のような適当な名前で保存します。
mainブランチにtagをpushすることにより、このワークフローが動作し、ECRへDockerイメージがpushされ、ECSへデプロイします。
Githubのリリースを用いることにより運用することを想定しています。
.github/workflows/deploy-to-ecs.yml
name: Deploy to ECS on: push: tags: - v* env: ECR_REPOSITORY: your-repository-name ECS_SERVICE: your-service-name ECS_CLUSTER: your-cluster-name jobs: deploy: name: Deploy to ECS if: github.event.base_ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Configure AWS Credentials # AWSアクセス権限設定 uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: Login to Amazon ECR # ECRログイン処理 id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Set Docker Tag Env # Docker Imageのバージョンをタグに合わせる run: echo "::IMAGE_TAG=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")" >> $GITHUB_ENV - name: Build, tag, and push image to Amazon ECR # Docker イメージ Build&Push env: DOCKER_BUILDKIT: 1 ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} run: | docker build --cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 -f Dockerfile -t $ECR_REPOSITORY . docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:latest docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest - name: Render Amazon ECS task definition for app container # appコンテナのECSタスク定義ファイルレンダリング id: render-app-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: task-definition: .aws/ecs/task-definition.json container-name: app image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} - name: Deploy to Amazon ECS service # ECSサービスデプロイ uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.render-app-container.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} wait-for-service-stability: false解説
ワークフローの動作について上から順に具体的に説明します。
1. ワークフロー名
name: Deploy to ECSワークフローの名前を決めています。Githubのレポジトリ、Actionタブからワークフローを一覧で確認する際などにこの名前が表示されます。検証環境や本番環境で複数のワークフローを作成する場合は、区別できる分かりやすい名前に変更する事を推奨します。
2. ワークフローの動作条件
on: push: tags: - v*
v1.0.0
のようなv
で始まるタグがpushされた場合に動作するようにしており、リリースの作成によりこのワークフローが動作することを想定しています。
また、今回は他のブランチにタグがpushされてしまった場合に動作をしないようにjobs内にif: github.event.base_ref == 'refs/heads/main'のようにmainブランチではない場合には動作をしないようにしています。
特定のブランチにpushされた場合に動作するようにするには
if
の記述を無くしon: push: branches: - target-branchのように記述してください。(target-branchはデプロイ対象とするブランチに変更して下さい。)
補足
on: push:
の記述方法で、特定のブランチにタグがpushされた場合動作するという事を実現するためにon: push: tags: - v* branches: - target-branchのように記述すると、and条件ではなくor条件(タグかブランチのどちらかがpushされた場合)になってしまう為、
on: push:
で対象のタグを指定し、if
で対象のブランチを指定しています。3. 環境変数への代入
env: ECR_REPOSITORY: your-repository-name ECS_SERVICE: your-service-name ECS_CLUSTER: your-cluster-namejobで何度も使う値の記述を減らすために環境変数へ代入しています。
your-〇〇〇-name
は各自の環境のものへ変更して下さい4. Jobsの実行開始
jobs: deploy: name: Deploy to ECS if: github.event.base_ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2
ubuntu-latest
の環境にて対象ブランチにcheckoutし、jobの実行を始めます。
(先程にも記述しましたが、タグがpushされた場合のmainブランチでのみ実行するようにif
行を記述しています。動作条件をブランチのpushに変更した場合は不要です。)5. AWSへのログイン
- name: Configure AWS Credentials # AWSアクセス権限設定 uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1pushを行うECR、デプロイ先のECSを作成してあるAWS アカウントへログインをしています。
Githubのシークレットを用いてデプロイを行うIAMのアクセスキーとシークレットキーをAWS_ACCESS_KEY_ID
とAWS_SECRET_ACCESS_KEY
へ登録してください。6. ECRログイン
- name: Login to Amazon ECR # ECRログイン処理 id: login-ecr uses: aws-actions/amazon-ecr-login@v15.でログインしたAWSアカウントのECRへのログインを行います。
7. Dockerのイメージタグの設定
- name: Set Docker Tag Env # Docker Imageのバージョンをタグに合わせる run: echo "::IMAGE_TAG=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")" >> $GITHUB_ENVDockerのイメージタグがgitのtagと同じ値になるようにpushされたtagを
v1.0.0
のような形式で取り出し、環境変数へ代入しています。
ワークフローの動作条件にタグを用いない場合は、run: echo "::IMAGE_TAG=${{ github.sha }}" >> $GITHUB_ENVのようにコミットハッシュを用いてイメージタグが一意になるようにすると良いと思います。
8. Dockerイメージのビルド&ECRへのPush
- name: Build, tag, and push image to Amazon ECR # Docker イメージ Build&Push env: DOCKER_BUILDKIT: 1 ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} run: | docker build --cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 -f Dockerfile -t $ECR_REPOSITORY . docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:latest docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker push $ECR_REGISTRY/$ECR_REPOSITORY:latestローカルでDockerイメージをビルドする場合、前回にビルドしたイメージを用いてビルドが高速化されますが、GitHub Actionでは前回のビルド結果を保持していないため、毎回ビルドに時間が掛かってしまいます。
そこで、ここではDockerのdocker build --cache-from
を用いてビルドの高速化を行っています。
行っている内容としては、dockerイメージをビルドし、環境変数IMAGE_TAGに保存されているタグをpushしつつ、その値はワークフローの動作毎に動的に変化してしまい、前回ビルドした際の値を取得することが難しいためlatestタグもpushし、latestタグをキャシュに用いるようにしています。このようにすることにより、リリースタグと整合性を取りつつ、キャッシュを用いれます。
(DOCKER_BUILDKIT
,BUILDKIT_INLINE_CACHE
は--cache-from
を用いるために必要なため記述しています。)
注意: Dockerのマルチステージビルドを用いている場合は、Dockerのイメージ中にビルドプロセスが全て含まれていないためこの方法ではキャッシュできません。その場合は、このような記事を参考にすると良いと思います。9. ECSタスク定義の作成
- name: Render Amazon ECS task definition for app container # appコンテナのECSタスク定義ファイルレンダリング id: render-app-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: task-definition: .aws/ecs/task-definition.json container-name: app image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}ECSの実行にはタスク定義が必要になり、そこに使用するDockerイメージのレポジトリやタグの情報を記述する必要があります。
従って、DockerImageを更新した際はタスク定義の更新も必要になり、その処理を行っています。今回はレポジトリへタスク定義ファイル
.aws/ecs/task-definition.json
を作成してあり、そのファイルを呼び出し、Dockerイメージの情報を更新しています。
task-definition.json
の参考例){ "containerDefinitions": [ "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ], "image": "your-image-name", "name": "app" } ], "cpu": "256", "executionRoleArn": "your-role-name", "family": "your-family", "memory": "512", "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc" }s3から読み出す事も可能のようなので各々お好きなタスク定義の管理をして下さい。
10. ECSへデプロイ
- name: Deploy to Amazon ECS service # ECSサービスデプロイ uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.render-app-container.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} wait-for-service-stability: false9で作成したタスク定義をもとにECSへデプロイしています。
wait-for-service-stability
をtrue
にすることにより、デプロイが完了するまで実行完了を待機させ、デプロイ完了を通知すること等が可能ですが、Github Actionsの実行時間が増加してしまい、実行枠を越えてしまう等の可能性が存在します。
AWS Lambdaを用いてデプロイの完了をフックし、通知する事も可能なのでデプロイの多い環境ではそうする事を推奨します。11. おわり
上記のフローが正しく動作すればデプロイ完了です。
おまけ. task単体の実行
- name: Run Migrate # Migrationを実行 env: CLUSTER_ARN: your_cluster_arn ECS_SUBNER_FIRST: your_subnet_first ECS_SUBNER_SECOND: your_subner_second ECS_SECURITY_GROUP: your_security_group run: | aws ecs run-task --launch-type FARGATE --cluster $ECS_CLUSTER --task-definition ${{ steps.put-migrate-task.outputs.render-app-container }} --network-configuration "awsvpcConfiguration={subnets=[$ECS_SUBNER_FIRST, $ECS_SUBNER_SECOND],securityGroups=[$ECS_SECURITY_GROUP],assignPublicIp=ENABLED}" > run-task.log TASK_ARN=$(jq -r '.tasks[0].taskArn' run-task.log) aws ecs wait tasks-stopped --cluster $CLUSTER_ARN --tasks $TASK_ARN今回デプロイ前にDBのmigrationを行いたく、このようなjobを手順10のECSへデプロイ前に追加しtaskを単体で実行しました。
このようにすることにより、Github Actions内でtask単体を実行することも可能です。まとめ
ECSへのデプロイですとAWS CodeBuild、AWS CodePipelineを組み合わせるといった選択肢もあると思いますが、GitHub Actionを用いても簡単にデプロイすることが可能です。
参考記事
下記の記事を大変参考にさせて頂きました。
- 投稿日:2020-11-15T01:56:50+09:00
APIとフロントのアプリ両方が含まれたdocker-composeプロジェクトに VSCode Remote Containersを導入する方法
背景
- 社内で新規プロジェクトを立ち上げる上で、Visual Studio Code(以下 VSCode)のプラグインであるRemote - Containersを使用して開発したかった。
- docker利用で、アプリケーションの動作環境はチーム内で共通化できるが、エディタの動作環境の構築は各メンバーに任されたままである。今回のプロジェクトでは、eslintやrubocopなどの構文チェックやコード補完ツールを複数個入れることが序盤から決まっていたので、Remote - Containersを入れることで、エディタの動作環境もまとめてdockerでメンバーと共有して効率化したかった。
- 今回のプロジェクトでは、同一プロジェクトの中で、APIとフロントを別々のレポジトリとしてgit管理しており、それらを同一のdocker-compose.ymlで管理しているという条件だった。この場合のRemote - Container設定の書き方でかなり悩んだ。
想定読者
- すでに
docker-compose.yml
で管理しているプロジェクトがあり、そのプロジェクトの中に複数のアプリケーション(例:APIとフロント)が含まれている- それぞれのアプリケーションを Remote - Containersで開発できるようにしたい
修正前のプロジェクト構成
フォルダ構成
project-docker
┣ project-api (railsのレポジトリ)
┃ ┣ app
┃ ┣ ...
┃ ┗ Gemfile
┣ project-front (Next.jsのレポジトリ)
┃ ┣ .next
┃ ┣ ...
┃ ┗ package.json
┣ docker-compose.yml
┣ Dockerfile.backend
┗ Dockerfile.frontend
project-docker
直下でdocker-compose up
を叩くと、APIとフロント(とDB)が同時に起動してハッピー、という構成。docker-compose.yml
docker-compose.yml
が 以下。ひとまずservices
が少なくとも以下の3つがある。
- db
- backend
- frontend
※本当はredisとかsmtpとかもあったけどこの記事の趣旨には関係ないから除外した
docker-compose.yml(一部省略)services: db: image: postgres:11.5 ports: - "5432:5432" backend: build: context: . dockerfile: Dockerfile.backend volumes: - ./project-api:/project-api command: /bin/sh -c "rm -f /api-okapi/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" ports: - "3000:3000" depends_on: - db frontend: build: context: . dockerfile: Dockerfile.frontend command: npm run dev volumes: - ./project-front:/project-front ports: - "8080:8080"Remote - Containers の導入手順
- 基本的には、各レポジトリ(project-api, project-front)の下に Remote - Containers の設定ファイルを入れるディレクトリ
.devcontainer
を作成し、その下にdevcontainer.json
とdocker-compose.extend.yml
の2つの設定ファイルを作成するのが目標になります。前提
- VScodeおよびdockerはインストール済み
- VScodeの拡張機能ペインから、Remote - Containers をインストール済み
- インストールすると、VScodeの画面左下にRemote - Containersのアイコンが追加されます
手順
api側を例に解説します。front側は同じことをやり直してください。
1.
.devcontainer
を自動作成する
- 「file(ファイル)」の「open workspace(ワークスペースを開く)」から、
project-docker
を開く- 画面左下にRemote - Containersのアイコンをクリックし、
Reopen in Container
を選択From docker-compose.yml
を 選択- select a service で
backend
を選択project-docker
直下に、.devcontainer
ディレクトリと、 その下にdevcontainer.json
とdocker-compose.yml
の2つの設定ファイルが作成されるので、これをproject-api
の下に移動させる2.
.devcontainer/devcontainer.json
の修正自動的に作られた直後の
.devcontainer/devcontainer.json
は以下です。devcontainer.json// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { "name": "Existing Docker Compose (Extend)", // Update the 'dockerComposeFile' list if you have more compose files or use different names. // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. "dockerComposeFile": [ "../docker-compose.yml", "docker-compose.yml" ], // The 'service' property is the name of the service for the container that VS Code should // use. Update this value and .devcontainer/docker-compose.yml to the real service name. "service": "backend", // The optional 'workspaceFolder' property is the path VS Code should open by default when // connected. This is typically a file mount in .devcontainer/docker-compose.yml "workspaceFolder": "/workspace", // Set *default* container specific settings.json values on container create. "settings": { "terminal.integrated.shell.linux": null }, // Add the IDs of extensions you want installed when the container is created. "extensions": [] // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Uncomment the next line if you want start specific services in your Docker Compose config. // "runServices": [], // Uncomment the next line if you want to keep your containers running after VS Code shuts down. // "shutdownAction": "none", // Uncomment the next line to run commands after the container is created - for example installing curl. // "postCreateCommand": "apt-get update && apt-get install -y curl", // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. // "remoteUser": "vscode" }これを以下に書き換えます。
devcontainer.json(修正部分のみ){ "name": "project-api-docker", // 適当にナイスな名前にする "dockerComposeFile": [ "../../docker-compose.yml", // フォルダ移動したのでパスを修正 "docker-compose.extend.yml" // .extend をつける (動作するだけなら不要だけど私はわかりやすさを重視して名前を変えました) ], "runServices": [ "db", "backend", // stmpなど他のサービスがあれば追加。 "frontend" を 含めないのが重要。空だと、デフォルトで全てのserviceを起動する。 ], "workspaceFolder": "/workspace/project-api/", // workspaceを project-api にする }3.
docker-compose.yml
の修正自動的に作られた直後の
.devcontainer/docker-compose.yml
は以下です。docker-compose.ymlversion: '3' services: # Update this to the name of the service you want to work with in your docker-compose.yml file backend: # If you want add a non-root user to your Dockerfile, you can use the "remoteUser" # property in devcontainer.json to cause VS Code its sub-processes (terminals, tasks, # debugging) to execute as the user. Uncomment the next line if you want the entire # container to run as this user instead. Note that, on Linux, you may need to # ensure the UID and GID of the container user you create matches your local user. # See https://aka.ms/vscode-remote/containers/non-root for details. # # user: vscode # Uncomment if you want to override the service's Dockerfile to one in the .devcontainer # folder. Note that the path of the Dockerfile and context is relative to the *primary* # docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile" # array). The sample below assumes your primary file is in the root of your project. # # build: # context: . # dockerfile: .devcontainer/Dockerfile volumes: # Update this to wherever you want VS Code to mount the folder of your project - .:/workspace:cached # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details. # - /var/run/docker.sock:/var/run/docker.sock # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. # cap_add: # - SYS_PTRACE # security_opt: # - seccomp:unconfined # Overrides default command so things don't shut down after the process ends. command: /bin/sh -c "while sleep 1000; do :; done"まず、ファイル名を
.devcontainer/docker-compose.extend.yml
に変更しておきます。
これは、.devcontainer/docker-compose.extend.yml
は、project-docker
直下のdocker-compose.yml
の一部要素を上書きしているだけの存在であることをわかりやすくするためです。そして、
.devcontainer/docker-compose.extend.yml
の中身を以下に書き換えます。docker-compose.extend.yml(修正部分のみ)services: backend: volumes: - .:/workspace:cached - ~/.gitconfig:/root/.gitconfig # ローカルの.gitconfig設定をコンテナ内に共有するため、コンテナ側のホームディレクトリ(この場合は/root)にマウントします。 - ~/.ssh:/root/.ssh # ローカルの.ssh 設定ををコンテナ内に共有するため(以下略) - /var/run/docker.sock:/var/run/docker.sock # 一応アンコメントしてるけど必要性がよくわかってない。誰か教えてください・・・ command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0' ; while sleep 1000; do :; done"
- 特に
command
の修正が重要。元の記述のままだと、親玉のdocker-compose.yml
のbackend
のcommand
(今回の場合はrailsのサーバー起動コマンド) を上書きしているので、サーバーが起動しません。 元の記述を持ってきて、最後にwhile sleep 1000; do :; done
を加えます。- circleci系のコンテナなど、 コンテナ側のユーザがrootではないコンテナを使っている場合は、"environment" で環境変数 HOME の指定が必要だそうです。詳しくはこっちの記事を参照してください。
4. Remote - Containers で開く
- 設定が完了したので、「file(ファイル)」の「open workspace(ワークスペースを開く)」から、このリポジトリの直下にcloneした api-okapi (or front-okapi) を開きます。
- 左下のアイコンをクリックし、
Remote-Containers: Reopen in Container
を選択します。- 自動的にcontainerが起動し、コンテナ内でVSCodeが開きます。(ビルドが必要な場合、長い時間がかかります)
front側の相違点
- front側を設定するときは、
runServices
の中をfrontend
のみにしてください。devcontainer.json(修正部分のみ){ "runServices": [ "frontend" // "db", // "backend", ], }
- このように、backend側とfrontend側で起動するserviceを振り分けることで、同時にbackend側とfrontend側をRemote - Containersで起動しても、それぞれのレポジトリで起動するserviceが衝突しないので安心。(必要ないかもしれない。誰か詳しい人教えてください)
- 親の
docker-compose.yml
の方でdepends_on
を指定していると、runServices
の設定から外しても起動するのでご注意ください。導入後の設定
VScodeのエディタ設定の変更
- 例: .tsファイルを保存する度に、ESLintでフォーマットが走るようにする
- 各レポジトリの
.devcontainer/devcontainer.json
のsettings
の中を修正してください。
- ここが
.vscode/settings.json
の代わりになります。.devcontainer/devcontainer.json{ "settings": { "editor.codeActionsOnSave": { "source.fixAll.eslint": true // ファイル保存時にESLintでフォーマット } ... }, }VScodeのプラグイン設定の変更
- 例: eslint の VScodeプラグインを入れる
- 各レポジトリの
.devcontainer/devcontainer.json
のextensions
の中を修正してください。
- 各プラグインのIDは、VScodeの拡張機能ペインにて、該当のプラグインを右クリックして「拡張機能IDをコピーする」で取得できます。
- 通常通り、VScodeの拡張機能ペインからプラグインを追加することもできますが、この場合、他の開発者の環境には追加されないっぽい?。
.devcontainer/devcontainer.json{ "extensions": [ "dbaeumer.vscode-eslint", ... ], }bash設定の変更
- 例: gitコマンドの補完スクリプトを入れる
.bashrc
などのファイルを準備した上で、docker-compose.yml
のvolume
を修正して、container側のホームディレクトリ(この場合は/root
)直下にマウントしてください。
- 以下では、
project-docker
の 下にbash-config
フォルダを用意して、親玉の方のdocker-compose.yml
でマウントの設定をしてます。docker-compose.ymlfrontend: volumes: - ./bash-config/.bashrc:/root/.bashrc - ./bash-config/.git-completion.bash:/root/.git-completion.bash - ./bash-config/.git-prompt.sh:/root/.git-prompt.sh ...
- 各レポジトリでbashの設定を変えたい場合は、 各レポジトリ以下に
bash-config
フォルダを用意してdocker-compose.extend.yml
の設定を変えるといいでしょう。参考
VSCode Remote Container関連
- VSCode Remote Containerが良い
- Dockerで立ち上げた開発環境をVS Codeで開く!
- VS Code Remote Development で Docker 開発環境を利用する
導入後の設定関連
- 投稿日:2020-11-15T01:20:35+09:00
Dockerコンテナ内でgnome-terminalの実行を試みるもエラー(ailed to execute child process “dbus-launch” (No such file or directory))
Dockerコンテナ内でgnome-terminalの実行を試みるも以下の通りエラー
# gnome-terminal -e "python3 test.py" # Option “-e” is deprecated and might be removed in a later version of gnome-terminal. # Use “-- ” to terminate the options and put the command line to execute after it. # Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Failed to execute child process “dbus-launch” (No such file or directory)dbus-x11をインストールして解決
sudo apt-get install -y dbus-x11gnome-terminalがない場合は以下でインストール可能
sudo apt-get install -y gnome-terminal参考
- 投稿日:2020-11-15T01:20:35+09:00
Dockerコンテナ内でgnome-terminalの実行を試みるもエラー(Failed to execute child process “dbus-launch” (No such file or directory))
Dockerコンテナ内でgnome-terminalの実行を試みるも以下の通りエラー
# gnome-terminal -e "python3 test.py" # Option “-e” is deprecated and might be removed in a later version of gnome-terminal. # Use “-- ” to terminate the options and put the command line to execute after it. # Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Failed to execute child process “dbus-launch” (No such file or directory)dbus-x11をインストールして解決
sudo apt-get install -y dbus-x11gnome-terminalがない場合は以下でインストール可能
sudo apt-get install -y gnome-terminal参考