- 投稿日:2020-06-23T23:58:24+09:00
[Ruby on rails] Docker & Travis CIを使ってHerokuデプロイしたときのエラーまとめ
概要
初めてDockerやTravis CIを使ってデプロイしたので流れとエラーをまとめておきます。
誰かの参考に慣れば・・・
Dockerの勉強はUdemyのこちらの動画で勉強しました。
初心者にもかなりわかりやすく説明されているのでお勧めです。
※この動画ではpostgesqlを使う方法が紹介されていますが、僕は開発環境も含めmysqlを使ってので違いなどもメモしておきます。環境設定
・Docker
・rails 5.2大まかなデプロイ時の流れ
- TravisCIに登録し、GitHubと連携
- .tarvis.yml ファイルを書く
- Travis CIにビルド
- Herokuでアプリ作成
- Heroku と Travis CI に環境変数を設定する。
2つのエラー
mysql2が読み込まれない
Herokuにデプロイした際に、Build failedとなってしまいました。
ブラウザからHerokuのリポシトリーのActivityにあるBuild log を見ると以下のところでエラーになっているようでした。LoadError: Could not load the 'mysql' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.これはブラウザのHerokuのリポジトリーのsettingsのConfig Varsを開き、
CLEARDB_DATABASE_URL : mysql://~~となっているところを
CLEARDB_DATABASE_URL : mysql2://~~と変更すると直ります。デフォルトではmysqlが書かれてしまうんですかね?
DBがない!?
Herokuのアプリの画面に移動した際、
We're sorry, but something went wrong.
というエラー表示がされてしまいました。これはローカルからHerokuへとアクセスし
$ heroku logs -tでログを見てみると
ActiveRecord::StatementInvalid (Mysql2::Error: Table 'heroku_067b02b8d8fb0b9.users' doesn't exist: SHOW FULL FIELDS FROM `users`):となっていて、DBができていないようなので、マイグレーションして解決しました。
$ heroku run rails db:migrate※ travis.yml ファイルにデプロイの際に、マイグレーションするように書いたはずなんだけどなー。なぜかうまく行っていなかったですね。
- 投稿日:2020-06-23T22:46:15+09:00
Docker+Rails6+MySQL+Nginx環境構築メモ
はじめに
弊社では未だにdockerを導入しておらず、このままだとマズいと思ったので勉強も兼ねて環境構築してみました。
ミスや間違った説明をしている箇所があるかもしれませんが、優しくご指摘頂けると助かります。
既に環境構築系の記事は出ていますが、実際試しても上手くいかないことがあったので自分の経験もまとめておきます。流れ
- "rails new"でプロジェクト作成
- "git init"でローカルリポジトリ作成
- GitHubにてリモートリポジトリ作成
- リモートリポジトリにプッシュ
-----ここから書きます-----
- EC2インスタンス作成
- gitインストール
- dockerインストール
- docker起動
- リモートリポジトリをプル
- イメージのビルド(docker-compose build --no-cache)
- コンテナ作成,起動(docker-compose up -d)
- マイグレーション(docker-compose exec sample-app_web_1 bundle exec rails db:migrate)
gitのインストール
Gitをインストールします
$ sudo yum install git $ git clone https://github.com/satou-yuuki/sample-app.gitdockerのインストール
AWS公式に従ってDockerをインストールします
参考:https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html$ sudo yum update -y $ sudo amazon-linux-extras install docker $ sudo systemctl start docker.service または sudo service docker start $ sudo usermod -a -G docker ec2-user 一度ターミナルを抜けるとグループが追加されていると思いますdocker-composeのインストール
docker公式に従ってdocker-composeをインストールします
参考:https://docs.docker.com/compose/install/$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-composedocker-compose build
$ docker-compose build --no-cachedocker-compose up
$ docker-compose up -drails db:migrate
$ docker exec sample-app_web_1 bundle exec rails db:migrateブラウザから確認
ブラウザで http://host/users を確認するとエラー画面が表示されてしまったのでログを確認します。
Started GET "/users" for 111.239.186.32 at 2020-06-22 00:17:50 +0000 Cannot render console from 111.239.186.32! Allowed networks: 127.0.0.0/127.255.255.255, ::1 Processing by UsersController#index as HTML Rendering users/index.html.erb within layouts/application User Load (0.4ms) SELECT `users`.* FROM `users` ↳ app/views/users/index.html.erb:16 Rendered users/index.html.erb within layouts/application (Duration: 3.8ms | Allocations: 1537) [Webpacker] Compiling... [Webpacker] Compilation failed: yarn run v1.22.4 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. error Command "webpack" not found. Completed 500 Internal Server Error in 1573ms (ActiveRecord: 0.9ms | Allocations: 23784) ActionView::Template::Error (Webpacker can't find application in /sample-app/public/packs/manifest.json. Possible causes: 1. You want to set webpacker.yml value of compile to true for your environment unless you are using the `webpack -w` or the webpack-dev-server. 2. webpack has not yet re-run to reflect updates. 3. You have misconfigured Webpacker's config/webpacker.yml file. 4. Your webpack configuration is not creating a manifest. Your manifest contains: { } ): 6: <%= csp_meta_tag %> 7: 8: <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 9: <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> 10: </head> 11: 12: <body> app/views/layouts/application.html.erb:9ググった結果以下のコマンドを実行で解決しました。
babelやpostceeなど各種設定ファイルの生成とyarn addを実行してくれるようです。
ただ設定ファイルはrails newした時点で存在していたのでyarn addする必要があるみたいですね。yarn add @rails/webpacker@4.2.2 from "."
yarn add --dev webpack-dev-server from "."$ docker exec bundle exec rails webpacker:installconflict config/webpacker.yml Overwrite /sample-app/config/webpacker.yml? (enter "h" for help) [Ynaqdhm] n skip config/webpacker.yml Copying webpack core config exist config/webpack identical config/webpack/development.js identical config/webpack/environment.js identical config/webpack/production.js identical config/webpack/test.js Copying postcss.config.js to app root directory identical postcss.config.js Copying babel.config.js to app root directory identical babel.config.js Copying .browserslistrc to app root directory identical .browserslistrc The JavaScript app source directory already exists apply /usr/local/bundle/ruby/2.5.0/gems/webpacker-4.2.2/lib/install/binstubs.rb Copying binstubs exist bin identical bin/webpack identical bin/webpack-dev-server File unchanged! The supplied flag value not found! .gitignore Installing all JavaScript dependencies [4.2.2] run yarn add @rails/webpacker@4.2.2 from "." yarn add v1.22.4 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@1.2.13: The platform "linux" is incompatible with this module. info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation. info fsevents@2.1.3: The platform "linux" is incompatible with this module. info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... warning " > webpack-dev-server@3.11.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0". warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0". [4/4] Building fresh packages... success Saved 0 new dependencies. Done in 49.21s. Installing dev server for live reloading run yarn add --dev webpack-dev-server from "." yarn add v1.22.4 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@2.1.3: The platform "linux" is incompatible with this module. info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation. info fsevents@1.2.13: The platform "linux" is incompatible with this module. info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... warning "webpack-dev-server > webpack-dev-middleware@3.7.2" has unmet peer dependency "webpack@^4.0.0". warning " > webpack-dev-server@3.11.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0". [4/4] Building fresh packages... success Saved 1 new dependency. info Direct dependencies └─ webpack-dev-server@3.11.0 info All dependencies └─ webpack-dev-server@3.11.0 Done in 4.67s. Webpacker successfully installed ? ?もう一度ブラウザから確認するとユーザー一覧画面が表示されていました!
ログを見るとwebpackでコンパイルされていることが分かります。Started GET "/users" for 111.239.186.32 at 2020-06-22 00:24:31 +0000 Cannot render console from 111.239.186.32! Allowed networks: 127.0.0.0/127.255.255.255, ::1 (17.7ms) SET @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 Processing by UsersController#index as HTML Rendering users/index.html.erb within layouts/application User Load (8.9ms) SELECT `users`.* FROM `users` ↳ app/views/users/index.html.erb:16 Rendered users/index.html.erb within layouts/application (Duration: 10.6ms | Allocations: 731) [Webpacker] Compiling... [Webpacker] Compiled all packs in /sample-app/public/packs [Webpacker] Hash: 15d1bb7b54cf6326b9ba Version: webpack 4.43.0 Time: 2988ms Built at: 06/22/2020 12:24:36 AM Asset Size Chunks Chunk Names js/application-9afcbb5693aa87623e69.js 124 KiB application [emitted] [immutable] application js/application-9afcbb5693aa87623e69.js.map 139 KiB application [emitted] [dev] application manifest.json 364 bytes [emitted] Entrypoint application = js/application-9afcbb5693aa87623e69.js js/application-9afcbb5693aa87623e69.js.map [./app/javascript/channels sync recursive _channel\.js$] ./app/javascript/channels sync _channel\.js$ 160 bytes {application} [built] [./app/javascript/channels/index.js] 211 bytes {application} [built] [./app/javascript/packs/application.js] 749 bytes {application} [built] [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 552 bytes {application} [built] + 3 hidden modules Completed 200 OK in 5083ms (Views: 5073.4ms | ActiveRecord: 8.9ms | Allocations: 6105)まとめ
勉強して分かったことを追記していく予定です。一旦ここまで。
誰かの参考になれば幸いです。
- 投稿日:2020-06-23T21:51:19+09:00
Dockerをnginxのリバースプロキシで制御する
概要
一つのレンタルサーバーに複数のWebサイトをURLで制御する必要性があり、Dockerとnginxを用いて組んでみたという話
環境
レンタルサーバー : さくらのVPS(1GBプラン)
os : CentOS7
Docker version 19.03.12, build 48a66213fe
nginx version: nginx/1.16.1Dockerの環境構築
Dockerを使ったこともない人が付け焼刃でDockerを組んでみたら意外と組めるものであったが...
数点はまったので書いておく
- systemctlが使えない まず、普通にCentosのDockerをたてたが、systemctlが認識されない..... なんと、起動時に指定しないといけないらしい....(知らなかった....) ということで、Docker runするときに以下のコマンドを追加
--tmpfs /tmp --tmpfs /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro --stop-signal SIGRTMIN+3
- portがかぶって複数のコンテナがたたない
docker container runをするときに ipオプションで ホスト:コンテナの順で、指定するDockerをnginxのリバースプロキシで制御する
ここからは本題のDockerをnginxのリバースプロキシで制御したという話
今回の最終目標は以下の図のようにすることである
図の説明をすると、URLを基にDocker1~Docker4のどれかに接続する
今回はSSLについては記述しない
nginxの設定は/etc/nginx/conf.d以下に記述する
接続したいDocckerのコンテナ名でconfファイルを生成する
そこに以下を記述するserver{ listen 80; server_name <接続したいURL>; location / { proxy_pass <DockerのIP>; } }この記述ができ次第nginxを再起動する
- 投稿日:2020-06-23T21:24:07+09:00
[2020Q2] Docker コンテナでの sshd 起動まとめ w/o init
はじめに
いくつかのディストリビューションにおいて sshd を起動するミニマムと思しき手順をまとめます。
今回想定しているのは init を使わないで直接 sshd を起動するケースです。・・・っていう出だしなんですが、どちらかと言うと、鍵を誰が作っているのか、鍵が無かったらどうなるのか、イメージ配布するのに鍵を消したいけど自動的に再生成されるのか、みたいなことがポイントになってます。
対象ディストリビューション:
- CentOS 8
- Ubuntu 20.04 LTS (Focal Fossa)
CentOS 6 と 7 それから Ubuntu 16.04 LTS (Xenial Xerus) と 18.04 (Bionic Beaver) については、古い投稿にて扱っています。
そろそろみんな systemd けれど少しずつ微妙に違う
CentOS 8 も Focal も sshd は systemd が管理しています。例えば sshd の起動は下記で共通です。
# systemctl start sshdCentOS はオンデマンドで鍵を生成する
伝統的に CentOS は sshd 起動時に自動的に鍵が生成されます。
もしイメージから鍵ファイルを消しておいたとすると、次回起動時に改めて生成されるということです。イメージ流用の観点からは、この方式は便利です。サンクス。CentOS 7 と 8 では鍵生成用の systemd unit ファイルが独立して存在し、sshd.service に依存関係が設定されています。ただちょっと 7 と 8 では unit ファイル構成が違っています。
CentOS 7 はシンプル
/lib/systemd/system/sshd-keygen.service[Unit] Description=OpenSSH Server Key Generation ConditionFileNotEmpty=|!/etc/ssh/ssh_host_rsa_key ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ecdsa_key ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ed25519_key PartOf=sshd.service sshd.socket [Service] ExecStart=/usr/sbin/sshd-keygen Type=oneshot RemainAfterExit=yesCentOS 8 は target を活用
/lib/systemd/system/sshd-keygen@.service[Unit] Description=OpenSSH %i Server Key Generation ConditionFileNotEmpty=|!/etc/ssh/ssh_host_%i_key [Service] Type=oneshot EnvironmentFile=-/etc/sysconfig/sshd ExecStart=/usr/libexec/openssh/sshd-keygen %i [Install] WantedBy=sshd-keygen.target/lib/systemd/system/sshd-keygen.target[Unit] Wants=sshd-keygen@rsa.service Wants=sshd-keygen@ecdsa.service Wants=sshd-keygen@ed25519.service PartOf=sshd.serviceふーん、て感じですw
Ubuntu は1回だけ鍵を生成する
伝統的に Ubuntu では openssh-server パッケージの postinst スクリプトが鍵を生成しています。
# dpkg-reconfigure openssh-serverもしイメージから鍵ファイルを消しておいたとすると、次回起動時に sshd は正常に動きません。イメージ流用の観点からは、この方式は不便です。ざんねん。
そして、鍵が無いとき、sshd の挙動が Bionic と Focal で異なります。Bionic も Focal も
sshd.service
のExecStartPre
でsshd -t
しているのですが・・・Bionic は諦めない
Bionic は鍵が無くても
sshd -t
が成功扱い($? が 0)で、sshd が起動します。しかし鍵が無いと ssh クライアントから接続できません。
ここで sshd を起動したまま鍵を生成すると、ssh クライアントから接続できるようになります。なんだか強い子っぽい。Focal は潔い
Focal は鍵が無いと
sshd -t
が失敗し、sshd は起動しません。
個人的には Focal の挙動が好きです。ところで
Ubuntu では伝統的に sshd.service は ssh.service へのシンボリックリンクです。
実は
dpkg-reconfigure openssh-server
では dsa 鍵が生成されません。なんでだろ。
ちょっとキモいけど今は無視します。
- 投稿日:2020-06-23T19:02:53+09:00
SpringBoot(Gradle)+MySQL8.0+CSVで初期DBインポート のアプリを Windows Dockerで動かす
目的
- SpringBootで作ったJavaサーバ、DBはMySQLの8.0を使用する
- サーバー起動時に、data.csvとinit.sqlを用意し、init.sqlから
local infile
コマンドを使用してdata.csvで初期DBをインポート- 他の人の環境で環境構築が大変なので、Dockerを使用することにした
- 結構ハマったり苦労したので共有
Dockerでどうやるか
- Dockerは1コンテナで1サービスが基本。JavaサーバコンテナとMySQLコンテナの2つを作り、docker-composeで連携させます
設定に必要な全体構成図
- root
- src/main/java
- @Entity をもったクラスファイル
- src/main/resources/application.yml
- docker-compose
- mysql
- config/my.cnf
- 権限は読み取り専用
- initdb
- data.csv
- init.sql
- Dockerfile
- spring
- Dockerfile
- docker-compose.yml
- build.gradle
How
- @Entity をもったクラスファイル
- GenerationType.AUTO ではなく、GenerationType.IDENTITY を使用してください
- CSVを事前インポートした後に、新しくデータを追加すると同じIDが重複するという問題が発生します
@Entity @Table(name="shohin") public class MyData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = true, unique = true) private Integer id;
- application.yml
- 上がローカルで回すとき、下がdocker-composeで回すときの設定です
- ローカルのurlが長いのは、何かとエラーがでて対策を入れた結果です
server: port: 8081 --- spring: datasource: driverClassName: com.mysql.cj.jdbc.Driver password: hogehoge url: jdbc:mysql://localhost:3306/hogehoge_db?allowPublicKeyRetrieval=true&useSSL=FALSE&characterEncoding=UTF-8&serverTimezone=JST username: hoge jpa: database: MYSQL hibernate: ddl-auto: update --- spring: profiles: docker-compose datasource: url: jdbc:mysql://dbserver/hogehoge_db username: hoge password: hogehoge driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update
- my.cnf
- MySQL8.0から「load data local infile」コマンドがデフォルトオフになりました。local_infile=1で有効にします
- また、Windows Proの環境のDockerならばこのままで問題ありませんが、Home環境だとパーミッション777のファイルはMySQL8.0が読みにいかないので読み取り専用にプロパティから変更しておきます
[Warning] World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored
- 文字コードも調整しておきます
[mysqld] character-set-server=utf8 local_infile=1 [mysql] default-character-set=utf8 [client] default-character-set=utf8 local_infile=1
- init.sql
- docker-compose up --build コマンドを叩いたとき、1回目に呼ばれるSQLです
- IDには「id int AUTO_INCREMENT PRIMARY KEY」を指定してください。 @Entity で指定したカラムにしてください。
use hogehoge_db; CREATE TABLE shohin(hogehoge); load data local infile '/docker-entrypoint-initdb.d/data.csv' INTO TABLE sector FIELDS TERMINATED BY ','; select * from shohin;
- mysql/Dockerfile
FROM mysql:8.0 RUN touch /var/log/mysql/mysqld.logFROM openjdk:jdk-alpine VOLUME /tmp RUN mkdir /app WORKDIR /app ENV JAR_TARGET "hogehoge-0.0.1-SNAPSHOT.jar" ENTRYPOINT ["sh","-c","java -jar -Dspring.profiles.active=docker-compose ./build/libs/${JAR_TARGET}"]
- docker-compose.yml
- データの永続化をすると、mysqlコンテナにデータが残らなくなり、後々CSVを読み込むとき面倒だったのでコメントアウト
- mysqlコンテナを docker rm hogehoge 等で削除しない限りは残りますので安心してください
version: "3" services: dbserver: container_name: mysql8.0_hogehoge_db image: mysql:8.0 environment: MYSQL_DATABASE: hogehoge_db MYSQL_USER: hoge MYSQL_PASSWORD: hogehoge MYSQL_ROOT_PASSWORD: hogehogehoge expose: - 3307 ports: - 3307:3307 volumes: # 起動スクリプト - ./docker-compose/mysql/initdb:/docker-entrypoint-initdb.d # MySQLの設定ファイル - ./docker-compose/mysql/config:/etc/mysql/conf.d # DBの永続化 アプリコンテナ、DBコンテナを消しても残り続ける。今回はCSVを読みたいのでコメントアウト。コンテナ消すとDB消えるから注意しろな! #- mysql_db:/var/lib/mysql # logの出力 - ./log/mysql:/var/log/mysql app: container_name: hogehoge_app build: ./docker-compose/spring depends_on: - dbserver ports: - "8081:8081" volumes: - .:/app environment: # mysqlの接続設定 host:portはコンテナ名指定 spring.datasource.driverClassName: "com.mysql.cj.jdbc.Driver" spring.datasource.url: "jdbc:mysql://dbserver/hogehoge_db" spring.datasource.username: "hoge" spring.datasource.password: "hogehoge" # DBの永続化先 volumes: mysql_db: driver: local
- build.gradle
- dependenciesにmysqlを追加。以下サンプル
dependencies { implementation 'org.springframework.boot:spring-boot-starter' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-thymeleaf' compile 'org.springframework.boot:spring-boot-devtools' compile('org.springframework.boot:spring-boot-starter-data-jpa') runtime('mysql:mysql-connector-java') }gitで配布するとき
- /build/libsの中のjarがデフォルトgitignoreに入ってると思いますが、gitで管理してください。このjarを元に回るため
- readmeに、mysql\config のmy.cnfを読み取り専用にするように記載してください
dockerの準備
- dockerをインストール済みのWindowsの用意
- docker desktopの設定を開き、Resources→File SharingでCドライブを追加する
- https://qiita.com/kikako/items/7b6301a140cf37a5b7ac
dockerで動かす
- エクスプローラのファイルよりpowershellを管理者で起動(管理者権限があるユーザなら普通のpowershellでよい)
- docker-compose up --build
- その後右下に警告がでたら share it を2回押下。2回でるきがする
- Ctrl Cで止められるが、怖いなら docker-compose up --build -d でバックグラウンド実行
- down叩くまで動き続ける
- 終わらせるときは同一フォルダで docker-compose down
- 1回目はアプリ起動時にSQLが実行されておらず、起動に失敗すると思う。2回目に起動成功します
2回目以降のCSVインポート、既存DB削除等
* 全コンテナ停止: docker stop $(docker ps -q) * 全コンテナ削除:docker rm $(docker ps -q -a) * 全イメージ削除: docker rmi $(docker images -q)
- 投稿日:2020-06-23T18:56:20+09:00
100日後にエンジニアになるキミ - 95日目 - 開発環境 - Docker について
昨日までのはこちら
100日後にエンジニアになるキミ - 94日目 - 開発環境 - 仮想化について
100日後にエンジニアになるキミ - 91日目 - 運用 - 監視について
100日後にエンジニアになるキミ - 90日目 - 開発 - CIについて
100日後にエンジニアになるキミ - 88日目 - データ - データ転送について
100日後にエンジニアになるキミ - 86日目 - データベース - Hadoopについて
100日後にエンジニアになるキミ - 76日目 - プログラミング - 機械学習について
100日後にエンジニアになるキミ - 70日目 - プログラミング - スクレイピングについて
100日後にエンジニアになるキミ - 66日目 - プログラミング - 自然言語処理について
100日後にエンジニアになるキミ - 63日目 - プログラミング - 確率について1
100日後にエンジニアになるキミ - 59日目 - プログラミング - アルゴリズムについて
100日後にエンジニアになるキミ - 53日目 - Git - Gitについて
100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて
100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて
100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1
100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1
100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1
100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1
本日はにコンテナとDockerについてです。
コンテナについて
仮想化
が何たるかは前回を見ていただければ良いかと思います。仮想化と言えば一昔前は
ゲストOS
を用いた仮想化がほとんどでした。
最近ではコンテナ
と呼ばれる技術が出てきています。参考:https://pfs.nifcloud.com/navi/tech/container_virtualization.htm
従来の仮想化では1台の物理マシン上には
ホストOS
が起動し
そのOS上で複数のゲストOS
が稼働していました。しかし仮想化ソフトを使用した仮想化環境にもデメリットがあります。
複数OSを利用することによる性能劣化や
仮想化ソフトウェアの介在による複雑化などがあります。そこで注目されているのが
コンテナ
です。
コンテナ
はホストOS
上にアプリケーションの起動に必要な
アプリケーション・ライブラリ・設定ファイルなどをひとまとめにした
コンテナ
を作成しコンテナエンジン
上で動作させる技術のことです。通常の仮想化と似ている点もありますが、大きく異なる点として
ゲストOS
を用いないということです。
コンテナ
ではゲストOS
を起動することなく
アプリケーションの実行環境を構築することが可能になるため
仮想マシンに比べて少ないリソースで済むのが特徴です。このような
コンテナ
技術を牽引するソフトウェアとしては
docker
と言うものがあります。Dockerについて
Docker
は2013年頃に発表されたコンテナ仮想化を用いて
アプリケーションを実行するためのソフトウェアです。
Docker
はコンテナ仮想化を用いたOSレベルの仮想化により
環境自体をアプリケーションと同じようにコード(イメージ)として管理可能にし
アプリケーションの素早い提供を実現します。
Docker
はミドルウェアのインストールや各種環境設定をコード化して管理します。
ソフトウェア開発で実施されてきた構成管理や自動化などを
サーバーの各種設定やミドルウェアのインストールなどにも応用できます。これらにより、以下のような利点が生まれます。
・ファイルを共有することで、誰でも同じ環境が作れる
・作成した環境イメージを配布しやすい
・スクラップ&ビルドが容易データ分析の観点から言えば、誰でも同じ環境を作る利点が大きいです。
Python言語を用いた分析環境ではライブラリのバージョン差異が生まれやすく
分析環境が異なることでのトラブルが発生しやすいです。環境の統一化をすることで軽減することができます。
また開発環境の構築をする時間の短縮化にもつながります。
新規の案件に参画した場合、開発環境の構築に1日かかってしまうこともあります。
それが配布されたイメージ1つで済みます。当然
Docker
の学習コストを支払わなければならないのですが
今後はコンテナを利用した開発が増えていくため、抑えておくメリットは大きいです。また最近では
コンテナ
を管理するオーケストレーションツール
を使うことで
より運用が楽になって来ています。最近では
オーケストレーションツール
としてKubernetes
が注目を浴びています。参考:https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/
まとめ
10年以上前は仮想化が流行った時期がありましたが
そこから少し経って今ではコンテナと言う技術が流行ってきています。コンテナを扱うことのできる
docker
の利用も高まってきており
開発者のニーズも高まってきています。これからの開発のスタンダードになると思いますので
抑えておいても損はないかと思います。明日はもう少し詳しく紹介していきます。
君がエンジニアになるまであと05日
作者の情報
乙pyのHP:
http://www.otupy.net/Youtube:
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMwTwitter:
https://twitter.com/otupython
- 投稿日:2020-06-23T16:55:20+09:00
「WordPress」で「docker-compose」の理解を深めた勉強会
概要
現場で
docker-compose
を使っており、復習も兼ねて勉強会で取り上げてみました。まず、勉強会にはdocker
やコンテナの概念が微妙な方もいらっしゃったため、まずはWordPress
を使ってコンテナに接続して、まずは触れてもらいながら学習してもらうことにしました。その学習内容を記事にまとめさせていただきます。勉強会自体はかなりボリュームになってしまい上記は前半の初心者向けの内容となります。なお後半は
docker-compose
でNode.js(Express)
とPostgresSQL
を使用した簡単なサービスを作成しました。こちらは初めてチャレンジしたモノで、それはそれで面白かったのでそちらの内容も別の記事にて投稿予定です。それでは以降からは学習内容のまとめになります。
そもそもdockerって何?コンテナって何?
VirtualBox
との比較がわかりやすかったりします。以下はさくらナレッジの記事を引用です。VirtualBoxなどの仮想マシンでは、ホストマシン上でハイパーバイザを利用しゲストOSを動かし、その上でミドルウェアなどを動かします。それに対し、コンテナはホストマシンのカーネルを利用し、プロセスやユーザなどを隔離することで、あたかも別のマシンが動いているかのように動かすことができます。
https://knowledge.sakura.ad.jp/13265/
と説明を受けても若干イメージしづらいのが正直なところです。以下のような現実での例で説明してみました。
VirtualBox
などの仮想マシン:一軒家Docker
などのコンテナ:マンションの1室あと、仮想マシンは触ったことがある人が多かったので以下のような説明もしました。
- 仮想環境をアプリケーションごとに分けたいな~と思います~
- そのときに共通で使用できそうなOSなどを新しく別に作るのはダルいよね~
- アプリケーションの部分だけ別の環境として作りたいよね~
- それを実現したのが
docker
やコンテナだと思います~dockerのコンテナってどうやって作られているの?
まずはdocker-hubにあるOfficialのイメージをみてもらいました。いろんなサービスのコンテナのイメージがあり、自分が使いたいプログラミング言語やデータベースのイメージを使用することですぐに動作できる環境を準備できます。
- 例:Node.jsを使いたい!
- Node.jsのイメージを使えばNode.jsを動作できる環境を作れる!
そもそも
docker
のコンテナやイメージってどうやって作られているかという話ですがほとんどがDockerfile
になると思います。実はOfficialイメージから各バージョンごとのDockerfile
を確認することができます。
- Node 14 の Dockerfile
もし独自にコンテナあるいはイメージを作成したい場合には
Dockerfile
を作ればよいわけです。また既存のイメージから拡張したい内容をDockerfile
に追加することも可能です。複数のサービスを連携してこそのコンテナ
1つのサービスを実行するだけだと普通の仮想マシンと変わりません。やはりコンテナ同士で連携するサービスを構築することで真価が出ると思います。口だけでいうと伝わらないと思ったので、お試しに
docker-compose
でWordPress
を実行してもらいました。docker-composeって何?
1つだけのサービスなら
Dockerfile
だけで問題ありませんが、複数のコンテナの連携になるとdocker-compose
が良いです。WordPressって何?
WordPress
はPHP
で作られているCMS(コンテンツ管理システム)でサイトの内容を保存するためにMySQL
を使用します。詳細については割愛させていただきますが、「PHP
が動作する環境」と「MySQL
のデータベース」を準備する必要があります。今回は必要な2つの環境をdocker-compose
で構築します。docker-composeでWordPressを動かす
docker-compose.yml
version: '2' services: db: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: image: wordpress:latest depends_on: - db ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpress実行内容
docker-compose build docker-compose up -d実行内容に関する説明
まずは実行内容の
build
でコンテナを作成します。実のところ今回の場合は特に意味はありません。ただし自分でDockerfile
を作成した場合はbuild
した方がよいです。直接up
した場合でもイメージがなければbuild
が実行されます。ここで気を付けてほしいのが以前に
build
したコンテナがある場合はそのコンテナを実行します。例えばDockerfileで読み込むプログラムを更新した場合でもup
だと以前のコンテナを実行するので、更新したプログラムが取り込まれないまま実行されます。新しい状態を作り直す意味でもbuild
をすることを意識しておいて損はありません。docker-compose -d の -d って何?
-d
をつけるとバックグラウンドで動作します。逆につけない場合は実行したコンソールでコンテナが稼働するため、実行したコンソールでは他の作業ができなくなります。もし-d
をつけ忘れて停止させたいよ~ってなった場合は、Windows
の方はCtrl
+C
、Mac
の方はControl
+C
で停止させることができます。docker-compose.ymlに関する説明
注意すべきポイントを抜粋して説明します。
WordPressのポート設定
まずはポートの設定を確認します。
wordpress: ~省略~ ports: - "8000:80"右がコンテナのポートで左がホストのポートです。ホストというのは今自分が操作しているでありコンテナを動かしている端末です。この設定では
WordPress
のコンテナのポート80を、ホストのポート8000に転送しています。これはWordPress
自体がデフォルトの設定ではポート80に転送されており、それをホストのポート8000に転送しています。
この設定により自分の端末(ホスト)のブラウザから http://localhost:8000 でアクセスすることができます。最初の頃は何がどうポート転送されているか把握しづらいのが正直なところです。このシンプルな構成でも
WordPress
のデフォルトのポートが80であることを知らなければ、なぜ8000:80
になっているかわからないまま進むことになるので、1つずつ説明しながら理解を深めてもらいました。環境変数を確認する
環境変数を確認します。
db: ~省略~ environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: ~省略~ environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_PASSWORD: wordpress元のコンテナイメージですでに使用されている環境変数を上書きすることができます。
今回は
MySQL
というデータベースを使用しており、データベースのパスワードの場合はMYSQL_PASSWORD
という環境変数を設定することでパスワードの内容を上書き・変更することができます。使うコンテナのイメージごとに設定されいている環境変数は異なりますので調べる必要はあります。環境変数の調べ方ですがサンプルなどで見つかったりするのと、ちゃんと調べる場合にはコンテナイメージのリポジトリなどを確認するとよいと思います。今回使う
MySQL
のコンテナイメージのリポジトリを調べてみるとdocker-entrypoint.sh
でMYSQL_PASSWORD
を使っていることが確認できました。
MySQL
の場合はMYSQL_ROOT_PASSWORD
などの環境変数を設定することで、データベース・ユーザーの作成などを自動的に行ってくれるようです。これらの設定はdocker
のコンテナの中に入ったときに改めて確認します。コンテナの中に入ってみる
コンテナの中に入る
コンテナの中に入ってみます。今回はデータベースのコンテナに入ります。
docker-compose exec db bashもし
Windows
の方で以下のようなメッセージが表示された場合は、winpty
を頭につければコンテナに入ることができます。the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty' winpty docker-compose exec db bashコンテナ内のデータベース(mysql)に接続する
コンテナの中に入った後は以下のコマンドを実行します。
(root@eb769a915d4d:/# は入力しないでください)root@eb769a915d4d:/# mysql -U wordpress -D wordpress -pこれは
MySQL
のデータベースに接続しようとしています。-U
はユーザー名、-D
はデータベース名を示し、-p
でパスワードを使用します。ここの設定はdocker-compose.yml
の環境変数で設定したモノになり、ユーザー名などを忘れてしまった場合にはdocker-compose.yml
を確認するとよいと思います。
この実行後パスワードを入力するよう求められるのでwordpress
と入力します。Enter password:パスワードは入力中の内容が他の人から見られないよう入力したい内容が表示されません。間違ってしまった場合(間違ったような気がした場合)は
backspace
で消しきるか、Ctrl
+C
などで抜けてもう一度MySQL
の接続からやり直してみてください。パスワードの入力が正しくできていればデータベースに接続できているはずです。データベースのテーブルを確認する
テーブルの確認をしてみます。
(mysql> は入力しないでください)mysql> show tables;まだ
WordPress
の設定されていないのでテーブルは何も作成されていない状態です。Empty set (0.00 sec)データベースから抜ける & コンテナから抜ける
以下のコマンドでデータベースから抜けます。
(mysql> は入力しないでください)mysql> \qデータベースから抜けるとコンテナの中に入っている状態になりますので以下のコマンドでコンテナから抜けます。
(root@eb769a915d4d:/# は入力しないでください)root@eb769a915d4d:/# exitWordPressを設定する
自分のパソコンのブラウザを開いて http://localhost:8000/ に接続します。
接続したら日本語を選択して画面を参考にしながら設定しましょう。
今回はWordPress
で何かサイトを作るわけではないので適当に設定します。無事に
WordPress
のインストールが完了できたら、改めてデータベースに接続してみます。WordPressインストール後にデータベースに接続する
いちいちコンテナの中に入ってからデータベースに接続するのは面倒だったりします。以下のコマンドで直接データベースに接続することも可能です。
(the input device is not a TTY. のメッセージが表示されたら頭にwinpty
をつけてください)docker-compose exec db mysql -U wordpress -D wordpress -p実行できた場合はパスワードを求められると思いますので
wordpress
と入力します。
データベースに接続できたらテーブルを取得してみましょう。mysql> show tables; +-----------------------+ | Tables_in_wordpress | +-----------------------+ | wp_commentmeta | | wp_comments | | wp_links | | wp_options | | wp_postmeta | | wp_posts | | wp_term_relationships | | wp_term_taxonomy | | wp_termmeta | | wp_terms | | wp_usermeta | | wp_users | +-----------------------+ 12 rows in set (0.00 sec)
WordPress
のインストールによって必要なテーブルが作成されていることが確認できます。更にユーザーのテーブルを確認してみましょう。mysql> select * from wp_users \G ; *************************** 1. row *************************** ID: 1 user_login: test user_pass: $P$BTqvOi17OHGROkW0ukBzJk0W356aVu0 user_nicename: test user_email: test@test.com user_url: http://localhost:8000 user_registered: 2020-06-23 07:25:13 user_activation_key: user_status: 0 display_name: test 1 row in set (0.00 sec)インストール時に設定したユーザー情報があることが確認できました。
確認できたら\q
でデータベースから抜けてください。コンテナを停止させる
以下のコマンドでコンテナを停止させます。
docker-compose downこれでコンテナを停止させることができました。ただし停止するとデータベースの状態が初期化され
WordPress
の設定などはなくなります。コンテナのデータの永続性については注意する必要があります。永続化させたい場合はdocker-compose.yml
でvolumes
の設定を行うなど少し工夫が必要になります。今回は学習内容が多くなってしまうので割愛させていただきます。学習内容をまとめてみた結果
内容自体は既存の
WordPress
というサービスを使ってみるだけのカンタンなモノですがdocker-compose
を理解しながらとなると学習量は多いと感じました。今回の勉強会ではかなりボリュームがあるとの感想をいただいたので、少し様子を見ながら勉強会の内容を分けていくことも検討しようかなと思います。
といいながらも何か理解しながら作り出すとドンドン進みたく性分なので、そこらへんを上手く付き合いながら取り組んでいきます。
- 投稿日:2020-06-23T16:45:40+09:00
AWSのEC2内でDockerコマンドを使えないときの対処法【目的:load遂行】
はじめに
ローカルにあるファイルをEC2へ送りたかったのですが、dockerコマンドが使えませんでした。
[ec2-user@ip-xxx-xx-xx-xx ~]$ docker load < dockerfiles.tar -bash: docker: command not found色々試行錯誤しながら、EC2環境にdockerをインストールすることで解決できたので共有したいと思います。
手順
[ec2-user@ip-xxx-xx-xx-xx ~]$ sudo yum install -y dockerEC2環境にDockerをインストール。EC2環境で上記コマンドを叩きます。「完了しました!」が最後に表示されたら成功。
[ec2-user@ip-xxx-xx-xx-xx ~]$ sudo service docker startdockerを起動させます(EC2インスタンスを再起動させたときはDockerが停止してしまうので、インスタンスを再起動したときは毎回このコマンドを使います)。
さあ、もう使えるだろうと思い、手始めにdockerイメージの一覧でも見るかとコマンドを叩くと
[ec2-user@ip-xxx-xx-xx-xx ~]$ docker imagesGot permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%43j432jd34fFdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission deniedエラーが発生。
dockerグループにec2-userを追加してなかったんですね。では追加します。
[ec2-user@ip-xxx-xx-xx-xx ~]$ sudo usermod -a -G docker ec2-userそして一度EC2から抜けます。
[ec2-user@ip-xxx-xx-xx-xx ~]$ exitまたEC2内に入ります。
nakajimakoutanoMacBook-ea:Desktop nakajimakouta$ ssh -i xxxxxxx.pem ec2-user@ホスト名そしてdocker imagesコマンドを叩くと無事に動きました。
[ec2-user@ip-xxx-xx-xx-xx ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE本来の目的であった「ローカルにあるファイルをEC2へ送りたい」をできるかどうか試すと
[ec2-user@ip-xxx-xx-xx-xx ~]$ docker load < Dockerfile.tar Loaded image ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[ec2-user@ip-xxx-xx-xx-xx ~]$ docker run -it xxxxxxxxxxxxx sh/ # $ ls bin dev etc home lib media mnt opt proc root run sbin srv sys Dockerfile←これ tmp usr var成功です。無事にDockerfileをEC2内へ送ることができました。
参考記事
- 投稿日:2020-06-23T16:37:42+09:00
Docker-compose ~volumeの罠~
はじめに
初投稿です。白菜と申します。プログラミングが趣味のしがない大学生です。先日コードを書いている最中に深めなツボにハマり、色々調べても関連する情報が出てこなかったので投稿させていただきます。
何が起こったのか
windowsを使っておりまして、wsl2が正式に導入されたと聞き、wsl2上でDocker-desktopを動かしてみようと思い立ちました。環境を整えてかれこれ一か月ほど遊んでいて、己のPCの環境を汚さずに様々な言語に触れられて、激アツやんと思っておりました。dockerで立ち上げたコンテナにvscodeのRemote Developmentを利用して接続し、コンテナ内でコードの編集・デバッグを行っていました。
しかし、問題発生
それはある日の暮れ、羅生門の下で雨やみを待ちながらコードを書いていた時のことでございます。springbootとかいう何某かがなんかとてもすごいつよいと聞いたので、試しておりました。日本語の公式チュートリアルのいくつかを軽く実装し、springMVCの基礎くらいはカンニングせずに書けるようになりました。調子に乗ってきたので、MySQLと連携させてデータベース処理やってみようと思い、dockerで環境を作りました。具体的には、
- javaコンテナ
- MySQLコンテナ
- phpmyadminコンテナ(データベース管理で楽するため)
の三つをdocker-composeで一つのネットワークとして作りました。ついでに書いたコード保存しときたかったので、volumeでテキトーなディレクトリをjavaコンテナ上にマウントしました。
しかしいざコードを書いてみると、データベースとの連携がうまくいきません。デバッグの度にデータベース接続エラーを吐き出します。コード自体はチュートリアルのほぼコピペなので、動かないはずがないのです・・・。これはコードじゃなくてdockerに原因があるんじゃないか?症状
上記以外にも、他のコンテナでも似たような症状が発生しました。以下はその一覧です。
- MySQLとの連携がうまくいかない
- というかおそらく連携用の設定ファイルの編集が反映されていない
- 手動で反映させたら上手くいった
- htmlを作成してコントローラと紐づけたのに、Not Foundと言われる
- React環境を作ったが、yarn startに一分以上かかる
- yarn start後、ファイルを編集してもブラウザに反映されない
共通しているのはファイルの編集・作成が反映されないということでした。
解決
色々実験してみたところ、dockerのvloumeに問題があるという結論に達しました。windows上のファイルをvolumeに指定した時に、volume内のファイルの変更がリアルタイムで反映されなくなるようです。なのでvolume指定しなけりゃいいというのも一つの解決ではあるのですが、コードを永続的に保存しておきたい場合、いちいちwindows上にコピーして持ってくるのは手間です。
volumeを使いつつ解決する方法があります。そもそもdocker for windows公式には以下のような記述があります。Store source code and other data that is bind-mounted into Linux containers (i.e., with docker run -v :) in the Linux filesystem, rather than the Windows filesystem.
「volumeマウントするファイルは、Windows上じゃなくてLinux上に置いといた方がいいよ!」
・・・・・・すみませんでした。
ちらっと見たことはあったんですけど、マウント自体はちゃんと機能してたし、別にWindows上でもよくね?と思っていたんです。まさかこんな変な不具合が出るとは思ってもいなかったんです。というわけで、wsl2のLinux上に作ったディレクトリをマウントしてReact環境を作り直したら解決しました。yarn startが20秒になったし、コードを変更したら逐一反映されるようになりました。Reactおもしれえ。
終わりに
結論、volumeでマウントするディレクトリはLinux上に作っておいた方がいいと思います。開発してる人たちが言ってるんだから多分間違いないです。我流でオラオラしようとしていた私が悪かったです。すみませんでした・・・。
公式ドキュメントはしっかり読まなきゃダメてことですね。
- 投稿日:2020-06-23T16:06:30+09:00
Docker+Rails+Vueの環境を迷わず作成するステップ
最近勉強したDockerを使って、railsとVueの環境構築をしてみました。
いろいろ検索してやってみたものの、多くのエラーと向き合う日々を迎えることに...(それでもだいぶ理解は深まった?)この記事では
- とにかく開発環境だけ欲しい
- 自分の忘備録
を主な対象として、最速でDokcer+Rails+Vueの環境を作成するステップをご紹介します?!
(多分エラーは出ないはず。。。)STEP1. 4つのファイルを作成しよう
まずは作業するフォルダ(ディレクトリ)に
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
の4つのファイルを作成します。内容はそれぞれ以下のようにします!
DockerfileFROM ruby:2.5.3 RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && apt-get update && \ apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update -qq && apt-get install -y build-essential libpq-dev 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 curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get install -y nodejs npm && npm install n -g && n 10.17.0 RUN yarn add node-sass RUN mkdir /app WORKDIR /app COPY Gemfile /app/Gemfile COPY Gemfile.lock /app/Gemfile.lock RUN bundle install COPY . /appdocker-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:Gemfilesource 'https://rubygems.org' gem 'rails', '5.2.3'作業しているディレクトリで
touch Gemfile.lock
を実行すると、からのGemfile.lockが作成されます。?バージョンやdbのパスワードなどはよしなにご変更ください〜。
STEP2. rails newをする
今回はdockerコンテナ上でrailsアプリを作成するので、コマンドラインにそのまま
rails new
を打つのは正しくありません。
(僕のPCはローカルにrailsを入れていないため、rails new
を打っても「そのコマンド知りませんけど?」って怒られます。)dockerコンテナ上でコマンドを実行したい場合は
docker-compose run
コマンドをつかえばOKです?。下記コマンドを実行します。
docker-compose run web rails new . --force --database=mysql --webpack=vue --skip-coffee
このコマンドにより、
- dbはMySQLを明示的に指名
- Vueを後入れしなくて済む(後入れでエラーが結構出た記憶)
- coffee使わないので、coffee関連のファイルを作成しない
という付加価値をつけた状態で、rails new しています。
?あと2ステップ!
STEP3. database.ymlを作成する
STEP2の読み込みが完了したら、config/database.ymlが作成されているはず。
このファイル内にある「default」の内容を少し書き換えます。config/databese.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password ←docker-compose.ymlで指定したdbのパスワード host: db ←docker-compose.ymlのservicesで指定したdbの名前STEP4. docker-compose up --build
ここまでできたら、
docker-compose up --build
を実行します!少し時間がかかりますが、読み込みが終わったあとにローカルホストにアクセスしてみると、「Yay! You’re on Rails!」の画面が表示されましたか?
もしそうなら成功です!だがしかしBut。。。?
僕の場合は、「ERROR -- : Unknown database 'app_development' (ActiveRecord::NoDatabaseError)」が表示されました。僕と同じという方は、
docker-compose exec web rails db:create
をしてあげればOK!
docker-compose down
をした後に、再度
docker-compose up --build
をすれば立ち上がるはずだぞ!お疲れ様でした?最後に
コロナ禍でWebエンジニア転職を頑張っていますが、railsポートフォリオだけだとお祈りしかされません。
AWSの冗長構成でインフラ構築しててもお祈りです。そこでRails+VueのRESTfulAPIを使ったアプリ(いわゆるSPA)を追加で作ったところ最終面接までは行けるようになりましたが、それでもやっぱり大変です。
もしWebエンジニア転職が大変だぁという方が読んでくれていたら、これだけは言いたいです。
諦めずに頑張ろうね!!!!以上、お粗末様でした。
- 投稿日:2020-06-23T15:51:06+09:00
"docker push"で"denied: requested access to the resource is denied"のエラーに遭遇したら
ググると、下記のサイトがヒットしますが…
- https://stackoverflow.com/questions/41984399/denied-requested-access-to-the-resource-is-denied-docker
- https://forums.docker.com/t/docker-push-error-requested-access-to-the-resource-is-denied/64468
いずれにも「
docker login
したらpushできる」と書いていますが、これで解決できない人が続出していて、いずれのスレッドにも終わりが見えない状況です。この問題の解決方法ですが、push先のディレクトリ・プロジェクトのpush権限を自分が持っていないことが考えられます。
私の場合は、adminからpush権限を付与してもらうことで、このエラーを解決できました。
- 投稿日:2020-06-23T14:35:27+09:00
rJavaをR3.6環境のLinuxにインストールする。
rJavaをR3.6環境のlinux にインストールする
というか、そういうDockerImageを作るDockerfileを書く必要があったが、
結構エラーがでて詰まった。
ネットを探してもドンピシャがなかなか出てこなかったで、メモ。#rJavaインストールのための準備 RUN apt-get update && apt-get install -y openjdk-8-jdk RUN R CMD javareconf # install packages(DB接続用追加) RUN R -e "install.packages(c(\ 'rJava' \ ), repos='https://cloud.r-project.org/')"
- 投稿日:2020-06-23T12:03:14+09:00
CUDA on WSL導入時,Docker Desktop for Windowsとケンカしてしまった件
CUDA on WSLの公開と,前回紹介したNeural Source Filterの実装がLinux環境でしか動作しないことを受けて,本格的に環境構築を行うことにした.ところが,
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"process_linux.go:385: running prestart hook 1 caused \\\"error running hook: exit status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig.real --device=all --compute --utility --require=cuda>=9.0 --pid=8276 /var/lib/docker/overlay2/b956d7f169cca157457e107ee8c99a050c33199ded8f4fa4d68e3ace612c6d0c/merged]\\\\nnvidia-container-cli: initialization error: driver error: failed to process request\\\\n\\\"\"": unknown.と言った感じでWSL側からGPUの認識ができず苦労した.なので,その解決法をメモしておく.
CUDA on WSLとは
Windows Subsystem for Linux(WSL)でCUDAを利用したPGU計算ができる仕組み.今まではWSL上にCUDAをインストールして行っていたそうだが,CUDA on WSLを使えばWindows側にGPUドライバーをインストールすればOK.Gigazineの記事がわかりやすかったので詳しく知りたい方はこちらを参照
環境構築
はじめに
もしCUDA on WSLの導入のみを考えている方は,必ず公式の手順のみに従って欲しい.以下に記すのは,導入につまずいた状況の整理であるため,上記のエラーが発生している人は,以下を見て同じような構築を行ってないかチェックして欲しい.
WSL上にAnaconda導入
まず,WSL上でPythonを動かせるようにして,ついでにPyCharmから実行したいなと思いそちらの構築から開始した.以下が参考にしたサイトである.
- WSL + Ubuntu + Anaconda + VScodeでPythonの環境構築
- SSHを使用してWSLベースのリモートインタープリターを作成する
- pycharmとwsl(Windows Subsystem for Linux)の連携方法
また,WSLのUbuntuにはgcc等がインストールされていないため,そちらのインストールも行った.
Docker Desktopの導入
あと,CUDA on WSLでDockerが必要というのを見たことと,Windows10 homeでも利用可能になったので嬉しくなり,Docker Desktop for Windowsをインストール.これが元凶
CUDA on WSLの導入
CUDA on WSL構築にあたって参考にしたサイト
解決方法
公式で,WSL上のUbuntuにdockerをインストールする項目がある.
$ curl https://get.docker.com | sh
このUbuntu上のDockerと,Docker Desktop for Windowsが別に動作していることに気づき,もしかすると2つのDockerが競合しているのでは?と考えた,そこで,Docker Desktop for Windowsが自動的に起動しないように設定,念の為NVIDIA Container Toolkitのアンインストールを行ってから再起動をして,再びDocumentation通りにインストール,CUDAサンプルの実行を行うと
Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance. -fullscreen (run n-body simulation in fullscreen mode) -fp64 (use double precision floating point values for simulation) -hostmem (stores simulation data in host memory) -benchmark (run benchmark to measure performance) -numbodies=<N> (number of bodies (>= 1) to run in simulation) -device=<d> (where d=0,1,2.... for the CUDA device to use) -numdevices=<i> (where i=(number of CUDA devices > 0) to use for simulation) compare (compares simulation results running once on the default GPU and once on the CPU) -cpu (run n-body simulation on the CPU) -tipsy=<file.bin> (load a tipsy model file for simulation) NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled. > Windowed mode > Simulation data stored in video memory > Single precision floating point simulation > 1 Devices used for simulation MapSMtoCores for SM 7.5 is undefined. Default to use 64 Cores/SM GPU Device 0: "GeForce RTX 2080 Ti" with compute capability 7.5 Compute 7.5 CUDA device: [GeForce RTX 2080 Ti] 69632 bodies, total time for 10 iterations: 119.463 ms = 405.868 billion interactions per second = 8117.351 single-precision GFLOP/s at 20 flops per interaction動いた!!!
そういえば,待ってました CUDA on WSL2にもこの時、
WSL DETECTED: We recommend using Docker Desktop for Windows.
なんて言われますが、無視。
って書かれてたのを考えると,Docker Desktop for Windowsが動いてるとエラー吐くのは当然だなと納得した.
ちなみに
試しに,CUDAサンプル実行後に,Docker Desktop for Windowsを起動して同じサンプルを実行するとエラーが出る.また,Docker Desktopを終了してもエラーが出てしまい,Windowsを再起動しないとサンプルが動かせなくなった.なので,CUDA on WSLを使用する方は,Docker Desktopのアンインストールをしてしまっても良いのかもしれない(保証はしない)
Pytorchで計算をした感想
そもそもPytorchがCUDA11に非対応なのだが,面白そうなので動かしてみたところ,GPUでの計算は可能だった.しかし,どこが原因か不明であるが,1iterの計算がけっこう重く実用的ではない.試しにWindows環境で同じプログラムを実行したところCUDA10.1のときと同じ速度で計算が行えるため,Python環境で直接実行するにはまだまだ改善の余地があるのでは,と思った.そもそもDockerの仕組みすら曖昧なペーペーであり,自分の知識不足である可能性が高いので,もっと勉強したい所存.
まとめ
- まだWSLの構築もしていない人は,CUDA on WSLのDocumentation通りに環境構築すべし
- Docker Desktop for Windowsをインストールしている場合は,自動的に起動しないよう設定またはアンインストール
- 投稿日:2020-06-23T11:31:50+09:00
Docker内のJooby(Kotlin × Gradle)をホットリロードさせながらIntelliJでRemoteDebugする
1-やること
タイトルの通り、DockerやIntellijの実行構成を含んだ全部入りリポジトリはこちら
Githubリポジトリ2-完璧でないところ
・後述のjoobyRunを行った後、RemoteDebugを走らせないとホットリロードが動きません。
→裏でport5005に対する接続待ちが起きてる??・ブレークポイントで止まっている間はホットリロードが効きませんでした。
3-ポイント
・Docker内のJDKとIntelliJのJDKは合わせよう!
→この記事ではamazoncorretto:11でそろえてます。・docker-compose.yml: environmentに環境変数GRADLE_OPTSを指定
docker-compose.ymlversion: '3' services: app: shm_size: 4096m build: "./build/app" ports: - '8015:8080' - '5005:5005' volumes: - "./app:/app" environment: TZ: 'Asia/Tokyo' GRADLE_OPTS: '-Dorg.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005' working_dir: /app cap_add: - SYS_ADMIN security_opt: - seccomp:unconfined tty: true・IntelliJにdocker-compose用の実行構成を作成
・RemoteDebug用の実行構成を作成
Command line arguments for remote JVMの内容が先述の「GRADLE_OPTS」とイコールになるはず
・docker-composeの起動構成を実行→コンテナ内部でjoobyRun実行
コマンド実行 ./gradlew joobyRun・RemoteDebugの起動構成を実行→適当に置いたブレークポイントを通るパスにアクセス
以下にアクセス http://localhost:8015/ソース修正するとホットリロードが行われる
※ブレークポイントで処理停止させている場合は勿論効かないです。(重要なので二度目)
4-おわり
・dockerでローカルを汚さないかつ、IntelliJの強力なアシスト+joobyRunでのホットリロード+RemoteDebug
LL言語並みに高速でリコンパイルされるわけでないですが、これで開発がとても楽になります。・後述のjoobyRunを行った後、RemoteDebugを走らせないとホットリロードが動きません。
→裏でport5005に対する接続待ちが起きてる??回避策としてはRemoteDebugが不要な時はdocker-compose.ymlのGRADLE_OPTSをコメントアウトすれば良いです。
- 投稿日:2020-06-23T11:11:17+09:00
Docker初心者に立ちはだかるエラー
下記サイトからDockerを学んでいるときに出会ったエラー
https://tech-lab.sios.jp/archives/19191Dockerイメージを作ろうと
docker buildをした際に起こりました。
Sending build context to Docker daemon
がひたすら続くというエラー。。
下のようなエラーも出たりで、、ERRO[0529] Can't add file /Users/shingo/Library/Application Support/Code/1.45.1-main.sock to tar: archive/tar: sockets not supported ERRO[0529] Can't add file /Users/shingo/Library/Application Support/Code/1.45.1-shared.sock to tar: archive/tar: sockets not supported一向にイメージを作れる気配もなく、中断しました。
色々と調べた結果
https://ytooyama.hatenadiary.jp/entry/2018/04/06/003019
この記事を発見!Dockerファイルをホームディレクトリに作成し、docker buildを実行していたので
DockerクライアントからDocker daemonに対して、ホームディレクトリ配下のファイルを全て転送していたようです。
~/working/dockerディレクトリを作成し、そこにDockerfile「だけ」を作成しました。
その後
buildが成功しました。なんとも簡単な、、
PC
余計な仕事させてごめんよ!!
- 投稿日:2020-06-23T02:03:51+09:00
リモートデバッグ可能なNginx, Spring Boot, MySQLの開発環境をDockerで作った
前置き
最近、WebサイトをSpring Bootで開発しています。以前に投稿した記事のような開発環境が欲しくなってきましたので調査しました。前回とほぼ同じ形式で執筆します。
動作環境
OS macOS Catalina 10.15.5 Docker docker desktop community 2.3.0.3 (45519) Spring Tool Suite Version: 4.5.1.RELEASE Spring Bootプロジェクト
InteliJ + Kotlin + gradleとしたいところですが、現在携わっている環境に近い構成でやっていこうと思います。
モダンJavaだとこの組み合わせ減ってると思います
- Spring Boot 2.2
- Java OpenJDK 11
- STS 4
- Maven 3.6.3
構築イメージ
以下のコンテナを作成します。
- MySQL
- ホストOSのMySQL Workbenchでアクセスできる(localhost:3306)
- Spring Boot
- ホストOSのブラウザでアクセスできる(localhost:8080)
- STS(Eclipse)からリモートデバッグできる(localhost:5005)
- Nginx
- HTTPSでアクセスできる(https://devnokiyo.example.com)
- ただし、GitHubにソースコードを公開する関係で自己署名SSL証明書)
もちろん、コンテナ間も通信を行います。
構成
GitHubに公開しています。併せてご覧ください。
前述の記事同様にDocker周りだけを管理したいディレクトリと永続化だけを管理したいディレクトリに分けました。
以降、粛々とファイルとその説明が続きます。「とにかくGitHubのコードを動かしたい」方はこちらまで飛んでください$ tree ├── README.md ├── docker # DockerやDocker Compose │ ├── containers # 各コンテナ(イメージ) │ │ ├── mysql # MySQL 5.7 │ │ │ ├── Dockerfile # MySQL 5.7のDockerファイル │ │ │ ├── initialize_data.sql # 初期セットアップでユーザとサンプルデータを作成するスプリプト │ │ │ └── my.cnf # 初期セットアップで反映するmy.cnf │ │ ├── nginx # Nginx 1.19.0 │ │ │ ├── Dockerfile # NginxのDockerファイル │ │ │ └── nginx.conf # 初期セットアップで反映するnginx.conf │ │ └── spring # OpenJDK 11 (Spring Boot構築用) │ │ └── Dockerfile # Spring Boot構築用のDockerファイル │ ├── docker-compose.yml # Docker Composeファイル │ └── environments # 環境変数定義 │ ├── common.env # 各コンテナ共通 │ └── db.env # DB接続用MySQL関連 └── volumes # 永続化するリソース ├── app # Spring Bootのプロジェクト (以下、特筆点するディレクトリ/ファイルのみコメント) │ ├── .m2 # Mavenのローカルリポジトリ │ ├── mvnw # Maven Wrapper 今回はこれを使ってSpring Bootを起動する │ └── src # ソースコード │ └── main │ └── resources # この配下にstaticディレクトリを作成しない (静的ファイルはNginxで返す) ├── db # MySQLのデータ このディレクトリは最初は無し └── web # Nginxのファイル ├── ssl # SSL証明書 │ ├── privkey.pem # 秘密鍵 │ └── server.crt # サーバー証明証 └── static # 静的ファイル置き場Composeファイル
docker/docker-compose.ymlversion: '3' services: # 各コンテナ(サービス) db: # MySQLのコンテナ 「db」と命名 build: containers/mysql # Dockerファイルのパス env_file: # 環境変数 - ./environments/common.env # 各コンテナ共通 - ./environments/db.env # DB接続用MySQL関連 volumes: # 永続化 - ../volumes/db/data:/var/lib/mysql # MySQLのデータ ports: # 開放ポート - 3306:3306 # ホストOSのWorkBenchでDBを参照する目的 app: # Spring Bootのコンテナ 「app」と命名 build: containers/spring # Dockerファイルのパス env_file: # 環境変数 - ./environments/common.env # 各コンテナ共通 - ./environments/db.env # DB接続用MySQL関連 # 実行するコマンド(後述) command: ./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005" volumes: # 永続化 - ../volumes/app:/app # Spring Bootのプロジェクト - ../volumes/app/.m2:/root/.m2 # Mavenのローカルリポジトリ ports: # 開放ポート - 8080:8080 # ホストOSからNginxを通さずTomcatを直接参照する目的 - 5005:5005 # IDEでリモートデバッグする目的 depends_on: # 起動する順番 - db # 「db」の後で起動 web: # Nginxのコンテナ 「web」と命名 build: containers/nginx # Dockerファイルのパス env_file: # 環境変数 - ./environments/common.env # 各コンテナ共通 volumes: # 永続化 - ../volumes/web/static:/usr/share/nginx/www/ # 静的ファイル (Spring Bootプロジェクトのresouce/staticには配置しない) - ../volumes/web/ssl:/etc/nginx/cert/ # SSL証明書 - ../volumes/web/log:/var/log/nginx/ # Nginxのログ ports: # 開放ポート - 443:443 # HTTPS この開発環境はHTTPSのみ想定 depends_on: # 起動する順番 - app # 「app」の後で起動db(MySQL)コンテナ
Dockerファイル
docker/containers/mysql/Dockerfile# MySQL 5.7 FROM mysql:5.7 # 初期セットアップで利用するmy.cnfをイメージへコピー # アーカイブを展開する必要などが無ければADDで無くてCOPYで良い。 COPY my.cnf /etc/mysql/conf.d # 初期セットアップで実行したいスクリプトをイメージへコピー COPY initialize_data.sql /docker-entrypoint-initdb.dコピーするファイルの概要
ホスト イメージ 概要 docker/containers/mysql/my.cnf /etc/mysql/conf.d/ 文字コード docker/containers/mysql/initialize_data.sql /docker-entrypoint-initdb.d/ Spring Bootアプリ向けDBアカウント/サンプルデータ Docker Comopseから設定される環境変数
docker/environments/common.envTZ=Asia/Tokyodocker/environments/db.envMYSQL_ROOT_PASSWORD=root MYSQL_USER=spring MYSQL_PASSWORD=springDocker Comopseから設定される永続化
ホスト コンテナ 概要 volumes/db/data /var/lib/mysql MySQLのデータ app(Spring Boot)コンテナ
Dockerファイル
docker/containers/spring/DockerfileFROM openjdk:11 # 永続化でマウントされるパスをワーキングディレクトリに指定 WORKDIR /appDocker Comopseから設定される環境変数
docker/environments/common.envTZ=Asia/Tokyodocker/environments/db.envMYSQL_ROOT_PASSWORD=root MYSQL_USER=spring MYSQL_PASSWORD=springDocker Comopseから設定される永続化
ホスト コンテナ 概要 volumes/app/ /app Spring Bootのプロジェクト
GitHubに公開しているものは予めサンプルアプリが入っています)volumes/app/.m2 /root/.m2 Mavenのローカルリポジトリ
./mvnw cleanを実行するとプラグイン/ライブラリなどを毎回ダウンロードしてしまうことを防ぎます。Docker Comopseのcommand
こちらのコマンドについて少し補足します。
./mvnw clean spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005"
コマンド 概要 ./mvnw Java -jar
による起動は開発中のコードが更新されたときの自動リロードが無効になってしまうので、Mavenで起動することにしました。Maven WrapperがあればMavenをインストールする必要がないので、mvnw
を採用しました。address=*:5005 JDWPのポートを指定しますが、 ホストOSからコンテナへアクセスするには *:5005
とする必要があります。ポート番号しか書いていないネット情報が多いのでご注意くださいweb(Nginx)コンテナ
Dockerファイル
docker/containers/nginx/DockerfileFROM nginx:1.19.0 # 初期セットアップで反映するファイルをコピー COPY nginx.conf /etc/nginx/conf.d/app.conf CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.confコピーするファイルの概要
ホスト イメージ 概要 docker/containers/nginx/nginx.conf /etc/nginx/conf.d/app.conf 後述 WEBサーバーの設定
トリッキーな設定は無いと思いますが簡単に補足します。
GitHubに公開しているものはSSL証明書については「*.example.com」の自己署名SSL証明書(所謂「オレオレ証明書」)を利用しています。筆者の環境ではLet's EncryptのSSL証明書を利用しています。docker/containers/nginx/nginx.confserver { listen 443 ssl; server_name devnokiyo.example.com; ssl_certificate /etc/nginx/cert/server.crt; ssl_certificate_key /etc/nginx/cert/privkey.pem; ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; root /app/public; try_files $uri /; client_max_body_size 10m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-CSRF-Token $http_x_csrf_token; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://app:8080; } # Spring Bootの静的ファイルはNginxで返す。 location ~* .*\.(jpg|gif|png|css|js|ico|svg) { root /usr/share/nginx/www; access_log off; } }Docker Comopseから設定される環境変数
docker/environments/common.envTZ=Asia/TokyoDocker Comopseから設定される永続化
ホスト コンテナ 概要 volumes/web/static/ /usr/share/nginx/www/ 静的ファイル volumes/web/ssl/ /etc/nginx/cert/ SSL証明書 volumes/web/log/ /var/log/nginx/ ログ 実行してみましょう!
Docker Composeで起動
だいぶ簡単でしたが各ファイルの説明が終わりましたので実行して確認します。
- GitHubから一式ダウンロードします。
dockerディレクトリへ移動します。
$ cd dockerビルドします。(初回なので起動でも構いません)
$ docker-compose build --no-cache Building db Step 1/3 : FROM mysql:5.7 ---> 9cfcce23593a Step 2/3 : COPY my.cnf /etc/mysql/conf.d ---> 4af29808e20c : : Successfully built b074e2d8831d Successfully tagged docker_web:latest起動します。
$ docker-compose up Creating network "docker_default" with the default driver Creating docker_db_1 ... done Creating docker_app_1 ... done Creating docker_web_1 ... done Attaching to docker_db_1, docker_app_1, docker_web_1 db_1 | 2020-06-22 23:04:49+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started. : : db_1 | Version: '5.7.30' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) : : app_1 | [INFO] Scanning for projects... app_1 | Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.2.8.RELEASE/spring-boot-starter-parent-2.2.8.RELEASE.pom app_1 | Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-dependencies/2.2.8.RELEASE/spring-boot-dependencies-2.2.8.RELEASE.pom : : app_1 | [INFO] Attaching agents: [] app_1 | Listening for transport dt_socket at address: 5005 app_1 | app_1 | . ____ _ __ _ _ app_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ app_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) ) app_1 | ' |____| .__|_| |_|_| |_\__, | / / / / app_1 | =========|_|==============|___/=/_/_/_/ app_1 | :: Spring Boot :: (v2.2.8.RELEASE) app_1 | app_1 | 2020-06-22 23:07:31.526 INFO 74 --- [ restartedMain] com.example.demo.DemoApplication : Starting DemoApplication on e5dd9a4954d8 with PID 74 (/app/target/classes started by root in /app) : : app_1 | 2020-06-22 23:07:37.683 INFO 74 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' app_1 | 2020-06-22 23:07:37.686 INFO 74 --- [ restartedMain] com.example.demo.DemoApplication : Started DemoApplication in 6.781 seconds (JVM running for 8.41)ブラウザからアクセス
hostsファイルにdevnokiyo.example.comをループバックIPで設定して
https://devnokiyo.example.com
にアクセスします。不正な証明書ということでエラーが出ると思いますが便宜上例外を許可してください。以下はChromeの例ですが表示自体はされています。
Nginxを経由でWebサイトにアクセスできています
なお、ポポデザイン様のテンプレートを利用させて頂きました。感謝申し上げます。前述のとおり筆者専用環境ではLet's EncryptのSSL証明書を利用しています。ご参考までに正常な証明書扱いの画像も載せておきます。独自ドメインを所有しておりhoge.devnokiyo.comで取得した例になります。
Tomcatへアクセス
Nginxの設定の誤りで動作不良になることもあると思いますので、Tomcatへの直接アクセスも許可しています。念のためアクセスできるか確認します。
http://localhost:8080
にアクセスします。レイアウトが崩れています
しかし、静的ファイルはNginxから返されるように設定しているので問題ありません
ホストOSからMySQLへ接続を確認
ホストOSのMySQL Workbenchから以下にアクセスします。
ホスト名 127.0.0.1 ポート 3306 ユーザー spring パスワード spring TomcatからMySQLへ接続を確認
Docker Composeで定義したコンテナ間でMySQLへ接続できるか確認します。
https://devnokiyo.example.com/form
へアクセスしてお問い合わせしてみます。
送信ボタンを押下します。
再度MySQL Workbenchでテーブルを参照するとレコードが1行増えていますね
リモートデバッグする
Spring BootをDockerでコンテナ化しましたが、ブレークポイントを利用できないと不便です。STS(Eclipse)からTomcatのコンテナをアタッチしてデバッグできるようにします。
準備
STS(Eclipse)のメニューから
Run
->Debug Configurations...
を選択します。Remote Java Applicaion
でdemo
プロジェクトをDebugします。
ブレークポイントを設定
RootControllerの29行目にブレークポイントを設定しました。
http://devnokiyo.example.com/form
へアクセスするとブレークポイントで処理が止まります。
自動リロード
ソースコードを修正したときに毎回ビルドするのは面倒なので、Spring Boot Devtoolsの自動リロードを利用します。前述のとおり
Java -jar
による起動は開発中のコードが更新されたときの自動リロードが無効になってしまいますが、Maven WrapperでSpring Bootを起動しているので自動リロードできます。ソースコード修正
以下のアクションメソッドを追加してみます。コントローラークラスのファイルを保存するとリロードされます。
RootController.java@GetMapping("/hoge") public String hoge() { return "root/index"; }自動リロード中
コンソールをみるとリロードの状況がわかります。1行目が初回起動時の日時で2行目以降が自動リロードの挙動になります。
app_1 | 2020-06-23 00:09:00.911 INFO 40 --- [ restartedMain] com.example.demo.DemoApplication : Started DemoApplication in 6.459 seconds (JVM running for 8.092) app_1 | 2020-06-23 00:21:51.379 INFO 40 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' app_1 | 2020-06-23 00:21:51.379 INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' app_1 | 2020-06-23 00:21:51.389 INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms app_1 | 2020-06-23 00:36:13.585 INFO 40 --- [ Thread-5] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' app_1 | 2020-06-23 00:36:13.588 INFO 40 --- [ Thread-5] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' app_1 | 2020-06-23 00:36:13.651 INFO 40 --- [ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... app_1 | 2020-06-23 00:36:13.755 INFO 40 --- [ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. app_1 | app_1 | . ____ _ __ _ _ app_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ app_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) ) app_1 | ' |____| .__|_| |_|_| |_\__, | / / / / app_1 | =========|_|==============|___/=/_/_/_/ app_1 | :: Spring Boot :: (v2.2.8.RELEASE) app_1 | app_1 | 2020-06-23 00:36:14.036 INFO 40 --- [ restartedMain] com.example.demo.DemoApplication : Starting DemoApplication on e5dd9a4954d8 with PID 40 (/app/target/classes started by root in /app) app_1 | 2020-06-23 00:36:14.037 INFO 40 --- [ restartedMain] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default app_1 | 2020-06-23 00:36:14.500 INFO 40 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. : : app_1 | 2020-06-23 00:36:15.884 INFO 40 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 app_1 | 2020-06-23 00:36:15.907 INFO 40 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' app_1 | 2020-06-23 00:36:15.908 INFO 40 --- [ restartedMain] com.example.demo.DemoApplication : Started DemoApplication in 1.965 seconds (JVM running for 1644.96) app_1 | 2020-06-23 00:36:15.911 INFO 40 --- [ restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged app_1 | 2020-06-23 00:36:30.177 INFO 40 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' app_1 | 2020-06-23 00:36:30.178 INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' app_1 | 2020-06-23 00:36:30.183 INFO 40 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms修正後の確認
https://devnokiyo.example.com/hoge
にアクセスしてトップページと同じページが表示されることを確認します。
終わりに
前回同様に基礎的なコマンドの説明よりは「筆者はこうやった」的なことをメインに記事を書いてみました。JVM系はRubyやGoと比較するとDocker周りの情報が少ない印象です。(点々とした情報はあるのですが、線になっている情報は少ない雰囲気です。)
ひととおりの手順を習得できたので、どのくらい開発環境として使っていけるか運用してみようと思います。