- 投稿日:2020-05-24T22:17:31+09:00
Docker Hubの使い方
環境
macOS 10.15.4
Docker 19.03.8アカウントの登録
下記のリンクからDocker Hubのアカウント登録を行います。
https://hub.docker.comDocker Hubを使う
Docker Hubにログインする
ターミナルから指定のディレクトリに移動してDocker Hubと連動させるためログインを行います。
$ docker loginするとUsenameとPasswordが求められるのでDocker Hubのアカウント登録した情報を入力します。
$ docker login Username:(アカウント名) Password:(パスワード) Login SucceededこれでDocker Hubとの連動が完了しました。
イメージIDを調べる
下記のコマンドを実行してイメージIDを調べます。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE recipegram_web latest a91018b6cf9c 7 days ago 1.3GB <none> <none> 1f63874cf252 7 days ago 1.3GB <none> <none> 38f311130abd 7 days ago 1.04GB docker_sample_web latest 604c94f14094 8 days ago 1.04GB <none> <none> a1cd1b5bdb2a 8 days ago 989MB ruby 2.5 a98425292e84 4 weeks ago 843MB postgres latest 0f10374e5170 4 weeks ago 314MB gihyodocker/echo latest 3dbbae6eb30d 2 years ago 733MB指定のイメージIDを探して下記のように記述します。
アップロードを実行する
$ docker tag a91018b6cf9c chisaki0606/recipegram:latestこの記述はわたしの場合の例ですが、
a91018b6cf9c
は指定のイメージIDになります。
そしてchisaki0606/recipegram:latest
の記述は(Docker Hubのアカウント名)/(リポジトリ名):(タグ名)
になります。最後のlatest
は指定はありませんが最新の場合にはこちらのタグ名にすることが慣例になっています。
- 投稿日:2020-05-24T21:08:39+09:00
Docker logs をgrepする
コンテナのログは、
標準エラー出力 (stderr)
に記録されます。一方、「|」で記述するパイプラインは、
標準出力(stdout)
で機能します。コンテナのログをパイプラインで受け取れるように、
標準エラー出力
を標準出力
へと出力先を2>&1
で変更します。これで、パイプ後の
grep
コマンドが動くようになります。docker logs app 2>&1 | grep "test"ちなみに、
2>&1
を省略した形として、次のように記載することもできます。docker logs app |& grep "test"
- 投稿日:2020-05-24T21:00:00+09:00
【Docker】使ってないやつらを葬り去る
内容
prune
コマンドのメモです。image
docker image prune
dangling
dangling(ダングリング;宙ぶらりんな状態)なイメージ (ブール値: true か false )
images — Docker-docs-ja 17.06.Beta ドキュメント より引用つまり、タグ付けされていないイメージをさします。
オプション
--all , -a 使っていない(containerとして起動していない)imageを全て削除 --filter filterをかけることができる (例: until=) --force , -f 確認してこなくなる container
docker container prune
network
docker network prune
volume
docker volume prune
system
docker system prune
停止中のコンテナ、ボリューム、イメージ、ネットワークを全て削除します。
参考にした記事
docker image prune | Docker Documentation
Docker一括削除コマンドまとめ - Qiita
Dockerで不要なコンテナとイメージを削除する - Qiita
- 投稿日:2020-05-24T20:37:24+09:00
Docker for Mac の Mutagen-based caching で Volume のパフォーマンスが劇的に改善した
Docker for Mac の Edge channel で、 Mutagen ベースのキャッシュが使えるようになっています。(手元のバージョンは 2.3.1.0)
従来、 EC-CUBE をはじめとする Symfony をベースとしたアプリケーションや、Composer や npm などのパッケージ管理システムのファイルをマウントすると、強烈に遅くなる問題がありました。
今回利用できるようになった Mutagen ベースのキャッシュを利用するには、
- Preferences -> Resources -> FILE SHAREING でマウントするディレクトリを指定
- キャッシュを ON にするだけ。
あとは通常通り、アプリケーション全体をボリュームにマウントして大丈夫です。
## 例 docker run --name ec-cube -p "8080:80" -v "$PWD:/var/www/html:cached" --link container_mysql:db eccube-php-apache以下、手元の環境での比較です。
約7倍にパフォーマンス向上しています。
(性能のよいディスク使っているので、体感的な差は少ないですが、古めの環境では大きく差が出ると思います)GitHub の issues にもパフォーマンス検証結果がコメントされていますので、併わせてご覧ください。
Ruby や Node.js など、 PHP 以外のアプリケーションでもパフォーマンス向上が期待できます。
Docker for Mac の遅さに手を焼いていた方はぜひお試しください!2020年5月26日追記
マウントしたファイルのパーミッションが変わってしまう問題 があります。
近いうちに改善されるかもしれませんが、 コンテナ上でchmod -R o+w <mounted volume>
するなりして凌ぎましょう...こちらのツイートも参考に
試した
— Koji Tanaka (@tenkoma) May 23, 2020
1. キャッシュ処理が終わるまでコンテナ内で使えない
2. 使わないときよりCPU消費してる気がする
3. owner/group/permissionが変わる。問題は報告されていて改善するかも? https://t.co/TGiY5wqkaU
- 投稿日:2020-05-24T20:27:13+09:00
Docker Network とは何ぞ?
ずっとDockerを使っていますが、あまりDockerNetworkを意識することが今までなく、役割とかいまいちよくわかっていないので、調査して、自分用のメモを残します。
ドキュメントはここを読みました。
Docker Networkとは
Dockerのネットワークを管理するものです。
Dockerをインストールすると、自動的に3つのネットワークを作成します。
確認するコマンドは$ docker network ls NETWORK ID NAME DRIVER 7fca4eb8c647 bridge bridge 9f904ee27bf5 none null cf03ee007fb4 host host確かに設定してあります。
bridgeネットワーク
ホスト側には、docker0 というブリッジができています。これがbridgeネットワークと繋がっています。
名前からして、ブリッジ接続でホストのネットワークと繋がっていると思われます。
確認は下記のコマンド$ ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:dc:ab:d1:d4 txqueuelen 0 (イーサネット) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0コンテナに接続するネットワークは --netのオプションで設定できます。
例えば、$ docker run -d --name container1 --net bridge busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"ような感じです。
何も指定しない場合、デフォルトのネットワーク bridgeが選択されます。デフォルトのネットワークはbridgeですが、他のものはどういうものなのか。
noneネットワーク
noneを指定するとネットワーク・インターフェースが欠如した状態でコンテナを作れます。
例えば、
$ docker run -d --name container2 --net none busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"でコンテナを作る。
確認は下記のコマンド$ docker exec container2 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters $ docker exec container2 ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)ループバックインターフェースしかないですね。
ちなみにbridgeネットワークで作った場合は、
$ docker exec container1 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 ba703c0e2904 $ docker exec container1 ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:76 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:11028 (10.7 KiB) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)eth0のネットワークインターフェースがありますね。
hostネットワーク
hostネットワークは名前の通り、ホスト側のネットワーク・スタックにコンテナを接続しており、
コンテナ内のネットワーク設定が、ホスト上と同じに見えます。$ docker run -d --name container3 --net host busybox /bin/sh -c "while true; do echo hello world; sleep 1; done" $ docker exec container3 cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 -- 127.0.2.1 -- # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters $ docker exec container3 ifconfig ※ホストでifconfigを使った時と同じ出力これは結構便利ですね。
ブリッジ・ネットワークの詳細
下記のコマンドで詳細を見ることができます。
$ docker network inspect bridge [ { "Name": "bridge", "Id": "e37815cd479e4272ea69f16c54b55fdf41ecb35151c1421a3b4bd2c16a46c34f", "Created": "2020-05-17T17:11:01.385296653+09:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "ba703c0e2904404891295f707c3b323a48ee01631e8082948038478c3fe89990": { "Name": "container1", "EndpointID": "51244eaedf829aea7887272f28bf7aeb61573b14894d304c7af215c0dbb4c13f", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]自動的にサブネットやゲートウェイが作られていて、それを見ることができます。
接続しているコンテナの情報も見れます。bridgeネットワークのコンテナにpingで接続確認をします。
$ docker exec container1 ping -w3 172.17.0.2docker exec container1 ping -w3 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.042 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.045 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.122 ms --- 172.17.0.2 ping statistics --- 4 packets transmitted, 3 packets received, 25% packet loss round-trip min/avg/max = 0.042/0.069/0.122 msコンテナ→ホストは繋がっていることがわかりますね。
カスタムネットワークを作る
下記のコマンドでユーザ独自のネットワークを作れます。
$ docker network create --driver bridge new_nw $docker network inspect new_nw [ { "Name": "new_nw", "Id": "129f288d936696f13caa17580e7c12f94d58e13d135e6eeb1662c1cdb85e0c73", "Created": "2020-05-24T18:19:00.890438557+09:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]この新規に作ったネットワークはbridgeのネットワークとは、独立しているので、
このネットワークにつなぐコンテナは、他のコンテナと独立することができます。
逆に、同じネットワークにすれば、他のコンテナと連携ができます。非常に便利ですね。オーバレイ・ネットワーク
まず、オーバーレイネットワークという用語を聞いたことなかったので、確認。
「オーバーレイネットワークとはあるネットワークの上に構築された別のネットワークのこと」ということを指す模様
インターネットVPNやP2Pネットワークもオーバーレイネットワークのようで、SDNの一方式として使われるようです。Dockerを使ったオーバーレイネットワークですが、ドキュメントを見ると、どうやら※VXLANをDockerNetworkで作れるようです。
※VXLANは私自身は情報処理試験で知識としてしかわかってなく、異なるネットワークを、仮想的に同一のネットワークとして通信ができるものくらいの理解です。
ここは他者様のサイトを参考
これにより、異なるネットワークのコンテナ同士で、通信ができるようになります。カスタム・ネットワーク・プラグイン
必要があれば、自分自身でネットワーク・ドライバ・プラグインを書けます。
書き方は、こことここ作成したネットワークを元に、派生してネットワークを作ります。
$ docker network create --driver weave mynet
参考
おうちで学べるネットワークのきほん
わかりやすいブリッジ接続
このサイトもすきDocker_VXLAN
図がわかりやすいネットワークの復習もできて、ちょっと調べて得しました。
- 投稿日:2020-05-24T18:11:04+09:00
超基礎からの 速習 Docker (3)
本稿は、Christffer Noring さん (@chris_noring) の Learn Docker, from the beginning, part III を翻訳し、分かりやすいように少しだけ追記、サンプルコードの実行上の補足等を行ったものです。シリーズ翻訳の意図については 超基礎からの 速習 Docker (1) の冒頭に掲載しています。併せてご参照くださいませ。
超基礎からの 速習 Docker シリーズ一覧
TLDR; とても長いけど、誓って、ここにあるのが最小限なんです。中盤で苦痛を伴うけど、きっと僕らは勝利する
- 超基礎からの 速習 Docker (1)
- なぜ Docker なのか、コンテナーやイメージ、Dockerfile の基本コンセプトの解説、もちろん、それらを管理するのに必要なコマンド群もカバーしています。
- 超基礎からの 速習 Docker (2)
- Volume を用いたデータの永続化や、開発環境の Volume 化を通じて、開発をより手軽なものにします。
- 超基礎からの 速習 Docker (3)
- いまここ。
- 超基礎からの 速習 Docker (4)
- Docker Compose を用いた複数サービスの管理方法を解説します(その1)
- 超基礎からの 速習 Docker (5)
- Docker Compose を用いた複数サービスの管理方法を解説します(その2)
本稿はシリーズ パート3 です。このパートでは、データベースと Docker がどのようにお互い動作するのかについて学ぶことにフォーカスします。また、コンテナ環境のデータベースと強く結びつける Link 機能のコンセプトについても解説しています。
本稿では以下のトピックをカバーしています。
- MySQL 実行に関する基本についてカバー データベース一般の基本をカバーすることは常に良いことで、本稿では、その一つとして MySQL を選択しています。
- なぜ MySQL Docker イメージを使う必要があるのか どのようにイメージからコンテナーを生成するか、動作させるために必要な環境変数についても説明します。
- MySQL コンテナーに接続する方法 Link 機能を使ったアプリケーション コンテナーから、二つのコンテナー間の基本的な Link 機能をどのように実現するか、データベースの初期設定を定義する際、どのような利点に使用できるかについてです。
- Link 機能の知識を広げる コンテナーを Link する新しい方法をカバーします。Link には 2種類の方法があります。一方の方法がよく使われ、他方は非推奨となっているため、僕らは新しい方法をカバーします。
- データベースを管理する良い方法を説明 初期構造や初期データ(シード データ)を与える方法です。
リソース
Docker を使う事、コンテナー化は、一枚岩をマイクロサービスに分解していくことです。このシリーズのいたるところで僕らは Docker やそのコマンド体系をマスターするために学ぶことになります。そうすれば、きっと君は自作のコンテナーをプロダクション環境で使いたくなるでしょう。その環境は大抵クラウド上にあります。十分な Docker 経験を積んだと思ったなら、次のリンクで Docker をクラウドでどのように活用できるか、ご確認してみると良いと思います。
- Azure 無料アカウントのサインアップ プライベート レジストリのようなクラウドのコンテナーを使うには、無料 Azure アカウントが必要でしょう。
- クラウドのコンテナー クラウドのコンテナーについて他に知っておくべきことについて網羅する概要ページです。
- 自作コンテナーをクラウドにデプロイ 今の Docker スキルをレバレッジしてクラウド上でサービスを動かすことがいかに簡単かを示すチュートリアル。
- コンテナー レジストリの作成 自作 Docker イメージを Docker Hub に入れられますが、クラウドのコンテナー レジストリも可能です。自作イメージをどこかにストアして、一瞬でレジストリから実際のサービスをできるようにすることは凄くないですか?
データベース一般、とりわけ MySQL を使うには
データベース一般について、僕らは以下のようなことをやりたくなります:
- read 僕らは様々な Query の方法でデータを読みたいと思います。
- alter/create/delete 僕らはデータを変更する必要があります。
- 構造を追加する 僕らは table や collection と言った構造を作成する方法が必要です。それにより、特定フォーマットでデータは保存されます。
- 初期データ(シード データ)の追加 シンプルなデータベースでは全く不要でかも知れませんが、複雑なシナリオの場合、table が基本データで事前入力されている必要があるかも知れません。表示状態を作るためや、既に存在するデータ、またはある状態に入るデータと言った、異なるシナリオのテストを容易にするため、開発フェーズではシード データが重要です。例えば、ショッピング カートにテストしたいアイテムが入っている状態で、会計ページをテストしたい時です。
インデックスの追加や、アクセス権の異なるユーザーの追加などなどなど、データベースで行いたいことは山ほどありますが、僕らが Docker を使う上で知るべきリファレンスとして、上記 4つのポイントにフォーカスしましょう。
インストールと MySQL への接続
MySQL をインストールする方法はたくさんありますが、全部が全部早いわけではありません
。Linux の場合は以下のようにタイプするのも簡単でしょう:
sudo apt-get install mysql-server
訳注
Linux と言ってもディストリビューションとか環境によって MySQL のインストール方法はマチマチでしょうけど、恐らく Linux ユーザーなら各々 MySQL のインストールはできますよね・・?Mac の場合、brew を使って次のように代わりにタイプするでしょう:
brew install mysql
訳注
上記方法で Mac に MySQL をインストールするには、Homebrew をインストールする必要があります。インストール方法などの詳細は以下を参照くださいませ。ターミナルから一行たたくだけです。
https://brew.sh/index_ja他のシナリオの場合でも、インストーラーをダウンロードして Wizard に従ってください。
Windows の場合、訳者の環境では XAMPP と言う、Apache + MySQL + PHP を自動でインストールするものを利用してしまいました。もちろん、MySQL 単体インストールも可能のようです。いずれにしても、PowerShell からインストールする方法はありませんので、各手順にある通り、インストーラーをご利用ください。
一旦、MySQL をインストールし終わると、以下のような情報が出てきます。もちろん、インストール パッケージによって異なるでしょう:
==> mysql We've installed your MySQL database without a root password. To secure it run: mysql_secure_installation MySQL is configured to only allow connections from localhost by default To connect run: mysql -uroot To have launchd start mysql now and restart at login: brew services start mysql Or, if you don't want/need a background service you can just run: mysql.server start上の例では、root パスワードがまだついてないって言ってます・・ギャー!。しかし、mysql-secure-installation を実行することで fix できます。今はとりあえず、提案されている通り
mysql -uroot
を実行してデータベースに接続しましょう。% mysql -uroot ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)NOOO、何が起きたんだ?インストール時に表示された画面でこの情報を得ましたが、
brew services start mysql
を実行して、MySQL を起動する必要があるのでした。OK、さっそくbrew services start mysql
を入力しましょう:% brew services start mysql ==> Tapping homebrew/services Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-services'... remote: Enumerating objects: 40, done. remote: Counting objects: 100% (40/40), done. remote: Compressing objects: 100% (29/29), done. remote: Total 731 (delta 10), reused 27 (delta 6), pack-reused 691 Receiving objects: 100% (731/731), 201.74 KiB | 470.00 KiB/s, done. Resolving deltas: 100% (282/282), done. Tapped 1 command (40 files, 277.3KB). ==> Successfully started `mysql` (label: homebrew.mxcl.mysql)一番最後、Successfully started `mysql`:
Matthew が正しいかどうか見てみよう(訳注:gif が Matthew David McConaughey?)接続できたかな?
訳注
Windows でも MySQL Server を起動しなくてはいけない場合があります。Linux はもちろんですね。Windows で、MySQL 単体インストール手順に従った場合は、サービスとして自動起動するようなので、特に起動しなくても大丈夫なのではないかと想像します(ごめんなさい、未検証)XAMPPを使っている場合、XAMPP Control Panel を使って MySQL を起動してくださいませ。
しかし、MySQL Server を起動しなければならない、ということは使ったことある人なら常識ですよね。全般、この章の MySQL 解説はちょっと丁寧すぎる感じもしてますけど、以降もいろいろハマりながら進めるために、基礎を一度再確認しておくと良い、ということなのでしょう。% mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.19 Homebrew Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>プロンプト
mysql>
を得ることができた。僕らは入れたOK、パスワードなしで接続していたので、それを Fix しましょう。まだデータベースを持ってなかった。これも Fix しよう
僕らがデータベースを持っていないというわけでもなく、自分でデータベースを作っていない、が正くて、僕らがタッチできない実行サポート用データベースはあります:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) mysql>次に新しいデータベースを作成、選択します。次のように Query を入力します:
mysql> CREATE DATABASE Customer; Query OK, 1 row affected (0.01 sec) mysql> USE Customer; Database changed mysql>OK、素晴らしい。でも待って。僕らはテーブルを持ってなくないか?そうそう、僕らはテーブルをどうにかして作らないといけない。ターミナルからテーブルを作ることもできるけど、ちょっと痛い。複数のステートメントがたくさん出てきます。ですので、もしできるなら MySQL にファイルでデータベースと作りたい全てのテーブルを入力しましょう。テーブルを追加し続ける最初のファイルを定義しましょう。
database.sql/* creates a table `tasks` */ CREATE TABLE IF NOT EXISTS tasks ( task_id INT AUTO_INCREMENT, title VARCHAR(255) NOT NULL, start_date DATE, due_date DATE, status TINYINT NOT NULL, priority TINYINT NOT NULL, description TEXT, PRIMARY KEY (task_id) ); /* add more tables below and indeces etc as our solution grows */OK、データベース構造のファイルを作ったので、その内容を取得するため、次のようにして source コマンドを使うことができます:
mysql> source /Users/・・・/database.sql Query OK, 0 rows affected (0.01 sec) mysql> SHOW TABLES; +--------------------+ | Tables_in_customer | +--------------------+ | tasks | +--------------------+ 1 row in set (0.00 sec) mysql>もし、君の database.sql ファイルのあるフルパスを知りたければ、君のファイルのある場所で
pwd
とタイプします。そして、source [path to sqlfile]/database.sql
とタイプします。先に示した通り、SQL ファイルを実行する前に、データベースを選択する必要があります。テーブルが作成されたかどうかはSHOW TABLES;
で確認します。同じコマンドを使ってデータベースにシードデータを入れることもできますが、CRWATE TABLE ではなく、INSERT ステートメントになっている sql ファイルを処理することになります・・OK、では、MySQL はこれで十分。次は Docker の中で動く MySQL について話そう。(訳注:MySQL のコンソールからは、
quit;
などとして抜けてくださいませ)なぜ MySQL Docker イメージが必要で、どのようにコンテナーとして起動・実行するのか
OK、それでは、アプリケーション用のコンテナーが欲しいとしましょう。更に、そのソリューションにはデータベースが必要だとしましょう。コンピューターが実行されているホストに MySQL をインストールすることはあまり意味がないでしょう。コンテナーのマントラの一つは、コンテナーが実行されているホスト システムについてケアする必要はない、という意味です(訳注:なぜマントラなんていう文教用語が出てきたのか分かりませんが、要はコンテナーで考えている時、ホストを考慮する必要はない、ということのようです)OK、なので、コンテナーに入っている MySQL が必要なのです。アプリがコンテナーを所有するのでしょうか。それとも、コンテナーを分離するのでしょうか。いい質問です。アプリに MySQL をインストールすることもできますし、別のコンテナーで MySQL を実行することもできます。その論拠は:
- ローリング アップデート これによって、アプリケーションが個別にリスタートしている間も、データベースは常にオンラインになり、ダウンタイムが発生しません。
- スケーラビリティ 疎結合でノードを追加してスケールすることができます。
これに対してはたくさんの議論・意見のあるところなので、どれが良いかは君だけが知ってます・・君のやり方でやるのが良いよ
スタンドアロン イメージとしての MySQL
MySQL のイメージを引っ張ってくるシナリオについて話しましょう。OK、一歩ずつ手順を追って、説明しましょう。最初に行うことは MySQL を実行してみることです。前章で学んだようにイメージを持っていなければイメージを引っ張ってきます。コマンドは次のようになります:
docker run --name=mysql-db mysql
OK、アウトプットはどうなっているでしょう?
% docker run --name=mysql-db mysql Unable to find image 'mysql:latest' locally latest: Pulling from library/mysql afb6ec6fdc1c: Pull complete 0bdc5971ba40: Pull complete 97ae94a2c729: Pull complete f777521d340e: Pull complete 1393ff7fc871: Pull complete a499b89994d9: Pull complete 7ebe8eefbafe: Pull complete 597069368ef1: Pull complete ce39a5501878: Pull complete 7d545bca14bf: Pull complete 211e5bb2ae7b: Pull complete 5914e537c077: Pull complete Digest: sha256:a31a277d8d39450220c722c1302a345c84206e7fd4cdb619e7face046e89031d Status: Downloaded newer image for mysql:latest 2020-05-24 02:36:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.20-1debian10 started. 2020-05-24 02:36:17+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' 2020-05-24 02:36:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.20-1debian10 started. 2020-05-24 02:36:17+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORDイメージを引っ張ってこれましたね(訳注:英語では pull down)アァァァンド、エラー。
僕らは間違ってばかりだ
データベースが初期化されていない、パスワード オプションが指定されていない、などなど。これを Fix していきましょう:
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=complexpassword -d -p 8001:3306 mysql
そして勝者は:
% docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=complexpassword -d -p 8000:3306 mysql docker: Error response from daemon: Conflict. The container name "/mysql-db" is already in use by container "3069364970cd5a876976180a89b30a51e41ae003f0ae75165c30d1d183694332". You have to remove (or rename) that container to be able to reuse that name. See 'docker run --help'.うげっ、エラーメッセージを出したにも関わらず、僕らが前に始めたコンテナーが起動・実行されている。OK、コンテナーを落としましょう。
docker rm mysql-db
上記のようにデータベース セットを再度実行しましょう。
% docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=complexpassword -d -p 8001:3306 mysql c352b4abe3adcb8af5f3155093d69ae85d8540cbc66cc780b55b0a047288aa73OK、全てのログはターミナルに表示されません。なぜなら、Daemon モード(訳注:Detached モードが正しい?)で実行されているからです。
docker ps
を実行して確認しましょう:% docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c352b4abe3ad mysql "docker-entrypoint.s…" 45 seconds ago Up 44 seconds 33060/tcp, 0.0.0.0:8001->3306/tcp mysql-dbこの時点で、外側から接続したくなります。ポート フォワーディングで 0.0.0.0:8001 に接続する必要があります:
mysql -uroot -pcomplexpassword -h 0.0.0.0 -P 8001
訳注
Windows では 0.0.0.0 にアクセスすることはできませんでした。そもそも 0.0.0.0 を宛先にするのは誤りだ、という意見もあるようです。ここでは単に MySQL が動いていることが分かれば良いので、docker exec -it mysql-db bash
などとして、コンテナー内にログインし、コンテナー内でmysql -uroot -pcomplexpassword
すれば良いかな、と思います。実行結果の様子は後述参照。OK、上記のように、パスワードを設定して -p と書くだけで、次の行で即座にパスワードが入力されます。結果はこんな感じ:
% mysql -uroot -pcomplexpassword -h 0.0.0.0 -P 8001 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>OK、データベースの接続を管理しました。到達してますね。エライ
訳注
前述の通り、Windows では 0.0.0.0 へアクセスできませんので、以下のようにしてコンテナー内から MySQL を実行して確認すると良いでしょう。> docker exec -it mysql-db bash root@c352b4abe3ad:/# mysql -uroot -pcomplexpassword mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>訳注
唐突ですが、MySQL コマンド プロンプトに入ったついでに、下記コマンドをタイプして、データベースを作っておいてくださいませ。次章以降の演習で外側からデータベースを接続する実験になるのですが、この "Customer" データベースがないとエラーとなります。mysql> CREATE DATABASE Customers; Query OK, 1 row affected (0.01 sec) mysql>待って、他のコンテナーからコンテナー内のデータベースに到達できるのしょうか。そこはトリッキーなところです。二つのコンテナーをリンクする必要がある個所です。
Node.js からデータベースに接続
訳注
以降の作業は、これまで作成してきたプロジェクトに追加することが想定されています。NPM パッケージのインストール等は作業してきた Node.jsプロジェクトのフォルダで行ってください。また、app.js も同じファイルを編集することが想定されています。OK、それではデータベースに接続するコードをアプリに追加しましょう。最初に MySQL のための NPM パッケージをインストールする必要があります:
npm install mysql
次に、以下のコードを app.js の最初に追加します。
app.jsconst mysql = require('mysql'); const con = mysql.createConnection({ host: "localhost", port: 8001, user: "root", password: "complexpassword", database: 'Customers' }); con.connect(function (err) { if (err) throw err; console.log("Connected!"); });それではターミナルで試してみましょう:
% node app.js Example app listening on port undefined! /Users/・・・・/node_modules/mysql/lib/protocol/Parser.js:437 throw err; // Rethrow non-MySQL errors ^ Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client痛みと苦悩とはこのこと
なぜ動かないのだろう?caching_sha2_password が MySQL 8.0 で導入されたが、Node.js ではまだ実装されていません。
OK、それがどうした、Postgres か他のデータベースで試すか?いえいえ、以下のようにコネクターに繋いで、Fix できます:
mysql -uroot -pcomplexpassword -h 0.0.0.0 -P 8001
訳注:
Windows の場合は、docker exec -it mysql-db bash
してコンテナーにログイン後、mysql -uroot -pcomplexpassword
してください。MySQL のプロンプトに入ったら、次のようにタイプします。
mysql> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'complexpassword'; mysql> FLUSH PRIVILEGES;
node app.js
コマンドを再度実行しましょう。次はこうなりますよ:% node app.js Connected!ついに!
訳注
この後、ポートエラーとかが出ていると思うのですが、無視していただいて結構です。これは Docker を経由せずに Node.js 単体として、app.js を呼び出しているためです。Dockerfile が設定する環境変数 "PORT" が入っていないんですね。Connected が出たかどうかが実験のすべてなので、"Connected" さえ出ていれば、エラーは気にせず進んでくださいませ。OK、mysql_native_password の呼び出しはすべてを Fix したようですね。兎穴のより深いところに行きましょう。これって何?
MySQL はネイティブの認証を実装した mysql_native_password Plug-In を含んでいます。この認証は Plug-In 可能な認証が導入される前から使用されているパスワード ハッシュ方式です。
OK、MySQL 8 は Node.js MySQL ライブラリがまだ追いついていない新しい Plug-In 化された認証にスイッチしているということですね。これは古いバージョンの MySQL を持ってくるか、native 認証に戻せばよいということです
訳注
先ほどの謎のコマンドで、MySQL パスワードの認証方式を caching_sha2_password から、mysql_native_password に変更しています。SHA256("シャーにごろ"とか発音しますね)はダイジェスティングの方式ですが、ここでは暗号化の方法を変えるぐらいにご理解いただければ十分かと思います。コンピューターはあらゆるところでハマりますね・・Link 機能
Link 機能のアイディアはコンテナーは実行しているデータベースの IP や Port といった詳細を知る必要はないということに由来します。アプリ コンテナーとデータベース コンテナーがお互いに到達するといったことがちょうど例となります。典型的なシンタックスはこのようになります:
docker run -d -p 5000:5000 --name product-service --link mypostgres:postgres chrisnoring/node
少し上記をブレイクダウンしましょう:
- アプリ コンテナー product-service と言う名前のアプリ コンテナーを作ります。
- --link 既存の mypostgres コンテナーと product-service をリンクするコマンドを読んでいます。
- link alias --link mypostgres:postgres は mypostgres をリンクし、 postgres と言う alias を与えています。この alias はデータベースに接続する際、product-service コンテナー内部で利用できます。
OK、 Link 機能をだいたい理解できたと思いますが、既存の my-container にどのように適合し、mysql-db データベース コンテナーにどのように link するか見ていきましょう。my-container を Link 機能なしにスタートしていますので、一旦停止・削除、--link 機能を追加パラメータで再起動する必要があります:
docker kill my-container && docker rm my-container
これで、コンテナーは終了します。起動する前に、コードをいくつか変更する必要があります。つまり、データベースに接続する部分です。--link mysql-db:mysql パラメータを使ってデータベース コンテナー と link しようとしています。これは、IP や Port 参照が不要になるという意味で、コードは次のようになります:
app.js// part of app.js, the rest omitted for brevity const con = mysql.createConnection({ host: "mysql", // we changed! user: "root", password: "complexpassword", database: 'Customers' }); // and the rest of the code below違いは、今やホストは、localhost やリンク先を数値でリンクする原因となっていた Port を 8001 と明示しません。僕らはリンクしたデータベースに与えた alias(e.g mysql)にフォーカスすることが全てです。コードの変更と他のライブラリーの追加から、僕らはイメージを次のようにリビルドする必要があります:
docker build -t chrisnoring/node .
今回は link を付けて起動しましょう:
docker run -d -p 8000:3000 --name my-container --link mysql-db:mysql chrisnoring/node
アウトプットをみてみましょう:
% docker logs my-container > nodejs@1.0.0 start /app > nodemon app.js [nodemon] 2.0.4 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node app.js` Example app listening on port 3000! Connected!アプリ コンテナーからのログを見る
docker logs my-container
でログを表示させると最後に、MySQL との接続成功を示すコールバック関数からの Connected! が出ています。訳注
これは、console.log("Connected!");
のことを言っていますが、このように書かれたログをdocker logs my-container
で表示できる、ということですね。今何時か分かる?BOOOM!(訳注:これ、何のジョークか分かる方、教えてください・・)
Link 機能の知識を広げる ―― 他の方法
OK、全部うまくいきました。アプリケーションをコンテナーに配置し、他のコンテナーにデータベースを配置し管理しました。しかし、僕らが見てきた Link 機能はレガシーとされていて、Link 機能に関する他のう方法を学ぶ必要があります。待って・・君が思うほど悪くない。実際、構文的に良くなるように見える。
この新しいやり方は、ネットワークを作る、またはカスタム ブリッジ ネットワークと呼ばれています。実際、僕らが作るネットワークの一つです。ポイントは、コンテナーが所属する特定のグループだということです。コンテナーは一つ以上のグループに横断して関係する、複数のネットワークに存在できます。そりゃまったくすごいことだ、構文を教えてくれないか?
最初に行うことは、アプリ コンテナーとデータベースコンテナーを所属させたいネットワークを作ることです。以下のコマンドでそのネットワークを作ることができます:
docker network create --driver bridge isolated_network
新しいネットワークができたので、追加のパラメータとして新しいネットワークと共に各コンテナーを作成する必要があります。
docker run -d -p 8000:3000 --net isolated_network --name my-container chrisnoring-node
上記で、--net シンタックスを用いて、isolated_network と呼ぶネットワークを作っています。残りのコンテナーを今まで通り、コンテナーの起動、実行です。簡単でしょう
データベース コンテナーはどうでしょうか?
docker run -p 8000:3306 --net isolated_network --name mysql-db -e MYSQL_ROOT_PASSWORD=complexpassword -d mysql
--net isolated_network だけを加えて、データベース コンテナーを起動、実行しています。
コンテナーと他のコンテナーを明示的に Link する必要はもはやありません。特定のネットワークに配置するだけです。ネットワークのコンテナーは、お互いをどうコミュニケーションするか知っています。
ネットワークについては更に学ぶことがたくさんあります。たくさんのタイプや、コマンド ホストがあります。レガシー Link 機能との違いと言った要点は理解できたのではないかと思います。更に学ぶ場合は、こちらのリンクを参照してください。→ docs on networking
コンテナー設定上の一般的なデータベース管理
OK、この章の最初でファイルとしてデータベース構造を作成する方法と、シード データをファイルとして作成する方法、それらを MySQL プロンプトで一括して実行する方法を話しました。つまりこういうことです。そこにどのように構造とシード データを取得するかはあなた次第ですが、大まかなガイドラインや考え方を示そうと思います:
- 構造(Structure) いくつかの点でこのファイルを実行したくなります。データベースに入れるためには、mysql クライアントを使って接続することと、ホストコンピューターから外部ファイルを参照することとできます。または、アプリのリポジトリとして配置することも、Dockerfile で ファイルを コンテナーの中にコピーして実行することもできます。他の方法は、Knex や Sequelize と言った マイグレーションをサポートするライブラリを確認し、マイグレーションを実行してデータベース構造を特定することです。少し異なるトピックですが、このことを行う他の方法があることをお知らせしたかったのです。
- シード データ 構造と同じ方法でシード データを扱うことができます。これは構造を得た後に起きることで、一回限りです。アプリやデータベースのスタート毎に実行したい事ではなく、シードが基本的な構造データなのか、テスト目的で必要なデータなのかに応じて、手動で実行したい場合がほとんどです。e.g クライアントから MySQL に接続して、source コマンドを実行する
サマリー
OK、この文書では、MySQL の一般的な情報、テーブルと言った構造をどう取得するかの議論、初期/テスト用のシード データについて触れ、それらのスタンドアロンのファイルを使ってデータベースへの入れ方をカバーしました。
次に、なぜ、ホストにインストールするより、Docker コンテナーでデータベースを実行するべきか議論し、続いて、レガシー Link テクニックを使って二つのコンテナーがコミュニケーションする方法を見せました。MySQL 8 の不幸と、MySQL Node.js モジュールが同期していない事実に時間を費やし、それを Fix しました。
レガシー Link 機能をカバーして、それで終わりにするわけにはいかず、コンテナーをネットワーク名を使って Link する新しい方法について話す必要がありました。
最後に、データベースの管理と希望について一般的なガイドラインを共有し、現時点では、データベースをアプリにどのように追加し、アプリの開発を続けていくか理解したところにいます。
Twitter をフォローして、トピックへのあなたの問い合わせやご質問、提案を頂けるとハッピーです。
- 投稿日:2020-05-24T17:56:42+09:00
DockerでMySQLなどのテスト環境を作っていたら(errno: 150 "Foreign key constraint is incorrectly formed")が出た話
背景
mariadbをdocker環境に移してテストしようとしたところ、30分くらい詰まってしまったのでここに供養します。
現象
外部参照用のテーブルを新規に作成しようとすると下記のエラーが出る。
ERROR 1005 (HY000): Can't create table `{dbname}`.`{tablename}` (errno: 150 "Foreign key constraint is incorrectly formed")原因(1)
参照しようとしている行がユニークでないためエラーになっていた。
下記のようなSQLで、重複データを削除し プレマリキーとした。CREATE TEMPORARY TABLE {table name}_tmp AS SELECT id,MIN(uid),MIN(name) FROM tweets GROUP BY id; DELETE FROM {table name}; INSERT INTO {table name} SELECT * FROM {table name}_tmp; DROP TABLE {table name}_tmp; ALTER TABLE {table name} ADD PRIMARY KEY (id);原因(2)
参照先と参照元の型が異なる場合に発生する。
同一の方であることを確認した。原因(3)
テーブルのcharsetが異なる場合に発生する。
下記のコマンドで確認する。SHOW CREATE TABLE {table name};とりあえず、対象テーブルを同一なcharsetに修正する。
※データが入っていると色々面倒ですが、私は何も入っていないのですんなり行きました。ALTER TABLE {table name} CONVERT TO CHARACTER SET {char set};あと、外部参照がある、テーブルにも設定させる
create table{table name}( {col} varchar(23) not NULL, ... )ENGINE=InnoDB DEFAULT CHARSET={char set};最後に
私は1と3で発生していました。
備忘録です、忘れぬように ここに刻む
- 投稿日:2020-05-24T17:40:03+09:00
Podmanでコンテナを動かす
しばらく前にアップグレードした Fedora 31 で Docker を動かそうとしたところ、エラーでコンテナを起動できない...
$ docker run node/test docker: Error response from daemon: cgroups: cgroup mountpoint does not exist: unknown. ERRO[0000] error waiting for container: context canceledFedoraの最新版では Cgroup V1 から Cgroup V2 への移行が行われたが、Docker ではまだ Cgroup V2 をサポートしていないことが原因らしい。
https://fedoraproject.org/wiki/Changes/CGroupsV2
そもそもFedoraではDockerパッケージは提供されていない。Cgroup V1に戻すことで使うこともできるが、おすすめは
podman
らしい。https://fedoraproject.org/wiki/Common_F31_bugs#Other_software_issues
The Docker package has been removed from Fedora 31. It has been replaced by the upstream package moby-engine, which includes the Docker CLI as well as the Docker Engine.
However, we recommend instead that you use Package-x-generic-16.pngpodman, which is a Cgroups v2-compatible container engine whose CLI is compatible with Docker's.Podman
Redhatが開発したコンテナ管理パッケージ。
オープンソースで、コンテナとイメージはOCI互換、CLIはDockerと互換性がある。
コンテナの管理はsystemdに統合されているらしい。(デーモンレス)https://podman.io/getting-started/
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/using-systemd-with-containers_building-running-and-managing-containersインストール
docker-ceは削除
$ sudo dnf remove -y docker-ce*podmanをインストール
$ sudo dnf install -y podman podman-compose podman-docker
podman
コンテナの管理ツール。Docker互換のCLIを含む。podman-compose
docker-compose.ymlをpodmanをバックエンドにして動かすためのツール。podman-docker
dockerコマンドでpodmanを呼ぶシェルスクリプトを提供する。いらないけど一応入れてみた。インストールを確認
$ podman -v podman version 1.9.2Podmanでコンテナイメージを起動する
Podman でも docker.io で配布されているイメージを利用することが出来る。
リポジトリの設定は/etc/containers/registries.conf
にある。registries.conf[registries.search] registries = ['registry.fedoraproject.org', 'registry.access.redhat.com', 'registry.centos.org', 'docker.io']左から定義されている順にイメージの検索が行われる。既定で
docker.io
も利用できるようになっている。動作確認に簡単な Dockerfile を用意した。nodeのイメージをベースにしてシェルを起動するだけのイメージ。
FROM node:lts-alpine ENTRYPOINT /bin/shビルドする。
$ podman build ./ -t node/test STEP 1: FROM node:lts-alpine STEP 2: ENTRYPOINT /bin/sh STEP 3: COMMIT node/test --> 3d522a27844 3d522a278442b3e028c8fdc3d0634d4e348ea54a403875d03734450c5f99b178イメージの確認
$ podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE localhost/node/test latest 3d522a278442 13 minutes ago 93.1 MB <none> <none> 7bf7394c1846 14 minutes ago 93.1 MB docker.io/library/node lts-alpine 7a48db49edbf 3 weeks ago 93.1 MBコンテナの起動
$ podman run -it --rm node/test / # npm -v 6.14.4podman-compose でイメージを起動する
簡単な docker-compose.yml ファイルを作成。
docker-compose.ymlversion: '2' services: node: build: .イメージを実行する
$ podman-compose run --rm node podman pod create --name=environment --share net b740e843a42a7c85fe68dc1d72b27ee78e3b79c5806dfdcc0b45caea31501eeb 0 Namespace(T=False, cnt_command=[], command='run', detach=False, dry_run=False, e=None, entrypoint=None, file=['docker-compose.yml'], label=None, name=None, no_ansi=False, no_cleanup=False, no_deps=False, podman_path='podman', project_name=None, publish=None, rm=True, service='node', service_ports=False, transform_policy='1podfw', user=None, volume=None, workdir=None) podman run --rm -i --name=environment_node_tmp1612 --pod=environment --label io.podman.compose.config-hash=123 --label io.podman.compose.project=environment --label io.podman.compose.version=0.0.1 --label com.docker.compose.container-number=1 --label com.docker.compose.service=node --add-host node:127.0.0.1 --add-host environment_node_1:127.0.0.1 --tty environment_node / # node -v v12.16.3気になったところあれこれ
podman-compose up
でサービス毎に起動出来ない。(最新版とかではひょっとすると実装されているかも)$ podman-compose up -d node services ['node'] Traceback (most recent call last): File "/usr/bin/podman-compose", line 11, in <module> load_entry_point('podman-compose==0.1.6.dev0', 'console_scripts', 'podman-compose')() File "/usr/lib/python3.7/site-packages/podman_compose.py", line 1267, in main podman_compose.run() File "/usr/lib/python3.7/site-packages/podman_compose.py", line 755, in run cmd(self, args) File "/usr/lib/python3.7/site-packages/podman_compose.py", line 939, in wrapped return func(*args, **kw) File "/usr/lib/python3.7/site-packages/podman_compose.py", line 1038, in compose_up return up_specific(compose, args) File "/usr/lib/python3.7/site-packages/podman_compose.py", line 1033, in up_specific raise NotImplementedError("starting specific services is not yet implemented") NotImplementedError: starting specific services is not yet implemented
podman-compose
にexec
コマンドがない。$ podman-compose exec node /bin/sh usage: podman-compose [-h] [-f file] [-p PROJECT_NAME] [--podman-path PODMAN_PATH] [--no-ansi] [--no-cleanup] [--dry-run] [-t {1pod,1podfw,hostnet,cntnet,publishall,identity}] {help,version,pull,push,build,up,down,ps,run,start,stop,restart} ... podman-compose: error: argument command: invalid choice: 'exec' (choose from 'help', 'version', 'pull', 'push', 'build', 'up', 'down', 'ps', 'run', 'start', 'stop', 'restart')他にもいろいろありそうなので、お仕事に使うにはまだ早そう。
個人で使う分には何とか出来そうなので、使ってみることにします。
- 投稿日:2020-05-24T16:25:09+09:00
【docker】覚えたdockerコマンドをアウトプットします。
はじめに
先程、下記の記事を投稿しました。
【Docker】CentOS7.8のdocker上にnginxを起動
その中で覚えたdockerコマンドを本記事にてアウトプットしていきたいと思います。コマンド
バージョン確認
docker --version【実行例】
[root@tspdocker yum.repos.d]# docker --version Docker version 19.03.9, build 9d988398e7 [root@tspdocker yum.repos.d]#image関連
取得済みのコンテナイメージ確認
- docker image ls
docker image ls【実行例】
[root@tspdocker docker]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 9beeba249f3e 8 days ago 127MB [root@tspdocker docker]#
- docker images
docker images【実行例】
[root@tspdocker docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 9beeba249f3e 8 days ago 127MB [root@tspdocker docker]#レジストリからイメージの検索
docker search <イメージ名>【実行例】
[root@tspdocker docker]# docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 6012 [OK] ansible/centos7-ansible Ansible on Centos7 129 [OK] consol/centos-xfce-vnc Centos container with "headless" VNC session … 115 [OK] jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 114 [OK] centos/mysql-57-centos7 MySQL 5.7 SQL database server 75 imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 58 [OK] tutum/centos Simple CentOS docker image with SSH access 46 centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 44 kinogmt/centos-ssh CentOS with SSH 29 [OK] pivotaldata/centos-gpdb-dev CentOS image for GPDB development. Tag names … 11 guyton/centos6 From official centos6 container with full up … 10 [OK] nathonfowlie/centos-jre Latest CentOS image with the JRE pre-install … 8 [OK] drecom/centos-ruby centos ruby 6 [OK] centos/tools Docker image that has systems administration … 6 [OK] pivotaldata/centos Base centos, freshened up a little with a Do … 4 darksheer/centos Base Centos Image -- Updated hourly 3 [OK] pivotaldata/centos-mingw Using the mingw toolchain to cross-compile t … 3 pivotaldata/centos-gcc-toolchain CentOS with a toolchain, but unaffiliated wi … 3 miko2u/centos6 CentOS6 日本語環境 2 [OK] blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK] mcnaughton/centos-base centos base image 1 [OK] indigo/centos-maven Vanilla CentOS 7 with Oracle Java Developmen … 1 [OK] pivotaldata/centos7-dev CentosOS 7 image for GPDB development 0 smartentry/centos centos with smartentry 0 [OK] pivotaldata/centos6.8-dev CentosOS 6.8 image for GPDB development 0 [root@tspdocker docker]#コンテナイメージの取得
docker pull <イメージ名>【実行例】
[root@tspdocker docker]# docker pull miko2u/centos6 Using default tag: latest latest: Pulling from miko2u/centos6 67f15db7c18f: Pull complete 509a26fd7457: Pull complete fc1eb556a306: Pull complete a64d7cf12062: Pull complete Digest: sha256:e0fde5482f052a54b8215300cbe06ec233e0527d70fe8b89e0b4a81be1b30a3c Status: Downloaded newer image for miko2u/centos6:latest docker.io/miko2u/centos6:latest [root@tspdocker docker]#コンテナイメージ削除
docker rmi <[REPOSITORY] or [IMAGE ID]>【実行例】
①削除するコンテナの確認
[root@tspdocker docker]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 9beeba249f3e 8 days ago 127MB miko2u/centos6 latest 092ba03e36dd 3 years ago 248MB [root@tspdocker docker]#→今回は「miko2u/centos6」を削除
②コンテナ削除
[root@tspdocker docker]# docker rmi miko2u/centos6 Untagged: miko2u/centos6:latest Untagged: miko2u/centos6@sha256:e0fde5482f052a54b8215300cbe06ec233e0527d70fe8b89e0b4a81be1b30a3c Deleted: sha256:092ba03e36ddfcb49881eba3b708f461b7334cc7c595411350b04258495bd160 Deleted: sha256:c6c375cf9281546ef63130efff84f0732fc45bfaca98307eb8055b0acd4392ef Deleted: sha256:0d222776efc8d8e95f128486c9df597c8f97148d700a585e92dd741b1d237d0c Deleted: sha256:6128ee232c96b4419361c6855b26025ec74e66490b281f900a332f356554843e Deleted: sha256:b1b065555b8aba5ae83d5d59d611a6b0cc470e9c14b7e4bee081398309e474a5 [root@tspdocker docker]#③コンテナが削除されていることを確認
[root@tspdocker docker]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 9beeba249f3e 8 days ago 127MB [root@tspdocker docker]#コンテナ起動/停止関連
起動済みコンテナ確認
docker ps
よく使うオプション 内容 -a 全てのコンテナ情報出力 【実行例】
- docker ps
[root@tspdocker docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b631bfb26b8e nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8080->80/tcp vibrant_engelbart [root@tspdocker docker]#
- docker ps -a
[root@tspdocker docker]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b631bfb26b8e nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8080->80/tcp vibrant_engelbart [root@tspdocker docker]#コンテナの作成
docker run -it <イメージ名>
オプションの意味 内容 -it コンソールに結果を出力 こちらのコマンドは、コンテナの作成&起動&ログインを同時にやってくれるコマンドになります。
【実行例】
[root@tspdocker docker]# docker run -it ubuntu root@644f6b5a46b9:/#コンテナの起動
docker start <CONTAINER IDまたはNAME>【実行例】
①「ubuntu」が停止されていることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 11 minutes ago Exited (0) 13 seconds ago intelligent_hamilton [root@tspdocker docker]#→「Exited」が表示されていることを確認
②「ubuntu」を起動する
[root@tspdocker docker]# docker start 644f6b5a46b9 644f6b5a46b9 [root@tspdocker docker]#→「644f6b5a46b9」はコンテナID
「ubuntu」が起動されていることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 12 minutes ago Up 8 seconds intelligent_hamilton [root@tspdocker docker]#→「Up」になっていることを確認
コンテナの停止(コンテナにログインしていない場合)
docker stop <CONTAINER IDまたはNAME>【実行例】
①「ubuntu」が起動していることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 23 minutes ago Up 10 minutes intelligent_hamilton [root@tspdocker docker]#→「Up」になっていることを確認
②「ubuntu」を停止する
[root@tspdocker docker]# docker stop 644f6b5a46b9 644f6b5a46b9 [root@tspdocker docker]#③「ubuntu」が停止されていることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 24 minutes ago Exited (0) 29 seconds ago intelligent_hamilton [root@tspdocker docker]#→「Exited」になっていることを確認
コンテナの停止(コンテナにログインしている場合)
exit【実行例】
①コンテナ「ubuntu」にログイン[root@tspdocker docker]# docker attach 644f6b5a46b9 root@644f6b5a46b9:/#②「exit」実行
root@644f6b5a46b9:/# exit exit [root@tspdocker docker]#③「ubuntu」が停止していることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 30 minutes ago Exited (0) 2 minutes ago intelligent_hamilton [root@tspdocker docker]#→「Exited」になっていることを確認
動作中のコンテナへログイン
- attach
docker attach <CONTAINER IDまたはNAME>【実行例】
①「ubuntu」が起動していることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 35 minutes ago Up 11 seconds intelligent_hamilton [root@tspdocker docker]#②「ubuntu」のコンテナにログインできることを確認
[root@tspdocker docker]# docker attach 644f6b5a46b9 root@644f6b5a46b9:/#※抜ける際は、「Ctrl」を押しながら「p」→「q」の順番で押す。
root@644f6b5a46b9:/# read escape sequence [root@tspdocker docker]#
- exec
docker exec -it <CONTAINER IDまたはNAME> /bin/bash
オプション名 内容 i 標準入力(STDIN)を開いたままにする t 擬似ttyに接続する。ディスプレイ(STDOUT)をつなぐイメージ 【実行例】
①「ubuntu」が起動していることを確認
[root@tspdocker docker]# docker ps -a | grep ubuntu 644f6b5a46b9 ubuntu "/bin/bash" 35 minutes ago Up 11 seconds intelligent_hamilton [root@tspdocker docker]#②「ubuntu」のコンテナにログインできることを確認
[root@tspdocker docker]# docker exec -it 644f6b5a46b9 /bin/bash root@644f6b5a46b9:/#※抜ける際は、「Ctrl」を押しながら「p」→「q」の順番で押す。
root@644f6b5a46b9:/# read escape sequence [root@tspdocker docker]#参考
Dockerコンテナの作成、起動〜停止まで
Docker コマンドチートシート
Dockerコンテナ内で操作 attachとexecの違い
初心者用Docker基本コマンド一覧(新旧スタイル対応)
- 投稿日:2020-05-24T16:07:06+09:00
docker compose upしてもlocalhostに接続できないとき
Dockerでlocalhostに接続できない
Mac環境でRails開発をしているときに、Dockerを取り入れたのでdocker compose upをしたところ、正常に起動しているのにlocalhostに接続できない現象が発生。
セキュリティソフト(ESET)が影響していた
Docker自体は正常に起動しているので調べ方も特にわからず1時間くらい悩みましたが、ふとセキュリティソフトが影響しているのではと思いました。
私はMacBookにセキュリティソフト(ESET)を入れており、ファイアウォールの設定をしていたので、試しにファイアウォールの設定を切ったところ、無事localhostに接続できました。ただ、できればファイアウォールは切りたくない、、、
他に解決方法がないか調べていたところ、CANONのサポート情報に解決方法が載っていました。Mac環境で特定の通信が遮断される(「パーソナルファイアウォール機能」に起因する場合)
これでファイアウォールを切らず、Dockerによる通信のみ許可するように設定変更できました。
同じようにお困りの方の参考になれば幸いです。
参考
- 投稿日:2020-05-24T16:06:39+09:00
MySQLのコンテナを作る方法
- 環境
- CentOS Linux release 7.8.2003 (Core)
- Docker Engine 19.03.8
- docker-compose version 1.25.5
1. docker-compose.ymlを作る
version: '3.8' services: app: ...省略... logdb: image: mysql:8.0.20 environment: MYSQL_DATABASE: logdb MYSQL_USER: log MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password MYSQL_TCP_PORT: 3306 ports: - 3304:3306 volumes: - ./logdb/my.cnf:/etc/mysql/conf.d/my.cnf - ./logdb/init:/docker-entrypoint-initdb.d container_name: logdb restart: always
image
にはDockerHubにあるMySQLを指定指定のやり方はいくつかあるようだが、後でバージョンがわかる書き方にしてみた。
mysql - Docker Hub
environment
にデータベースの情報を指定
MYSQL_DATABASE
: 初期作成するデータベース名を指定MYSQL_USER
MYSQL_PASSWORD
:MYSQL_DATABASE
で指定したデータベースのスーパーユーザーになるユーザーとそのパスワードを指定MYSQL_ROOT_PASSWORD
: rootユーザーのパスワードを指定MYSQL_TCP_PORT
: MySQLのポート番号を指定
- 指定しなくても3306になりそうだけれど自信がないので指定しておく
ports
に公開するポートを指定ほかのコンテナやホストの外部からデータベースを使えるように
{ホストでのポート}:{コンテナでのポート}
を指定
volumes
の指定設定ファイルの配置
文字コードなどの必要な設定を記載した設定ファイル
my.cnf
を用意しておき/etc/mysql/conf.d
に配置するmy.cnf[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_general_ci init-connect='SET NAMES utf8mb4' skip-character-set-client-handshake port=3306 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES [mysqldump] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [client] default-character-set=utf8mb4初期テーブル作成用SQLの配置
最初に作成しておいてほしいテーブル定義を書いたSQLを
init
ディレクトリに格納しておきdocker-entrypoint-initdb.d
に配置するとデータベース作成後に作成しておいてもらえる
データを作成しておきたい場合もSQLをディレクトリに入れておけば実行してもらえるUSE logdb; DROP TABLE IF EXISTS rhel6; CREATE TABLE rhel6 ( -- ...省略... ); DROP TABLE IF EXISTS rhel7; CREATE TABLE rhel7 ( -- ...省略... );
restart
でコンテナの自動起動を設定
always
(常に再起動)を設定することでホストを起動したときに自動で起動してもらえる2. コンテナを作る
--no-recreate
をつけて既存のコンテナを作り直さないようにしてコンテナを作成する$ docker-compose up -d --no-recreate --build ...省略... Creating logdb ... done $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 625ce72a719 mysql:8.0.20 "docker-entry…" 23 seconds ago Up 21 seconds 33060/tcp, 0.0.0.0:3304->3306/tcp logdb 5cead7ffb9b host-java... "/usr/sbin/init" 7 hours ago Up 28 minutes 0.0.0.0:18080->8080/tcp app3. データベースにログインしてみる
ホストからログイン
ホストからつなぐときは、[コンテナに入る] > [データベースにログイン]でちょっと面倒くさい
けれどホストからつなぐことはあまりない・・・と思う# 1.コンテナに入る $ docker exec -it logdb bash # 2. データベースにログイン root@793f7ed80b16:/# mysql -u log -D logdb -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # my.cnfの設定が使われてるっぽい mysql> select default_character_set_name, default_collation_name from information_schema.schemata where schema_name = 'logdb'; +----------------------------+------------------------+ | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | +----------------------------+------------------------+ | utf8mb4 | utf8mb4_general_ci | +----------------------------+------------------------+ 1 row in set (0.00 sec) # テーブルもできている mysql> show tables; +-----------------+ | Tables_in_logdb | +-----------------+ | rhel6 | | rhel7 | +-----------------+ 2 rows in set (0.00 sec) mysql>アプリ用コンテナからログイン
ほかのコンテナからログインするときは
-h
(ホスト)に「コンテナ名」を指定する$ mysql -h logdb -u log -D logdb -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>ローカルPC(Windows)のGitBashでログイン
ホスト外部からログインするときは
-h
(ホスト)に「ホストのIPアドレス」を-P
(ポート)に「docker-compose.ymlで指定したホストのポート」を指定する
winpty
はGitBashを使用しているからつけているだけなので普通はいらない$ winpty mysql -h {ホストのパブリックIP} -P 3304 -u log -D logdb -p Enter password: ******* Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 14 Server version: 8.0.20 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
- 投稿日:2020-05-24T15:36:14+09:00
WSLでdockerをinstallするときにハマった話
はじめに
基本的には、dockerの公式サイトを参考にinstallを進めます。ちなみにWSLでdockerをinstallします。
Install Docker Engine on Debian
環境
$ cat /etc/os-release NAME="Ubuntu" VERSION="20.04 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04 LTS" VERSION_ID="20.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=focal UBUNTU_CODENAME=focalC:\Users\user>ver Microsoft Windows [Version 10.0.18362.836](windows subsystem for linux)
➀GnuPG
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - gpg: can't connect to the agent: IPC connect call failedgpg、別名は「Gnu Privacy Guard」「GPG」「GnuPG」である。
これは、公開鍵でファイルの署名を検証したり、公開鍵と秘密鍵のペアでメールの暗号化・復号化を行ったり署名を添付したりするツールである。
解決方法Ⅰ
システム上でgpg-agentがすでに実行されている可能性があるので、gpg-agentを起動しなおす。
$ pkill -9 gpg-agent $ source <(gpg-agent --daemon)解決方法 Ⅱ
gpgをinstallし直す。自分はこれで解決した。
$ apt remove gpg $ apt install gnupg1➁apt-add-repository
~$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian \ $(lsb_release -cs) \ stable" Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease Get:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease [107 kB] Ign:3 https://download.docker.com/linux/debian focal InRelease Err:4 https://download.docker.com/linux/debian focal Release 404 Not Found [IP: 2600:9000:2157:4000:3:db06:4200:93a1 443] Get:5 http://archive.ubuntu.com/ubuntu focal-backports InRelease [98.3 kB] Get:6 http://security.ubuntu.com/ubuntu focal-security InRelease [107 kB] Reading package lists... Done E: The repository 'https://download.docker.com/linux/debian focal Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.まだ公式にfocal versionがリリースされていないようである。(2020/05/18)
解決方法
$ sudo vi /etc/apt/sources.listfocal (ubuntu20.04) stableをコメントアウトして、eoan (ubuntu19.10) stableを追記する
# deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable deb [arch=amd64] https://download.docker.com/linux/ubuntu eoan stable # deb-src [arch=amd64] https://download.docker.com/linux/ubuntu focal stable参考) Can’t install docker on Ubuntu 20.04
➂docker daemon
~$ sudo docker run hello-world docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. See 'docker run --help'.解決方法
(以下のコマンドはwslを「管理者として実行」から開く)
$ service docker start * Starting Docker: docker$ service docker status * Docker is running➃ユーザの所属グループ
$ docker run hello-world docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'.解決方法
$ grep -i docker /etc/group docker:x:999:$ sudo gpasswd -a userhoge docker [sudo] password for userhoge: Adding user userhoge to group docker$ grep -i docker /etc/group docker:x:999:userhoge
- 投稿日:2020-05-24T15:08:09+09:00
DockerでMySQLを起動して、Intelij IDEAで接続する方法
DockerでMySQLを起動して、Intelij IDEAにdockerプラグインを導入して接続する方法を紹介します。画像多めです。
作業環境
OS:Windows 10
エディション:HOME
バージョン:2004事前準備
①Windowsを最新版にアップデートする
下記のサイトを参考に、Windows 10 HOMEの場合は必ず最新版までアップデートしておきます。
https://www.atmarkit.co.jp/ait/articles/1701/07/news037.html
最新版になるまで、何回もやる可能性があります。下のような画面になれば、OKです。
②IntelliJ IDEAのインストールする
以下のサイトを参考にIntelliJ IDEAの Community Edition をインストールし、日本語化します。
https://sukkiri.jp/technologies/ides/intellij-idea/intellij-idea-win.html
※Editionが2つあるので、注意してください。
③Dockerをインストールする
以下のサイトを参考に、Dockerをインストールします。
https://techracho.bpsinc.jp/ebi/2020_03_27/90477Windows 10 HOMEの場合は、インストール方法が特殊なので、下記のサイトを参考にインストールしてください。
https://tech.guitarrapc.com/entry/2020/04/21/034236④Dockerの設定
Dockerのインストールが終わったら、起動して、上の歯車のアイコンを押して、設定を開きます。
「General」の中にある「Expose daemon on …」をオンにし、下にある「Apply & Restart」を押します。
※Dockerの画面が出ない場合は、ここからアクセスします。
サンプルソースをダウンロードする
今回は下記のサイトから、サンプルコードをダウンロードします。
https://github.com/miyabayt/spring-boot-doma2-sample
下の画像にように、「Clone or download」という緑のボタンを押すと、下のような画面が出てくるので、「Download ZIP」を押してダウンロードします。
ZIPファイルをダウンロードして、デスクトップなどに解凍してから、Cドライブ直下に移動してください。
私の環境下では、Cドライブ直下に解凍すると、下記のように解凍されました。元のフォルダの構成がとは異なるので、エラーの原因になります。上記の画像と同じ構成になるように解凍してください。
IntelliJ IDEAにプラグインを導入する
事前準備が完了したら、IntelliJ IDEAに4つプラグインを導入します。
①Lombok pluginをインストールする
「構成」→「プラグイン」を押します。
下記のような、プラグインを追加する画面に変わります。
赤枠で囲ったところに「Lombok」と入力すると プラグインが表示されるので、インストールボタンを押して、インストールします。
②Eclipse Code Formatterをインストールする
次に「Eclipse Code Formatter」と入力すると プラグインが表示されるので、インストールボタンを押して、インストールします。
③Dockerをインストールする
次に「Docker」と入力すると プラグインが表示されるので、インストールボタンを押して、インストールします。
④Python Community Editionをインストールする
次に「Python Community Edition」と入力すると プラグインが表示されるので、インストールボタンを押して、インストールします。
※このプラグインはIntelliJ IDEAからおすすめされて入れたので、不要の可能性もあります。
プラグインのインストールが終わったら、OKを押すと前の画面に戻ります。導入したプラグインを設定する
次にプラグインの設定をしていきます。
「構成」→「設定」を押し、設定の画面を開きます。
①Lombok pluginの設定
左側の「ビルド、実行、デプロイ」を押し、「コンパイラー」を開き、その中の「注釈プロセッサー」を押します。
右側の画面が変わるので、「注釈処理を使用可能にする」にチェックを入れ、上の画面のようになればOKです。②Eclipse Code Formatterの設定
左側の「その他の設定」→「Eclipse Code Formatter」を押します。
右側の画面が変わるので、「Use the Eclipse code formatter」にチェックを入れ、「Eclipse Java Formatter config file」の右の「参照」を押すと、ファイル選択の画面が出てきます。
先程解凍した「spring-boot-doma2-sample-master」というフォルダを開き、その中の「eclipse-formatter.xml」を選びます。eclipse-formatter.xmlまでのパスは、Cドライブ直下に「spring-boot-doma2-sample-master」がある場合は、下記の通りになります。
C:\spring-boot-doma2-sample-master\eclipse-formatter.xml③Dockerの設定
左側の「ビルド、実行、デプロイ」を押し、「Docker」を押します。
「TCPソケット」を選び、接続が完了すればOKです。
接続できない場合は、まずはDockerが起動しているかどうか確認してください。以上でプラグインの設定は終了です。
IntelliJ IDEAの設定を変更する
プラグインの設定が完了したら、IntelliJ IDEAの設定を変更していきます。
①bootRunを実行している場合でもビルドされるようにする
Intellij上で「Ctrl+Shift+A」を押すと、小さい画面が出てくるので、「レジストリー」と入力します。
すると下に「レジストリー」と出てくるので、ここを選びます。
「compiler.automake.allow.when.app.running」という項目探して、右側のチェックボックスにチェックを入れます。終わったら、「閉じる」を押します。②コンソール出力の文字化けを防ぐ
Windowsの場合は、コンソール出力が文字化けするため、C:¥Program Files¥JetBrains¥IntelliJ Idea xx.x.x¥binの中にある「idea64.exe.vmoptions」というファイルを開きます。
一番下の行に「-Dfile.encoding=UTF-8」を追記して保存します。
③Java11を設定する
「構成」→「プロジェクト構造」を選びます。
設定が開くので、「プロジェクト設定」→「プロジェクト」を開き、「プロジェクトSDK」と「プロジェクト言語レベル」をそれぞれ、「11」を選びます。
もし、「プロジェクトSDK」で「11java version “11.0.7”」といった項目が出ない場合は、以下のページより「Java SE 11 (LTS)」の「JDK Download」からダウンロードして、インストールしてください。
https://www.oracle.com/java/technologies/javase-downloads.html※詳しいインストール手順が必要な場合はこちらを参考にしてみてください。
https://sukkiri.jp/technologies/processors/jdk/jdk-win_install.htmlDockerでMySQLを起動する
初回起動の場合
①docker-compose.ymlが存在するフォルダを確認する
サンプルコードの中には、DockerでMySQLを起動するための設定ファイル「docker-compose.yml」が含まれています。
Cドライブ直下に「spring-boot-doma2-sample-master」がある場合は、「C:\spring-boot-doma2-sample-master\docker」にあります。②Windows Power Shell を管理者権限で起動する
Dockerにコンテナなどを追加するので、タスクバーのwindowsマークの上で右クリックして、Windows Power Shell を管理者権限で起動します。
③Windows Power ShellからDockerのMySQLを起動する
急にWindows Power Shellが出てきて、難しそうですが、入力するのは以下の2行だけです。
cd C:\spring-boot-doma2-sample-master\docker docker-compose up先程の「docker-compose.yml」というファイルが存在するフォルダまで移動します。Cドライブ直下に「spring-boot-doma2-sample-master」がある場合は、以下のようになります。
cd C:\spring-boot-doma2-sample-master\docker“docker-compose”というコマンドが使えるかどうかを確かめるために、以下のように入力します。
docker-compose --version以下のようにバージョンが表示されればOKです。
docker-compose version 1.25.5, build 8a1c60f6次に以下のように入力して、MySQLを起動します
docker-compose upエラーが出てうまく行かない場合は、docker-compose.ymlが存在するフォルダまで移動してから、上記のコードを実行しているかどうか、確認してください。
このコマンドが終了すると、Dockerの画面が下記のように変わります。
簡単にDockerでMySQLを起動することができますね。2回目以降
Dockerを起動します。Dockerの画面が出ない場合は、ここからアクセスします。
白いクジラのアイコンの上で右クリックをして、「Dashboard」を選びます。
Dockerの画面が出てきたら、赤枠で囲った▶部分を押します。
MySQLが出てくるので、赤枠で囲ったボタンを押すと、サーバーの起動が始まります。
下の画面が出てくればOKです。
Dockerで起動したMySQLに、Intelij IDEAを接続する
Intelij IDEAを起動して、「オープンまたはインポート」を選びます。
Cドライブ直下に解凍した「spring-boot-doma2-sample-master」を選び、OKを押します。
下のような画面が出てくるので、「サービス」を選びます。
画面が変わると「Docker」が出てくるので、選ぶと接続が始まります。
接続が完了すると、以下のような画面になります。
以上で、Dockerで起動したMySQLに、Intelij IDEAで接続することができました。サンプルコードを動かす
ここからは、サンプルコードを動かしていきます。
サンプルコードを動かす前に、プラグインの設定とJavaの設定を確認してください。
確認が終了したら、Intelij IDEAの「ターミナル」を開きます。
①バージョン確認
ターミナルが起動したら、以下のように入力します。
cd C:\spring-boot-doma2-sample-master次に、以下のようにコードを入力します。
gradle -v以下のように、バージョンが表示されます。
------------------------------------------------------------ Gradle 6.3 ------------------------------------------------------------ Build time: 2020-03-24 19:52:07 UTC Revision: bacd40b727b0130eeac8855ae3f9fd9a0b207c60 Kotlin: 1.3.70 Groovy: 2.5.10 Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019 JVM: 11.0.7 (Oracle Corporation 11.0.7+8-LTS) OS: Windows 10 10.0 amd64②サンプルコードを動かす
次にサンプルコードを動かします。以下のように入力します。
gradlew composeUpプログラムが終わったら、以下のように入力します。
gradlew :sample-web-admin:bootRunしばらく待つと、95%で止まりますが、そのままでOKです。
これでアプリが起動したので、http://localhost:18081/adminにアクセスします。
上のような画面が出てきたら、成功です。お疲れさまでした。この記事は先輩エンジニアからアドバイスを受け、個人ブログから移植しました。おかしいところなどありましたら、ご指摘いただけると幸いです。
- 投稿日:2020-05-24T14:49:19+09:00
【Docker】CentOS7.8のdocker上にnginxを起動
はじめに
dockerの学習の一環として、下記を実施しました。
1.CentOS7.8にdockerインストール
2.nginxインストール&起動
3.htmlファイル作成&表示今回は、こちらの流れについて解説していきたいと思います。
環境
・HyperVisor
VMware Workstation 15 Player・仮想マシン
CPU:2
メモリ:10088MB
HDD:300GB
ネットワークアダプタ:ブリッジ
※NICは1つになります。・OS
CentOS7.5(1804)
※「yum update」により「CentOS7.8(2003)」にアップデート[root@tspdocker yum.repos.d]# cat /etc/redhat-release CentOS Linux release 7.8.2003 (Core) [root@tspdocker yum.repos.d]#※仮想マシン設定のエビデンス(ネットワークアダプタ設定)
構成図
今回の構成はこちらになります。
事前設定
下記について事前に設定済みになります。
- ホスト名:tspdocker
- IPアドレス:192.168.0.40
- DNS:8.8.8.8,8.8.4.4
※Google Public DNSを使用しています。- firewalld:停止/自動起動停止
- selinux:無効
- NTP:設定済み(ntp.nict.jp)
- yum update:済み
手順
docker準備
旧バージョンのdockerアンインストール
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine公式リポジトリのインストール
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repoDOCKER CE のインストール
最新版のDocker CEをインストールします。
yum install -y docker-ce docker-ce-cli containerd.ioDocker の起動/自動起動
Docker起動
systemctl start dockerDocker自動起動設定
systemctl enable dockerバージョンの確認
docker --version実行例
[root@tspdocker yum.repos.d]# docker --version Docker version 19.03.9, build 9d988398e7 [root@tspdocker yum.repos.d]#docker上にnginxの準備
nginxのイメージ取得
docker pull nginx実行例
[root@tspdocker yum.repos.d]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx afb6ec6fdc1c: Pull complete b90c53a0b692: Pull complete 11fa52a0fdc0: Pull complete Digest: sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest [root@tspdocker yum.repos.d]#イメージ確認
docker images実行例
[root@tspdocker yum.repos.d]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 9beeba249f3e 8 days ago 127MB [root@tspdocker yum.repos.d]#nginx起動
docker run -d -p 8080:80 nginx実行例
[root@tspdocker yum.repos.d]# docker run -d -p 8080:80 nginx b631bfb26b8eb469437f55731abadc6d1e308149bf89062d0282ae11db722faa [root@tspdocker yum.repos.d]#nginx起動確認
docker ps -a実行例
[root@tspdocker yum.repos.d]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b631bfb26b8e nginx "nginx -g 'daemon of…" 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp vibrant_engelbart [root@tspdocker yum.repos.d]#WEB画面確認
「http://<サーバのIPアドレス>:8080」へブラウザからアクセス
例)http://192.168.0.40:8080/アクセスするとこちらの画面が表示される。
実際にhtmlファイルを作成後に表示する
コンテナへログイン
コンテナ名を調べる
docker ps -a実行例
[root@tspdocker yum.repos.d]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b631bfb26b8e nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:8080->80/tcp vibrant_engelbart [root@tspdocker yum.repos.d]#→実行例の場合は、「vibrant_engelbart」がコンテナ名。
コンテナへログイン
docker exec -it vibrant_engelbart /bin/bash→「vibrant_engelbart」はコンテナ名
実行例
[root@tspdocker yum.repos.d]# docker exec -it vibrant_engelbart /bin/bash root@b631bfb26b8e:/#OSバージョン確認
cat /etc/os-release実行例
root@b631bfb26b8e:/# cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" root@b631bfb26b8e:/#→OSが「Ubuntu」であることを確認
vim/sudoインストール
※ファイル編集に使用するパッケージになります。
インストール可能なパッケージ一覧の更新
apt-get update実行例
root@b631bfb26b8e:/# apt-get update Get:1 http://deb.debian.org/debian buster InRelease [121 kB] Get:2 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB] Get:3 http://deb.debian.org/debian buster-updates InRelease [49.3 kB] Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [201 kB] Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7905 kB] Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [7380 B] Fetched 8350 kB in 3s (3209 kB/s) Reading package lists... Done root@b631bfb26b8e:/#vimのインストール
apt-get install vim apt-get install sudohtmlファイルの文字化け対策
export LANG=C.UTF-8 export LANGUAGE=en_US: env | grep LANG※こちらは一時的な設定になります。(ログアウトするとリセットされます。)
実行例
root@b631bfb26b8e:/usr/share/nginx/html# export LANG=C.UTF-8 root@b631bfb26b8e:/usr/share/nginx/html# export LANGUAGE=en_US: root@b631bfb26b8e:/usr/share/nginx/html# root@b631bfb26b8e:/usr/share/nginx/html# env | grep LANG LANGUAGE=en_US: LANG=C.UTF-8html作成
htmlのデフォルトのルートディレクトリは「/usr/share/nginx/html」になります。
test用htmlファイル作成
vim /usr/share/nginx/html/test.html記載内容
<!DOCTYPE html> <meta http-equiv="content-type" charset="utf-8"> <html> <head> <title>主な要素</title> </head> <body> <h1>タイトル</h1> <h2>副題</h2> <p> これはパラグラフです。文節を記述するためのタグです。 一部分だけをマーキングする場合は<span>スパン</span>を使用します。 </p> <h3> 箇条書きの例 </h3> <ul> <li>HTMLの基本</li> <li>スタイルの基本</li> <li>スクリプトの基本</li> </ul <button>OKボタン</button> <button>NGボタン</button> </body> </html>作成したhtmlファイル表示
「http://<サーバのIPアドレス>:8080/test.html」へブラウザからアクセス
例)http://192.168.0.40:8080/test.htmlこちらの画面が表示される。
参考記事
Install Docker on CentOS 7
docker上のnginxのドキュメントルート
[Docker] Docker でNginx を起動して Web ページを表示する
- 投稿日:2020-05-24T13:23:45+09:00
Rails6 API をGKEにデプロイして動作確認する
今回Rails6 APIをGoogle Kubernetes Engineにデプロイしたので手順のみメモ
ちょっとやり方は特殊かもしれません構成 (一部のみ)
├── .docker │ ├── dev │ │ ├── .bashrc │ │ ├── Aptfile │ │ └── Dockerfile │ └── prod │ ├── .bashrc │ ├── Aptfile │ └── Dockerfile │ ├── dip.yml ├── docker-compose.development.yml └── docker-compose.production.yml手順
rails 導入
Rails 6: Docker/docker-compose/dipで
rails new
力を取り戻すを参考にdipを使ってrails new します。Dockerfileとdocker-composeの作成
構成に従ってDockerfileとdocker-compose.production.ymlを作成。
今後dev環境はdip
を、production環境はdocker-compose -f docker-compose.production.yml
を使っています(今後はproduction環境をもっとシンプルなものにしたい)。build
$ docker-compose -f docker-compose.production.yml buildローカルでの確認
$ docker-compose -f docker-compose.production.yml uplocalhostで確認
push
$ docker-compose -f docker-compose.production.yml pushGKEにデプロイ
GCPからKubernetes Engineに移動
5.1 クラスタを作成
5.2 ワークロードからデプロイを選択
5.3 既存のコンテナイメージのイメージパスから「選択」→たった今となっているイメージを選択
公開
- デプロイ後のボタンから公開を選択 すでに同様のimageを公開などして表示されない場合などはServicesのサービスを削除する
以上
- 投稿日:2020-05-24T13:08:37+09:00
Dockerのインストールでつまずいたのでメモ
暇だったのでDockerでも構築してみるか~
と軽い気持ちでやったら初手インストールでつまずいたのでメモ【環境】
Windows10 HOME経緯(基本Twitterで上げたもののコピペ)
Docker Desktop Installer.exeをPCへダウンロード
https://www.docker.com/get-started
↓
ダウンロードしたDocker Desktop Installer.exeを実行。
↓
インストール失敗。
OSのバージョンを上げろ、と言われる
↓
OSを最新の状態にする
↓
再度、実行。
↓
バージョンを上げろと言われる
(確かにDockerのエラーメッセージ内のビルド番号がPCのビルド番号より上である。。。
でもOSは最新の状態だし・・・)
↓
解決策をググる
↓
どうやらDocker Toolboxなるものを使ってDocker環境構築できる記事を見つける(光が見える)
↓
Docker Toolboxでの構築法をググる
↓
現在、Docker Toolboxはダウンロードできないという記事を見つける(希望が途絶え暗闇にぶっこまれる)
↓
根本に立ち返る
↓
最新の状態にしたPC以上のビルド番号を求めてくるということは自身のOSは最新に見えて、実は最新じゃない!?と仮定を建てる
↓
調べていくとどうやらWindows Insider Programに登録すれば一般公開前の最新ビルドをインストールできるらしい
↓
Windows Insider Programに登録
↓
設定の「システム」から最新のバージョンがないか検索をかけてみると見事にヒット!!
↓
アップグレードして、ビルド番号がDockerが求めているもの以上である事を確認
↓
Docker Desktop Installerを再度実行、無事インストール完了参考にした記事
https://po-what.com/docker-install-for-win10#i-3
補足
・Docker Toolboxについて
公式見たけど、普通にインストールできるっぽい。ただし、Docker Toolboxはレガシーであり、システム要件を満たせない古いMacやWindowsシステム向けとのこと【補足2】
Windows Insider Programについて
Windows 10 の次のレベルアップを目指すプログラム。
参加すればいろいろ特典があるらしい
https://insider.windows.com/ja-jp/about-windows-insider-program/
- 投稿日:2020-05-24T08:47:29+09:00
OS再起動時にWSL2 for Docker Desktopでcannot find cgroup mount が出る
この記事では基本的なWSL導入までの流れは汲みません。
進化中のWSL
WSL2
から連携可能になったDocker Desktop
これでwindows上でもlinuxサーバ開発ができるヤッター!
面倒臭いデュアルブートの設定しなくて済むし、Aviutl使いながらdockerビルドとかもできるワーイ!
Microsoft Build 2020イベントでGPUサポートの話まで出た!nvidia dockerまで使えるようになったら最高や!しかしながら、お披露目からそんなに経って無いということもあり動作に直結する細かいバグがちらほら見られる。
個人的にメンドくさいと思ってるのがタイトルの事象。
初回起動時
WSL構築当初はそもそもマウント先を指定する必要があるのでgit hub issueに則った方法は必須となる。
cgroups: cannot find cgroup mount destination: unknown上記エラーがでるので下記コマンドで対処
sudo mkdir /sys/fs/cgroup/systemd sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemdこれでdockerは難なく動くようになる。
OS再起動すると認識されなくなる
問題はここからでOS再起動時にdockerも立ち上がるように設定しておりdocker自体も問題なく起動しているようだが、
docker build
なりをWSL上で使おうとすると同じエラーが出て動かない。sudo mkdir /sys/fs/cgroup/systemd sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemdもう一度同じコマンドを打つと(当たり前だが)ディレクトリが存在しているエラーを吐き、
マウント解除してから同じコマンドぶつけても症状は変わらず。調べてみると、どうもOS終了前の状態を記憶しているようで再起動時に同期が取れないことが原因のようである。
(リフレッシュ前にwindows側のdockerを操作するとWSL側のdockerの状態が一致していないことが確認できる)対処法
同期取れててないなら再起動だ。もしくはWSLとdockerを連携したときの手順を思い返そう。
docker ->「setting」にある「resource」->「WSL Integration」をUbuntuを使おうとした場合、これをonにしたはずだ。
一旦offでリスタートしてからonに戻してリスタートするエラーが回避できた。バージョン2.3.0.2の場合
五月頭にリリースされたバージョン2.3.0.2から画面が変わりました。
「Refresh」ボタンが追加されたようですが現状機能してないみたいです。今後のアップデートで実装されるのかな?この場合「WSL Integration」の項目を全てオフにして「apply & restart」で適用させてから、もう一度項目すべてをonにして「apply & restart」すると
無事WSL上でdockerが使えるようになります。自分の環境だと再起動するたびに必須なのですが、他の環境だとこの限りではないのかもしれません。
参考文献
https://github.com/microsoft/WSL/issues/4189#issuecomment-518277265
- 投稿日:2020-05-24T02:55:39+09:00
Docker Desktop for WSL2 を使ってみる
WSLを2に更新する
WSL2にCentOSを設定する
の続き
今回はWSLでDocker Desktopを使ってみます。
一旦WSLでDockerを動かしてCentOSのコンテナ環境を作ろうと思います。
WSL上にすでにCentOSいるのにね。準備
Docker Desktop for Windowsは Windowsネイティブの Hyper-V 仮想化とネットワークを使用していました。
そのためWindows 10 Professional が前提でした。
今回はWSL2上でDocker Desktopを実行します。準備としてWSL2を準備しておく必要がありますが、前回まで済ませているのでそちらを参照ください。
PCのOSはWindows HomeでOKです。インストール
Docker Desktop for Windows
こちらからインストールください。Dockerの確認
PS C:\Users\XXX> docker version #Dockerのバージョン確認 Client: Docker Engine - Community Version: 19.03.8 API version: 1.40 Go version: go1.12.17 Git commit: afacb8b OS/Arch: windows/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.8 API version: 1.40 (minimum version 1.12) Go version: go1.12.17 Built: Wed Mar 11 01:29:16 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.2.13 GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683 PS C:\Users\XXX> wsl -l -v #wsl上にいることを確認 NAME STATE VERSION * CentOS7 Running 2 Legacy Stopped 1 kali-linux Stopped 1 docker-desktop-data Running 2 Ubuntu Stopped 2 CentOS8 Stopped 2 PS C:\Users\XXX> docker run hello-world #hollow worldの起動確認 Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/Dockerのインストールは無事できていそうです。
ProだったらHyper-Vは動いてないよね?WSLで動いてるよね?って確認も必要かもしれないけど、HomeのOSなのでそこはなしで!CentOSの環境を作ってみる
WSL上にいるCentOSとは別にDockerに仮想環境を作ってみます。
PS C:\Users\XXX> docker pull centos:centos7 #CentOS7 の Docker イメージを取得 centos7: Pulling from library/centos 524b0c1e57f8: Pull complete Digest: sha256:e9ce0b76f29f942502facd849f3e468232492b259b9d9f076f71b392293f1582 Status: Downloaded newer image for centos:centos7 PS C:\Users\XXX> docker image #Docker イメージを確認 centos centos7 b5b4d78bc90c 2 weeks ago 203MB hello-world latest bf756fb1ae65 4 months ago 13.3kB PS C:\Users\XXX> docker run -it --name="centos7f" centos:centos7 /bin/bash #コンテナ を作成・起動 [root@6fbe3d9ddbe5 /]# pwd / [root@6fbe3d9ddbe5 /]# exit #コンテナから出ていく exit PS C:\Users\XXX> docker ps #動いているコンテナリストを取得(なにもない) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES PS C:\Users\XXX> docker ps -a #存在するコンテナリストを取得 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6fbe3d9ddbe5 centos:centos7 "/bin/bash" About a minute ago Exited (0) About a minute ago centos7f 5484f528bb46 hello-world "/hello" 24 minutes ago Exited (0) 24 minutes ago festive_ganguly PS C:\Users\XXX> docker start centos7f #CentOSコンテナを再開 centos7f PS C:\Users\XXX> docker ps #起動の確認 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6fbe3d9ddbe5 centos:centos7 "/bin/bash" 2 hours ago Up 2 hours centos7f PS C:\Users\XXX> docker attach centos7f #起動したコンテナに接続接続したコンテナでの作業
とりあえずCentOSをアップデートだけしてみます。
[root@6fbe3d9ddbe5 /]# yum update Loaded plugins: fastestmirror, ovl Determining fastest mirrors * base: ftp.yz.yamagata-u.ac.jp * extras: ftp.yz.yamagata-u.ac.jp * updates: ftp.yz.yamagata-u.ac.jp base | 3. extras | 2. updates | 2. (1/4): base/7/x86_64/group_gz | 15 (2/4): extras/7/x86_64/primary_db | 19 (3/4): updates/7/x86_64/primary_db | 1. (4/4): base/7/x86_64/primary_db | 6. Resolving Dependencies --> Running transaction check ---> Package bind-license.noarch 32:9.11.4-16.P2.el7_8.2 will be updated ---> Package bind-license.noarch 32:9.11.4-16.P2.el7_8.3 will be an update ---> Package binutils.x86_64 0:2.27-43.base.el7 will be updated ---> Package binutils.x86_64 0:2.27-43.base.el7_8.1 will be an update ---> Package device-mapper.x86_64 7:1.02.164-7.el7_8.1 will be updated ---> Package device-mapper.x86_64 7:1.02.164-7.el7_8.2 will be an update ---> Package device-mapper-libs.x86_64 7:1.02.164-7.el7_8.1 will be updated ---> Package device-mapper-libs.x86_64 7:1.02.164-7.el7_8.2 will be an update ---> Package systemd.x86_64 0:219-73.el7_8.5 will be updated ---> Package systemd.x86_64 0:219-73.el7_8.6 will be an update ---> Package systemd-libs.x86_64 0:219-73.el7_8.5 will be updated ---> Package systemd-libs.x86_64 0:219-73.el7_8.6 will be an update ---> Package yum-plugin-fastestmirror.noarch 0:1.1.31-53.el7 will be updated ---> Package yum-plugin-fastestmirror.noarch 0:1.1.31-54.el7_8 will be an update ---> Package yum-plugin-ovl.noarch 0:1.1.31-53.el7 will be updated ---> Package yum-plugin-ovl.noarch 0:1.1.31-54.el7_8 will be an update ---> Package yum-utils.noarch 0:1.1.31-53.el7 will be updated ---> Package yum-utils.noarch 0:1.1.31-54.el7_8 will be an update --> Finished Dependency Resolution Dependencies Resolved =============================================================================================================================================== Package Arch Version Repository ===============================================================================================================================================Updating: bind-license noarch 32:9.11.4-16.P2.el7_8.3 updates binutils x86_64 2.27-43.base.el7_8.1 updates device-mapper x86_64 7:1.02.164-7.el7_8.2 updates device-mapper-libs x86_64 7:1.02.164-7.el7_8.2 updates systemd x86_64 219-73.el7_8.6 updates systemd-libs x86_64 219-73.el7_8.6 updates yum-plugin-fastestmirror noarch 1.1.31-54.el7_8 updates yum-plugin-ovl noarch 1.1.31-54.el7_8 updates yum-utils noarch 1.1.31-54.el7_8 updates Transaction Summary ===============================================================================================================================================Upgrade 9 Packages Total download size: 12 M Is this ok [y/d/N]: y Downloading packages: Delta RPMs disabled because /usr/bin/applydeltarpm not installed. warning: /var/cache/yum/x86_64/7/updates/packages/bind-license-9.11.4-16.P2.el7_8.3.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5 Public key for bind-license-9.11.4-16.P2.el7_8.3.noarch.rpm is not installed (1/9): bind-license-9.11.4-16.P2.el7_8.3.noarch.rpm | 8 (2/9): device-mapper-libs-1.02.164-7.el7_8.2.x86_64.rpm | 32 (3/9): device-mapper-1.02.164-7.el7_8.2.x86_64.rpm | 29 (4/9): yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch.rpm | 3 (5/9): yum-plugin-ovl-1.1.31-54.el7_8.noarch.rpm | 2 (6/9): yum-utils-1.1.31-54.el7_8.noarch.rpm | 12 (7/9): systemd-libs-219-73.el7_8.6.x86_64.rpm | 41 (8/9): systemd-219-73.el7_8.6.x86_64.rpm | 5. (9/9): binutils-2.27-43.base.el7_8.1.x86_64.rpm | 5. 2/18 Failed to get D-Bus connection: Operation not permitted Updating : 7:device-mapper-libs-1.02.164-7.el7_8.2.x86_64 3/18 Updating : 7:device-mapper-1.02.164-7.el7_8.2.x86_64 4/18 Updating : yum-utils-1.1.31-54.el7_8.noarch 5/18 Updating : yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch 6/18 Updating : 32:bind-license-9.11.4-16.P2.el7_8.3.noarch 7/18 Updating : binutils-2.27-43.base.el7_8.1.x86_64 8/18 install-info: No such file or directory for /usr/share/info/as.info.gz install-info: No such file or directory for /usr/share/info/binutils.info.gz install-info: No such file or directory for /usr/share/info/gprof.info.gz install-info: No such file or directory for /usr/share/info/ld.info.gz install-info: No such file or directory for /usr/share/info/standards.info.gz Updating : yum-plugin-ovl-1.1.31-54.el7_8.noarch 9/18 Cleanup : yum-utils-1.1.31-53.el7.noarch 10/18 Cleanup : yum-plugin-fastestmirror-1.1.31-53.el7.noarch 11/18 Cleanup : 32:bind-license-9.11.4-16.P2.el7_8.2.noarch 12/18 Cleanup : yum-plugin-ovl-1.1.31-53.el7.noarch 13/18 Cleanup : 7:device-mapper-libs-1.02.164-7.el7_8.1.x86_64 14/18 Cleanup : 7:device-mapper-1.02.164-7.el7_8.1.x86_64 15/18 Cleanup : systemd-219-73.el7_8.5.x86_64 16/18 Cleanup : systemd-libs-219-73.el7_8.5.x86_64 17/18 Cleanup : binutils-2.27-43.base.el7.x86_64 18/18 Verifying : 7:device-mapper-1.02.164-7.el7_8.2.x86_64 1/18 Verifying : systemd-219-73.el7_8.6.x86_64 2/18 Verifying : yum-plugin-ovl-1.1.31-54.el7_8.noarch 3/18 Verifying : systemd-libs-219-73.el7_8.6.x86_64 4/18 Verifying : binutils-2.27-43.base.el7_8.1.x86_64 5/18 Verifying : 32:bind-license-9.11.4-16.P2.el7_8.3.noarch 6/18 Verifying : 7:device-mapper-libs-1.02.164-7.el7_8.2.x86_64 7/18 Verifying : yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch 8/18 Verifying : yum-utils-1.1.31-54.el7_8.noarch 9/18 Verifying : systemd-219-73.el7_8.5.x86_64 10/18 Verifying : yum-utils-1.1.31-53.el7.noarch 11/18 Verifying : 32:bind-license-9.11.4-16.P2.el7_8.2.noarch 12/18 Verifying : yum-plugin-ovl-1.1.31-53.el7.noarch 13/18 Verifying : binutils-2.27-43.base.el7.x86_64 14/18 Verifying : 7:device-mapper-libs-1.02.164-7.el7_8.1.x86_64 15/18 Verifying : systemd-libs-219-73.el7_8.5.x86_64 16/18 Verifying : yum-plugin-fastestmirror-1.1.31-53.el7.noarch 17/18 Verifying : 7:device-mapper-1.02.164-7.el7_8.1.x86_64 18/18 Updated: bind-license.noarch 32:9.11.4-16.P2.el7_8.3 binutils.x86_64 0:2.27-43.base.el7_8.1 device-mapper.x86_64 7:1.02.164-7.el7_8.2 device-mapper-libs.x86_64 7:1.02.164-7.el7_8.2 systemd.x86_64 0:219-73.el7_8.6 systemd-libs.x86_64 0:219-73.el7_8.6 yum-plugin-fastestmirror.noarch 0:1.1.31-54.el7_8 yum-plugin-ovl.noarch 0:1.1.31-54.el7_8 yum-utils.noarch 0:1.1.31-54.el7_8 Complete!無事できました。
とりあえずアップデートできたのでネットワークにもつながってるぽいしOKです!最後に
正直、DockerもよくわかってないのにWSLにCentOS環境作ってWSLのDockerにCentOS作って・・・
自分で何がしたいのかわからないですwいつも仮想環境作ったりするとネットワークに繋がらなかったり問題が起こりますが今回はセーフ
※前回作ったCentOS8は動いてないので7使ってます。
ちょっといろいろ復習します!!
- 投稿日:2020-05-24T01:01:13+09:00
https-portalで簡単https対応!
前提
【初心者向け】20分でLaravel開発環境を爆速構築するDockerハンズオンを参考に設定した
docker-compose.yml
を使って、3層アーキテクチャの構築をしました。手元には以下3つのコンテナが作成されています。
- ウェブサーバー(web)コンテナ
- アプリケーションサーバー(app)コンテナ
- データベースサーバー(db)コンテナ
また、VPSサーバーにこれらのファイルをアップロードし、任意のドメインでhttpの動作を確認しています。さて、https対応をするために、
https-portal
を使ってLet's encrypt
の更新を自動化したいと考えています。作成している
docker-compose.yml
は以下の通りです。docker-compose.ymlversion: "3" services: app: build: context: ./docker/php args: - TZ=${TZ} volumes: - ./src:/work - ./logs:/var/log/php - ./docker/php/php.ini:/usr/local/etc/php/php.ini working_dir: /work environment: - DB_CONNECTION=mysql - DB_HOST=db - DB_DATABASE=${DB_NAME} - DB_USERNAME=${DB_USER} - DB_PASSWORD=${DB_PASS} - TZ=${TZ} web: image: nginx:1.17-alpine depends_on: - app ports: - 10080:80 volumes: - ./src:/work - ./logs:/var/log/nginx - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf environment: - TZ=${TZ} db: image: mysql:8.0 volumes: - db-store:/var/lib/mysql - ./logs:/var/log/mysql - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_PASS} - TZ=${TZ} volumes: db-store:本記事の内容
https-portal
を使用するために、docker-compose.yml
とdocker/nginx/default.conf
を修正します。docker-compose.ymlの修正
docker-compose.yml
ファイルを修正していきます。結論を述べると、https-portal
コンテナを追加し、ウェブサーバー(web)
コンテナのみ修正しました。docker-compose.ymlversion: "3" services: app: build: context: ./docker/php args: - TZ=${TZ} volumes: - ./src:/work - ./logs:/var/log/php - ./docker/php/php.ini:/usr/local/etc/php/php.ini working_dir: /work environment: - DB_CONNECTION=mysql - DB_HOST=db - DB_DATABASE=${DB_NAME} - DB_USERNAME=${DB_USER} - DB_PASSWORD=${DB_PASS} - TZ=${TZ} https-portal: image: steveltn/https-portal:1 ports: - '80:80' - '443:443' restart: always environment: DOMAINS: 'test.com(yourdomain) -> http://web:8000' # STAGE: 'production' # Don't use production until staging works # FORCE_RENEW: 'true' web: image: nginx:1.17-alpine ports: - 8000:8000 depends_on: - app volumes: - ./src:/work - ./logs:/var/log/nginx - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf environment: - TZ=${TZ} db: image: mysql:8.0 volumes: - db-store:/var/lib/mysql - ./logs:/var/log/mysql - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_PASS} - TZ=${TZ} volumes: db-store:https-portalコンテナから見ていきましょう。restartまでは公式からそのまま持ってきています。
docker-compose.ymlhttps-portal: image: steveltn/https-portal:1 ports: - '80:80' - '443:443' restart: always environment: DOMAINS: 'test.com(yourdomain) -> http://web:8000' # STAGE: 'production' # Don't use production until staging works # FORCE_RENEW: 'true'DOMAINSでは、左側でどのドメインを受けるか、右側でどのコンテナに転送するかを定義できます。左側にはhttpでアクセス可能なドメインを入力しましょう。また、今回はwebサーバーに転送するので、右側はこの例の通りに入力しましょう(ただし、port番号が被らなければ8000番以外でも可能です)。
docker-compose.ymlDOMAINS: 'test.com(yourdomain) -> http://web:8000'また、本番環境の場合、STAGEのコメントを外しておきましょう。''内には
local or staging or production
を入れることができますが、local
はLet's encryptが取得できません。docker-compose.yml# STAGE: 'production' # Don't use production until staging works
ウェブサーバー(web)
コンテナでは、https-portal
コンテナからの転送を受け取るためにポート番号を8000に変更しています。すでに述べたとおり、8000番以外を設定した場合は、その番号を設定します。docker-compose.ymlweb: image: nginx:1.17-alpine ports: - 8000:8000 depends_on: - app volumes: - ./src:/work - ./logs:/var/log/nginx - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf environment: - TZ=${TZ}これでdocker-compose.ymlの修正は完了です。
docker/nginx/default.confの修正
default.confファイルを修正します。それぞれ環境が異なる可能性もありますので、どのファイルを修正するかはwebコンテナのvolumesを確認しましょう。
docker-compose.ymlvolumes: - ./src:/work - ./logs:/var/log/nginx - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.confそれでは
docker/nginx/default.conf
を編集します。以下が設定されているので、8000番に変更しましょう(番号はDOMAINSで変更したもの)。default.confserver { listern 80 ...default.confserver { listern 8000 ...最後にdockerを再起動して数分待ち、httpsでページが表示されることを確認しましょう。
$ docker-compose down $ docker-compose up -dお疲れさまでした!
参考
- 投稿日:2020-05-24T00:57:59+09:00
(備忘録)TensorFlowを使ってオススメの楽曲名を類推するWebアプリ【機械学習】
はじめに
本記事は(備忘録)TensorFlowを使ってオススメの楽曲名を類推するWebアプリ
【docker-composeで実行環境作り】の続きです。
前回は、docker-composeでTensorFlowとFlask環境作ったので、
今回は、TensorFlow + Kerasを使った機械学習について整理したいと思います。
自分用に作った記事なので、分かりにくい点や情報、技術が古いかもしれませんがご了承ください
また何かしらのWebアプリを独りで作りたい方のご参考になれば嬉しいです。Webアプリ実物は以下のGIFのようになります。
検索ボックスに文章で入力すると、ハンバード・ハンバードさんの「同じ話」と言う回答頂きました
$\tiny{※学習データが少ないため、一部の曲しかヒットしません。。しょぼいです}$
$\tiny{※楽譜リンクをクリックすると楽譜の一部が表示されていますが、記事の対象外です}$参考文献
この記事を作るにあたって参考にさせて頂きました
- Sequentialモデルのガイド
- 【ニューラルネット】多層パーセプトロン(MLP)の原理・計算式
- Kerasの使い方まとめ【入門者向け】
- 機械学習入門者がKerasでマルチレイヤーパーセプトロンのサンプルを読む
- Denseを調べます
- 【Kerasの引数備忘録】01_kerasの引数はなにを指定しているのか
- TF-IDF
- Kerasの使い方をざっくりと
- すぐに使える! 業務で実践できる! Pythonによる AI・機械学習・深層学習アプリのつくり方
TODO マップ
(備忘録)TensorFlowを使ってオススメの楽曲名を類推するWebアプリ
【docker-composeで実行環境作り】の続きで、
今回は機械学習です。
章 区分 状況 内容 言語、FW、環境等 序 章 共通 済 アプリの概要 Python
TensorFlow
Keras
Google Colaboratory第一章 Web API 済 環境構築(実行環境) docker-compose
Flask
Nginx
gunicorn第二章 Web API 済 (今回)機械学習 Python
TensorFlow
Keras
Flask第三章 画面 未着手 環境構築 Python
Django
Nginx
gunicorn
PostgreSQL
virtualenv第四章 画面 未着手 表示、Web API呼出し部分 Python
Django第五章 AWS 未着手 AWS自動デプロイ Github
EC2
CodeDeploy
CodePipeline※まだ記事は全然整理できていないので時間ある時につくります。
未着手のまま命尽きるかも
またマップは書いてるうちに変わる可能性ありますのでご了承下さい。。環境
※以下のVerでなくても動くと思いますが、古いのでご注意下さい
OS:Ubuntu 18.04.4 LTS ---------------------- ----------- Flask 1.1.0 gunicorn 19.9.0 Keras 2.3.1 Keras-Applications 1.0.8 Keras-Preprocessing 1.1.2 matplotlib 3.1.1 mecab-python3 0.996.2 numpy 1.16.4 pandas 0.24.2 Pillow 7.1.2 pip 20.1 Python 3.6.9 requests 2.22.0 scikit-learn 0.21.2 sklearn 0.0 tensorflow 2.2.0オススメ曲を類推する部分のフロー
まず、ここで作りたいは以下のような機能です。
入力して文章(曲雰囲気等)を与えるとオススメの曲名を返してくれるWeb APIです。
Web APIの実物は以下です。
例ではGETメソッドのパラメータとして「切なくて誰かの幸せ願う歌」とし、
JSONで「雲がゆくのは」という曲名が取得できました。
(例)Web APIリンクこのWeb API内部の処理フローは以下となっています。
フローのように最後に曲名を返しますが、途中で重みデータを読み込みます。
これは、事前に機械学習によって作成された学習済みモデルの事です。
なので、学習済みモデルを作成する方法について整理します。機械学習のフロー
以下フローは開発者目線で、機械学習を行うまでの流れとなります。
まず、学習元のデータを準備します。こちらは人間が見ても分かるようなテキストで作ります。
次に機械(コンピュータ)に分かってもらうために前処理をします。
今回の例では、TF-IDFと呼ばれる方法で学習元のデータを数値ベクトルに変換します。
最後にMLP(多層パーセプトロン)で機械学習を行います。
各々の詳細は後述します。学習元データの作成
学習元となるデータは以下のようにカンマ区切り作っています。
機械学習の元データ
類推対象の曲名に対して曲の情報(雰囲気、アーティスト名等)が入っています。
"|"(パイプ)で区切ってますが、無くても大丈夫です。前処理(TF-IDF)
TF-IDFで数値ベクトルに変換します。
まず、上記で作成した学習元データを読み込みます。
その後、TF-IDF計算するために文章を単語に分けます(分かち書き)
この処理では形態素解析にMeCabを使っています。
参考までに分かち書きのソースは以下です。以下は、Google Colaboratoryに貼り付けるコードです。
$\tiny{※凝視したらダメです}$
上から順番に貼り付けて実行してください。。必要なライブラリをインストール# 必要なライブラリをインストール !apt-get install mecab libmecab-dev mecab-ipadic-utf8 !pip3 install mecab-python3分かち書き部分(一部抜粋)import MeCab # MeCabの初期化 tagger = MeCab.Tagger() def tokenize(text): '''MeCabで形態素解析を行う''' result = [] word_s = tagger.parse(text) for n in word_s.split("\n"): if n == 'EOS' or n == '': continue p = n.split("\t")[1].split(",") h, h2, org = (p[0], p[1], p[6]) if not (h in ['名詞', '動詞', '形容詞']): continue if h == '名詞' and h2 == '数': continue result.append(org) return result # モジュールのテスト if __name__ == '__main__': print(tokenize("映画|武田鉄矢|切ない|知らない誰かの幸せ願う"))実行すると以下のようにコンソールに表示されると思います。
['映画', '*', '武田', '鉄矢', '*', '切ない', '*', '知る', '誰か', '幸せ', '願う']単語ごとに区切られました。上記例は1文だけですが、
実際のプログラムではこの処理をファイル中の文章(行数)分繰り返しています。分かち書きできたら、TF-IDFの計算します。
TF-IDFについては、わかり易い説明がありましたので引用させて頂きます。
引用元:TF-IDF文書の中から、その文書の特徴語を抽出する時に使う値です。
いくつかの文書があったときに、それらに出てくる単語とその頻度(Frequency)から、
ある文書にとって重要な単語はなんなのかというのを数値化しますTF-IDFは以下の式で表されます。
\textrm{TF_IDF}(t) = \textrm{tf}(t,d) × \textrm{idf}(t)また、$\textrm{tf}(t,d)$と$\textrm{idf}(t)$は以下の式で表されます。
\textrm{tf}(t,d) = \frac{n_{t,d}}{\sum_{s \in d}n_{s,d}} \textrm{ , } \textrm{idf}(t) = \log{\frac{N}{df(t)}} + 1$n_{t,d}$ : ある単語 $t$ の文書 $d$ 内での出現回数
$\sum_{s \in d}n_{s,d}$ : 文書 $d$ 内のすべての単語の出現回数の和
$N$ : 全文書数
$df(t)$ : ある単語 $t$ が出現する文書の数上記の式をプログラムに直すと以下になります。
TF-IDFの計算(一部抜粋)def calc_files(): '''追加したファイルを計算''' global dt_dic result = [] doc_count = len(files) dt_dic = {} # 単語の出現頻度を数える for words in files: used_word = {} data = np.zeros(word_dic['_id']) for id in words: data[id] += 1 used_word[id] = 1 # 単語tが使われていればdt_dicを加算 for id in used_word: if not(id in dt_dic): dt_dic[id] = 0 dt_dic[id] += 1 # 出現回数を割合に直す --- (*10) data = data / len(words) result.append(data) # TF-IDFを計算 for i, doc in enumerate(result): for id, v in enumerate(doc): idf = np.log(doc_count / dt_dic[id]) + 1 doc[id] = min([doc[id] * idf, 1.0]) result[i] = doc return result※こちらの文献のサンプルソース1をほぼ流用させて頂いていますが、Githubに今回のソースをあげております。
(ソース)
学習元ファイル読み込みからTF-IDFを計算・出力するソースは以下です。
肝心のTF-IDFを計算するソースは長いのでモジュール化して読み込みます
また、学習元のデータも読み込みます。
以下に格納していますので、アップロードしてください。
tfidfWithIni.py ← TF-IDFを計算するモジュール
ans_studyInput_fork.txt ← 学習元ファイルTF-IDFベクトル作成手順
以下は、ご参考までにGoogle Colaboratoryに貼り付けるコードです。
$\tiny{※凝視したらダメです}$
上から順番に貼り付けて実行してください。。手順1_ファイルをアップロード# ファイルをアップロード(「tfidfWithIni.py」、「ans_studyInput_fork.txt」) from google.colab import files uploaded = files.upload()手順2_必要なライブラリをインストール# ファイル保存用のディレクトリ作成 !mkdir text # 必要なライブラリをインストール !apt-get install mecab libmecab-dev mecab-ipadic-utf8 !pip3 install mecab-python3手順3_TF-IDFベクトルに変換import os, csv, glob, pickle import tfidfWithIni import importlib # モジュール(tfidfWithIni)のリロード importlib.reload(tfidfWithIni) # 変数の初期化 y = [] x = [] # ラベルのコード変換用 辞書 labelToCode = {} # csvファイルを読み込む def read_file(path): '''テキストファイルを学習用に追加する''' # --- (*6) with open(path, "r", encoding="utf-8") as f: reader = csv.reader(f) label_id = 0 for row in reader: # ラベルコード作成 if row[2] not in labelToCode: labelToCode[row[2]] = label_id label_id += 1 y.append(labelToCode[row[2]]) # ラベルをセット tfidfWithIni.add_text(row[3]) # 文章をセット # print("ラベル: ", row[2], "(", labelToCode[row[2]], ")", " 文章: ", row[3]) # モジュールのテスト --- (*15) if __name__ == '__main__': # TF-IDFベクトルを初期化(filesを空にする) tfidfWithIni.iniForOri() # ファイル一覧を読む --- (*2) read_file("ans_studyInput_fork.txt") # TF-IDFベクトルに変換 --- (*3) x = tfidfWithIni.calc_files() # 保存 --- (*4) pickle.dump([y, x], open('text/genre.pickle', 'wb')) tfidfWithIni.save_dic('text/genre-tdidf.dic') pickle.dump(labelToCode, open('text/label_to_code.pickle', 'wb'))実行すると以下のようにフォルダーとファイルが出来上がります。
- /content/text/genre.pickle : 単語をTF-IDFでベクトル化したもの
- /content/text/label_to_code.pickle : 学習元ファイルを元に曲名をラベル化した辞書
- /content/text/genre-tdidf.dic : TF-IDF計算用の辞書
TF-IDF計算用の辞書は以下のように計算に使った単語をIDに変換したものです。
機械学習(MLP)
前処理をしたので、機械学習の準備終わりました。
上記までの学習データを元に曲名を正しく判別できるように学習を行います。
学習の手法としてMLP(多層パーセプトロン)を使います。
MLPとは、人の神経を模したニューラルネットワークの一種で、
3つ以上のノードの層からなるものだそうです。
MLPはある手法で学習データ(正解となるデータ)を元に学習を行い、
未知のデータ(この例では曲の雰囲気)がきても正しく判別(この例では曲名)できるようになります。
これを行うために機械学習フレームワークのTensorFlow+Kerasを使います。
そして、今回は以下のような構造のニューラルネットワークを作ります※イメージです
このニューラルネットワーク作るためにTensorFlow+Kerasでモデル化するとこのようになります1。
# MLPモデル構造を定義 model = Sequential() model.add(Dense(512, activation='relu', input_shape=(in_size,))) model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) model.add(Dense(nb_classes, activation='softmax'))レイヤーにはKerasのDenseと呼ばれるものを使います。これを使うと各々のパーセプトロンが次のレイヤーの
パーセプトロンに全て繋がるそうです。
また、イメージ図のx1〜xtまでが入力数ですが、これは引数のinput_shapeで定義しており、
全文章を分かち書きしてできた単語の数分です。サンプルの学習ファイルでは144個(次元)になります。
出力はy1〜yclassで学習ファイルの曲名数分あり、引数のnb_classesで指定してます。
サンプルでは10個(曲)です。次に正しく判別できるようにどのように学習を行うか設定します(コンパイル)。
Keras Documentationのマルチクラス分類問題を元に最適化アルゴリズムとしてRMSprop、
損失関数としてcategorical_crossentropyとします。
※(言葉のイメージ)損失関数:学習のズレを計る指標、最適化アルゴリズム:正解に近づける修正方法# モデルをコンパイル model.compile( loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'])最後に学習の実行部分です。
学習はfitメソッドで実行します。入力(曲の雰囲気等)と出力(曲名)
のNumpy配列をsequenceモデルのfitメソッドに与えると学習してくれます。hist = model.fit(x_train, y_train, batch_size=16, # 1回に計算するデータ数 epochs=150, # 学習の繰り返し回数みたいなもの verbose=1, validation_data=(x_test, y_test))機械学習の実行
以下は、ご参考までにGoogle Colaboratoryに貼り付けるコードです。
上記TF-IDFベクトル作成手順の手順3まで実行した上で、
以下を実行すると機械学習実行できるはずです。手順4_機械学習(MLP)の実行import pickle from sklearn.model_selection import train_test_split import sklearn.metrics as metrics import keras from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import RMSprop import matplotlib.pyplot as plt import numpy as np import h5py # 分類するラベルの数 labelToCode = pickle.load(open("text/label_to_code.pickle", "rb")) nb_classes = len(labelToCode) # データベースの読込 data = pickle.load(open("text/genre.pickle", "rb")) y = data[0] # ラベルコード x = data[1] # TF-IDF # ラベルデータをone-hotベクトルに直す y = keras.utils.np_utils.to_categorical(y, nb_classes) in_size = x[0].shape[0] # 入力x[0]の要素数 # 学習用とテスト用を分ける x_train, x_test, y_train, y_test = train_test_split( np.array(x), np.array(y), test_size=0.2) # MLPモデル構造を定義 model = Sequential() model.add(Dense(512, activation='relu', input_shape=(in_size,))) model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) model.add(Dense(nb_classes, activation='softmax')) # モデルをコンパイル model.compile( loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy']) # 学習を実行 hist = model.fit(x_train, y_train, batch_size=16, # 1回に計算するデータ数 epochs=150, # 学習の繰り返し回数みたいなもの verbose=1, validation_data=(x_test, y_test)) # 評価する score = model.evaluate(x_test, y_test, verbose=1) print("正解率=", score[1], 'loss=', score[0]) # 重みデータを保存 model.save_weights('./text/genre-model.hdf5') # 学習の様子をグラフへ描画 plt.plot(hist.history['val_accuracy']) plt.title('Accuracy') plt.legend(['train', 'test'], loc='upper left') plt.show()実行終わると、以下のようなグラフが表示され、ファイル(/content/text/genre-model.hdf5)が
追加で作成されているはずです。これで機械学習終わりです。
学習済みモデルを使って曲名を類推
類推部分でも機械学習時と同様のモデルを定義します。
学習済みモデル、TF-IDF辞書、結果ラベル用辞書を読み込みます。
そして未知の文書(曲の雰囲気)をTF-IDFベクトルに変換します。
最後にSequencialが持つpredictメソッドにTF-IDFベクトル与えると曲名を類推します。以下は、ご参考までにGoogle Colaboratoryに貼り付けるコードです。
上記 機械学習の実行の手順4まで実行した上で、
以下を実行すると曲名が類推できるはずです。曲名の類推import pickle, tfidfWithIni import numpy as np import keras from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import RMSprop from keras.models import model_from_json import importlib # モジュール(tfidfWithIni)のリロード importlib.reload(tfidfWithIni) def inverse_dict(d): return {v:k for k,v in d.items()} # テキストを指定して判定 def getMusicName(text): # TF-IDFのベクトルに変換 data = tfidfWithIni.calc_text(text) # MLPで予測 pre = model.predict(np.array([data]))[0] n = pre.argmax() print("オススメの楽曲名 : " + label_dic[n], "(", pre[n], ")") # ラベルの定義 labelToCode = pickle.load(open("text/label_to_code.pickle", "rb")) nb_classes = len(labelToCode) label_dic = inverse_dict(labelToCode) # 辞書から入力 要素数を求める。 in_size_hantei = pickle.load(open("text/genre-tdidf.dic", "rb"))[0]['_id'] # TF-IDFの辞書を読み込む tfidfWithIni.load_dic("text/genre-tdidf.dic") # Kerasのモデルを定義して重みデータを読み込む model = Sequential() model.add(Dense(512, activation='relu', input_shape=(in_size_hantei,))) model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) model.add(Dense(nb_classes, activation='softmax')) model.compile( loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy']) model.load_weights('./text/genre-model.hdf5') if __name__ == '__main__': requestParam = """ 切なくて誰かの幸せ願う歌 """ getMusicName(requestParam)学習結果によって変わるかもしれませんが、以下のように表示されると思います。
オススメの楽曲名 : 雲がゆくのは ( 0.99969995 )Flaskを使ったWeb APIでの曲名類推は前回ちょっとやってますので、割愛したいと思います
![]()
今後について
今回は機械学習まで少し整理できました。
また、時間のある時に少しづつブラッシュアップ、整理できればと思います
未定ですが、次回は画面側の環境構築について整理できればと思います。
章 区分 状況 内容 言語、FW、環境等 序 章 共通 済 アプリの概要 Python
TensorFlow
Keras
Google Colaboratory第一章 Web API 済 環境構築(実行環境) docker-compose
Flask
Nginx
gunicorn第二章 Web API 済 機械学習 Python
TensorFlow
Keras
Flask第三章 画面 未着手 (次回)環境構築 Python
Django
Nginx
gunicorn
PostgreSQL
virtualenv第四章 画面 未着手 表示、Web API呼出し部分 Python
Django第五章 AWS 未着手 AWS自動デプロイ Github
EC2
CodeDeploy
CodePipeline