- 投稿日:2020-02-20T21:52:04+09:00
Laravelでミニブログを作ろう #1
laravelの使い方を一通り習ったので、laravelを使って(競プロの勉強の合間に)ちょこちょこミニブログを作っていくことにします。
作成していく過程で最近学習したAWSだったりCircle CIだったりの復習をしていければと考えてます。
(果たして完成するまでに何ヶ月かかるのか)要件定義
アプリの概要
Markdown記法で記事が書けるミニブログ
主要な機能
- 記事の作成、編集、更新、削除、下書き(ユーザーは複数人登録できる)
- 画像投稿
- タグ付け機能(記事を作成したユーザー以外もタグ付けできる)
- いいね機能
- Markdownエディタ
- レスポンシブデザイン
- 管理人機能(ユーザー一覧、ユーザー詳細表示)
技術要件
- フロント
- Vue.js (いいね機能、タグ付け機能の実装のため)
- Scss
- バックエンド
- php
- laravel
- サーバー
- nginx
- DB
- mysql 5.7(ローカル)
- RDS(AWS)
- インフラ
- AWS
- ECS/ECR
- RDS(mysql)
- EC2
- S3
- VPC
- Route53
- ALB
- ACM
- Terraform(AWSをコード化)
- heroku(多分AWS版のアプリ完成した後、herokuに移行すると思います。お金無いので)
- CircleCI
その他Googleアナリティクスの導入
(非技術要件も定義できれば尚良いんですが...)
作成手順
環境設定(Dockerfile→Circle CI,PHPUnit(テスト),Terraform等)→laravelでアプリの中身を作り上げていく→デプロイ の流れ
laravelのインストール
rootディレクトリに移動してlaravelをインストールします
$ composer create-project laravel/laravel larablog─── laravel(ルートディレクトリ) ├── larablog ・・・今回のアプリ ├── app ├── bootstrap . . .次回からDockerfileを書いていきます
- 投稿日:2020-02-20T21:38:29+09:00
手探りDocker #1
Dockerというものを最近目にするので少しずつやっていこうかと思います。
まったく何が何だかわからないままやり始めます。
ちょろっとdockerとはなんぞや?と事を読んだくらい。
全然頭に入ってません。導入や理解は以下を参考にさせていただきました。
Docker入門 #1 【Dockerとは】Dockerインストール
英語読めないので翻訳しちゃいました・・・
どうやらDocket Hubからインストーラーを入手する模様
メモリが4GBのPCのせいか、メモリ不足のエラーがでたので、タスクトレイの赤いアイコンを右クリック
→ Setting → Resources → Memoryを1GBにしました。
この設定でリスタート
何をすればよいのかわからない・・・
DockerのサイトのGet startedを参考にやってみる
Get startedPowerShellで
run hello-world
をやってみる
docker image ls
やdocker container ls -all
を打って、なんかダウンロードされていることが確認できます。
続いてその下のExplore the applicationもやっていきます。
OSイメージ取得
Ubuntu?イメージの取得らしいです。Linux自体もあまり経験がなくて、疎いです・・・
docker run --interactive --tty ubuntu bash
なんかTerminalを表示させたみたいな感じになりました!
WebServer取得
次にnginxというフリーのWebServerを取得します。(初めて聞いた・・・)
docker run --detach --publish 80:80 --name webserver nginx
実行後、
https://localhost
にアクセスすると下記が表示されました。
ポートを指定しなくてよいのは
--publish 80:80
としているからっぽいですね。WebServerを停止する際は以下コマンドのようです。
docker container stop webserver
いままでのコマンドの中で
--xxx
等がありましたが、それらの日本語説明が以下にあるようです。
Docker-docs-jaふとdockerの画面に目をやると以下のように、いままで取得したコンテナ?が表示されてました。
GUIから、表示されているそれぞれのアイコンをクリックすることで、コンテナの開始や停止、削除等ができるようです。
左から
- ブラウザで表示
- CLIを起動
- Stop
- Restart
- Delete
今回はここまでとして
次回はサンプルアプリを動かしてみたいと思います。
- 投稿日:2020-02-20T20:13:39+09:00
Railsチュートリアルの開発環境を Docker でもっと便利にしなイカ!?
【概要】
本記事では、Gem の永続化、データベース及びテスト用メールサーバをコンテナ化していきます。
Railsチュートリアルの開発環境を Docker にしてみなイカ?の続きです。さて、前回の記事では、Railsチュートリアルの Sample App をコンテナ化しました。
しかし、実際の開発にあたり、煩わしい部分や便利になるところがありますので、改善していきましょう。
- 開発環境
- macOS Mojave: 10.14.6
- Docker Engine: 19.03.5
- Docker Compose: 1.25.4
- コンテナ環境
- Alpine Linux: 3.11.3
- Ruby: 2.4.9
- Rails: 5.1.2
- 参考: 学習情報 URL
【本文】
□ 事前準備
- 前回の記事と同じファイル及びディレクトリ構成です。
docker/DockerfileFROM ruby:2.4.9-alpine3.11 ENV LANG C.UTF-8 \ TZ Asia/Tokyo ENV BUILD_PACKAGES="build-base" \ DB_PACKAGES="sqlite-dev postgresql-dev" \ RAILS_PACKAGES="tzdata nodejs imagemagick" \ FAVORITE_PACKAGES="less" RUN apk update && \ apk upgrade && \ apk --update --no-cache add \ ${BUILD_PACKAGES} \ ${DB_PACKAGES} \ ${RAILS_PACKAGES} \ ${FAVORITE_PACKAGES} WORKDIR /app COPY Gemfile \ Gemfile.lock \ /app/ RUN bundle install --jobs=4 # 下記のコードは、頻繁に Gemfile を変更する場合、コメントアウトを推奨します。 # RUN apk del ${BUILD_PACKAGES} # https://github.com/bundler/bundler/issues/6154 ENV BUNDLE_GEMFILE='/app/Gemfile'docker-compose.ymlversion: '3' services: app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - ./:/app:cached stdin_open: true tty: true□ Gem の永続化
■ 現状の問題点
- 結論から言うと、現状では Gemfile を編集する度に
docker-compose build
をする必要があリます。つまり、大量の Gem を初めから全てbundle install
することになる煩わしい状態なのです。- 理由としては、コンテナの構造によるものであり、この問題点を体験したい場合、事前準備の条件で以下の通り動かしてみると良いでしょう。1
bash(省略可)# (1) コンテナのイメージ構築(ここのイメージがコンテナ構築時のデフォルト設定) $ docker-compose build # (2) コンテナを構築及び起動 $ docker-compose up -d # (3) Gemfile に Gem を追加 ... group :development, :test do ... gem 'pry-rails' gem 'pry-byebug' end ... # (4) 起動済のコンテナ内で bundle install $ docker-compose exec app bundle install # (5) 追加した Gem が確認できる( /usr/local/bundle/ にインストールされている) $ docker-compose exec app gem list # (6) コンテナを削除 $ docker-compose down # (7) コンテナを起動すると... $ docker-compose up > Starting sample_app_app_1 ... done > Attaching to sample_app_app_1 > app_1 | Could not find pry-byebug-3.4.3 in any of the sources > app_1 | Run `bundle install` to install missing gems. > sample_app_app_1 exited with code 7 # (8) 結果 - pry-byebug が見つからないため、bundle install が必要な状態です。 - つまり、コンテナの状態が(1)に戻ってきていることがわかります。■ 解決策
- 前述の通り原因は、
起動したコンテナ内で bundle install
するだけで、設計図となるコンテナのイメージ自体に反映されていないことです。解決策としては、Gem をコンテナ外で管理することです。コンテナを削除しても、Gem が存在する場所に影響しません。ここでは、コンテナ外に Gem の保管場所( = volume )を作成して、コンテナ内の Gem を保存する場所と繋げます( = mount )。
参考URL
○ 1: docker-compose.yml に data volume を追加
docker-compose.ymlversion: '3' services: datastore: image: busybox + volumes: + - bundle_install:/usr/local/bundle app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: + - bundle_install:/usr/local/bundle - ./:/app:cached stdin_open: true tty: true + volumes: + bundle_install:○ 2: 再度 bundle install
bash# 前の手順で、Gemfile に Gem を追加していましたら、該当箇所を一度コメントアウトしてください。 # (1) コンテナのイメージ構築 $ docker-compose build # (2) コンテナを構築及び起動 $ docker-compose up -d # (3) Gemfile に Gem を追加 ... group :development, :test do ... gem 'pry-rails' gem 'pry-byebug' end ... # (4) 起動済のコンテナ内で bundle install $ docker-compose exec app bundle install # (5) コンテナを削除 $ docker-compose down # (6) コンテナを起動すると正常に動作しています。 $ docker-compose up○ 3: どこに保存されたのか?
- では、データの保管先を確認してみましょう。
- 追加した volume は、通常のディレクトリに存在せず、別の場所に存在しています。なお、ディレクトリ内を探検してみると、コンテナも保存していることがわかります。
bash(省略可)# Moby VM にアクセス $ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty -s # 〜VM内操作へ移行〜 # 以下のコマンドにより、`sample_app_bundle_install/`の存在が確認できる。 $ ls /var/lib/docker/volumes/ # この Volume は、data_store で定義した通り、`/usr/local/bundle`を保存する。 $ ls /var/lib/docker/volumes/sample_app_bundle_install/_data # 終了時 $ `controll` + `A` + `K` $ yes○ 4: Gem の永続化完了
- ここまでで、Gem の永続化が完了したため、次はデータベースをコンテナ化します。
- もちろん、データベースをコンテナ化したとしても、コンテナの削除時にデータベースに保存したデータは失われてしまいます。そのため、Gem の永続化と同様にデータベースも併せて永続化していきます。
□ データベースのコンテナ化
■ 現状の問題点
- Sample App における本番環境のデータベースは PostgreSQL で、開発環境は SQLite を使用しています。しかし、基本的に開発環境と本番環境は、同一化が求められます。「開発環境では動いたのに本番で動かない(絶望)」ということ自体があってはなりません。
しかし、これを実践しようとしてローカル環境で開発するとき、逐一 PostgreSQL を起動したり、プロジェクトによって異なるバージョンを用意する必要があったり、煩わしい部分があるため、コンテナ化します。
参考URL
■ 解決策
○ 1: docker-compose.yml の編集
docker-compose.ymlversion: '3' services: datastore: image: busybox volumes: - bundle_install:/usr/local/bundle + - db_data:/var/lib/postgresql/data + db: + image: postgres:12.2-alpine + volumes: + - db_data:/var/lib/postgresql/data + ports: + - 5432:5432 + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: pass app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - bundle_install:/usr/local/bundle - ./:/app:cached + depends_on: + - db + environment: + APP_DATABASE_HOST: db + APP_DATABASE_USERNAME: root + APP_DATABASE_PASSWORD: pass stdin_open: true tty: true volumes: bundle_install: + db_data:○ 2: config/database.yml の編集
- Rails の DB 設定は、SQLite のままであるため、PostgreSQL に変更します。
- なお、ここでは差分表示していませんので、全て置換してください。
config/database.ymldefault: &default adapter: postgresql pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: <%= ENV.fetch("APP_DATABASE_HOST") { '127.0.0.1' } %> port: <%= ENV.fetch("APP_DATABASE_PORT") { '5432' } %> username: <%= ENV.fetch("APP_DATABASE_USERNAME") { 'root' } %> password: <%= ENV.fetch("APP_DATABASE_PASSWORD") { 'pass' } %> development: <<: *default database: sample_app_development test: <<: *default database: sample_app_test production: <<: *default database: sample_app_production○ 3: Gemfile の編集
- 開発環境を PostgreSQL に変更するため、現在の Gemfile の構成もついでに変更しておきます。
Gemfile... group :development, :test do - gem 'sqlite3', '1.3.13' gem 'byebug', '9.0.6', platform: :mri gem 'pry-rails' gem 'pry-byebug' end ... - group :production do - gem 'pg', '0.18.4' - end + gem 'pg', '0.18.4' ...○ 4: DB コンテナの起動
bash# コンテナと volume を削除してから起動 $ docker-compose down -v $ docker-compose up -d○ 5: データベースの作成
bash$ docker-compose exec app rails db:create $ docker-compose exec app rails db:migrate $ docker-compose exec app rails db:seed○ 6: DB のコンテナ化完了
- これで、DB のコンテナ化が完了です。
- DBコンテナに入って実際に確認したい場合は、次の通り操作してみてください。
bash(省略可)# DB コンテナに入る $ docker-compose exec db ash # PostgreSQL に登録されている Sample App のデータベースに接続 $ psql -U root -d sample_app_development # テーブル生成の確認 sample_app_development=$ \dt sample_app_development=$ exit□ メールサーバのコンテナ化
■ 現状の問題点
- 特にありませんが、一つのコマンド打つだけで見れるのですから、あったら便利ですよね。
また、メールのデータも永続化できますが、ここで残すメリットを感じられなかったため、実装していません。永続化したい方は、参考URL等を確認しつつ実装してみてください。要領は前項までと同じです。
参考URL
■ 解決策
○ 1: docker-compose.yml の編集
docker-compose.ymlversion: '3' services: datastore: image: busybox volumes: - bundle_install:/usr/local/bundle - db_data:/var/lib/postgresql/data db: image: postgres:12.2-alpine volumes: - db_data:/var/lib/postgresql/data ports: - 5432:5432 environment: POSTGRES_USER: root POSTGRES_PASSWORD: pass app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - bundle_install:/usr/local/bundle - ./:/app:cached depends_on: - db environment: APP_DATABASE_HOST: db APP_DATABASE_USERNAME: root APP_DATABASE_PASSWORD: pass stdin_open: true tty: true + smtp: + image: mailhog/mailhog + ports: + - '8025:8025' volumes: bundle_install: db_data:○ 2: 開発環境のメール設定を編集
config/environments/development.rb... # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = true - config.action_mailer.delivery_method = :test - host = 'railstutorial-yasulab.c9users.io' - config.action_mailer.default_url_options = { host: host, protocol: 'https' } + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { + address: "smtp", + port: "1025", + } + config.action_mailer.default_url_options = { host: "localhost:3000" } ...○ 3: メールサーバのコンテナ化完了
- これで、メール確認が容易になりました。試しに SignUp してみるとアクティベーションメールが以下のURLに届きます。
- http://localhost:8025
□ 特記事項
■ 注意事項
- 今のところ特になし
■ 使用イメージ、ライブラリ
- ruby - Docker Hub
- busybox - Docker Hub
- postgres - Docker Hub
- mailhog/MailHog: Web and API based SMTP testing
- mysql - Docker Hub
□ おまけ: DB を MySQL にしたい場合
○ 1: Dockerfile の編集
docker/Dockerfile... ENV BUILD_PACKAGES="build-base" \ - DB_PACKAGES="postgresql-dev" \ + DB_PACKAGES="mysql-client mysql-dev" \ RAILS_PACKAGES="tzdata nodejs imagemagick" \ FAVORITE_PACKAGES="less" ...○ 2: docker-compose.yml の編集
docker-compose.yml... + db: + image: mysql:5.7 + volumes: + - db_data:/var/lib/mysql + ports: + - 3306:3306 + environment: + MYSQL_ROOT_PASSWORD: pass - db: - image: postgres:12.2-alpine - volumes: - - db_data:/var/lib/postgresql/data - ports: - - 5432:5432 - environment: - POSTGRES_USER: root - POSTGRES_PASSWORD: pass ...○ 3: config/database.yml の編集
config/database.ymldefault: &default adapter: mysql2 charset: utf8mb4 collation: utf8mb4_bin encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: <%= ENV.fetch("APP_DATABASE_HOST") { '127.0.0.1' } %> port: <%= ENV.fetch("APP_DATABASE_PORT") { '3306' } %> username: <%= ENV.fetch("APP_DATABASE_USERNAME") { 'root' } %> password: <%= ENV.fetch("APP_DATABASE_PASSWORD") { 'pass' } %> development: <<: *default database: sample_app_development test: <<: *default database: sample_app_test production: <<: *default database: sample_app_production○ 4: Gemfile の編集
Gemfile... - gem 'pg', '0.18.4' + gem 'mysql2', '~> 0.4.4' ...
- 参考URL
- MySQL の charset 等について、上記の通り設定しない場合は以下の問題が発生するため、utf8mb4 を設定しておく( Rails のデフォルトだと utf8 になる )。
- Rail5.1 だと、mysql2 のバージョンを指定する必要がある。
docker-compose stop
とstart
なら作業状態を継続できることから、Gem もインストール済で作業を継続できる。 ↩
- 投稿日:2020-02-20T20:13:39+09:00
Railsチュートリアルの開発環境を Docker でもっと便利になイカ!?
【概要】
本記事では、Gem の永続化、データベース及びテスト用メールサーバをコンテナ化していきます。
Railsチュートリアルの開発環境を Docker にしてみなイカ?の続きです。さて、前回の記事では、Railsチュートリアルの Sample App をコンテナ化しました。
しかし、実際の開発にあたり、煩わしい部分や便利になるところがありますので、改善していきましょう。
- 開発環境
- macOS Mojave: 10.14.6
- Docker Engine: 19.03.5
- Docker Compose: 1.25.4
- コンテナ環境
- Alpine Linux: 3.11.3
- Ruby: 2.4.9
- Rails: 5.1.2
- 参考: 学習情報 URL
【本文】
□ 事前準備
- 前回の記事と同じファイル及びディレクトリ構成です。
docker/DockerfileFROM ruby:2.4.9-alpine3.11 ENV LANG C.UTF-8 \ TZ Asia/Tokyo ENV BUILD_PACKAGES="build-base" \ DB_PACKAGES="sqlite-dev postgresql-dev" \ RAILS_PACKAGES="tzdata nodejs imagemagick" \ FAVORITE_PACKAGES="less" RUN apk update && \ apk upgrade && \ apk --update --no-cache add \ ${BUILD_PACKAGES} \ ${DB_PACKAGES} \ ${RAILS_PACKAGES} \ ${FAVORITE_PACKAGES} WORKDIR /app COPY Gemfile \ Gemfile.lock \ /app/ RUN bundle install --jobs=4 # 下記のコードは、頻繁に Gemfile を変更する場合、コメントアウトを推奨します。 # RUN apk del ${BUILD_PACKAGES} # https://github.com/bundler/bundler/issues/6154 ENV BUNDLE_GEMFILE='/app/Gemfile'docker-compose.ymlversion: '3' services: app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - ./:/app:cached stdin_open: true tty: true□ Gem の永続化
■ 現状の問題点
- 結論から言うと、現状では Gemfile を編集する度に
docker-compose build
をする必要があリます。つまり、大量の Gem を初めから全てbundle install
することになる煩わしい状態なのです。- 理由としては、コンテナの構造によるものであり、この問題点を体験したい場合、事前準備の条件で以下の通り動かしてみると良いでしょう。1
bash(省略可)# (1) コンテナのイメージ構築(ここのイメージがコンテナ構築時のデフォルト設定) $ docker-compose build # (2) コンテナを構築及び起動 $ docker-compose up -d # (3) Gemfile に Gem を追加 ... group :development, :test do ... gem 'pry-rails' gem 'pry-byebug' end ... # (4) 起動済のコンテナ内で bundle install $ docker-compose exec app bundle install # (5) 追加した Gem が確認できる( /usr/local/bundle/ にインストールされている) $ docker-compose exec app gem list # (6) コンテナを削除 $ docker-compose down # (7) コンテナを起動すると... $ docker-compose up > Starting sample_app_app_1 ... done > Attaching to sample_app_app_1 > app_1 | Could not find pry-byebug-3.4.3 in any of the sources > app_1 | Run `bundle install` to install missing gems. > sample_app_app_1 exited with code 7 # (8) 結果 - pry-byebug が見つからないため、bundle install が必要な状態です。 - つまり、コンテナの状態が(1)に戻ってきていることがわかります。■ 解決策
- 前述の通り原因は、
起動したコンテナ内で bundle install
するだけで、設計図となるコンテナのイメージ自体に反映されていないことです。解決策としては、Gem をコンテナ外で管理することです。コンテナを削除しても、Gem が存在する場所に影響しません。ここでは、コンテナ外に Gem の保管場所( = volume )を作成して、コンテナ内の Gem を保存する場所と繋げます( = mount )。
参考URL
○ 1: docker-compose.yml に data volume を追加
docker-compose.ymlversion: '3' services: datastore: image: busybox + volumes: + - bundle_install:/usr/local/bundle app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: + - bundle_install:/usr/local/bundle - ./:/app:cached stdin_open: true tty: true + volumes: + bundle_install:○ 2: 再度 bundle install
bash# 前の手順で、Gemfile に Gem を追加していましたら、該当箇所を一度コメントアウトしてください。 # (1) コンテナのイメージ構築 $ docker-compose build # (2) コンテナを構築及び起動 $ docker-compose up -d # (3) Gemfile に Gem を追加 ... group :development, :test do ... gem 'pry-rails' gem 'pry-byebug' end ... # (4) 起動済のコンテナ内で bundle install $ docker-compose exec app bundle install # (5) コンテナを削除 $ docker-compose down # (6) コンテナを起動すると正常に動作しています。 $ docker-compose up○ 3: どこに保存されたのか?
- では、データの保管先を確認してみましょう。
- 追加した volume は、通常のディレクトリに存在せず、別の場所に存在しています。なお、ディレクトリ内を探検してみると、コンテナも保存していることがわかります。
bash(省略可)# Moby VM にアクセス $ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty -s # 〜VM内操作へ移行〜 # 以下のコマンドにより、`sample_app_bundle_install/`の存在が確認できる。 $ ls /var/lib/docker/volumes/ # この Volume は、data_store で定義した通り、`/usr/local/bundle`を保存する。 $ ls /var/lib/docker/volumes/sample_app_bundle_install/_data # 終了時 $ `controll` + `A` + `K` $ yes○ 4: Gem の永続化完了
- ここまでで、Gem の永続化が完了したため、次はデータベースをコンテナ化します。
- もちろん、データベースをコンテナ化したとしても、コンテナの削除時にデータベースに保存したデータは失われてしまいます。そのため、Gem の永続化と同様にデータベースも併せて永続化していきます。
□ データベースのコンテナ化
■ 現状の問題点
- Sample App における本番環境のデータベースは PostgreSQL で、開発環境は SQLite を使用しています。しかし、基本的に開発環境と本番環境は、同一化が求められます。「開発環境では動いたのに本番で動かない(絶望)」ということ自体があってはなりません。
しかし、これを実践しようとしてローカル環境で開発するとき、逐一 PostgreSQL を起動したり、プロジェクトによって異なるバージョンを用意する必要があったり、煩わしい部分があるため、コンテナ化します。
参考URL
■ 解決策
○ 1: docker-compose.yml の編集
docker-compose.ymlversion: '3' services: datastore: image: busybox volumes: - bundle_install:/usr/local/bundle + - db_data:/var/lib/postgresql/data + db: + image: postgres:12.2-alpine + volumes: + - db_data:/var/lib/postgresql/data + ports: + - 5432:5432 + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: pass app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - bundle_install:/usr/local/bundle - ./:/app:cached + depends_on: + - db + environment: + APP_DATABASE_HOST: db + APP_DATABASE_USERNAME: root + APP_DATABASE_PASSWORD: pass stdin_open: true tty: true volumes: bundle_install: + db_data:○ 2: config/database.yml の編集
- Rails の DB 設定は、SQLite のままであるため、PostgreSQL に変更します。
- なお、ここでは差分表示していませんので、全て置換してください。
config/database.ymldefault: &default adapter: postgresql pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: <%= ENV.fetch("APP_DATABASE_HOST") { '127.0.0.1' } %> port: <%= ENV.fetch("APP_DATABASE_PORT") { '5432' } %> username: <%= ENV.fetch("APP_DATABASE_USERNAME") { 'root' } %> password: <%= ENV.fetch("APP_DATABASE_PASSWORD") { 'pass' } %> development: <<: *default database: sample_app_development test: <<: *default database: sample_app_test production: <<: *default database: sample_app_production○ 3: Gemfile の編集
- 開発環境を PostgreSQL に変更するため、現在の Gemfile の構成もついでに変更しておきます。
Gemfile... group :development, :test do - gem 'sqlite3', '1.3.13' gem 'byebug', '9.0.6', platform: :mri gem 'pry-rails' gem 'pry-byebug' end ... - group :production do - gem 'pg', '0.18.4' - end + gem 'pg', '0.18.4' ...○ 4: DB コンテナの起動
bash# コンテナと volume を削除してから起動 $ docker-compose down -v $ docker-compose up -d○ 5: データベースの作成
bash$ docker-compose exec app rails db:create $ docker-compose exec app rails db:migrate $ docker-compose exec app rails db:seed○ 6: DB のコンテナ化完了
- これで、DB のコンテナ化が完了です。
- DBコンテナに入って実際に確認したい場合は、次の通り操作してみてください。
bash(省略可)# DB コンテナに入る $ docker-compose exec db ash # PostgreSQL に登録されている Sample App のデータベースに接続 $ psql -U root -d sample_app_development # テーブル生成の確認 sample_app_development=$ \dt sample_app_development=$ exit□ メールサーバのコンテナ化
■ 現状の問題点
- 特にありませんが、一つのコマンド打つだけで見れるのですから、あったら便利ですよね。
また、メールのデータも永続化できますが、ここで残すメリットを感じられなかったため、実装していません。永続化したい方は、参考URL等を確認しつつ実装してみてください。要領は前項までと同じです。
参考URL
■ 解決策
○ 1: docker-compose.yml の編集
docker-compose.ymlversion: '3' services: datastore: image: busybox volumes: - bundle_install:/usr/local/bundle - db_data:/var/lib/postgresql/data db: image: postgres:12.2-alpine volumes: - db_data:/var/lib/postgresql/data ports: - 5432:5432 environment: POSTGRES_USER: root POSTGRES_PASSWORD: pass app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - bundle_install:/usr/local/bundle - ./:/app:cached depends_on: - db environment: APP_DATABASE_HOST: db APP_DATABASE_USERNAME: root APP_DATABASE_PASSWORD: pass stdin_open: true tty: true + smtp: + image: mailhog/mailhog + ports: + - '8025:8025' volumes: bundle_install: db_data:○ 2: 開発環境のメール設定を編集
config/environments/development.rb... # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = true - config.action_mailer.delivery_method = :test - host = 'railstutorial-yasulab.c9users.io' - config.action_mailer.default_url_options = { host: host, protocol: 'https' } + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { + address: "smtp", + port: "1025", + } + config.action_mailer.default_url_options = { host: "localhost:3000" } ...○ 3: メールサーバのコンテナ化完了
- これで、メール確認が容易になりました。試しに SignUp してみるとアクティベーションメールが以下のURLに届きます。
- http://localhost:8025
□ 特記事項
■ 注意事項
- 今のところ特になし
■ 使用イメージ、ライブラリ
- ruby - Docker Hub
- busybox - Docker Hub
- postgres - Docker Hub
- mailhog/MailHog: Web and API based SMTP testing
- mysql - Docker Hub
□ おまけ: DB を MySQL にしたい場合
○ 1: Dockerfile の編集
docker/Dockerfile... ENV BUILD_PACKAGES="build-base" \ - DB_PACKAGES="postgresql-dev" \ + DB_PACKAGES="mysql-client mysql-dev" \ RAILS_PACKAGES="tzdata nodejs imagemagick" \ FAVORITE_PACKAGES="less" ...○ 2: docker-compose.yml の編集
docker-compose.yml... + db: + image: mysql:5.7 + volumes: + - db_data:/var/lib/mysql + ports: + - 3306:3306 + environment: + MYSQL_ROOT_PASSWORD: pass - db: - image: postgres:12.2-alpine - volumes: - - db_data:/var/lib/postgresql/data - ports: - - 5432:5432 - environment: - POSTGRES_USER: root - POSTGRES_PASSWORD: pass ...○ 3: config/database.yml の編集
config/database.ymldefault: &default adapter: mysql2 charset: utf8mb4 collation: utf8mb4_bin encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: <%= ENV.fetch("APP_DATABASE_HOST") { '127.0.0.1' } %> port: <%= ENV.fetch("APP_DATABASE_PORT") { '3306' } %> username: <%= ENV.fetch("APP_DATABASE_USERNAME") { 'root' } %> password: <%= ENV.fetch("APP_DATABASE_PASSWORD") { 'pass' } %> development: <<: *default database: sample_app_development test: <<: *default database: sample_app_test production: <<: *default database: sample_app_production○ 4: Gemfile の編集
Gemfile... - gem 'pg', '0.18.4' + gem 'mysql2', '~> 0.4.4' ...
- 参考URL
- MySQL の charset 等について、上記の通り設定しない場合は以下の問題が発生するため、utf8mb4 を設定しておく( Rails のデフォルトだと utf8 になる )。
- Rail5.1 だと、mysql2 のバージョンを指定する必要がある。
docker-compose stop
とstart
なら作業状態を継続できることから、Gem もインストール済で作業を継続できる。 ↩
- 投稿日:2020-02-20T20:03:59+09:00
RailsアプリをDockerで作ってCircleCIで自動テストしてHerokuにデプロイした話
はじめに
どうも、Pirikaraです。
久しぶりの投稿となりました。今回は、Docker環境でRailsアプリケーションを開発し、
CircleCIで自動テスト、Herokuにデプロイするところまでやっていきたいと思います。
個人開発でやってみましたが、このエラーの山々......
一つ一つエラーを解決して設定ファイルを修正してを繰り返し繰り返し......
やっとまともに動くようになりました。
初めてやるよって方は僕の屍を踏み越えていってください。
ちなみに間違ってるよーとか改善点とかご指摘いただけると幸いです。環境
・Mac OS
・Ruby 2.5.3
・Rails 5.2.2
・MySQL 5.7また、Dockerがインストールされていることを前提としています(Dockerコマンドが使用できる状態)。
インストールしていない場合は、公式サイトからアカウントを作ってログインし、DockerHubからダウンロード・インストールします。
DockerhubHerokuについても登録していない場合は登録の必要があります。
公式サイトから登録が可能です。
Herokuアプリの構成
開発環境からDockerを導入し、RailsとMySQLのimageでコンテナを作りました。苦労していた環境構築がすぐに出来て感動。
GithubにpushするとCircleCIによる自動テストが行われて、テストをパスするとHerokuに自動でデプロイされる仕様です。
また、Herokuでは有料であればMySQLが使用できるみたいですが、僕はお金がないので本番環境のみPostgreSQLを使用します。では、
1. Docker開発環境の構築
2. CircleCIの導入と自動テスト
3. Herokuに自動デプロイ
の順番でやっていきましょう。1.Docker開発環境の構築
まず、アプリケーションのディレクトリを作成します。
ここではsample_appとします。sample_appディレクトリを作成 $ mkdir sample_app sample_appディレクトリに移動 $ cd sample_appディレクトリ内に「Dockerfile」「docker-compose.yml」「Gemfile」「Gemfile.lock」の4ファイルを作成します。
$ touch Dockerfile $ touch docker-compose.yml $ touch Gemfile $ touch Gemfile.lockでは、それぞれ中身を書いていきましょう。(Gemfile.lockは空のままです)
DockerfileFROM ruby:2.5.3 #必要なパッケージのインストール RUN apt-get update -qq && \ apt-get install -y build-essential \ libpq-dev \ nodejs #作業ディレクトリの作成 RUN mkdir /bbs_app #作業ディレクトリをAPP_ROOTに割り当てる ENV APP_ROOT /bbs_app WORKDIR $APP_ROOT #ローカルのGemfileを追加 ADD ./Gemfile $APP_ROOT/Gemfile ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock #Gemfileのbundle installを実行 RUN bundle install ADD . $APP_ROOTdocker-compose.ymlversion: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "4306:3306" web: build: . command: rails s -p 3000 -b '0.0.0.0' environment: RAILS_ENV: development volumes: - .:/bbs_app ports: - "3000:3000" links: - dbGemfilesource 'https://rubygems.org' gem 'rails', '5.2.2'ところどころ違いますが、
設定の内容についてはこちらの記事が詳しくて参考になったので、任せます。
DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】ここまで書けたら、dockerコマンドでrails newします。
$ docker-compose run web rails new . --force --database=mysql --skip-bundleあとでimageを構築する際にDockerfileにしたがってbundle installが実行されるので、ここではスキップします。
作成されたconfig/database.ymlを編集します。
database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password # docker-compose.ymlのMYSQL_ROOT_PASSWORD host: db # docker-compose.ymlのservice名dockerを起動します。
imageを構築(コンテナは作成しない) $ docker-compose build コンテナを構築・起動 $ docker-compose upデータベースを作成します。
$ docker-compose run --rm web rails db:create--rmオプションをつけることで、コンテナが実行されたあと削除されます。
「rails g controller ~」や「rails console」など、docker-composeから始まるコマンドで実行していくことになりますが、
--rmをつけていないと実行するたびにコンテナが増えていってしまうので、都度削除しています。僕は。ここまでできると、localhost:3000へアクセスしてサーバーの起動を確認することができます。おめでとう。
2.CircleCIの導入と自動テスト
こちらのブログをパク・・・参考にしました。
導入まで大変わかりやすく、参考になりました。こちらを参考に導入してみてください。「.circleci」というディレクトリを作成し、これ以下に「config.yml」というファイルを作成します。
また、configディレクトリ以下に「database.yml.ci」というファイルを作成します。では、作成したファイルの中身を書いていきましょう。
config.ymlversion: 2 jobs: build: docker: - image: circleci/ruby:2.5.3-node-browsers environment: - BUNDLER_VERSION: 2.0.2 - RAILS_ENV: 'test' - image: circleci/mysql:5.7 environment: - MYSQL_ALLOW_EMPTY_PASSWORD: 'true' - MYSQL_ROOT_HOST: '127.0.0.1' working_directory: ~/bbs_app steps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "Gemfile.lock" }} - v1-dependencies- - run: name: install dependencies command: | gem install bundler -v 2.0.2 bundle install --jobs=4 --retry=3 --path vendor/bundle - save_cache: paths: - ./vendor/bundle key: v1-dependencies-{{ checksum "Gemfile.lock" }} # Database setup - run: mv ./config/database.yml.ci ./config/database.yml # Database setup - run: name: Databasesetup command: | bundle exec rake db:create bundle exec rake db:schema:load # run tests! - run: name: Run rspec command: | mkdir /tmp/test-results TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \ circleci tests split --split-by=timings)" bundle exec rspec \ --format progress \ --format RspecJunitFormatter \ --out /tmp/test-results/rspec.xml \ --format progress \ $TEST_FILES # collect reports - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results destination: test-resultsdatabase.yml.citest: adapter: mysql2 encoding: utf8 pool: 5 username: 'root' port: 3306 host: '127.0.0.1' database: app_test #database.ymlのテスト環境のデータベース名を参照これでGithubへpushすると、自動でテストが実行されるようになります。
プルリクエストを作ってmasterブランチへmergeしていくと思うのですが、テストに失敗するとmergeすることができません。
ほらね。テストをパスすると、Mergeボタンがアクティブになります。
※ seeds.rbを読み込みたい場合
.circleci/config.ymlでseeds.rbの読み込み設定をしたところ、うまくいかなかったのでspec_helperにseeds.rbを読み込む設定をしました。
「database_cleaner」というgemを導入し、spec_helperへ処理を書いていきます。
これで、Rspec実行の際にデータベースがリフレッシュされ、seeds.fileが読み込まれます。Githubへpushした際に実行された場合は大丈夫なのですが、ローカルでdocker-composeコマンドからrspecを実行した場合にデータベースがリセットされてしまうので注意してください。
Gemfilegroup :development, :test do # rspec実行時にDBをリセットする gem 'database_cleaner' endspec_helper.rb# テスト実行時にDatabaseをリセットし、seeds.rbを読み込む RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with(:truncation) Rails.application.load_seed end end3.Herokuに自動デプロイ
Herokuにデプロイするため、ファイルを修正・追加します。
まずはGemfile。
開発環境ではMySQL、本番環境ではPostgeSQLを使用するので、「pg」のgemをインストールします。Gemfile# 変更前 gem 'mysql2', '>= 0.4.4', '< 0.6.0' # 変更後 gem 'mysql2', '>= 0.4.4', '< 0.6.0', groups: %w(test development), require: false gem 'pg', '~> 0.19.0', group: :production, require: false次に、database.ymlを編集していきます。
本番環境でPostgreSQLを使う設定をします。database.ymlproduction: <<: *default adapter: postgresql encoding: unicode pool: 5そして、「heroku.yml」というファイルを新たに作成します。
作成場所はアプリ直下です。(GemfileとかDockerfileと一緒)
今回はDockerコンテナを使用して開発をしているので、コンテナごとHerokuのサーバーに持っていきます。
そのための設定ファイルです。知らんけど。DockerコンテナをHerokuにアップする方法は公式サイトを参考にしました。
heroku.ymlbuild: docker: web: Dockerfile run: web: bundle exec puma -C config/puma.rbアプリケーション側の設定はこれで完了です。
ではHeroku側の設定をしてデプロイしていきましょう。
ターミナルから、Herokuにログインします。$ heroku login # ログインするかどうか確認されます。 # クリックするとブラウザが立ち上がり、Herokuのログイン画面になります。ログインしてください。 heroku: Press any key to open up the browser to login or q to exit: # ログインが完了すると、ターミナルに「ログインしたよー」って表示されます。 Opening browser to https://cli-auth.heroku.com/auth/browser/************** Logging in... done Logged in as *******@email.com次に、Herokuにアプリケーションを作成します。
# アプリケーション名のところには好きな名前を入れてください。それでURLが作成されます。 $ heroku create アプリケーション名 Creating app... done, ⬢ ******* https://******.herokuapp.com/ | https://git.heroku.com/*******.gitちなみにこの時、Herokuのリポジトリが作成されています。
もしアプリケーションの名前を変更したいときは、Herokuの管理画面から名前を変更することに加えて、リポジトリを削除する必要があります。$ git remote rm herokuこのコマンドで消せます。
消さないとアプリ名とリポジトリ名が異なるためにデプロイできなくなります。そして、Heroku側でPostgreSQLを使用する設定をします。
$ heroku addons:create heroku-postgresql:hobby-dev # PostgreSQLのデータベース作ったよーって通知がきます。 Creating heroku-postgresql:hobby-dev on ⬢ ******... free Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-transparent-70433 as DATABASE_URL Use heroku addons:docs heroku-postgresql to view documentation今回DockerコンテナをHerokuにのせるので、Heroku側でコンテナにアプリのStackをセットします。
$ heroku stack:set containerこの辺の話は「heroku.yml」の設定の時に出てきた公式サイトに全部載ってます。
Dockerを使用したデプロイこれでデプロイするための設定は完了しました。
masterブランチにアプリをpushしたのち、$ git push heroku masterこのコマンドでHerokuのリポジトリにpushすることでデプロイが完了します。エラーが起こらなければ。
さて、ついに自動デプロイです。
circleciを通してHerokuにデプロイしていくので、config.ymlファイルにdeployの処理を追加します。config.yml# 省略 - deploy: name: Deploy Master to Heroku command: | if [ "${CIRCLE_BRANCH}" == "master" ]; then git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git master fi「HEROKU_API_KEY」と「HEROKU_APP_NAME」については、CircleCIに設定した環境変数が読まれるため、
こちらを設定していきます。どちらもHerokuの管理画面から取得できます。
アカウント設定からHEROKU_API_KEYに当たるAPI KEYを......
アプリケーションの設定からHEROKU_APP_NAMEを......
それぞれ取得します。CircleCIのアプリケーション管理画面から、右上の「Project Setting」をクリックします。
Environment Variablesから「Add Variables」をクリックして、先ほど取得した値を環境変数として設定します。
これがconfig.ymlで使用されます。
設定は以上です。
これで、Githubへpush → CircleCiが自動でテスト → パスすればHerokuに自動でデプロイ
という風に動きます。良かったね。
終わりに
DockerとCircleCIを利用したのは初めてでしたが、
環境構築もテスト・デプロイも簡潔になったので、非常に便利でした。特にテストコマンドやデプロイコマンドについては「コマンド打つだけやしなぁ......」と自動化の恩恵を甘く見ていましたが、
チリも積もればなんとやらです。
いちいちコマンドを打つ煩わしさから解放され、アプリの開発スピードも段違いだったように感じます。参考にしていただけたら幸いです。
またね。
- 投稿日:2020-02-20T19:58:11+09:00
docker system pruneでも上手くいかない時のoverlay2の掃除用スクリプト
問題
/var/lib/docker/overlay2
が肥大化- 特にデータを大量に使っているimage, containerはない
docker system df
の合計値は数十GBにも関わらず、 overlay2 の合計は数百GBあるdocker system prune
系のコマンドを打っても解決せず考えられる原因
このコメントによると、古いバージョンで
docker rm -f
を実行した際にlayerが削除されないことがあるよう。(overlay2配下のディレクトリが正確に1 layerなのか知らないですが、ここではlayerと呼びます)
解決策
inspectコマンドで今あるimage, containerが使ってるlayerを洗い出して、
/var/lib/docker/overlay2
と比較する。スクリプト
chmod +x
で実行権限を付与しておくused_layers.sh#!/bin/sh expr='s;/var/lib/docker/overlay2/\(.*\)/.*;\1;g' print_layers () { data=`echo $1 | jq '.[0].GraphDriver.Data'` # この3つは必要なさそう echo $data | jq -r '.MergedDir' | sed -e "$expr" echo $data | jq -r '.UpperDir' | sed -e "$expr" echo $data | jq -r '.WorkDir' | sed -e "$expr" for dir in `echo $data | jq -r '.LowerDir' | tr ':' ' '` do echo $dir | sed -e "$expr" done } docker images | tail -n +2 | while read -r line do image=`echo $line | awk '{print $1}'` tag=`echo $line | awk '{print $2}'` print_layers "`docker image inspect $image:$tag`" done for container_id in `docker ps | awk '{print $1}' | tail -n +2` do print_layers "`docker container inspect $container_id`" donediff_layers.sh#!/bin/sh ./used_layers.sh | sort | uniq > used_layers.txt ls /var/lib/docker/overlay2 > all_layers.txt comm -13 --nocheck-order used_layers.txt all_layers.txt > diff_layers.txt実行
まだ試したことないので自己判断でお願いします
# 3つのファイルが生成される # used_layers.txt: 現在あるimage, containerで使われているlayer一覧 # all_layers.txt: /var/lib/docker/overlay2 内にあるdirectory一覧 # diff_layers.txt: all_layers.txtにあってused_layers.txtにないもの一覧 ./diff_layers.sh # 差分を削除 sed -e 's;^;/var/lib/docker/overlay2/;' diff_layers.txt | xargs rm -rf
- 投稿日:2020-02-20T19:57:21+09:00
ECSにおいてdocker runコマンドの-t,--ttyオプションに相当する設定をした話
はじめに
こんにちは。
現在私は社内のデータ分析基盤の刷新に取り組んでおります。今回は検証中のDataSunriseをECSに乗せるべくを試行錯誤を行っていた中で発見した、
docker run
コマンドの-t
,--tty
オプションに相当するであろう設定をECSで行う方法について記載します。DataSunriseについてはこちらをご参照下さい。
事の起こり
localでできることがECSでできない
検証のためにlocal環境にてコンテナを立てていました。
docker run -itd -p 11000:11000 [datasunrise image id]
(local環境にて)
この場合は期待通りコンテナが立ち上がり、https://[グローバルIP]:11000で繋ぐことができました。これをECSで実現したかったのですが、ECSのタスクは即時終了し、
CloudWatchLogsに流れてくるのはservice is started.
のメッセージのみでした。試しにlocal環境にて、
docker run [datasunrise image id]
を実行してみると、
service is started.
との表示のみでコンテナは即時終了していました。
(本メッセージはDataSunriseコンテナが起動、即時終了した際に残すログのようです。)結果的にECSにおいて
docker run
コマンドの-t
,--tty
オプションに相当するようなことを設定しなければならないと判断しました。結論
タスク定義において
pseudoTerminal
をtrue
にすることで、コンテナを起動させ続けることができました。
なお、本問題を解決に導いて下さった記事はこちらのstackoverflowです。具体的な設定方法は次の通りです。
設定方法
GUIでの設定方法を記載します。
最終的にJSONをいじることになるのでCLIで設定する場合も対応可能ではないかと思います。
pseudoTerminalをtrueに変更
初期設定でnullとなっていましたが、trueに書き換えて保存を押せば適用できました。(EC2/Fargateともに適用可能)
*こちらは説明用画像ですので、当該箇所以外は環境に合わせてよしなに設定下さい。念の為。まとめ
ECSにおいて
docker run
コマンドの-t
,--tty
オプションに相当するであろう設定ができました。
今回は試行錯誤段階において、stackoverflowに行き着いた事によって解決したのですが、
よくよく公式ドキュメントを読んでみるとpseudoTerminal
Type: BooleanRequired: no
When this parameter is true, a TTY is allocated. This parameter maps to Tty in the Create a container section of the Docker Remote API and the --tty option to docker run.
という記載がありました。
ちゃんと公式ドキュメント読みましょうという教訓でした。。。
参考
- DataSunrise公式
- Stack Overflow当該記事 How to enable tty and run interactive console with AWS ECS?
- AWS ECS公式ドキュメント
また、試行錯誤段階にて以下記事も参考にさせて頂きました。ありがとうございます。
Dockerのコンテナを起動したままにする
- 投稿日:2020-02-20T19:32:06+09:00
Rails6のdocker-compose環境をwebpackerまで含めて構築する
Rails6のSoftware Stack
今回は以下の内容で構成します
- Ruby 2.6.5
- Rails 6.0.2
- Postgresql 11.6
- Redis 3.2.11
- Nodejs 12.14.0
- yarn 1.21.1
- Bundler 2.1.3
サンプルプロジェクトは以下で提供しています
こちらでは、bootstrapのsassの、変数を変更してホットリロードするところまで確認できるかと思いますDockerfile
Dockerfileでは以下のように、Rails6から必須になったyarnを入れておきます。
ここでは、Dockerfileでは主に以下の作業を行わせています。
- node, ruby, yarnの設定
- bundlerをglobalにインストール
- entrypoint.shの設定
- ロケールの設定
DockerfileFROM node:12.14.0 as node FROM ruby:2.6.5 RUN apt-get update -qq && apt-get install -y postgresql-client && \ apt-get install -y locales COPY --from=node /usr/local/bin/node /usr/local/bin/node COPY --from=node /usr/local/include/node /usr/local/include/node COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs && \ ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm ENV YARN_VERSION 1.21.1 COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn COPY --from=node /usr/local/bin/node /usr/local/bin/ RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \ && ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg ENV BUNDLER_VERSION 2.1.3 RUN gem install bundler -v $BUNDLER_VERSION RUN mkdir -p /var/www/app WORKDIR /var/www/app # Add a script to be executed every time the container starts. COPY ./docker/entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] RUN locale-gen ja_JP.UTF-8 # timezoneをJSTに変更 RUN apt-get install -y tzdata \ && rm /etc/localtime \ && ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \ && dpkg-reconfigure -f noninteractive tzdata # キャッシュ削除 RUN rm -rf /var/lib/apt/lists/* EXPOSE 3000docker-compose.yml
- docker-composeでは、アプリケーションとwebpackerを起動しておきます
- webpackerでコンパイルされたJSは
public/packs
以下に配置されます- wait-for-it.shを使って、webpackにはアプリケーションが起動するのを待ってもらっています
.env.example
から.env
にコピーしてローカル側のポートを変更できるようにしています- ここでは起動時に
bundle install
とyarn install
を行っていますが、好みで変更してくださいdocker-compose.ymlversion: '3' services: app: &app_base build: "." stdin_open: true tty: true ports: - $HTTP_PORT:3000 command: /bin/sh -c "bundle install && yarn install --check-files && bundle exec puma -C config/puma.rb" environment: RAILS_ENV: $RAILS_ENV NODE_ENV: $RAILS_ENV # .bundle/config を gitに含めて提供してください BUNDLE_APP_CONFIG: ./.bundle DB_USER: pguser DB_PASS: pgpass DB_HOST: postgres DB_PORT: 5432 REDIS_URL: redis://redis:6379 volumes: - .:/var/www/app - bundle:/var/www/app/vendor/bundle - node-modules:/var/www/app/node_modules - packs:/var/www/app/public/packs depends_on: - postgres - redis webpack: <<: *app_base command: /bin/sh -c "docker/wait-for-it.sh app:3000 --timeout=600 && bundle install && yarn install --check-files && bin/webpack-dev-server" environment: NODE_ENV: $RAILS_ENV RAILS_ENV: $RAILS_ENV BUNDLE_APP_CONFIG: ./.bundle WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 ports: - $WEBPACK_PORT:3035 tty: true stdin_open: true depends_on: - app postgres: stdin_open: true tty: true restart: always image: postgres:11.6 ports: - $DB_PORT:5432 environment: POSTGRES_USER: pguser POSTGRES_PASSWORD: pgpass TZ: Asia/Tokyo volumes: - pgsql-data:/var/lib/postgresql/data redis: restart: always image: redis:3.2.11 environment: TZ: Asia/Tokyo ports: - $REDIS_PORT:6379 command: redis-server --appendonly yes volumes: pgsql-data: bundle: node-modules: packs:application.html.erbでpack_tagを使うよう変更する
- Rails 6: the missing developer setup guideを参考に、
application.html.erb
はpack_tag
を使うように変更しておいてくださいdata-turbolinks-track
がreload
になっていることも確認してくださいapplication.html.erb<%= stylesheet_pack_tag "application", media: "all", "data-turbolinks-track": "reload" %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>webpacker.yml を docker-composeに合わせて変更する
- webpackerの設定ファイルを、docker-composeのservice名に合わせて変更します
- また、HMR(Hot Module Replacement)の設定を有効にしてホットリロードできるようにしておきます
config/webpacker.yml# Reference: https://webpack.js.org/configuration/dev-server/ dev_server: host: webpack # docker-composeのservice名に合わせて変更 hmr: true # ホットリロードできるようにする起動とホットリロード
- 以上で
docker-compose up
でサービスを起動すれば、アプリケーションとwebpack-dev-serverが動作するかと思います- bootstrapなど、コンパイルが必要なassetsを追加して、変数などを変更すれば、画面をリロードすることなく、色などの変更が行えます
webpacker と sprockets
Rails6で導入された
webpacker
と、既存のsprockets
について以下は必読です。
読まずにpack周りでJSを書くと、かなり回り道をすることになるかと思います。
長文にお付き合いいただきありがとうございました。
- 投稿日:2020-02-20T17:23:11+09:00
docker desktop ver 2.2、insecure-registriesどこ行ったんだ問題
前のバージョンまでは
Preferences -> Advanced
でGUIから設定できたinsecure-registries
ですが、v2.2になって設定のGUIが大きく変わったあげく、見つからない……
- 投稿日:2020-02-20T17:21:17+09:00
Docker入門|基本コマンド等
インストール
Docker
$ brew install docker docker-machine
Docker Compose
$ brew install docker-compose
状況確認
起動中コンテナ確認
$ docker ps
停止中を含む全てのコンテナ確認
$ docker ps -a
コンテナの稼働確認
$ docker stats
現状のイメージの確認
$ docker images
イメージの詳細確認
$ docker inspect [オプション] [コンテナ識別子またはイメージ識別子]
Docker のバージョン確認
$ docker -v
Docker Compose のバージョン確認
$ docker-compose -v
Dockerの実行環境確認
$ docker info
生成/起動
コンテナの生成+起動
$ docker run [オプション] イメージ名[:タグ名] [引数]
コンテナの起動
$ docker start [オプション] [コンテナ識別子]
コンテナの再起動
$ docker restart [オプション] [コンテナ識別子]
DockerfileからDockerイメージの作成
$ docker build -t [生成するイメージ名]:[タグ名] [Dockerfileの場所]
[Dockerfileの場所]は、ビルドコンテキストの指定でもある。
--no-chash オプションをつけると、ビルド済みの部分もビルドし直す。
Docker Compose からの起動
$ docker-compose up -d
Docker Compose からDockerイメージの作成
$ docker-compose build
停止
コンテナの停止
$ docker stop [コンテナIDもしくはコンテナ名]
一括停止の場合は以下のコマンド
$ docker stop $(docker ps -q)
Docker Compose からの停止
$ docker-compose stop
削除
コンテナの削除
$ docker rm [コンテナID]
コンテナIDの複数指定OK
一括削除の場合は以下のコマンド
$ docker rm
docker ps -a -q``docker ps -a -q は、コンテナIDの一覧表示
イメージの削除方法
$ docker rmi [イメージID]
イメージの前にコンテナを削除する必要あり。
forceオプション(以下)で強制削除も可能。ただしコンテナは残る。
$ docker rmi -f [イメージID]
※削除時は順番を考慮する必要あり
削除を行う際は、下記順番を考慮して作業をすすめる必要あり。
- 起動中のコンテナを停止する
- 停止中のコンテナ
- Dockerイメージ
(理由)
- 起動中のコンテナは削除できない
- コンテナが存在すると、そのコンテナで使用しているイメージは削除できないその他
Docker Hubへのログイン
$ docker login
Docker Hubへのイメージアップロード
$ docker push イメージ名[:タグ名]
Docker Hubからのログアウト
$ docker logout
- 投稿日:2020-02-20T17:05:30+09:00
docker-composeで起動中のログにアタッチする方法
docker-compose up -d $serviceName
でコンテナを起動した時、logの出力を確認するには
docker-compose logs $serviceName
で確認できる
ただこの場合だとそれ以降のlogを取得するには再度同じコマンドを打たなければならないdocker-composeででタッチ起動したコンテナのlogを出力させ続けるには以下のコマンドを打つ
docker-compose logs -f $serviceName
-f
または--follow
オプションをつけることでその後もログを出力させ続けることができる
- 投稿日:2020-02-20T16:35:26+09:00
(IT業界における)新型コロナウィルス対策(案)組織編
(IT業界における)新型コロナウィルス対策(案)個人編
https://qiita.com/kaizen_nagoya/items/f6996fe6d49ee6095d61に対応した組織編です。
個人による新型コロナウィルス対策の周知
1 手洗い前の素手で直接、口、鼻、目を触らない。
2 手洗い
3 咳・くしゃみ時推奨習慣
4 健康管理(免疫力・抵抗力の保持)
を周知1 手洗い前の素手で直接、口、鼻、目を触らない。
マスクをする理由の一つでもある。
手洗いが必要な理由の一つでもある。2 手洗い
出勤時、昼食前、昼食後、退勤時の4度は最低限。
用便の際に前後で手洗いを推奨するかどうか、組織で判断。3 咳・くしゃみ時推奨習慣
マスクをする理由の一つでもある。
4 健康管理(免疫力・抵抗力の保持)
手洗い場の確保
空間
建築系の法規で、何人いる場合に、手洗い場の大きさ、種類などについて推奨がある。
時間
朝の出勤時の手洗いを励行しようとしても、人数分手洗い場が確保できない場合は、
出勤時間をばらけさせるとよいかもしれない。昼休みの始まり、終わりにも手洗いを励行する。手洗い時間は、事業の継続性にとっては業務時間と見做すのが妥当かもしれない。
清掃
共用の机などは、水拭きだけでなく、アルコール消毒なども励行するとよい。
旅館などの生活衛生関係営業におけるSARS感染防止対策のための自主管理マニュアル
http://www.seiei.or.jp/db-pdf/sars_01.pdf
- トイレの流水レバー、便座、フタは、台所用合成 洗剤の希釈液に浸した雑巾で二度拭きする。
- 便器の内側は、台所用合成洗剤の希釈液を用 いて、トイレ清掃用のブラシ(スポンジブラシなど) で周囲に飛び散らないように清掃し、フタをして5 分以上経過してからフタをしたままフラッシュする。 なお、使用したブラシは台所用合成洗剤の希釈液又はやや濃いめの希釈液の中に5分以上漬けておく。
- 体液や汚物によって汚れたモノの消毒 体液や汚物によって汚れた部分は、台所用合成洗 剤の希釈液、あるいはこれに十分浸したティッシュペー パーなどで汚染されたところを覆い、5分以上経過し てから、から拭きする。
- 利用客が触れた可能性のあるモノの消毒 ドアノブ、エレベーターの押しボタン、エスカレータ ーや階段の手摺りなどは、台所用合成洗剤の希釈液 に浸した雑巾で二度拭きする。
作業上の留意
- 作業開始前
清掃従業員等は作業前に必要に応じてサージカルマスクなどの感染防御可能なマスク(以下 「感染防御マスク」という。)やゴム手袋、ゴーグル、使い捨てガウン、エプロン、汚染除去可能な履物で個人防御をすること。
- 作業終了後
○ 清掃・消毒終了後は、石鹸による手指の手洗いや速乾性皮膚消毒剤(エタノール等)を用いた手指の消毒を行うとともに、うがいを励行すること。
○ 使用後の感染防御マスク等は、回収されたゴミ等と一緒にビニール袋で密閉し焼却等適正な方法で廃棄すること。健康管理
通勤時間等拘束時間の削減のため在宅勤務を可能にする。
混雑した通勤時間を避けるため、フレックスタイムを可能にする。
食事時間を近隣とずらして、混雑した食事を避ける。
遠隔業務
github/gitlab/bitbucket
git系のサービスで、private接続可能な範囲設定をどのようにするかは、ネットワーク管理者とご相談ください。
個々の企業での、ネットワーク接続方法は、千差万別で、どうしたらいいか、一般論では妙案がありません。
cloud
amazon, google, microsoftなどのcloud利用について、組織外かrの接続については、ネットワーク管理者と各接続サービス会社とご協議ください。
Office 365等
Office 365, Teams など、ID, Password管理している場合に、管理方法
docker等
cloudサービスとの連携など、ネットワーク管理者と各接続サービス会社とご協議ください。
テレビ会議
skype
https://www.skype.com/ja/features/calling-and-instant-messaging/#calls
使用するデバイスに関係なく最大 50 名 (自分に加えて 49 名) が参加できる 電話会議またはビデオ会議を開催できます。
teams
Microsoft Teams
Office 365 でチームワークを実現するハブ
https://products.office.com/ja-jp/microsoft-teams/group-chat-softwarewebEX
https://www.cisco.com/c/m/ja_jp/solutions/webex.html
zoom
https://zoom.us/jp-jp/meetings.html
行事の遠隔開催
あらかじめ遠隔開催を想定していた事業であれば、
講師の方と綿密な著作権上の取り決めをしておくことができる。集合開催を遠隔開催に変更する場合には、
講師の方と著作権を含めて、交渉事項が多岐に渡る。講師の登壇条件区分(案)
講師の所属組織、講師個人の判断を尊重し、下記の区分に回答をもらう。直接登壇またはオンライン登壇の別。(直接・オンライン(動画・音声・文字))
・オンライン登壇の場合の動画の記録の可否。(可・否)
・動画でのインタネットへの配信の可否。(可・否)
・・動画の再上映(インタネットを覗く)の可否。可の場合は再上映回数。(可( 回)・否)
動画の再上映可の場合でも、再上映日程、場所については事前にご相談いたします。行事開催時の注意事項(新型コロナウイルス・インフルエンザ等流行時を含む)
https://qiita.com/kaizen_nagoya/items/92fe0b8076111a3c1bc4文書履歴(document history)
ver. 0.01 初稿 20200220 午後4時
ver. 0.02 行事追記 20200220 午後5時
- 投稿日:2020-02-20T15:25:17+09:00
Kubernetes + Envoyでクラスタ内からクラスタ外のサーバーへの接続をロードバランシングする
Kubernetesのクラスタ内のPodからクラスタ外にあるMySQLなどのサーバに接続するときには、Envoyを使うと良さそうという話です。
まだ運用はしていませんが、設定方法を載せるので迷っている方の参考になったら幸いです。
Envoyを選択する理由
要件にもよりますが、次のような理由からです。
- productionやstagingなどの環境によりMySQLの接続先を自由に切り替えたかったので、ELBやEC2上でプロキシを立てるのではなく、サイドカーコンテナを立てる方向で考えていた
- 今回は、マイクロサービスを構築するわけではなかったため、Istioはtoo muchと判断した
- HAProxyやnginxはこちらの比較記事を読んだ結果、除外した
- KubernetesのNon-selector Serviceを使うという手もあるが、手元で検証したところヘルスチェックが動作しなかった。(もしかしたらやりようはあるのかもしれません)
構成図
設定内容
envoyの設定はconfigmapにまとめています。
envoy-configmap.ymlkind: ConfigMap apiVersion: v1 metadata: name: envoy-conf data: envoy.yaml: | static_resources: listeners: - name: mysql_listener address: socket_address: address: 0.0.0.0 port_value: 3306 filter_chains: - filters: - name: envoy.filters.network.mysql_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.mysql_proxy.v1alpha1.MySQLProxy stat_prefix: egress_mysql - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: mysql_tcp cluster: mysql_cluster clusters: - name: mysql_cluster connect_timeout: 1s health_checks: - healthy_threshold: 3 interval: 5s tcp_health_check: {} timeout: 1s unhealthy_threshold: 3 type: strict_dns load_assignment: cluster_name: mysql_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: **.**.**.** # ここにそれぞれのMySQLのIPアドレスを設定する port_value: 3306 - endpoint: address: socket_address: address: **.**.**.** # ここにそれぞれのMySQLのIPアドレスを設定する port_value: 3306 admin: access_log_path: "/dev/null" address: socket_address: address: 0.0.0.0 port_value: 8001Podの設定は、nginx+php-fpmのサイドカーとしてEnvoyを追加しています。
api.ymlapiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: hostname: myhostname containers: - name: nginx image: nginx:latest ports: - containerPort: 80 - name: php-fpm image: phpfpm:latest ports: - containerPort: 9000 - name: envoy-proxy image: envoyproxy/envoy-dev:latest imagePullPolicy: IfNotPresent ports: - containerPort: 3306 name: proxy-mysql protocol: TCP resources: limits: cpu: 0.5 memory: 1Gi volumeMounts: - name: envoy-conf mountPath: /etc/envoy/envoy.yaml subPath: envoy.yaml volumes: - name: envoy-conf configMap: name: envoy-conf items: - key: envoy.yaml path: envoy.yaml mode: 0644 --- apiVersion: v1 kind: Service metadata: name: web-service labels: app: nginx spec: ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 80 type: LoadBalancer selector: app: nginxこの設定により、php-fpmのコンテナから0.0.0.0:3306に接続するとMySqlに繋がります。
まとめ
Kubernetesのクラスタに外部から接続する方法は、ネットで探すと色々出てくるのですが、クラスタから外部サーバに接続する方法についての情報はあまりない印象だったので書くことにしました。
- 投稿日:2020-02-20T15:01:30+09:00
Dockeでminioを立ち上げる
OSはubuntu 18.04 LTS。
dockerでminioをセットアップする。
dockerの設定を一括でできる便利なdocker-composeを使う。準備
docker-compose.ymlが必要なので、準備する。
$ mdkir minio $ cd minio $ mkdir data 保存先のストレージを用意する。 dataディレクトリ(パスは/home/hoge/data)が生成された。 $ vi docker-compose.yml version: '3.7' services: minio1: image: "minio/minio" # docker hubにあるminio/minioイメージをpullする volumes: - /home/hoge/minio/data:/data ports: - 9000:9000 environment: MINIO_ACCESS_KEY: minio MINIO_SECRET_KEY: minio123 command: server /dataこれでとりあえず準備完了。
doker hubにあるminioイメージをpull
docker-compose upでもpullされるが、ここではpullからしておく。公式でもそうしている。
$ docker-compose pull docker hubにあるminio/minioがpullされる。 $ docker images minio/minioが保存されていることを確認できるはず。minioコンテナの起動
$ docker-compose up
戻ってこないので、別のターミナルでコンテナを確認すると、実行できていることを確認できる。
$ docker ps
- 投稿日:2020-02-20T14:47:55+09:00
Ubuntu18.04LTSにDockerをインストールする
Ubuntu18.04 LTSにDockerとdocker-composeをインストールする。
apt-getでのインストール
公式に詳細が書いてあるので、簡単に記載する。
https://docs.docker.com/install/linux/docker-ce/ubuntu/1. 古いバージョンのアンインストール
$ sudo apt-get remove docker docker-engine docker.io containerd runc2. 必要なパッケージをインストール
$ sudo apt-get update $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common3. Dockerの公式GPGキーの入手
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -4. 安定版リポジトリの入手
CPUアーキテクチャで異なるが、基本的にはx86_64/amd64だと思うので、下記で問題ないはず。
$ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"5. Dockerのインストール
$ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io6. 動作確認
$ sudo docker run hello-world $ sudo docker ps -a hello-worldコンテナが停止していることがわかる $ sudo docker images hello-worldイメージを確認できる $ sudo docker rm コンテナID コンテナを削除する コンテナIDはsudo docker ps -aで確認できる $ sudo docker rmi イメージID イメージを削除する イメージIDはsudo docker imagesで確認できる7. sudoなしでの実行
dockerグループに所属させることで、sudoなしでdockerコマンドを使える。
$ sudo adduser $USER docker $ newgrp dockersnapでのインストール
1. dockerグループの作成・所属
$ sudo addgroup --system docker $ sudo adduser $USER docker $ newgrp docker2. dockerのインストール
snapではこのとき、docker-composeもインストールされる。
$ sudo snap install docker3. 動作確認
apt-getでのインストール - 6. 動作確認 と同様。
$ sudo docker run hello-world $ sudo docker ps -a hello-worldコンテナが停止していることがわかる $ sudo docker images hello-worldイメージを確認できる $ sudo docker rm コンテナID コンテナを削除する コンテナIDはsudo docker ps -aで確認できる $ sudo docker rmi イメージID イメージを削除する イメージIDはsudo docker imagesで確認できるdocker-composeのインストール
snapでインストールした場合は不要。
詳細は下記を参照。https://docs.docker.com/compose/install/1. docker-composeの入手
最新版であるか、URLを要確認。1.25.3が変わっている恐れがある。
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose2. docker-composeに実行権を付与
sudo chmod +x /usr/local/bin/docker-compose
3. 動作確認
$ mkdir test $ cd test $ vi docker-compose.yml # 下記をdocker-compose.ymlに書き込む version: '3' services: test: image: hello-world $ docker-compose up # 下記のように出力されるはず。 Pulling hello-world (hello-world:)... latest: Pulling from library/hello-world 1b930d010525: Pull complete Creating test_hello-world_1 ... done Attaching to test_hello-world_1 hello-world_1 | hello-world_1 | Hello from Docker! hello-world_1 | This message shows that your installation appears to be working correctly. hello-world_1 | hello-world_1 | To generate this message, Docker took the following steps: hello-world_1 | 1. The Docker client contacted the Docker daemon. hello-world_1 | 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. hello-world_1 | (amd64) hello-world_1 | 3. The Docker daemon created a new container from that image which runs the hello-world_1 | executable that produces the output you are currently reading. hello-world_1 | 4. The Docker daemon streamed that output to the Docker client, which sent it hello-world_1 | to your terminal. hello-world_1 | hello-world_1 | To try something more ambitious, you can run an Ubuntu container with: hello-world_1 | $ docker run -it ubuntu bash hello-world_1 | hello-world_1 | Share images, automate workflows, and more with a free Docker ID: hello-world_1 | https://hub.docker.com/ hello-world_1 | hello-world_1 | For more examples and ideas, visit: hello-world_1 | https://docs.docker.com/get-started/ hello-world_1 | test_hello-world_1 exited with code 0snapで動作しない...
ルートディレクトリにディレクトリを作って、docker-compose upすると、docker-compose.ymlを見つけられない...
stack overflowで質問中。
https://ja.stackoverflow.com/questions/63172/snapでdockerをインストールした場合-docker-composeを実行するとdocker-compose-ymlを見つけられないERROR: Can't find a suitable configuration file in this directory or any parent. Are you in the right directory? Supported filenames: docker-compose.yml, docker-compose.yaml
- 投稿日:2020-02-20T14:08:46+09:00
Docker for Windowsでdockerの時刻がずれてbuildにコケる問題に対応する
大したことではないのですが、全然情報が出てこなくて大変だったので。
ある日、dockerをbuildしようとすると内部時刻が合わなくてapt-getが失敗してコケるという事態に見舞われました。
※私はdocker内の時刻が3日前になるという具合でしたわかってみると解決策は簡単でした。
Docker Desktopをrestartする!
どうやらWindowsをスリープしていると時刻がずれてくるというバグがあるらしい。
なんだこのバグ…。
- 投稿日:2020-02-20T13:04:10+09:00
docker-compose.yml → Dockerfile 変数渡し & 複数FROM構成での注意点
docker-compose.yml → Dockerfile に変数を渡す方法
↓この記事で使ったネタです
https://qiita.com/yagrush/items/2fbff71c1c2bf12f7d711/2 docker-compose.yml側
build
キーの子要素としてargs
キーを追加し、
その下に配列として、渡したい変数名と値を書いていきます。services: my-s3access-app: build: context: ./app dockerfile: Dockerfile args: - GITHUB_ACC=hogehige - GITHUB_ACC_PASSWORD=agd82gfo3gfagkaf ・ ・ ・2/2 Dockerfile側
ARG
コマンドで宣言(キャッチ)すると、それ以降$HOGE
で利用可能になります。FROM golang:1.13 ARG GITHUB_ACC ARG GITHUB_ACC_PASSWORD RUN echo -e "machine github.com\nlogin $GITHUB_ACC\npassword $GITHUB_ACC_PASSWORD" > ~/.netrc RUN go mod download ・ ・ ・Dockerfileが複数FROM構成のときの注意点
次の
FROM
コマンドに処理が移るとき引き継がれないので、ARG
しなおさないといけません。ちなみに複数
FROM
が必要となるのは
[ソースコードをビルドするイメージ]
と
[ビルド結果の実行体だけを配備して実行するためのイメージ]
を分けたい時などですね。FROM golang:1.13 as base FROM base as builder ARG GITHUB_ACC ARG GITHUB_ACC_PASSWORD RUN echo -e "machine github.com\nlogin $GITHUB_ACC\npassword $GITHUB_ACC_PASSWORD" > ~/.netrc RUN go mod download ・ ・ ・ FROM base as scratch ARG GITHUB_ACC ARG GITHUB_ACC_PASSWORD ・ ・ ・
- 投稿日:2020-02-20T11:06:24+09:00
GitLab CI で docker-compose を使う
数時間苦闘したのでメモ。
.gitlab-ci.yml
build: stage: build image: docker:stable services: - docker:dind script: - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true - docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG app - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG test: stage: test image: tmaier/docker-compose:19.03 services: - docker:dind script: - docker version - docker-compose version - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - sed -i "s|build:|# build:|" docker-compose.yml - sed -i "s|context:|# context:|" docker-compose.yml - sed -i "s|app_image|$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG|" docker-compose.yml - docker-compose -p $CI_COMMIT_SHA config - docker-compose -p $CI_COMMIT_SHA pull - docker-compose -p $CI_COMMIT_SHA run test after_script: - docker-compose -p $CI_COMMIT_SHA down -v - docker-compose -p $CI_COMMIT_SHA rm -f
- build ジョブは標準的な手順のまま。1
- test では
- image: docker/compose もあったが、 variables を設定してもサーバーとうまく接続できなかったので、 tmaier/docker-compose を使うようにした2。このイメージで直接テストを行うのは難があるので、テストスクリプトを実行して終了するサービス test を追加している。
- sed: ローカルでは build context で作っているのでそれをコメントアウトしている。イメージは build ジョブで作ったものを使用するようにしている。
- $CI_COMMIT_SHA: 複数のジョブまたはパイプラインが同時に実行される可能性がある場合は
-p project_name
で一意にしないとおそらく破綻する。- after_script: コンテナとボリュームとネットワークの後始末。
docker-compose.yml
そのまま。
ローカルで test イメージを起動したくないときはdocker-compose up -d app
などする。version: "3.0" services: redis: image: redis:5.0 volumes: - redis_data:/data app: build: context: app image: app_image depends_on: - redis ports: - "80:80" command: "/app/main.py" test: image: app_image depends_on: - app volumes: - ./:/work:ro command: "/work/test.sh" volumes: redis_data:CI Runner の config.toml
関係する部分を抜粋。
[[runners]] name = "xxx" url = "xxx" token = "xxx" executor = "docker" [runners.custom_build_dir] [runners.docker] tls_verify = false image = "ubuntu:18.04" privileged = true volumes = ["/certs/client", "/cache"]検証環境
CI のログから。
$ docker version Client: Docker Engine - Community Version: 19.03.5 API version: 1.40 Go version: go1.12.12 Git commit: 633a0ea838 Built: Wed Nov 13 07:22:05 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.6 API version: 1.40 (minimum version 1.12) Go version: go1.12.16 Git commit: 369ce74a3c Built: Thu Feb 13 01:32:22 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.2.12 GitCommit: 35bd7a5f69c13e1563af8a93431411cd9ecf5021 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683 $ docker-compose version docker-compose version 1.25.1, build a82fef0 docker-py version: 4.1.0 CPython version: 2.7.16 OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019
- 投稿日:2020-02-20T10:49:38+09:00
docker メモ
概要
docker を使うたびに毎回ググっていて非効率的なので自分がよく使うものをまとめました。
そのうち内容を追加するかもしれないです。
本記事の任意の内容は暗黙的に (おれだったらこうする) の意を込めているので、参考にされる場合は適宜修正してもらえばと思います。ベターな方法あるよ〜 / 間違ってるよ〜などあったら教えていただけると助かります。
前提
リモートサーバー上にコンテナを立てて中で機械学習したい。
コンテナ編
コンテナを立てる
コンテナを立てる時にすることは、
- コンテナに名前をつける
--name $CONTAINER_NAME
- マウントするディレクトリを指定する
-v $DIR_SERVER:$DIR_CONTAINER
- マウントするディレクトリが前、コンテナ内にマウントしたディレクトリを配置する場所が後
- ディレクトリの指定は絶対パスで行う
- ポートを指定する
-p $PORT_SERVER:$PORT_CONTAINER
- サーバーのポートが前、コンテナのポートが後
この3つ。なお、これらの操作はコンテナを立てた後には変更できないので、変更したい場合はコンテナを作り直す必要がある。
自分のいつも使っているコマンドはこんな感じ。
docker run --runtime=nvidia -it --privileged -v /home/$USER:/home/$USER -p 6006:6006 -p 8888:8888 --name $CONTAINER_NAME $IMAGE_NAME① ホームディレクトリをマウントしつつ、②
6006
と8888
のポートを外と繋げる。ポートを増やしたい or マウントするディレクトリを追加したい
前述の通り、これらの操作はコンテナを立てる時にしか実行できないので、
- 新しくイメージからコンテナを立て直す
- 現在使用しているコンテナをイメージ化して再びコンテナを立て直す
のどちらかを行う。前者は普通に
docker run
でOK。
後者はdocker commit
でコンテナをイメージ化してdocker run
する。docker stop $CONTAINER_NAME docker commit $CONTAINER_NAME $IMAGE_NAME docker run ...コンテナに入りたい
バックエンドで起動しているコンテナに入りたい →
docker attach $CONTAINER_NAME
終了しているコンテナに入りたい →docker start $CONTAINER_NAME
+docker attach $CONTAINER_NAME
コンテナから抜けたい
バックエンドで起動したまま抜けたい →
ctrl + q + p
コンテナ自体を終了させたい →exit
サーバー編
ポート設定
jupyter notebook や tensorboard をブラウザ上で使いたい場合、ローカルとリモートサーバを繋ぐ設定をする必要がある。
- ローカルのポートとサーバのポートを繋ぐ
ssh -L $PORT_LOCAL:$PORT_SERVER
- ローカルのポートが前、サーバーのポートが後
- 踏み台サーバを経由する場合は、踏み台のポートも繋ぐ
- ex)
ssh -L $PORT_ROCAL:$PORT_VIA:$PORT_SERVER
- サーバのポートとコンテナのポートを繋ぐ
docker run -p $PORT_SERVER:$PORT_CONTAINER
の2つをやればOK。
自分の場合、2. に関しては、サーバの
8888
とコンテナの8888
を繋いだので、
1. はローカルの18888
(任意のポート番号) とサーバの8888
を繋げば、localhost:18888
でコンテナの8888
にアクセスできる。ssh $SERVER_NAME -L 18888:8888 -L 16006:6006ポートを複数繋げたいときは上記のように適宜
-L
オプションを増やす。
- 投稿日:2020-02-20T02:35:27+09:00
Docker Desktop for Mac でApacheのコンテナを立ち上げる
- 投稿日:2020-02-20T00:47:27+09:00
【Docker入門②】『Docker』のセットアップと基本操作
この記事では、《Docker や コンテナ》について、
僕が学習した内容をまとめています。
- 『Docker』のセットアップ
- 『Docker』の基本操作
こういった疑問についてまとめています。
※本記事は、自分で学習したことのまとめ用として書いています。
尚、解説で誤った点があれば、スローして頂ければ喜んでキャッチしますのでお願い致します。<前回のお話>
【Docker入門①】そもそも『Docker』とは…?(参考)サーバーの準備
まずは・・・
『Docker』を使用する環境を準備しましょう!
本記事では、詳しく触れませんが…
今回は『CentOS』を前提として、解説していきます。
ですので・・・
『VirtualBox』や『VMware』などを利用して、仮想マシンを準備してみて下さい。
※『仮想マシン作成』の記事に関しては、今後まとめる予定です。
(参考)『Docker』のセットアップ
yumのリポジトリ設定などを行って、『Docker CE』をインストールしていきます。
Docker CE をインストールするためのリポジトリ設定
ホストOS上に『Docker CE』をインストールする前に、『Docker リポジトリ』のセットアップが必要です。
そのため、まずは・・・
- yum-utils
- devicemapper
で必要とされるパッケージをインストールします。
『yum-utils』は、
yum-config-manager
などのコマンドが含まれます。そして・・・
『device-mapper-persistent-data』と『lvm2』は、『devicemapper』の使用に必要です。
devicemapperに関して知りたい方は、下記の記事で丁寧に解説されていますので、参照してみて下さい。
》Dockerのストレージドライバを理解する$ yum install -y yum-utils device-mapper-persistent-data lvm2次に・・・
『Docker CE』をインストールするために、『yumリポジトリ』を追加します。
『CentOS 7』では、パッケージ管理ソフトウェアとして『yum』を利用していますが、『Docker』は公式の『yumリポジトリ』を提供していますので、その公式『yumリポジトリ』からインストールすることができます。
そのため・・・
『CentOS 7』に『Docker』の公式『yumリポジトリ』の情報を追加して、リポジトリを使えるようにします。
$ yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo下記コマンドで、リポジトリが追加され、有効化されていることを確認しましょう。
$ yum repolist all | grep -i docker次に・・・
以下のコマンドで『edgeリポジトリ』を無効化します。
【余談】『Docker CE』の『edge』『stable』について
『Docker CE』のDockerエンジンには、頻繁にリリースされる『edge』と約半年ごとに安定版としてリリースされる『stable』の2種類あります。
今回は、安定版の『stable』のみを利用ので、『edgeリポジトリ』を無効にします。
$ yum-config-manager --disable docker-ce-edgeパッケージの最新情報を取得します。
$ yum makecache fastそれでは、インストール可能な『Docker』をリストアップしてみましょう。
『edgeリポジトリ』の有効・無効かで表示が異なるので、気になる方は確認してみてください。
$ yum list docker-ce.x86_64 --showduplicatesそして・・・
お待ちかねの『Docker CE』のインストールです。
$ yum install docker-ceこれで『Docker CE』がインストールできました。
ついでに、以下のコマンドでインストールされているか確認しておきましょう。
$ yum list installed | grep docker-ce再読込し、設定を反映させます。
新規にユニットファイルを作った際や、/etc/systemd/system/配下のファイルを編集した際にリロードします。
$ systemctl daemon-reload『Docker』を起動します。
$ systemctl start docker以下のコマンドでサービス自動起動設定をしておくと、マシンの再起動後も自動で『Docker』が起動します。
$ systemctl enable docker以上で『Docker』のセットアップは終了です。
次は、『Docker』の基本操作について見ていきましょう。
『Docker』の基本操作
ここからは、公開されている『Dockerイメージ』を使用し、下記の4つの基本操作について見ていきましょう。
- 公開されている『Dockerイメージ』の取得
- それを元にコンテナを起動
- 起動の確認ができたら、コンテナの停止
- 停止したコンテナの削除
STEP①:『Dockerイメージ』の取得
『Dockerイメージ』の一覧を表示
以下のコマンドで、ローカル環境の『Dockerイメージ』の一覧を確認できます。
$ docker images現状、ヘッダーのみで、何も表示されないと思います。
『Dockerイメージ』のダウンロード
それでは、『Dockerイメージ』を取得してみましょう。
『Dockerイメージ』は、Docker Hubと呼ばれるオンラインサービスが提供されており、そこでイメージの共有やダウンロードが可能です。
Docker Hubからイメージを取得するには、
docker pull
コマンドを使用します。
docker pull
コマンドの書式は、以下の通りです。$ docker pull NAME[:TAG]
- NAME:イメージ名
- TAG:タグ名(省略した場合はlatest)
今回は最新の『Apache httpd』を含んだイメージを取得しますので、コマンドの引数に
httpd
を指定します。$ docker pull httpdタグ名にはバージョンを指定することが一般的ですが、タグ名を省略した場合はデフォルトで
latest
を指定したことになり、最新版がインストールされます。『Dockerイメージ』の確認
『httpd イメージ』のダウンロードが完了し、イメージに追加されたことを確認するため、
docker images
コマンドを実行します。$ docker images『httpd イメージ』が追加されたことが分かるかと思います。
これで『Dockerイメージ』の取得は完了です。
STEP②:コンテナの起動
以下のコマンドでは、ローカル環境のコンテナの一覧を確認できます。
$ docker psまだコンテナの起動は行っていないので、ヘッダーのみしか表示されません。
『httpd イメージ』を使ってコンテナを動かしてみる
イメージからコンテナを作成して起動するには、
docker run
コマンドを実行します。
docker run
コマンドの書式は、次の通りです。$ docker run [OPTION] NAME[:TAG] [COMMAND]
- OPTION:オプション
- NAME:Dockerイメージ名
- TAG:タグ名(省略した場合はlatest)
- COMMAND:実行時に上書きしたいコマンド
さっそく
docker run
コマンドを実行して、コンテナを作成・起動してみましょう。
(コマンドのオプションについては、次で解説します)$ docker run --name httpd -p 8080:80 -d httpd
オプション 概要 -d コンテナの実行をバックグラウンドで行うオプション。
仮に、このオプションを指定しなかった場合は、ターミナルのコマンド操作がCtrl+C
を実行するまでコンテナに奪われてしまいます。–name コンテナ名を指定。
(指定しなかった場合は、自動で名前が付けられます)-p コンテナのポート番号とローカルのコンピュータのポート番号を紐づけるオプション。
今回実行したコンテナは、80番ポートでhttpdが開始されます。 ただし、80番ポートで設定されているのは『コンテナ』であり、『Docker』を実行しているローカルマシンではありません。
そこで、この-p
オプションで、『コンテナ』と『ローカルマシン』のポートを紐づけることで、あたかもローカルマシンでhttpdがサービスを提供しているかのような状態を作ることができます。
今回の例では、ローカルマシンの8080番ポートをコンテナの80番ポートに紐づけています。これで『httpd コンテナ』の実行が完了しましたので・・・
にアクセスしてみてください。
すると・・・
みなさんおなじみの『It work!』が表示されるはずです。
実行中のコンテナを確認する
次に、実行中のコンテナの状態を確認してみましょう。
本記事に沿って操作をしている場合、現時点で『httpd コンテナ』が実行中かと思うので、
docker ps
コマンドで確認してみましょう。$ docker ps実行中のコンテナが1つあることが確認できるかと思います。
STEP③:コンテナの停止
実行中のコンテナを停止したい場合は、
docker stop
コマンドを使用します。$ docker stop [CONTAINER]
- CONTAINER:CONTAINER ID(コンテナID)、NAMES(コンテナ名)
コマンドの引数として、『コンテナID』または『コンテナ名』を指定します。
今回は、起動したコンテナに『httpd』という名前を付けたので…
$ docker stop httpdとして、コンテナを停止させます。
停止したコンテナの確認
コンテナを停止したら、同様に
docker ps
コマンドで停止したかを確認しましょう。$ docker ps実行結果にコンテナが表示されなくなったかと思います。
停止させたコンテナも表示させたい場合は…
docker ps
コマンドに-a
オプションをつけて実行します。$ docker ps -a表示された結果の『STATUS』欄に
Exited
と表示されているのが確認できるかと思います。STEP④:コンテナの削除
停止中のコンテナを削除せずそのままにしておくと、ゴミが残ったままになり、容量の圧迫にもつながるので…
不要になったコンテナは、削除するようにしましょう。
コンテナを削除する場合は、
docker rm
コマンドを使用します。$ docker rm [CONTAINER]
- CONTAINER:CONTAINER ID(コンテナID)、NAMES(コンテナ名)
今回は、起動したコンテナに『httpd』という名前を付けたので…
$ docker rm httpdとして、コンテナを削除します。
削除したコンテナの確認
コンテナを削除したら、同様に
docker ps -a
コマンドで削除されたか確認しましょう。$ docker ps -a一覧にコンテナが表示されなくなったかと思います。
まとめ
最後に、今回ご紹介した『Docker コマンド』についてまとめます。
- イメージのダウンロード:
docker pull
- イメージの一覧の確認:
docker images
- コンテナの実行:
docker run
- コンテナの一覧確認:
docker ps
、docker ps -a
- コンテナの削除:
docker rm