- 投稿日:2020-03-16T23:58:04+09:00
EC-CUBE4 プラグイン開発 ①Dockerで環境構築
概要
EC-CUBE4でプラグインを開発することになった。
プロジェクトの最初から最後まで関わるのは初めてなので、あとで自分が振り返るために考えたことや試したことをどこかに記録しておこうと思った。
あと、忘れても問題ない状況を作って早く忘れてしまいたい。本記事では、Dockerで開発環境を構築する手順を書く。内容は、他のメンバーに共有するために仕事中に調べてまとめたものを加筆・修正しただけ。
環境構築は、EC-CUBE 4.0 開発者向けドキュメントの通り進めれば簡単に終わる。目次
EC-CUBE4 プラグイン開発 ①環境構築手順 (本記事)
EC-CUBE4 プラグイン開発 ②プラグイン開発特有のTips (未投稿)
EC-CUBE4 プラグイン開発 ③プラグイン開発を通して得た知識、考えたこと (未投稿)たぶん3本立てで書きそうな気がする。
SymfonyやEC-CUBE4についていろいろ知ったとはいえ、学んだことのうち、今後のプログラミングに活かせることはたぶん少ない。動作確認環境
Windows10 Pro PHPStorm 2019.3.3 Docker Desktop 2.1.0.5 Docker 19.03.5 EC-CUBE 4.0.3 Symfony 3.4 PHP 7.3 MySQL 5.7Postgresを使用する場合はMySQLと置き換えてください。
環境構築手順
Docker Desktop for Windows/Mac をインストール
既にDockerが使える状態にある場合は次のステップへ。
Docker Desktop for Windowsgit configがglobalで
core.autocrlf=input
になっていることを確認する既に設定されている場合は次のステップへ。
※他のプロジェクトに影響させたくない場合は、次のステップ「EC-CUBE本体をgit clone」でcloneするときだけglobalの設定を変更し、cloneが終わったら元に戻す。
gitconfig の基本を理解する理由:
core.autocrlf=true
の状態でEC-CUBE本体をcloneすると、LF -> CRLF に変換されることによって次のエラーが発生するため。
EC-CUBE4のコマンド叩いたら謎のエラーが出てきた(/usr/bin/env: 'php\r': No such file or directory )ファイルの改行コードをLFで統一するため。混在していると、文字化けなどバグの原因になることがある。
1年目か2年目にこの記事を読んで以来、globalの設定はずっとcore.autocrlf=input
にしている。
気をつけて!Git for Windowsにおける改行コードEC-CUBE本体をgit clone
// 任意のディレクトリへ移動 cd xxx git clone https://github.com/EC-CUBE/ec-cube.git.envをコピー
cd ec-cube cp .env.dist .env.envの内容を書き換える
Mysql、メールデバッグ用サーバを使うため。
# DATABASE_URL=sqlite:///var/eccube.db DATABASE_URL=mysql://dbuser:secret@mysql/eccubedb # MAILER_URL=null://localhost MAILER_URL=smtp://mailcatcher:1025 # 開発者間で暗号処理を統一したい場合は、この値を統一する。テストデータに含まれる暗号化したパスワードなどを共用できる。 ECCUBE_AUTH_MAGIC=xxxxxdocker-compose.ymlを書き換える
①PhpStormのコード補完機能を有効にするため、vender配下をホスト・コンテナ間で同期させる。
(ちなみにvar配下を同期させるとlocalでlogファイルが閲覧できる。しかし、logに吐かれる内容が非常にわかりづらく、ほぼ活用しなかった。また、ホスト・コンテナ間の同期が増えればその分動作が重くなると考え、最終的には同期するのをやめた。)下記に示す通り、計3行をコメントアウト、または削除する。
docker-compose.yml 15行目~39行目付近 Before### ignore folder volume ##### var: driver: local vender: ★この行を消す★ driver: local ★この行を消す★ services: ### ECCube4 ################################## ec-cube: build: context: . args: # ビルド時のECCubeインストールスクリプトをスキップする場合にtrueを指定する。 # ビルド時点でDBサーバの起動や接続が出来ない、という場合等にエラーとなるため。 SKIP_INSTALL_SCRIPT_ON_DOCKER_BUILD: "true" ports: - 8080:80 - 4430:443 volumes: - ".:/var/www/html:cached" ### 同期対象からコストの重いフォルダを除外 ##################### - "var:/var/www/html/var" - "vender:/var/www/html/vendor" ★この行を消す★ networks: - backenddocker-compose.yml 15行目~39行目付近 After
### ignore folder volume ##### var: driver: local ★消した!★ services: ### ECCube4 ################################## ec-cube: build: context: . args: # ビルド時のECCubeインストールスクリプトをスキップする場合にtrueを指定する。 # ビルド時点でDBサーバの起動や接続が出来ない、という場合等にエラーとなるため。 SKIP_INSTALL_SCRIPT_ON_DOCKER_BUILD: "true" ports: - 8080:80 - 4430:443 volumes: - ".:/var/www/html:cached" ### 同期対象からコストの重いフォルダを除外 ##################### - "var:/var/www/html/var" ★消した!★ networks: - backend②Postgresコンテナは利用しないので、次のコードをコメントアウトまたは削除する
### Postgres ################################ postgres: image: postgres:10 environment: - POSTGRES_DB=eccubedb - POSTGRES_USER=dbuser - POSTGRES_PASSWORD=secret ports: - 15432:5432 volumes: - pg-database:/var/lib/postgresql/data networks: - backendDockerコンテナを起動
// docker-compose.ymlが存在するディレクトリに移動 cd xxx/ec-cube docker-compose up -d --buildcomposer install
docker-compose exec ec-cube composer installインストールスクリプトを実行する
注意:このスクリプトを実行すると、データやプラグインがすべて初期化される。初回は気にしなくてOKだが、誤って実行して初期化しないように。
docker-compose exec ec-cube bin/console eccube:installInstaller Wizard が立ち上がるので、画面に従ってインストールを実行する。
既に.envを書き換えてあるので、Enter連打して全部OKするだけ。↓こんな感じのログが出る$ docker-compose exec ec-cube bin/console eccube:install EC-CUBE Installer Interactive Wizard ==================================== If you prefer to not use this interactive wizard, define the environment valiables as follows: $ export APP_ENV=dev $ export APP_DEBUG=1 $ export DATABASE_URL=database_url $ export DATABASE_SERVER_VERSION=server_version $ export MAILER_URL=mailer_url $ export ECCUBE_AUTH_MAGIC=auth_magic ... and more $ php bin/console eccube:install --no-interaction Database Url [mysql://dbuser:secret@mysql/eccubedb]: > Mailer Url [smtp://mailcatcher:1025]: > Auth Magic [xxxxxx]: > ! ! [CAUTION] Execute the installation process. All data is initialized. ! Is it OK? (yes/no) [yes]: > Run doctrine:database:create --if-not-exists... Database `eccubedb` for connection named default already exists. Skipped. Run doctrine:schema:drop --force... Dropping database schema... [OK] Database schema dropped successfully! Run doctrine:schema:create... ! [CAUTION] This operation should not be executed in a production environment! Creating database schema... [OK] Database schema created successfully! Run eccube:fixtures:load... > Finished Successful! Run cache:clear --no-warmup... // Clearing the cache for the dev environment with debug // true [OK] Cache for the "dev" environment (debug=true) was successfully cleared. [OK] EC-CUBE installation successful.これでlocal環境でEC-CUBE標準サイトが見れる状態になったことを確認する。
フロント側 http://localhost:8080/
管理画面 http://localhost:8080/adminデフォルトのID/PW 公式サイトのデモサイトと同じ。 ID: admin PW: passwordメールデバッグ用SMTPサーバ http://localhost:1080/
次回以降は、次のコマンドでDockerコンテナを起動/終了する。
※EC-CUBEに限らず、PCシャットダウン時にコンテナを終了しておかないと時々Dockerがバグるので注意。毎日終了する。docker-compose up -d docker-compose downここまでは、localにEC-CUBE標準サイトが動作する環境を作る手順。
ここから先は、開発するプラグインをEC-CUBEに反映する手順。開発するプラグイン用のリポジトリをcloneする
予め、開発する開発するプラグイン用のリポジトリを作っておく。
cd xxx/ec-cube/app/Plugin // 任意のディレクトリ名を指定する。 app/Plugin/SamplePluginというディレクトリ構成になる git clone https://github.com/xxx/sample_plugin.git ./SamplePluginプラグインジェネレータでプラグインの骨組みを自動生成
docker-compose exec ec-cube bin/console eccube:plugin:generateConsoleに答えてEnterで進む。
プラグインには、nameとcodeを設定できる。
nameは、プラグイン一覧ページで表示されるプラグインの名称。日本語も可らしい。codeは、コマンドを叩くとき、またはプラグインストアで利用される一意の文字列。命名規則は[a-zA-z_]で、数字は使えない。
(市場に出回っているプラグインのなかで一意のはず。自分たちでしか使わないような独自プラグインの場合は、導入したい市場のプラグインと重複しなければなんでもOK)
このcodeは、コマンドを叩くときに使用する。$ docker-compose exec ec-cube bin/console eccube:plugin:generate EC-CUBE Plugin Generator Interactive Wizard =========================================== name [EC-CUBE Sample Plugin]: > SamplePluginName code [Sample]: > SamplePluginCode ver [1.0.0]: > [OK] Plugin was successfully created: SamplePluginName SamplePluginCode 1.0.0これで準備が整った。
骨組みを作った時点でgit pushすれば、他の開発者にも共有できる。
他の開発者がこのプラグインをlocalのEC-CUBEにインストールするには、app/Plugin配下にgit cloneして次の項開発の流れ(大まかに)
のプラグインをインストール
をすればOK開発の流れ(大まかに)
- コードを書く。
- プラグインをインストール
docker-compose exec ec-cube bin/console eccube:plugin:install --code=Sampleすると、こういう感じのログが出てインストールが完了する。(デバッグモード)
コードにタイポがあったりすると、途中で止まってエラーを吐き出してくれる。$ docker-compose exec ec-cube bin/console eccube:plugin:install --code=Sample gen -> /tmp/proxy_VLW2B0Y0vtbO/src/Eccube/Entity/Product.php // Clearing the cache for the dev environment with debug true [OK] Cache for the "dev" environment (debug=true) was successfully cleared. [OK] Installed.
- プラグインを有効化する。
docker-compose exec ec-cube bin/console eccube:plugin:enable --code=Sampleこういうログが出て、正常に有効化すればOK。
$ docker-compose exec ec-cube bin/console eccube:plugin:enable --code=Sample gen -> /var/www/html/app/proxy/entity/src/Eccube/Entity/Product.php // Clearing the cache for the dev environment with debug true [OK] Cache for the "dev" environment (debug=true) was successfully cleared. [OK] Plugin Enabled.
- 管理画面/フロント画面で動作確認する。エラーが出ていれば修正する。
- 適宜commit,pushする。
(必要なら)外部プラグインを開発環境で有効にする
初回のみ
プラグインを探すより、外部プラグインを導入する。
ソースコードを落とす必要があるため、初回は認証コードを発行して画面上でプラグインをインストールする。また、ソースを落としてこないとプラグインのコードが分からず、コマンドを叩けない。(プラグインのコードはcomposer.jsonに記述してある)※codeが判明しているなら、eccube:plugin:installコマンドでも初回ソースDLは可能かもしれない。
e:p:iコマンドを叩いてかなり待ったが処理が進まない、ということがあったため画面上からインストールするようにしているが、e:p:iコマンドが完了するまで待てば正常にソースDLできたのかも・・・。初回以降
ソースを落とすことができたら、以降は下記コマンドでインストール、有効化を行う。// プラグインをインストール docker-compose exec ec-cube bin/console eccube:plugin:install --code={code} // インストール後、プラグインを有効化 docker-compose exec ec-cube bin/console eccube:plugin:enable --code={code}または、ec-cubeコンテナに入ってから
// プラグインをインストール ./bin/console eccube:plugin:install --code={code} // インストール後、プラグインを有効化 ./bin/console eccube:plugin:enable --code={code}リンク集
EC-CUBE4で開発するなら一度は目を通したほうがよいサイト集。実装に慣れるまではしょっちゅう閲覧していたのでブックマークしている。
EC-CUBE 4.0 開発者向けドキュメント
EC-CUBE 4 Style Guide 開発者向けドキュメントからアクセスできる。フロントのCSSで匙を投げる前に。
EC-CUBE 4の決済プラグインサンプル
4.0(旧3.n)ドキュメント化に向けた情報や実装の参考にしたい情報
EC-CUBE4 デモサイト プラグインで拡張しまくると標準の状態を忘れるので確認用に使ってた。実装する上で調べたもっと細かな情報は②③を書いたときにまとめる。
次
EC-CUBE4 プラグイン開発 ②プラグイン開発特有のTips (未投稿)
- 投稿日:2020-03-16T23:11:35+09:00
犬でもわかるDocker導入手順 for Mac in 2020
初めに
当方はレガシーな環境からの脱却を試みる若輩ソフトウェアデベロッパーであり、業務でDockerを使用した経験はない。
当記事はDocker入門者の私が備忘録的に書き記すものであり、あわよくば他の入門者の一助になればと思っている。
その為深い知識の説明はしないし、微妙なニュアンスの違いには目を瞑っていただきたい。
(ただ、気を付けていますが明らかな間違いは他の方の妨害にもなり得るのでご指摘ください。。)Dockerとは
チーム内での環境差異による不具合などを起こらなくしてくれる物。
「イメージ」と呼ばれる開発環境プリセットのような物を使用することで、そのイメージを使用して作成したアプリは、別環境で同様のイメージを使って環境構築すれば動く。便利!!
わかりやすく言うと(多分ちょっと違うけど)開発環境をUSBに入れてシェアできるみたいな物だと思う。環境構築
Dockeの説明についてはもっと死ぬほどわかりやすいものがインターネットの海には大量に存在するので、ここからは知識を入れずにとにかく脳死で環境構築したい方のために手順を紹介する。
と言っても、Hello,World!を出力するところまでなので手順というほどのものは存在しない。
本当に犬でもできるレベルである。Docker for Macのダウンロード
まず、今からDockerを使用する場合、何をダウンロードするかを悩む必要はない。
WindowsならDocker for Windows
MacならDocker for Mac
これだけでいい。
(古いバージョンのOSを使用している場合、少し異なる場合がある。)ダウンロードはこちらから行える。
接続すると、下記ページが表示されるので、「Get Started」をクリック。
すると、OSの選択画面になるので使用しているOSに適した方をクリック。
Dockerのダウンロードページに遷移するので、「Get Docker」をクリックするとダウンロードが開始されます。
Docker for Macのインストール
ダウンロードが完了したらFinderを開き、ダウンロードディレクトリから「Docker.dmg」ファイルをダブルクリック。
すると下記のような画面が表示されるので、DockerをApplicationsへドラッグ&ドロップ。
パスワードを求められるので、PCへログインしているユーザーのパスワードを入力すれば、インストールは完了!
Hello,World!
ステータスバーの鯨くんが画像のような状態で停止していればインストールは完了している。
(くるくる動いている場合は大人しく待ちましょう。)停止したらいよいよ皆大好きHello,Worldを試してみる。
terminalを開き、以下のコマンドを実行。
$ docker version
以下のようにバージョン情報が出力されればOK
動作確認ができたら下記コマンドでHello,Worldを実行する。
$ docker run hello-world
これは、「Hello,Worldを表示する」というイメージをダウンロードし実行しているということになる。
次のように表示されていれば環境構築はひとまず完了。終わりに
Dockerの導入は個人的にかなりハードルが高いものだと思い込んでいたが、案外すんなり導入できたのでここから実際の開発にも使用していきたい。
実際の開発で詰まった点などはまた記事にまとめていきたいとも思うので、お見かけになった際はマサカリを投げていってください。
- 投稿日:2020-03-16T22:12:00+09:00
エセイー(エセSE)が挑戦する、初めてのDocker
下記サイトに基本的な使い方は書いてある。
https://qiita.com/kariyaitaru/items/83fe1c8c9ed4f8732a63下記サイトを参考に、dockerhubよりデータを取得する。
https://kitsune.blog/docker-installdocker run -d -p 8080:80 --name nginx nginxnginxにアクセスする。
http://localhost:8080上記コンテナを停止・起動する。
# コンテナを停止 $ docker stop nginx nginx # コンテナを起動 $ docker start nginx nginx次に、コンテナからイメージを作成してみる。以下は「https://kitsune.blog/docker-comman」を参照している。
- Dockerベースイメージの取得
- Dockerコンテナの起動
- Dockerコンテナに変更を加える
- Dockerイメージの作成
Dockerイメージの確認
C:\Users\XXXXX>docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 6678c7c2e56c 11 days ago 127MBDocker Hubからベースイメージを検索するには、「docker search」コマンドを実行します。
C:\Users\XXXXX>docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 5884 [OK] ansible/centos7-ansible Ansible on Centos7 128 [OK] jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 114 [OK] consol/centos-xfce-vnc Centos container with "headless" VNC session… 111 [OK] centos/mysql-57-centos7 MySQL 5.7 SQL database server 71 imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 58 [OK] tutum/centos Simple CentOS docker image with SSH access 45 centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 43 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] mamohr/centos-java Oracle Java 8 Docker image based on Centos 7 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] indigo/centos-maven Vanilla CentOS 7 with Oracle Java Developmen… 1 [OK] blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK] pivotaldata/centos6.8-dev CentosOS 6.8 image for GPDB development 0 pivotaldata/centos7-dev CentosOS 7 image for GPDB development 0 smartentry/centos centos with smartentry 0 [OK]コンテナをダウンロードするには「docker pull OS名:バージョン」とする(:バージョンは省略可能)。今回は「docker pull centos:7」を実行する。
C:\Users\XXXXX>docker pull centos:7 7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:7 docker.io/library/centos:7「
docker images
」でイメージを確認する。C:\Users\XXXXX >docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 6678c7c2e56c 11 days ago 127MB centos 7 5e35e350aded 4 months ago 203MBDockerコンテナの一覧確認
Dockerコンテナの一覧確認は下記コマンド。
- 起動中のコンテナのみを表示する:
docker ps
- 停止中のコンテナも表示する:
docker ps -a
docker fileを作成する。
https://kitsune.blog/dockerfile-summary
- 投稿日:2020-03-16T21:37:19+09:00
パワーワードが作れる?ランダム単語合成アプリを作ってみた
はじめに
クリックするだけ!ランダムに2つの単語を「反応」させて、パワーワードを作りましょう!
モードは
- 形容詞+名詞
- 副詞+動詞
- 名詞+助詞+動詞
の3種類です!
ソースコード
GitHub - Syuparn/LiteralReaction: ランダムに単語を「反応」させて、パワーワードを作ろう
(DockerやVue.jsをはじめて使ったので、汚いところもあると思います…ツッコミ、修正歓迎です)
Webアプリの形で作りましたが、web上では公開していません。
(単語が本当にランダムなので、暴言や不謹慎な表現も生成されるかもしれないからです…)試したい方は上記リンクからダウンロードしてください。docker-composeを使用しているので、
$ docker-compose -f docker-compose.prod.yml up -dでコンテナを起動すれば
localhost:8080
からアクセスできます。webアプリケーションの構成
WebサーバとAPIサーバの2段構成になっています。
WebサーバはUI(html)、APIサーバは単語情報(JSON)をやりとりします。
コンテナもWebサーバとAPIサーバの2つに分けています。
(UIと単語生成を疎結合にして修正しやすくするためです)docker-compose.prod.ymlversion: '3' services: apiserver: build: context: ./apiserver/ dockerfile: Dockerfile ports: - "127.0.0.1:5050:5050" # host:container expose: - "5050" # port for other containers (not host) vue-frontend: build: dockerfile: Dockerfile context: ./vue-frontend ports: - "127.0.0.1:8080:80" # host:containerただし、ユーザーから見ても別々のURLになってしまうと不格好なので、Webサーバの
/api/
ではじまるURLにリクエストされた場合はAPIサーバに転送するようにしています。vue-frontend/nginx_config/default.confserver { listen 80; server_name localhost; server_tokens off; location / { # デフォルトではhtmlを返す root /usr/share/nginx/html; try_files $uri $uri/ @dynamic; } location /api/ { # URLが"/api/"ではじまる場合のみ、APIサーバに転送 # URLのうち"/api/"に続く部分のみを取り出す rewrite /api/(.*) /$1 break; # docker-composeの機能によって、exposeされた他コンテナのポートはアプリケーション名でアクセス可能 proxy_pass http://apiserver:5050; # redirectを無効化(既にrewriteでリダイレクトを設定しているため) proxy_redirect off; proxy_set_header Host $host; } }単語情報GETの流れは以下の通りです。(例は「形容詞+名詞」の場合)
- クライアントは、単語生成(「反応」)ページを開いたときに、形容詞を
localhost:8080/api/rand/adjective
へGETリクエスト- WebサーバがリクエストをAPIサーバ
http://apiserver:5050/rand/adjective
へ転送- APIサーバがリクエストに基づきランダムな形容詞1つをJSON形式で(Webサーバに)返す
- Webサーバはレスポンスをクライアントへ転送
- クライアントに形容詞データのJSONが届く
- 名詞についても同様
単語データ生成
「MeCab IPADIC」を使用しました。
MeCabは、文章を単語(正確には形態素、ことばの最小単位)ごとに分かち書きするソフトウェアです。
そして、MeCabが参照する形態素の辞書の1つがIPADICです。
品詞ごとにcsvファイルで書かれていて、各行に各形態素の表記、読み、品詞、活用などが格納されています。
Adj.csvあらっぽい,19,19,6956,形容詞,自立,*,*,形容詞・アウオ段,基本形,あらっぽい,アラッポイ,アラッポイ あらっぽし,23,23,6956,形容詞,自立,*,*,形容詞・アウオ段,文語基本形,あらっぽい,アラッポシ,アラッポシ あらっぽから,27,27,6956,形容詞,自立,*,*,形容詞・アウオ段,未然ヌ接続,あらっぽい,アラッポカラ,アラッポカラ ...このアプリの単語合成モードは
- 形容詞(終止形)+名詞
- 副詞+動詞(終止形)
- 名詞+(助詞)+動詞(終止形)
の3種類です。
この形式で最大限単語を利用するため、(文法的用語には少し不正確ですが)以下のルールで単語を抽出しました。apiserver/db/format-ipadic-csv.bash# 形容詞として利用 # 形容詞終止形 cat $PATH_FROM/Adj.csv | awk -F"," '$10~/^基本形$/ {print $1}' > $PATH_TO/adj.txt # (「な」を付けると形容詞になる名詞)+「な」 cat $PATH_FROM/Noun.adjv.csv | awk -F"," '{print $1 "な"}' >> $PATH_TO/adj.txt # (「ない」を付けると形容詞になる名詞)+「ない」 cat $PATH_FROM/Noun.nai.csv | awk -F"," '{print $1 "ない"}' >> $PATH_TO/adj.txt # 名詞として利用 # 「ナンセンスさ」を出したいので人名、地名、専門用語は除外し、一般名詞だけ使用 # 名詞 cat $PATH_FROM/Noun.csv | awk -F"," '{print $1}' > $PATH_TO/noun.txt # 「する」を付けると動詞になる名詞 cat $PATH_FROM/Noun.verbal.csv | awk -F"," '{print $1}' >> $PATH_TO/noun.txt # 「な」を付けると形容詞になる名詞 cat $PATH_FROM/Noun.adverbal.csv | awk -F"," '{print $1}' >> $PATH_TO/noun.txt # 「ない」を付けると形容詞になる名詞は単体で使うと不自然なので未使用) # 副詞として使用 # 副詞 cat $PATH_FROM/Adverb.csv | awk -F"," '{print $1}' > $PATH_TO/adverb.txt # 副詞としても使える名詞(「毎日」等) cat $PATH_FROM/Noun.adverbal.csv | awk -F"," '{print $1}' >> $PATH_TO/adverb.txt ## 形容詞連用形(小さい「っ」で終わるものは動詞が後続できないので削除) cat $PATH_FROM/Adj.csv | awk -F"," '$10~/^連用テ接続$/ {print $1}' \ | awk '!/っ$/' >> $PATH_TO/adverb.txt # 動詞として利用 # 動詞 cat $PATH_FROM/Verb.csv | awk -F"," '$10~/^基本形$/ {print $1}' > $PATH_TO/verb.txt # (「する」を付けると動詞になる名詞)+「する」 cat $PATH_FROM/Noun.verbal.csv | awk -F"," '{print $1 "する"}' >> $PATH_TO/verb.txt上記で生成したcsvをSQLiteに流し込んだものを、単語データベースとして使用しました。
apiserver/db/csv2sqlite.bashsqlite3 $SQL_PATH/$SQL_NAME << EOS /* create tables */ .read ./db/init.sql /* let col separator "," */ .separator ',' /* import word data csvs */ .mode csv .import $CSV_PATH/adj.csv adjectives .import $CSV_PATH/adverb.csv adverbs .import $CSV_PATH/noun.csv nouns .import $CSV_PATH/verb.csv verbs EOSapiserver/db/init.sqldrop table if exists adjectives; create table adjectives ( id integer primary key, word text ); drop table if exists adverbs; create table adverbs ( id integer primary key, word text ); drop table if exists nouns; create table nouns ( id integer primary key, word text ); drop table if exists verbs; create table verbs ( id integer primary key, word text );(個人的)面白かった生成結果
意外とフレーズが成立する割合が高く(体感100回に1回くらい?)、他にも以下のような「まともな」フレーズが生成されました。
居場所を失う 酷い蛇行 自我を失う 泥棒を訴える 移り気なロマンチスト やさしいインターフェースはまったところ
docker-compose buildできない
docker-compose
はapt install
でインストールすると古いバージョンが入ってしまいます…そして、古いバージョンのdocker-composeでバージョン3の
docker-compose.yml
を使うとビルドに失敗します。
apt install
ではなくcurl
で最新バージョンをダウンロードしましょうInstall Docker Compose | Docker Documentation
(公式ドキュメントはちゃんと読まねば…反省)
go buildできない
Go1.13からはライブラリ管理の方法が変わったため、最初に
go mod init
をする必要があります。このコマンドを打つと、モジュールの依存関係ファイル
go.mod
やモジュールが本物か確かめるためのチェックサムgo.sum
が生成されます。Go 1.13 に向けて知っておきたい Go Modules とそれを取り巻くエコシステム - blog.syfm
その代わり、
go.mod
のおかげでライブラリを手動でgo get
する必要がなくなりました!
(go build
時に自動でダウンロードされる)コンテナ作成中に生成した実行ファイルが消える
volumes
とCOPY
を混同していました。
Dockerfile
中でCOPY
すると、コンテナのビルド時にホストのディレクトリをコピーします。
docker-compose.yml
中でvolumes
を指定すると、コンテナの起動時にコンテナのディレクトリにホストのディレクトリをマウントします。そのため、ホストのソースを
COPY
してせっかく実行ファイルをビルドしても、同じディレクトリをvolumes
に指定するとホストのディレクトリ(もちろん実行ファイルは無い)に隠されてしまいます…docker-composeのvolumesで指定したホストのディレクトリがマウントされずハマった
conic-gradientが使えない
単語生成画面の集中線はCSSの
conic-gradient
関数を使用する予定でした…が、この関数はFirefoxでは非対応です。
conic-gradient() - CSS: カスケーディングスタイルシート | MDN
そこで、同名のnpmパッケージを使ってjs側で模様を生成しました。
しかし、このパッケージはES5で書かれているのでVue CLI内部で
import
できません。結局、
index.html
で直接グローバルに読み込む- Vue側では
window.ConicGradient
の形で呼び出すnpm run build
ではビルドされないので、別途モジュールをstaticにコピーするという手順を取りました。
vue-frontend/index.html<!DOCTYPE html> <html> ... <body> <div id="app"></div> <!-- built files will be auto injected --> <!-- ここでモジュールを読み込む(prefixfreeはconic-gradientの依存モジュール) --> <script src="./static/prefixfree.min.js"></script> <script src="./static/conic-gradient.js"></script> </body> </html>vue-frontend/src/components/bangBackground.vue<script> export default { name: 'bangBackground', data: function () { return { bangSVG: new window.ConicGradient({ repeating: true, stops: `#ffffff 0, #ffffff 2.0%, #AAAAAA 2.125%, #AAAAAA 2.375%, #ffffff 2.5%` }) } } } </script>vue-frontend/DockerfileFROM node:lts-alpine as builder RUN mkdir -p /app WORKDIR /app RUN npm install -g http-server COPY ./package*.json ./ RUN npm install \ # conic-gradientモジュールをstaticにコピー && mkdir -p static/ \ && cp node_modules/conic-gradient/conic-gradient.js static/ \ && cp node_modules/prefixfree/prefixfree.min.js static/ COPY . . RUN npm run build FROM nginx:stable-alpine as product COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx_config/default.conf /etc/nginx/conf.d/default.conf CMD ["nginx", "-g", "daemon off;"]参考文献
Go言語
APIサーバ
golangでREST APIをやってみた① - QiitaSQLiteとの接続
golangでSQLite3を使ってデータベースを操作する方法まとめ | Black Everyday CompanyMeCab
IPADICダウンロード方法
Alpine LinuxでMeCab with NEologd - QiitaVue.js
SPA(シングルページアプリケーション)のつくり方
【Vue.js】爆速でSPAを作る - Qiitaaxiosを使ったJSONのGET/POST
Vue-CLIのプロジェクトでaxiosを使ってAPIや外部リソースからのデータを取得する | 大阪市天王寺区SOHOホームページ制作 | デザインサプライ-DesignSupply.-コンポーネント内部に要素を入れる(公式)
スロット — Vue.jsnginx
URLの一部分だけ取り出してポートフォワーディング(
/api/hoge -> apiserver:5050/hoge
)
Nginx reverse proxy + URL rewrite - Server FaultDocker,docker-compose
docker-compose基本操作
docker-compose コマンドまとめ - Qiita複数サーバ(複数コンテナ)を協調させる方法
マイクロサービスほどじゃないけどウェブサービスを分割開発したい人向けDocker設定を集めるスレ - Qiitavue-cliビルド方法(公式)
Vue.js アプリケーションを Docker 化する — Vue.jsGolangマルチステージビルド方法
(マルチステージビルドのメリット)
Dockerのマルチステージビルドを使う - Qiita
(Go1.7の記事ですが、Go1.13以上の場合Dockerfileでgo get
をする必要はありません)(go-sqlite3ライブラリを使う場合)
go-sqlite3 が入った状態での Docker のマルチステージビルドを行う - Pistatium note
- 投稿日:2020-03-16T20:21:29+09:00
おうちk8sクラスタを作る: Dockerレジストリ編
1. 概要
本記事は、学習用に構築しているRaspberry Piによるk8sクラスタ、いわゆる「おうちk8sクラスタ」の製作記の「Dockerレジストリ編」です。
k8sクラスタでDockerコンテナを起動する場合、ノードにDockerイメージを配布するために、Dockerイメージを格納した「Dockerレジストリ」が必要です。(話を簡単にするために、Docker前提で話を進めます)
今回は、Docker Inc.が提供しているDockerイメージ「registry」を使い、k8sのマスターノードにDockerレジストリを構築しました。なお、今回のk8sクラスタは限定された環境下でのみアクセスされるため、Dockerレジストリの認証は行っていません。
認証が必要な場合はHarbor、Portusなどのソフトウェアを使ってDockerレジストリを構築するのが良いかと思います。2. 環境
今回の環境は以下の通りです。詳しい環境、構築方法については別記事『Raspberry Pi 4に64ビット版UbuntuでKubernetes環境を構築する』をご参照ください。
- ハードウェア: Raspberry Pi 4 4GB 4台
- OS: Ubuntu Server 19.10 ARM64(AArch64)版
- ノード構成:
- マスターノード: 1台
- ワーカーノード: 3台
ubuntu@k8s-m1:~$ cat /etc/os-release NAME="Ubuntu" VERSION="19.10 (Eoan Ermine)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 19.10" VERSION_ID="19.10" 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=eoan UBUNTU_CODENAME=eoan ubuntu@k8s-m1:~$ uname -a Linux ubuntu 5.3.0-1014-raspi2 #16-Ubuntu SMP Tue Nov 26 11:18:23 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux ubuntu@k8s-m1:~$ cat /proc/cpuinfo ... Hardware : BCM2835 Revision : c03112 Serial : 10000000794dd63d Model : Raspberry Pi 4 Model B Rev 1.2 ubuntu@k8s-m1:~$ cat /proc/meminfo MemTotal: 3882408 kB MemFree: 1965400 kB MemAvailable: 3563220 kB ... ubuntu@k8s-m1:~$ kubectl get nodes --output wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s-m1 Ready master 26m v1.17.3 192.168.1.211 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6 k8s-n1 Ready <none> 17m v1.17.3 192.168.1.212 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6 k8s-n2 Ready <none> 2m44s v1.17.3 192.168.1.213 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6 k8s-n3 Ready <none> 2m39s v1.17.3 192.168.1.214 <none> Ubuntu 19.10 5.3.0-1017-raspi2 docker://19.3.6 ubuntu@k8s-m1:~$ kubectl get pods --all-namespaces --output wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-6955765f44-jz5pv 1/1 Running 0 26m 10.244.0.3 k8s-m1 <none> <none> kube-system coredns-6955765f44-whxsx 1/1 Running 0 26m 10.244.0.2 k8s-m1 <none> <none> kube-system etcd-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none> kube-system kube-apiserver-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none> kube-system kube-controller-manager-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none> kube-system kube-flannel-ds-arm64-58rgk 1/1 Running 0 21m 192.168.1.211 k8s-m1 <none> <none> kube-system kube-flannel-ds-arm64-7gcj5 1/1 Running 0 17m 192.168.1.212 k8s-n1 <none> <none> kube-system kube-flannel-ds-arm64-b4lc9 1/1 Running 0 3m4s 192.168.1.213 k8s-n2 <none> <none> kube-system kube-flannel-ds-arm64-skgjw 1/1 Running 0 2m59s 192.168.1.214 k8s-n3 <none> <none> kube-system kube-proxy-bh8c5 1/1 Running 0 2m59s 192.168.1.214 k8s-n3 <none> <none> kube-system kube-proxy-shjkv 1/1 Running 0 17m 192.168.1.212 k8s-n1 <none> <none> kube-system kube-proxy-tngmj 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none> kube-system kube-proxy-ttx28 1/1 Running 0 3m4s 192.168.1.213 k8s-n2 <none> <none> kube-system kube-scheduler-k8s-m1 1/1 Running 0 26m 192.168.1.211 k8s-m1 <none> <none>3. 構築
今回利用する
registry
は単一のDockerイメージで構成されており、とても簡単にデプロイすることができます。今回は以下の設定でデプロイしました。
- Dockerレジストリはマスターノード
k8s-m1
に配置する。- 永続化が必要なファイルは、マスターノードのストレージに格納する。
- Dockerイメージは
registry:2.7
を使用する。- ホストネットワークを利用し、
5000/tcp
で待ち受けする。使用した定義ファイルは以下の通りです。
docker-registry.yamlapiVersion: apps/v1 kind: Deployment metadata: name: docker-registry labels: app: docker-registry spec: replicas: 1 selector: matchLabels: app: docker-registry template: metadata: labels: app: docker-registry spec: hostNetwork: true tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule nodeSelector: kubernetes.io/hostname: k8s-m1 containers: - name: docker-registry image: registry:2.7 ports: - containerPort: 5000 volumeMounts: - name: registry mountPath: /var/lib/registry volumes: - name: registry hostPath: type: Directory path: /var/lib/registry定義ファイルの適用、
curl
による簡易的な動作確認の手順は以下の通りです。ubuntu@k8s-m1:~$ kubectl apply -f docker-registry.yaml ubuntu@k8s-m1:~$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES docker-registry-5c5cb844f-h7mzb 1/1 Running 0 4m34s 192.168.1.211 k8s-m1 <none> <none> nginx-munin-7kvf8 1/1 Running 12 23d 10.244.3.14 k8s-n3 <none> <none> nginx-munin-8f88x 1/1 Running 7 23d 10.244.1.9 k8s-n1 <none> <none> nginx-munin-jw4jd 1/1 Running 5 23d 10.244.0.18 k8s-m1 <none> <none> nginx-munin-m8flt 1/1 Running 5 23d 10.244.2.8 k8s-n2 <none> <none> ubuntu@k8s-m1:~$ curl -v http://localhost:5000/ * Trying 127.0.0.1:5000... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 5000 (#0) > GET / HTTP/1.1 > Host: localhost:5000 > User-Agent: curl/7.65.3 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Cache-Control: no-cache < Date: Mon, 09 Mar 2020 07:45:47 GMT < Content-Length: 0 < * Connection #0 to host localhost left intact4. 動作確認
Dockerデーモンは、デフォルトではTLS接続(暗号化あり)のDockerレジストリのみ使用できます。
今回構築したDockerレジストリは非TLS接続(暗号化なし)を用いるため、Dockerデーモンの設定を変更する必要があります。
具体的には、設定ファイル/etc/docker/daemon.json
のinsecure-registries
キーにホスト名、ポート番号を記載する必要があります。
設定ファイルを変更し、Dockerデーモンの再読み込み(再起動は不要)を行うことで、非TLS接続のDockerレジストリに接続できるようになります。なお、この設定はすべてのノードで行う必要があります。ubuntu@k8s-m1:~$ sudo vim /etc/docker/daemon.json ubuntu@k8s-m1:~$ cat /etc/docker/daemon.json { "insecure-registries": ["k8s-m1.local:5000"] } ubuntu@k8s-m1:~$ sudo systemctl reload docker動作確認の第1ステップとして、マスターノード(
k8s-m1
)にてDocker Hubからhello-worldイメージを取得(docker pull
)し、構築したDockerレジストリに転送(docker push
)してみました。
マスターノードの/var/lib/registry
以下に、転送されたDockerイメージが格納されているのが確認できます。ubuntu@k8s-m1:~$ docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world 256ab8fe8778: Pull complete Digest: sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752 Status: Downloaded newer image for hello-world:latest docker.io/library/hello-world:latest ubuntu@k8s-m1:~$ docker tag hello-world k8s-m1.local:5000/hello-world ubuntu@k8s-m1:~$ docker push k8s-m1.local:5000/hello-world The push refers to repository [k8s-m1.local:5000/hello-world] 167d9097a0a0: Pushed latest: digest: sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343 size: 525 ubuntu@k8s-m1:~$ ls -l /var/lib/registry/ total 4 drwxr-xr-x 3 root root 4096 Mar 9 16:53 docker続いて、ワーカーノードの1つ(
k8s-n1
)で、構築したDockerレジストリからDockerイメージを取得してみました。ubuntu@k8s-n1:~$ sudo vim /etc/docker/daemon.json ubuntu@k8s-n1:~$ sudo systemctl reload docker ubuntu@k8s-n1:~$ docker pull k8s-m1.local:5000/hello-world Using default tag: latest latest: Pulling from hello-world 256ab8fe8778: Pull complete Digest: sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343 Status: Downloaded newer image for k8s-m1.local:5000/hello-world:latest k8s-m1.local:5000/hello-world:latest
docker push
、docker pull
ともに正常に動作することが確認できました。なお、認証は行っていないのでdocker login
は不要です。以上、Dockerレジストリ編でした。
また余裕があれば、他の記事(電源編、ファン編、ケース編)なども書きたいと思います。
- 投稿日:2020-03-16T20:07:30+09:00
RaspberryPi4(Raspbian 10 buster)にdockerインストールでハマったのでメモ
背景
RaspberryPi4にflask(Python用Webフレームワーク)を構築するためdockerを入れようとしたところハマったのでメモ。
結論
- systemdの設定ファイルを変更する
- iptables-nfsをやめてiptables-legacy(従来のiptables)を使用する
まとめたコマンド↓
$ sudo apt install docker.io $ sudo sed --in-place=~ 's/fd:\/\//unix:\/\/\/var\/run\/docker.sock/' /lib/systemd/system/docker.service $ sudo update-alternatives --set iphtables /usr/sbin/iptables-legacy $ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy $ sudo systemctl daemon-reload $ sudo systemctl restart docker過程
aptでインストールするも進捗33%でコケる。
$ sudo apt install docker.ioいろいろ環境をいじって(どのようにかは忘れた)もNG。
$ sudo apt install docker.io ... Running kernel seems to be up-to-date. Failed to check for processor microcode upgrades. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries.デーモンを手動で起動して怒られたのでログを見る
$ sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details. $ journalctl -xe ... -- The job identifier is 1439. 3月 16 14:15:18 raspberrypi systemd[1]: docker.service: Start request repeated too quickly. 3月 16 14:15:18 raspberrypi systemd[1]: docker.service: Failed with result 'exit-code'. -- Subject: Unit failed -- Defined-By: systemd -- Support: https://www.debian.org/support -- -- The unit docker.service has entered the 'failed' state with result 'exit-code'. 3月 16 14:15:18 raspberrypi systemd[1]: Failed to start Docker Application Container Engine. -- Subject: A start job for unit docker.service has failed ...よく分かんないのでsystemdの設定ファイルを確認しつつこんな記事を発見。
14行目をコメントアウト、15行目を追加して設定のリロード。(まだデーモンは起動しない)
参考記事1$ vim /lib/systemd/system/docker.service ... 8 [Service] 9 Type=notify 10 # the default is not to use systemd for cgroups because the delegate issues still 11 # exists and systemd currently does not support the cgroup feature set required 12 # for containers run by docker 13 EnvironmentFile=-/etc/default/docker 14 #ExecStart=/usr/sbin/dockerd -H fd:// $DOCKER_OPTS 15 ExecStart=/usr/sbin/dockerd -H unix:///var/run/docker.sock $DOCKER_OPTS ... $ sudo systemctl daemon-reload手動で確認。めっちゃ進んだが、まだエラー。
iptablesでエラーが出てるっぽいので、手動でiptablesのみを起動。
ん?なんか動かん。iptables変わってる?
参考記事2
このお方が絡んでるのであんまり昔のiptablesに変えたくないけど。。。
変えたくない理由$ sudo /usr/sbin/dockerd -H unix:///var/run/docker.sock ... INFO[2020-03-16T14:50:38.947663447+09:00] Loading containers: start. INFO[2020-03-16T14:50:39.335799251+09:00] stopping event stream following graceful shutdown error="<nil>" module=libcontainerd namespace=moby INFO[2020-03-16T14:50:39.336934234+09:00] stopping healthcheck following graceful shutdown module=libcontainerd INFO[2020-03-16T14:50:39.337271358+09:00] stopping event stream following graceful shutdown error="context canceled" module=libcontainerd namespace=plugins.moby INFO[2020-03-16T14:50:39.337955589+09:00] pickfirstBalancer: HandleSubConnStateChange: 0x492c070, TRANSIENT_FAILURE module=grpc INFO[2020-03-16T14:50:39.338036439+09:00] pickfirstBalancer: HandleSubConnStateChange: 0x492c070, CONNECTING module=grpc Error starting daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables: Operation not supported. (exit status 1) $ sudo iptables -t nat -N DOCKER iptables: Operation not supported. $ sudo iptables --list iptables: Operation not supported. $ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy $ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacyやっと動いた。
$ sudo systemctl restart docker $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 投稿日:2020-03-16T20:00:21+09:00
Docker + VSCodeでGoの環境構築(ホットリロード対応)
はじめに
個人開発で最近Go言語を使う機会が増えてきました。
Go言語で開発するにあたり私が感じたことは、
- Dockerで動かしたい
- ホットリロード機能が欲しい
- 開発用・本番用でコンテナを分けたい
- 開発時は、VSCode上でコンテナ内とリモート接続して作業したい
色々な方々のDocker環境を参考にDockerでGo環境を作りました。
よろしければ参考にしてください。ホスト環境
- Docker: ver.19.03.8
- docker-compose: ver.1.25.4
- VSCode: ver.1.43.0
ホットリロード
Go言語でホットリロードをする際、調べていたら、
- fresh
- realize
があるのを知りました。
しかし、筆者はrealize の方はエラー(error: returned a non-zero code: 1
)が発生してgo get
ができませんでした。一度コンテナを立ち上げて、コンテナ内で
go get
したらうまく行くのですが解決出来ませんでした...ですので今回はfresh を使用します。
手順
- Dockerfile(開発用&本番用) + docker-compose.yml の作成
- Remote Containers の設定
- ホットリロードの設定
- 開発環境の起動
- 開発環境の動作確認
- 本番環境の起動
開発環境
はじめに作業ディレクトリを作ります。
/# 作業ディレクトリ作成 $ mkdir go-work # 作業ディレクトリへ移動 $ cd go-work1. Dockerfile(開発用&本番用) + docker-compose.yml の作成
続いてDockerfile とdocker-compose.yml を書いていきます。
下記コマンドからファイルを作成してください。/go-work$ touch docker-compose.yml $ mkdir -p docker/golang $ touch docker/golang/Dockerfile.dev $ touch docker/golang/Dockerfile.dep※ Dockerfileの言語サポート
Dockerfile.dev(.dep) はVSCodeの標準では言語サポートされていないので設定を追加します。
設定されている方は次へ飛ばしてください。
- [Code] -> [基本設定] -> [設定]
Files: Associations
で検索settings.json
で編集settings.json{ "files.associations": { "Dockerfile.dev": "dockerfile", "Dockerfile.dep": "dockerfile" } }Docker + docker-composeの設定
- 開発用Dockerfile
/go-work/docker/golang/Dockerfile.devFROM golang:1.14.0-alpine3.11 SHELL ["/bin/ash", "-c"] WORKDIR /go/src/app COPY ./app ./ EXPOSE 8080 ENV GO111MODULE=on RUN apk add --no-cache alpine-sdk # Golang ホットリロード(freshのインストール) RUN go get github.com/pilu/fresh # Golang 環境構築(任意) RUN go get github.com/go-delve/delve/cmd/dlv \ github.com/rogpeppe/godef \ golang.org/x/tools/cmd/goimports \ golang.org/x/tools/cmd/gorename \ sourcegraph.com/sqs/goreturns \ github.com/ramya-rao-a/go-outline \ golang.org/x/tools/gopls@latest
- 本番用Dockerfile
/go-work/docker/golang/Dockerfile.depFROM golang:1.14.0-alpine3.11 as builder WORKDIR /go/src/app COPY ./app ./ ENV GO111MODULE=on RUN go mod download RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/app FROM alpine:latest RUN apk --no-cache add ca-certificates COPY --from=builder /go/bin/app /go/bin/app ENTRYPOINT [ "/go/bin/app" ] EXPOSE 8080
- docker-compose
/go-work/docker-compose.ymlversion: '3.7' services: app: container_name: go-app build: context: . # Remote Containerが立ち上がるまで待機 dockerfile: docker/golang/Dockerfile.dev ports: - 8080:8080 volumes: - ./app:/go/src/app:cached command: /bin/ash -c "while sleep 1000; do :; done"2. Remote Containers の設定
インストール
インストールしていない方は、 Remote-Containers からインストールしてください。
準備
まずはじめにVSCode の左下のアイコンをクリックしてください。
すると、コマンドパレッドが開きますので、
Remote-Containers: Add Development Container Configuration Files...
と検索して選択してください。選択したら、
From 'docker-compose.yml'
を選択してください。選択後
.devcontainer
ディレクトリが作成され、設定ファイルが格納されています。設定
.devcontainer ├── devcontainer.json └── docker-compose.ymlまずはじめに、docker-compose.yml はもう作成してあるので、
.devcontainer 内のdocker-compose.yml は削除してください。下記のコマンドを実行してファイルを削除してください。
/go-work$ rm .devcontainer/docker-compose.yml次にdevcontainer.json を編集します。
/go-work/.devcontainer/devcontainer.json{ "name": "go", "dockerComposeFile": [ "../docker-compose.yml" ], "service": "app", "workspaceFolder": "/go/src/app", "settings": { "terminal.integrated.shell.linux": "/bin/ash", "go.gopath": "/go" }, "extensions": [ "ms-vscode.go", ], "shutdownAction": "stopCompose" }3. ホットリロードの設定
準備
まずはGoアプリを開発する作業ディレクトリを作成します。
その後ホットリロードを行うためのfresh の設定ファイルを作成します。ちなみに設定ファイルを作成しなくても大丈夫ですのでこちらは任意で!
下記のコマンドを実行してください。
/go-work$ mkdir app $ cd app # /go-work/app $ touch .fresh.conf設定
/go-work/app/.fresh.confroot: . tmp_path: ./tmp build_name: runner-build build_log: runner-build-errors.log valid_ext: .go, .tpl, .tmpl, .html no_rebuild_ext: .tpl, .tmpl, .html ignored: assets, tmp build_delay: 600 colors: 1 log_color_main: cyan log_color_build: yellow log_color_runner: green log_color_watcher: magenta log_color_app:上記の設定はテンプレートから持ってきています。
細かい設定は任意で!4. 開発環境の起動
さて、いよいよコンテナを起動します。
VSCode から左下のアイコンをクリックしてください。すると、コマンドパレッドが開きますので、
Remote-Containers: Reopen in Container
を検索して選択してください。すると、画面が切り替わります。
この時点でDockerイメージが作成され、コンテナが自動で起動します。
起動するまでしばらく時間がかかりますので待機...しばらくするとコンテナとリモートで繋がり作業ディレクトリに移ります。
VSCode の左下のアイコンも変わっているはずです。
VSCode 上でターミナルを開くと、コンテナ内のターミナルに切り替わっています。コンテナ内/go/src/app #
5. 開発環境の動作確認
ここからはコンテナ内で作業していきます。
ホットリロードの動作を確認するためにGo のプログラムを開発していきます。main.go の作成
開発するためのファイルを作成します。
/go/src/apptouch main.go go mod init main
つづいてmain.go に簡単なWebサーバを作成します。
/go/src/app/main.go// ...省略 func init() { http.HandleFunc("/", index) } func index(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello World") } func main() { fmt.Print("Server Start") if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) } }実行
main.go を実行するのですが今回はfresh を使って実行します。
VSCode 内のコンテナで実行しても良いのですが、こちらは開発時で利用したいので今回は別ターミナルで実行します。別ターミナルでコンテナ内に入り、ホットリロードを起動させます。
別ターミナル$ docker exec -it go-app /bin/ash # コンテナ内: /go/src/app fresh -c .fresh.confmain.go が実行されますので確認作業に移ります。
確認
確認は、ブラウザ または、ターミナル で確認します。
- ブラウザの場合は、http://localhost:8080 にアクセス
- ターミナルの場合は、
curl http://localhost:8080
を実行
Hello World
が返ってくれば起動しています。変更
つづいてホットリロードが正常に起動しているかを確認したいので、
fresh を起動したままVSCode に戻ってください。VSCode上でmain.go を変更し、保存してください。
/go/src/app/main.gofunc index(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "Hello World") + fmt.Fprint(w, "Hello Golang") }保存したら再度、確認作業を行ってください。
Hello Golang
が返ってくればホットリロードは正常に起動しています。6. 本番環境の起動
本番環境はDockerをビルドして実行すれば良いだけです。
イメージのビルド
/go-work$ docker build -t go-app -f ./docker/golang/Dockerfile.dep .コンテナの実行
/go-work$ docker run --name go-app go-app -p 8080:8080 -d . /bin/ash
- 投稿日:2020-03-16T18:20:37+09:00
Dockerコンテナへローカルファイルのダンプをコピーしてリストアする
私自身の覚えが良くないのもあり、何度も複数コマンドをググって辛みだったため、備忘録として。
まだエンジニアとして8ヶ月ですので、何かミスなどあればマサカリいただければと。1. ローカルファイルディレクトリへ移動
cd your/local/dump
2. (docker起動中で)dockerのデータベースコンテナのIDを調べる
コンテナIDは 「23fd80dl」のような文字列です。
docker ps3. ローカルからコンテナへコピーする
docker cp ローカルダンプファイル コンテナ名:/ダンプファイル名
例えばこんな感じ
docker cp qiita.20200316.dump コンテナ名:/tmp/qiita.20200316.dump
4. 起動中のデータベースコンテナに入る
docker-composeを利用していて、かつ、bashの場合(docker-compose.yml直下で)
docker-compose exec データベースサービス名 bash
5. ダンプファイルをcpしたディレクトリへ移動
3.で /tmpへコピーしたので移動
cd tmp
6. ダンプする
lsしたら、dockerコンテナへコピーしたダンプファイルが直下に見えることを確認してください。
mysql -u ユーザー名 -pパスワード -D データベース名 < ダンプファイル名以上です〜
- 投稿日:2020-03-16T17:53:35+09:00
使ったことがないDockerを使う気にさせる使用事例
はじめに
Dockerを学ぶ場合、会社のプロジェクトで使うから勉強する事になるパターンと
よく使われていることから使ってみたい!という2パターンに分けられると思います(自分は後者でした)勉強した際いまいちどう使えばいいのかわからず、業務で使って理解した部分が色々あったので
便利だなと思ったユースケースと利点についてまとめました。
読んで使ってみたいと思う人が一人でも増えればいいと思います。個人開発で使用する
PC内にDockerでlinuxの開発環境を作る(Win or Mac)
メリット
・母艦PCと言語バージョンが違う開発がパッケージ切り替え無しで実施できる
DockerでLinux環境を作成し、その中に言語パッケージ等を入れて開発環境を構築します。
本質は「どこから接続しても同条件で開発できる環境をDockerイメージとしてパッケージ化できる」点です。
イメージさえあれば別PCを購入してもDockerさえ導入すれば同じ環境がすぐ構築でき、
AWS等のクラウド上でコンテナを立てればSSH接続するだけですぐ開発に取り掛かることができます。
※Linuxを含んだDockerコンテナを作る・実質linux内で開発しているためデプロイする場合のOS差異がなく、コンテナ作成から公開が簡単にできる。
上とほぼ似ていますが、linux内での開発になるのでそのままdockerfileを記述しイメージを作成、
ECR、GCR等のコンテナ用クラウドにアップすることですぐに開発したコンテナを公開できます。
自分の環境で開発した物をEC2等にデプロイする場合と比べて環境差異が生まれる可能性が少なく便利です。会社のプロジェクトで使用する
開発環境として使用する
コンテナを用いて複数人の環境をすぐに作成できる
Dockerイメージをpushするインスタンスを変更するだけで複数環境を簡単に作成することができます。
開発環境の配布も可能なためプロジェクトインが簡単にできたり、テスト用のインスタンス生成等にも
柔軟に対応が可能です。スタートアップ時にはいろいろなモジュールを変更して試してみることも多いため、
変更しない部分(メインロジック等)を1個のDockerイメージにして変更がある部分のみを別イメージとして
docker-composeの記述で環境を試し、必要ないコンテナはすぐ廃棄することで作業効率が向上します。
(ローカルで同様の事をする場合、パッケージの削除・エラー解消などが必要となり膨大な作業が発生します)本番運用のために使用する
スケーリングが容易なため、サービスの規模に応じてベストな運用ができる
ソーシャルゲームなどではイベントがあるとアクセスが多くなったり、夜間のアクセスが減少することから
スケーリング不可なシステムだとリソースの無駄やアクセス過多によるサーバー落ちの可能性があります。
Dockerを使用することによりコンテナ単位でのスケールアウト・スケールインが可能なため、
アクセスに応じた構成をフレキシブルに適応しながら運用することができます。
サービス運用の潤滑化・高速化
開発に関わる作業(テスト・デプロイ・スケーリング等)が楽になることからプロダクトそのものに集中でき、
技術面だけではなく企画時間~作業時間など全体の時間削減に繋がります。
※うまく説明ができるメンバーがいる前提であれば、テストメンバーを増やす際も環境構築が即時可能で
開発メンバーのスケーリングが容易にできるのはすごくメリットに感じました。Dockerに関する気になること
別に使わなくても開発はできる・採用企業にジョインする難しさ
そもそもDockerが使用されるまでの運用法が間違っているわけでもないので、新規に導入する時間を考えると
案件を1件でも多く受注し、同じ開発を続けることも企業にとっては一つの選択だと思います。
2019年の記事では国内でDockerコンテナを本番利用している企業は9.2%という話もあり、該当企業に参加し
その案件に参画するまでもいくつかの壁が存在します。0からの勉強コストが高い
経験のあるメンバーがいない場合、7人のメンバーが1日でDockerを学んでも1人週の工数がかかります。
どんな新しい技術でも調査時間は必要ですが、前述の「使用しなくても開発は進められる」ということもあり
この時間を「必要」と捉えるか・チームで何人Docke経験があるかで導入のハードルが変化します。採用事例・知見の問題
特に運用フェーズでの採用率の低さはナレッジが全然なかったことが大きい気がします。
最近はAWSのイベントでも有名企業Docker採用事例のプレゼンテーションがあったり、
企業が開催しているLT記事でも便利だなーと思う事例を見つけたりします。
後追いで採用する上では参考にできるユースケースも増えており選択肢としては非常に魅力的だと思います。
便利とは言っても決して銀の弾丸ではないので、他技術と比べ有利かを考えながら採用する必要があります。まとめ
メリット
・環境差異を最小限に抑えることができストレスが少なく開発・運用することができる
・使い方によってあらゆるフェーズで使えるため、トータルの時間が削減できる
・採用企業の面接を受ける時、Docker運用について受け答えができるとウケが良いデメリット
・ある程度勉強時間が必要なので継続的に使用していくつもりがないならメリットが薄い
・採用チームに参加できるか、あるいは導入を認めてもらえるかは企業次第参考
個人開発
★Dockerで開発環境構築を10倍楽にしたはなし
VS CodeのRemote Containersを使ってコンテナ内で開発する
★VSCode の Remote - Containers 拡張を試してみた運用・スケーリング関連
★【AWS】Auto Scalingする前に知っておくべき7つのこと
ロマサガRSで大規模負荷を処理する Amazon ECS & Docker運用知見
スケールアウトの基礎的な考え方
★2018年なぜ私達はコンテナ/Dockerを使うのか
★Mastodon・Netflixに見る、コンテナの未来 コンテナはサービス開発の主流になり得るか?※★は参考にした以上に個人的に面白かった記事です
- 投稿日:2020-03-16T15:39:23+09:00
1行追加のみ! Net::HTTPで発生するcertificate verify failedを回避
外部APIを叩くのに、Docker使っていたらエラーが発生
SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain)
原因を調べるのに疲れた。
ローカル環境のみで発生するので真面目に対応するのも面倒。
本番はDocker使ってないし。
楽できる方法、探した。解決策1
config/initailizersのファイルに以下を追記する。
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE if Rails.env.development?参照:Rails5 devise twitterソーシャルログイン ローカル環境でのエラー解消
ただ、これだと、
・サーバー再起動が必要
・ローカル環境のログでalready initialized constant OpenSSL::SSL::VERIFY_PEER
的な警告がうざい
というデメリットがある。もっと楽、したい。
テキトーに生きたい。解決策2
def api(url) uri = URI.parse(url) req = Net::HTTP::Get.new(uri) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.scheme == 'https') http.verify_mode = OpenSSL::SSL::VERIFY_NONE # これ追加。 res = http.start { |h| h.request(req) } JSON.parse(res.body) end1行追加で動いた。
テキトーにif分岐追加しても1行で済む。
- 投稿日:2020-03-16T15:21:11+09:00
Laradockをやる時にコンテナがdocker-composeでもなかなか立ち上がってくれなかった話
Laradockを使っての環境構築にチャレンジしてみました。
Windows10 homeを使っているので、Docker for Desktopは使えず、
かつInsider Previewには切り替えたくないなと思いましたので、
Docker Toolboxをインストール!https://docs.docker.com/toolbox/toolbox_install_windows/
こちらリンクですが、入ってみても分かる通り、非常にわかりにくいUIですが頑張ってインストールしましょう。
その際に、gitとvirtual boxがインストールしますかと選択肢がでますが、
すでにインストールしている人はダブルと不具合になるのでチェックは外しておきましょう。インストール完了するとDocker Quickstart Terminalgが使えるのでクリックして起動。
初回はけっこう時間がかかります。
終了したら、おなじみのクジラのAAとIPアドレスが採番されて完了です。実際にVirtual Boxを開いてみてみると、「default」というボックスが立ち上がっているのが見てわかります。
その後、任意のターミナル(せっかく開いているのでDocker Quickstart Terminalでよいかと)で
$ docker --versionと入力するとバージョンが返ってきたらインストール完了です。
続いて任意のディレクトリ(僕はいつもCフォルダ直下に作っています)で
/c$ mkdir docker-workspaceと打って作業用フォルダを作りましょう。
/c$ cd docker-workspaceでそこに移動して、Laradockをインストールします。
docker-workspace$ git clone https://github.com/Laradock/laradock.git $ ls > laradock $ cd laradock次にenvファイルの名前を書き換えます。
laradock$ cp env-example .envここまでできたら、いよいよコンテナを立ち上げていきます。
laradock$ docker-compose up -d nginx mysql phpmyadmin workspaceこちらもプロセスにかなりの時間が初回はかかります。
そして、ほとんどの方は問題なく終了するかと思いますが、
私の場合は、こんなエラーがでてきました。Starting phpmyadmin ... error ERROR: for phpmyadmin Cannot start service phpmyadmin: driver failed programming external coStarting phpmyadmin ... error 006): Bind for 0.0.0.0:8080 failed: port is already allocated ERROR: for workspaceCannot start service workspace: driver failed programming external connectivity on endpoint workspace(xxxxxxxxx): Bind for 0.0.0.0:8080 failed: port is already allocatedどうやら、ポートが被っている??
一旦、再起動してみたり、コンテナを削除して作り直しても無駄なうえ、
lsofコマンドができず、起動しているファイルをkillすることもできなかったので、
.envファイルを編集することにしました。.env### WORKSPACE ############################################# WORKSPACE_COMPOSER_GLOBAL_INSTALL=true WORKSPACE_COMPOSER_AUTH=false WORKSPACE_COMPOSER_REPO_PACKAGIST= WORKSPACE_NVM_NODEJS_ORG_MIRROR= WORKSPACE_INSTALL_NODE=true WORKSPACE_NODE_VERSION=node WORKSPACE_NPM_REGISTRY= WORKSPACE_INSTALL_YARN=true WORKSPACE_YARN_VERSION=latest WORKSPACE_INSTALL_NPM_GULP=true WORKSPACE_INSTALL_NPM_BOWER=false WORKSPACE_INSTALL_NPM_VUE_CLI=true WORKSPACE_INSTALL_NPM_ANGULAR_CLI=false WORKSPACE_INSTALL_PHPREDIS=true WORKSPACE_INSTALL_WORKSPACE_SSH=false WORKSPACE_INSTALL_SUBVERSION=false WORKSPACE_INSTALL_BZ2=false WORKSPACE_INSTALL_GMP=false WORKSPACE_INSTALL_XDEBUG=false WORKSPACE_INSTALL_PCOV=false WORKSPACE_INSTALL_PHPDBG=false WORKSPACE_INSTALL_SSH2=false WORKSPACE_INSTALL_LDAP=false WORKSPACE_INSTALL_SOAP=false WORKSPACE_INSTALL_XSL=false WORKSPACE_INSTALL_SMB=false WORKSPACE_INSTALL_IMAP=false WORKSPACE_INSTALL_MONGO=false WORKSPACE_INSTALL_AMQP=false WORKSPACE_INSTALL_CASSANDRA=false WORKSPACE_INSTALL_GEARMAN=false WORKSPACE_INSTALL_MSSQL=false WORKSPACE_INSTALL_DRUSH=false WORKSPACE_DRUSH_VERSION=8.1.17 WORKSPACE_INSTALL_DRUPAL_CONSOLE=false WORKSPACE_INSTALL_WP_CLI=false WORKSPACE_INSTALL_AEROSPIKE=false WORKSPACE_INSTALL_OCI8=false WORKSPACE_INSTALL_V8JS=false WORKSPACE_INSTALL_LARAVEL_ENVOY=false WORKSPACE_INSTALL_LARAVEL_INSTALLER=false WORKSPACE_INSTALL_DEPLOYER=false WORKSPACE_INSTALL_PRESTISSIMO=false WORKSPACE_INSTALL_LINUXBREW=false WORKSPACE_INSTALL_MC=false WORKSPACE_INSTALL_SYMFONY=false WORKSPACE_INSTALL_PYTHON=false WORKSPACE_INSTALL_POWERLINE=false WORKSPACE_INSTALL_SUPERVISOR=false WORKSPACE_INSTALL_IMAGE_OPTIMIZERS=false WORKSPACE_INSTALL_IMAGEMAGICK=false WORKSPACE_INSTALL_TERRAFORM=false WORKSPACE_INSTALL_DUSK_DEPS=false WORKSPACE_INSTALL_PG_CLIENT=false WORKSPACE_INSTALL_PHALCON=false WORKSPACE_INSTALL_SWOOLE=false WORKSPACE_INSTALL_TAINT=false WORKSPACE_INSTALL_LIBPNG=false WORKSPACE_INSTALL_IONCUBE=false WORKSPACE_INSTALL_MYSQL_CLIENT=false WORKSPACE_INSTALL_PING=false WORKSPACE_INSTALL_SSHPASS=false WORKSPACE_INSTALL_INOTIFY=false WORKSPACE_INSTALL_FSWATCH=false WORKSPACE_INSTALL_YAML=false WORKSPACE_INSTALL_MAILPARSE=false WORKSPACE_PUID=1000 WORKSPACE_PGID=1000 WORKSPACE_CHROME_DRIVER_VERSION=2.42 WORKSPACE_TIMEZONE=UTC WORKSPACE_SSH_PORT=2222 WORKSPACE_INSTALL_FFMPEG=false WORKSPACE_INSTALL_WKHTMLTOPDF=false WORKSPACE_INSTALL_GNU_PARALLEL=false WORKSPACE_INSTALL_AST=true WORKSPACE_AST_VERSION=1.0.3 WORKSPACE_VUE_CLI_SERVE_HOST_PORT=8008 #ここ、8080になってたので適当な番号に書き換えました! WORKSPACE_VUE_CLI_UI_HOST_PORT=8001 WORKSPACE_INSTALL_GIT_PROMPT=falseこれでコマンドをやり直したらできました!!
docker-compose upとだけやってしまうと、容量不足になってしまい、
ERROR: Service 'web' failed to build: failed to copy files: failed to copy directory: Error processing tar file(exit status 1): open /node_modules/hosted-git-info/CHANGELOG.md: no space left on deviceみたいな感じでエラーになってしまうので、立ち上げるコンテナを-dで指定しましょう。
立ち上げた後は、laradock$ docker-compose exec workspace bashと打ってワークスペースに接続します。ディレクトリがroot@var/wwwみたいな感じに変わったら成功。いつもやるようにプロジェクトをコマンドを打って作りましょう。
laradock$ composer create-project --prefer-dist laravel/laravel #アプリ名またこれで少しの間完了するまで放置します。
root@var/www$ ls >laradock #アプリ名できたらexitで接続を終了します。
laradock$ cd nginx/sites/最後にnginxの設定ファイルを編集します。
laradock/nginx/sites$ cp default.conf default.conf.backup $ cp laravel.conf.example default.conf $ vim default.confdefalut.confserver { listen 80; listen [::]:80; # For https # listen 443 ssl; # listen [::]:443 ssl ipv6only=on; # ssl_certificate /etc/nginx/ssl/default.crt; # ssl_certificate_key /etc/nginx/ssl/default.key; server_name laravel.test; root /var/www/laravel/#ここにアプリ名を入れる!/public; index index.php index.html index.htm;laradockに戻って $docker-compose restartをして、
Docker Quickstart Terminal起動時に出るIPアドレスをブラウザで入力すると、
Laravelトップページがでます。これで、環境構築は完了です!
- 投稿日:2020-03-16T14:04:48+09:00
フロント・バックエンドサービスをコンテナ化してもGitコミット時にLefthookでテストやLint実行
TL;DR
- フロント・バックエンドサービスをそれぞれコンテナ化、docker-composeで全てのコンテナを管理する
- monorepoで管理した際に1リポジトリとなるので気軽にGit Hookの処理ができない
- Lefthookを導入してpre-commit時にすべてのコンテナに対してLintツールを動作させるようにした
サンプルコード
https://github.com/MegaBlackLabel/lefthook-docker-node-go-dev-sample
1リポジトリで開発環境を管理したい
渋川さんの記事
マイクロサービスほどじゃないけどウェブサービスを分割開発したい人向けDocker設定を集めるスレ
https://qiita.com/shibukawa/items/fd49f98736045789ffc3を読んでフロントエンドとAPIがごっちゃになっている開発環境ヨクナイ!ってことでサービス単位でコンテナ化してvs codeのリモートコンテナ機能を使って開発環境を再構築をしていたらGitとGItHooksの扱いで躓く。
Git Hooksの扱い
1リポジトリでサービスをコンテナ化してmonorepoを構築した際に.gitはルートディレクトリのみに存在する。
何が起こるかというと、フロントエンド開発時に「Husky+lint-stagedでコミット前にeslintやprettierを実行してコミット前にソースをチェックする」ができなくなります。これは治安が悪くなるってことで調査を進めた結果、試してみたのがLefthookです。Lefthookを使ってみる
Lefthookとは?ということで公式の説明を引用
The fastest polyglot Git hooks manager out there
Fast and powerful Git hooks manager for Node.js, Ruby or any other type of projects.
- Fast. It is written in Go. Can run commands in parallel.
- Powerful. With a few lines in the config you can check only the changed files on pre-push hook.
- Simple. It is single dependency-free binary which can work in any environment.
- GO製。コマンドを並列実行できる
- かんたんな設定ファイルでpre-pushのhookが使えるようになる
- (GOによる)シングルバイナリなので、どのOSでも実行可能
今回は以下のことを実装しました。
- 起動時にdocker-composeでインスタンス起動
- 起動したインスタンスに対してコマンドを実施
- 更新対象のファイルの拡張子をgrepして対象の拡張子がstageにあるときのみ実行する
※、余談ですが日本語での紹介記事は2つのみ。1つは公式の翻訳ともう一つはRubyでのHusky置き換え記事です。
Lefthook: 多機能GItフックマネージャ
https://techracho.bpsinc.jp/hachi8833/2019_10_16/79052Git HooksマネージャーのLefthookを試してHusky(+lint-staged)と比較した結果、乗りかえました
https://blog.solunita.net/posts/change-lefthook-instead-of-lintstaged-with-husky/Lefthookインストール
Lefthookインストールですが、公式サイトのInstallationか、リリースページから直接ダウンロードします。自分はWindows環境なのでプロジェクト内にlefthook.exeをそのまま置いて使っています。
インストール後に対象のリポジトリで以下のコマンドを実行lefthook install #Windowsで直下に置いている場合は lefthook.exe installインストールが完了するとリポジトリのルートに「lefthook.yml」が作成されますので、こちらに設定を書きます。
Lefthook設定ファイル解説
lefthook.yml# EXAMPLE USAGE # Refer for explanation to following link: # https://github.com/Arkweid/lefthook/blob/master/docs/full_guide.md # # pre-push: # commands: # packages-audit: # tags: frontend security # run: yarn audit # gems-audit: # tags: backend security # run: bundle audit # # pre-commit: # parallel: true # commands: # eslint: # glob: "*.{js,ts}" # run: yarn eslint {staged_files} # rubocop: # tags: backend style # glob: "*.rb" # exclude: "application.rb|routes.rb" # run: bundle exec rubocop --force-exclusion {all_files} # govet: # tags: backend style # files: git ls-files -m # glob: "*.go" # run: go vet {files} # scripts: # "hello.js": # runner: node # "any.go": # runner: go run pre-commit: piped: true commands: 1_docker-compose: root: . run: docker-compose up -d 2_eslint: root: "containers/frontend/" glob: "*.{js,jsx,ts}" run: docker exec -it frontend-container yarn eslint-check 3_frontend-test: root: "containers/frontend/" glob: "*.{js,jsx,ts}" run: docker exec -it frontend-container yarn test 4_api-test: root: "containers/api/" run: docker exec -it api-container go testサンプルとインデントの数が違うのはご愛嬌。今回使っている処理は以下の通り。
- pre-commit: コミット実施前に実行してほしい処理
- piped:commandsを名前順に実施する。そのため頭文字に数字をつける
- commands:実行するコマンド
- root:どの階層でコマンドを実施するかを記載
- glob:stagedのファイルのうち、コマンド実行対象とするファイルを選別する
- run:実行するコマンド
コマンドの内容ですが以下の処理を実施しています。
- docker-composeでコンテナを起動
- docker execを使用してフロントエンドコンテナでeslint+Prettierを実施
- docker execを使用してフロントエンドコンテナでテストを実施
- docker execを使用してAPIコンテナでテストを実施
フォルダ・ファイル構成
以下の想定でファイル構成を行っています。
- フロントエンドとAPIサーバをそれぞれコンテナ化して管理
- docker-composeでコンテナを一元管理
- フロントエンドではeslint+Prettierでのソース整形とテストを実施
- APIサーバではテストを実施
- それぞれ正常に実行時のみコミットを実施するファイル構成lefthook-docker-node-go-dev-sample │ .gitignore │ docker-compose.yml │ lefthook.exe │ lefthook.yml │ LICENSE │ README.md │ └─containers ├─api │ docker-entrypoint.sh │ Dockerfile │ go.mod │ go.sum │ main.go │ main_test.go │ └─frontend │ .eslintrc.json │ docker-entrypoint.sh │ Dockerfile │ package.json │ README.md │ yarn.lock │ ├─node_modules ├─public │ favicon.ico │ index.html │ logo192.png │ logo512.png │ manifest.json │ robots.txt │ └─src App.css App.js App.test.js index.css index.js logo.svg serviceWorker.js setupTests.jsLefthookでpre-commit時にコンテナに対してコマンド実行
pre-commitをrunしてみる。
実行結果.\lefthook.exe run pre-commit RUNNING HOOKS GROUP: pre-commit EXECUTE > 1_docker-compose api-container is up-to-date frontend-container is up-to-date EXECUTE > 2_eslint yarn run v1.22.4 $ eslint --print-config .eslintrc.json | eslint-config-prettier-check No rules that are unnecessary or conflict with Prettier were found. Done in 0.69s. EXECUTE > 3_frontend-test yarn run v1.22.4 $ CI=true react-scripts test PASS src/App.test.js ✓ renders learn react link (39ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.081s Ran all test suites. Done in 3.23s. EXECUTE > 4_api-test [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /ping --> github.com/MegaBlackLabel/lefthook-docker-node-go-dev-sample.setupRouter.func1 (3 handlers) [GIN] 2020/03/15 - 03:43:28 | 200 | 44.742µs | | GET /ping PASS ok github.com/MegaBlackLabel/lefthook-docker-node-go-dev-sample 0.014s SUMMARY: (done in 7.78 seconds) ✔️ 1_docker-compose ✔️ 2_eslint ✔️ 3_frontend-test ✔️ 4_api-testコマンドが順番に実行されそれぞれの実行結果が表示。最後にサマリーとしてOK・NGが出力されます。
まとめ
- サービス単位でコンテナ化して開発するのは便利だね。でもGit Hooksの処理ができない
- Lefthook使えばできるよ。シングルバイナリだから導入もかんたんだよ
- コンテナ化してもGit Hooksが使えるので複数の開発者がいても治安が維持できそう
以上
- 投稿日:2020-03-16T11:57:41+09:00
Dockerコンテナ上で動くGinサーバーにアクセスできないエラーの解決法
概要
GolangのWebフレームワークであるGinを使ったAPIサーバーを、Dockerコンテナ上にデプロイして動かそうとしたところ、APIにアクセスできずかなり長い時間悩まされました。
結果的には、Ginサーバーのコードの書き方の問題だったことが分かったのですが、解決方法を念のためここにメモしておきます。
ちなみに、このエラーはWindows10及びAWS上のUbuntuサーバー(t2.small)で起こりました(尤も、実行環境はこのエラーの発生にあまり関係ないようでしたが)。
状況
Ginを用いたAPIサーバーを立てようとしていました。まだ環境構築の段階なので、コードは以下のようなモックのものになっています。
package main import ( "log" "os" "github.com/gin-gonic/gin" ) func main() { logConfig() r := gin.Default() r.GET("/accounting-api", func(c *gin.Context) { log.Println("GET") c.JSON(200, gin.H{ "state": "success", }) }) r.DELETE("/accounting-api", func(c *gin.Context) { log.Println("DELETE") c.JSON(200, gin.H{ "state": "success", }) }) log.Println("Start Server") r.Run() } func logConfig() { logFile, _ := os.OpenFile("log/log.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) log.SetOutput(logFile) log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile) log.SetPrefix("[LOG] ") }単純に、
GET
かDELETE
メソッドで特定のパスへのリクエストが来たら、{"state": "success"}
というjsonを返すだけのサーバーです。そして、このサーバーを動かすためのDockerfileが以下です。
FROM golang:alpine RUN apk update && apk add --no-cache git RUN go get -u github.com/gin-gonic/gin && mkdir /usr/src && mkdir /usr/src/api COPY ./api /usr/src/api WORKDIR /usr/src/api CMD ["go","run","main.go"]ホスト上の
api
というディレクトリには上記のGoファイル等があるため、それをコンテナ上にコピーして、サーバーを立ち上げます。このDockerfileをapi
という名前でビルドして、それを以下のコマンドで立ち上げました。docker run -p 8083:8080 api
ホスト上のポート
8083
をコンテナ上のポート8080
にマッピングしています。上記のコマンドを実行すると、以下のような出力がなされ、Ginサーバーが立ち上がっていることが確認できます。[GIN-debug] GET /accounting-api --> main.main.func1 (3 handlers) [GIN-debug] DELETE /accounting-api --> main.main.func4 (3 handlers) [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on localhost:8080ポートを指定しなかったので、デフォルトでポート
8080
で動いています。このように一見ちゃんと動いているようにも見えますが、ホスト側でhttp:localhost:8083
にcurlでアクセスしてみても、以下のようにエラーが出てしまいました。curl: (52) Empty reply from serverエラー解消のため試みたこと
1. コンテナの中に入って、APIにアクセスできるか確認
まず最初に、コンテナ上で本当にGoのプログラムがちゃんと動いているのかを確認します。そのために立ち上げたdockerコンテナの中に入ってみます。
# apiサーバーの動くコンテナの中に入る docker exec -it api /bin/ashこのコンテナのベースとなっているAlpineには
/bin/bash
がなかったので、/bin/ash
を使います。そして以下のコマンドを打って、ちゃんとプログラムが動いているのか確かめます。# そもそもcurlが入っていないので、インストールする apk add --no-cache curl # 念のためプロキシを無効にして、curlでapiサーバーにアクセスする curl -x "" http://localhost:8080/accounting/apicurlの実行結果がこちら。
{"state": "success"}ちゃんと結果が取れています。なので、コンテナ上ではちゃんとGinサーバーのプログラムが動いているようです。
2. DockerfileでポートをEXPOSE
コンテナ上ではプログラムは動いているようなので、次はポートマッピングの部分がうまくいっていないのではないかと疑ってみます。調べてみるとDockerfileには
EXPOSE
というコマンドが書けるようなので、追加してみます。EXPOSE 8080これをやっても、解決しませんでした。
そもそも公式ドキュメントによると、
EXPOSE
コマンドは実際は何の働きもせず、特定のポートを開放する旨を開発者に知らせるための、ドキュメントのような役割しかもっていないようです。なので、EXPOSE
コマンドをつけただけで問題が解決するはずがありませんでした。3. Windowsのファイアウォールの設定の確認
開発は基本的にWindows上のDockerで行っていたため、Windowsのファイアウォールの設定を見直してみましたが、これも意味がありませんでした。
そもそも、このDockerfileをUbuntu上でビルドして立ち上げてみても、同様にAPIサーバーにアクセスできなかったため、最初からなんとなくWindowsのファイアウォールのせいではないことが分かっていましたが。
4. (これで解決)Ginサーバー側でポートの指定
Goのプログラムの中で、GInサーバーを立ち上げる部分でポートを指定するようにしたところ、上手くアクセスできるようになりました。具体的には、以下の部分です。
r := gin.Default() r.Run(":8080")何も指定しなくてもデフォルトで
8080
で立ち上がるため気にしていなかったのですが、しっかりと指定しないとどうやらダメなようです。なぜポートはデフォルトではダメで、明示的に記さなければならないかは、よくわかりません。分かったら追記します。
- 投稿日:2020-03-16T11:32:40+09:00
Laravelの開発環境をDockerで構築したらcould not find driver
Laravelの開発環境をDockerで構築しようとしてハマったのでメモを残しておきます。
Laravelの開発環境をDockerで構築する方法は以下を参照してください。
Dockerを使って1コマンドで起動できるLaravel開発環境を構築する以下のようにDockerfileを作成しました。
DockerfileFROM php:7.3-apache COPY --from=composer /usr/bin/composer /usr/bin/composer RUN apt-get update && apt-get install -y \ unzip \ libzip-dev \ zlib1g-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && a2enmod rewrite COPY ./apache2.conf /etc/apache2/apache2.conf COPY ./php.ini /usr/local/etc/php/php.ini WORKDIR /var/www/myappコンテナを起動してアクセスしてみると、PDOExceptionでcould not find driverが出力されました。
MySQLのPDOドライバが有効になってなかったかと思って、php.iniのexentionのコメントを外すもエラー消えず。そもそもインストールされてないっぽいです。
対処法はDocker Hub に答えがありました。======Docker Hub引用=========
PHP Core Extensions
For example, if you want to have a PHP-FPM image with the gd extension, you can inherit the base image that you like, and write your own Dockerfile like this:FROM php:7.4-fpm RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd======Docker Hub引用=========
どうやら
docker-php-ext-install
でいけるようです。最終的にこんな形にして、エラーは解消しました。
FROM php:7.3-apache COPY --from=composer /usr/bin/composer /usr/bin/composer RUN apt-get update && apt-get install -y \ unzip \ libzip-dev \ zlib1g-dev \ && docker-php-ext-install \ zip \ pdo_mysql \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && a2enmod rewrite COPY ./apache2.conf /etc/apache2/apache2.conf COPY ./php.ini /usr/local/etc/php/php.ini WORKDIR /var/www/myapp
- 投稿日:2020-03-16T09:50:03+09:00
Windows10 Pro×VSCode×Dockerでお手軽Pythonデータ分析環境構築
概要
環境構築、嫌いですよね?
私はエラーを出しまくって平気で数日かけてしまうダメ人間なので、発狂するレベルで嫌いです。
弱小ながらも一応エンジニアの私が発狂するような作業を一緒に分析業務を行う非エンジニアにやらせようとしたら、背後から刺されかねない。
というわけで、多少は流用できそうかなというレベルの表題のものを作ったので、備忘録も兼ねて載せます。非エンジニアにVSCode上でJupyter NotebookライクにPythonを書ける環境を提供する
ことを目標としています。
こんな人が読むと良いかも
- お手軽にPython環境を作りたい
- Visual Studio Codeをメインに使いたい
- 環境構築なんぞに労力を割きたくない
- 非エンジニアにも手軽にPythonを使ってデータ分析をしてもらいたい
- できることならマウスポチポチだけしかしたくない(させたくない)
(各ソフトウェアや技術詳細の説明はしていません)
前提環境
OS:Windows 10 Pro 64bit(Docker使用時にHyper-V機能を利用するため)
環境構築
大まかに、以下の流れ。
1. 環境のベースとなるフォルダ構成取得
2. Docker Desktop for Windowsのインストールとセットアップ
3. Visual Studio Codeのインストールとセットアップ
4. 環境作成1. 環境のベースとなるフォルダ構成取得
GitHubにベースに使うフォルダ構成と必要なファイル群を用意したので、こちらをCloneするなりダウンロードするなりして任意のフォルダに配置(私の場合はCドライブ配下にGit用フォルダを作成)
https://github.com/m0p1nt/ds_base_env_for_vscodeお好みで
devcontainer.json
のname属性の値を変更。
2. Docker Desktop for Windowsのインストールとセットアップ
環境構築はすでに他の投稿者さんがわかりやすい記事を書いてくださっているので、大まかな手順のみ(参考サイトは後述の補足にて)。
1) Hyper-Vの有効化
コントロールパネル
->プログラムと機能
->Windows の機能の有効化または無効化
の項目群にあるHyper-v
のチェックをオンにする(再起動を求められたら再起動する)。
2) Docker Desktop for Windowsダウンロードサイトよりインストーラをダウンロードしてインストール
3) ドライブのマウント設定
(1)Widndowsタスクバー右下Dockerアイコンより[Setting]で設定画面を開く(アイコンがない場合はDockerを起動してから再度確認)。
(2)分析環境用のフォルダを配置したドライブに対するマウント許可にチェックを入れる
3. Visual Studio Codeのインストールとセットアップ
1)Visual Studio Codeダウンロードサイトよりインストーラをダウンロードしてインストール
4. 環境作成
1)VSCodeの画面左下の緑色のアイコンをクリックし、
Remote-Containers: Open Folder in Container...
を選択。
上記「1. 環境のベースとなるフォルダ構成取得」で配置したフォルダを選択。
新規画面が立ち上がり環境構築が始まるので数分待つとできあがり。
VSCode上でJupyter Notebookライクな使い方ができるので便利。
閉じるときは、左下の緑色のアイコンをクリックし、
リモート接続を終了する
を選択。
補足
Pythonライブラリを追加したくなったら
→VSCodeのターミナル上でpipコマンドでインストール
他の人にライブラリの追加を反映させたい場合はVSCodeのターミナル上で、
$ pip freeze > .devcontainer/requirements.txt
でインストール済みのライブラリを一覧化できる。VSCodeの拡張機能を追加したくなったら
→devcontainer.json
のextensions属性を編集する
名称は、拡張機能検索時に表示される下図の値が該当。
(例:拡張機能Python
の場合)
参考にしたもの
- 投稿日:2020-03-16T09:35:38+09:00
【Docker】データボリュームをバックアップ→リストア
データが入ったDBがあると仮定して話を進めます。
ボリュームと紐づいているコンテナの名前を確認
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b6a79314721 sample-app_web "/bin/sh -c 'rm -f t…" 5 minutes ago Up 5 minutes 0.0.0.0:3000->3000/tcp sample-app_web_1 2ed21c2aac12 postgres "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:5434->5432/tcp sample-app_db_1
NAMES
を参照。今回の場合はsample-app_db_1
コンテナをストップ
$ docker-compose stopバックアップ
docker run --rm --volumes-from sample-app_db_1 -v `pwd`:/backup busybox tar cvf /backup/backup.tar /var/lib/postgresql/data
Postgresqlの場合の例です。
sample-app_db_1
の部分に、先ほどのステップで確認したコンテナ名を設定
mysplの場合/var/lib/postgresql/data
の部分を/var/lib/mysql
に変更
(mysqlの場合)
$ docker run --rm --volumes-from sample-app_db_1 -v `pwd`:/backup busybox tar cvf /backup/backup.tar /var/lib/mysqlコンテナとボリュームを削除→コンテナを再作成
$ docker-compose down --volumes $ docker-compose up -dコンテナをストップ
$ docker-compose stopリストア
$ docker run --rm --volumes-from sample-app_db_1 -v `pwd`:/backup busybox tar xvf /backup/backup.tar
(mysqlの場合)
同じ$ docker run --rm --volumes-from sample-app_db_1 -v `pwd`:/backup busybox tar xvf /backup/backup.tar最後に
本当はこの方法より、SQLによるダンプでバックアップを取るほうが望ましいらしいです。
まだ検証できていないので、興味がある方はご自身で調べてみてください。
参考
- 投稿日:2020-03-16T09:18:32+09:00
WSL2+docker+PHPのWindows開発環境構築(3) PHPStorm編
本ページに直接来た方はWSL2+docker+PHPのWindows開発環境構築(1) WSL2編から読んでね。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 余談はここから ↓-------------------
関連記事:
- Bash on Ubuntu on Windowsを使う(1)
- Bash on Ubuntu on Windowsを使う(2):初期設定
- Bash on Ubuntu on Windowsを使う(3):WindowsからLinuxを使う
- WSL2+docker+PHPのWindows開発環境構築(1) WSL2編
- WSL2+docker+PHPのWindows開発環境構築(2) docker編
- WSL2+docker+PHPのWindows開発環境構築(3) PHPStorm編 ← イマココ
前回docker起動までいけた。
あとはPHPStormと繋げれば良い。('ω')ノ あとすこしやで
------------------- ↓ 本題はここから ↓-------------------
Dockerの調整
タスクバーのdockerアイコンから「setting」を選択
以下にチェックを入れて「Appli&Restart」
Expose daemon on tcp://localhost:2375 without TLS
PHPStormの調整
Pluginのインストール
兎にも角にもプラグイン。
Docker
とPHP Docker
をインストール[File]-[Setting]-[Plugins]から以下の二つをインストール
Docker
PHP Docker
(
PHP Remote Interpreter
ってのも一緒に入る)Docker Pluginの設定
「Build, Execution, Deployment」-「Docker」-「+」を押下
「TCP socker」にチェックを入れて「OK」を押下PHP Pluginの設定
「Languages & Frameworks」-「PHP」-「Cli Interpreter」-「...」を押下
「Cli Interpreters」欄の「+」を押下、
「From Docker, Vagrant, Vm, WSL, Remote...」を押下する。「Image Name」欄の「▼」を押し、
「laradock_php-fpm:latest」を選択コード補完が効いていたら成功だ。
これで実際の開発に入ることができるだろう。
(゜-゜) こんなに頑張らないと物作れないってどうなんだろ・・・。このあとGitやらXdebugやら使うことになると思うが、
それは一般的なものなので今回は省く。
(過去記事のどれかでやったっけな。)
------------------- ↓ 後書はここから ↓-------------------
これだけやって、
ようやく使えるDockerってどうなの?
(ワイだけかな)
まぁ、AWSのデプロイ考えたらdockerなのかなぁ。
ほかの方法だとイメージを量産する感じになっちゃうし。
環境を作るって観点だけで物事を考えたらいかんか。今回はlaradockでやったけど、
これがなければ環境作りだけで時間を食い潰してただろうな。
いまいちDocker Hubの扱い方がよくわからない。MySQLが起動しない
PHPとは関係ないが、
Dockerがらみ。
DockerコンテナでMySQLだけが起動しない。$ docker-compose up -d --build mysqlシーン・・・。
(?_?) アレ?
ログ見てみよう。2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:48:39.973002Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:48:39.973444Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:48:39.986553Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted) 2020-03-14T09:48:45.126054Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:48:45.126403Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:48:45.126758Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:48:46.659592Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.|ω・) ナニコレ
データディレクトリをいったん削除してもう一回起動
2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:48:39+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:48:39.973002Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:48:39.973444Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:48:39.986553Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted) 2020-03-14T09:48:45.126054Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:48:45.126403Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:48:45.126758Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:48:46.659592Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL. 2020-03-14 18:53:21+09:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started. 2020-03-14 18:53:21+09:00 [Note] [Entrypoint]: Initializing database files 2020-03-14T09:53:21.968144Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-03-14T09:53:21.969067Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 22 2020-03-14T09:53:21.987587Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive 2020-03-14T09:53:27.708440Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem 2020-03-14T09:53:27.708719Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it. 2020-03-14T09:53:27.709077Z 0 [ERROR] [MY-010119] [Server] Aborting 2020-03-14T09:53:29.169116Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.( ゚Д゚)ハァ? 余計悪化した。。。
ちょっと掘り下げてみるか。。。permissionって書いてあるから権限回りだろう・・・( ゚д゚)ハッ!
そういえばこのDocker設定作ったのはMac野郎だった。docker-compose.ymlmysql: image: mysql:8.0 ports: - 3306:3306 user: "500:500" volumes: ・・・・やっぱり。
WSL上のuserIDとdocker上のuserIDがあってない。
WSL上のUIDを確認してみよう。C:\> wsl $ id uid=1000(dozo) gid=1000(dozo) groups=1000(dozo),・・・docker-compose.ymlを調整
docker-compose.ymlmysql: image: mysql:8.0 ports: - 3306:3306 user: "1000:1000" volumes: ・・・・Mysqlのデータを全削除。
イメージを削除して、コンテナを再構成$ rm -Rf /mnt/c/Users/magic/mysql/data/* $ docker rm bc57ea450000 bc57ea450000 $ docker rmi 9b51d9270000 Untagged: mysql:8.0 Untagged: mysql@sha256:4a30434ce03d2fa39 ・・・ 79e9d07a19e3a8d49010ab9c98a2c348fa116c87 $ docker-compose up -d --build mysql Creating laradock_mysql_1 ... done直った・・・。
- 投稿日:2020-03-16T08:56:19+09:00
Amazon LinuxにKubernetes環境構築【kubeadm】
前提
EC2でAmazonLinuxインスタンスを作成してあること(CPUとメモリは最低でも2以上を要求されるのでt2.microではダメ)
背景
当たり前のようにkubernete環境構築で詰まったので手順をメモ
環境
2020/3月時点でのバージョン
[root@kube-master work]# kubectl version Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.4", GitCommit:"8d8aa39598534325ad77120c120a22b3a990b5ea", GitTreeState:"clean", BuildDate:"2020-03-12T21:03:42Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.4", GitCommit:"8d8aa39598534325ad77120c120a22b3a990b5ea", GitTreeState:"clean", BuildDate:"2020-03-12T20:55:23Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}事前準備
- host名の設定/hostsファイル編集
- Dockerのインストール
- swapの無効化
- SELinuxを止める(本番環境ではやらないほうがいいらしい)
- iptables編集
- Dockerのkubelet向けcgroup設定
host名の設定
# いちおうrootユーザーになっとく [ec2-user@ip-10-0-10-176 ~]$ sudo su - [root@kube-master ~]# hostnamectl set-hostname kube-master [root@kube-master ~]# echo "[your aws ec2 public ipaddress] kube-master" >> /etc/hosts [root@kube-master ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost6 localhost6.localdomain6 3.112.45.181 kube-masterDockerインストール
[root@kube-master ~]# yum update -y [root@kube-master ~]# yum install -y docker [root@kube-master ~]# systemctl enable docker && systemctl start dockerインストールの確認
[root@kube-master ~]# docker info | grep -i version Server Version: 18.09.9-ce containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30 init version: fec3683 Kernel Version: 4.14.171-136.231.amzn2.x86_64 [root@kube-master ~]# docker info | grep -i driver Storage Driver: overlay2 Logging Driver: json-file Cgroup Driver: cgroupfs # あとでここ変えるswapの無効化
swap無効化し、swap領域が使われていないことを確認する。
公式サイトにswap無効化してくださいと書かれている(Swap disabled. You MUST disable swap in order for the kubelet to work properly.)
[root@kube-master ~]# swapoff -a [ec2-user@ip-10-0-10-176 ~]$ free total used free shared buff/cache available Mem: 8166360 224408 7181288 484 760664 7695804 Swap: 0 0 0SELinuxを止める
以下の理由により
Setting SELinux in permissive mode by running setenforce 0 and sed ... effectively disables it. This is required to allow containers to access the host filesystem, which is needed by pod networks for example. You have to do this until SELinux support is improved in the kubelet.
[ec2-user@ip-10-0-10-176 ~]$ setenforce 0 setenforce: SELinux is disabled [root@kube-master ~]# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/configsysctlでネットワークをブリッジできるようする
Some users on RHEL/CentOS 7 have reported issues with traffic being routed incorrectly due to iptables being bypassed. You should ensure net.bridge.bridge-nf-call-iptables is set to 1 in your sysctl config, e.g.
[root@kube-master ~]# cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF [root@kube-master ~]# sysctl --systemDockerのkubelet向けcgroup設定
DockerのcgroupDriverをsystemdに設定する
[root@kube-master ~]# cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF [root@kube-master ~]# mkdir -p /etc/systemd/system/docker.service.d [root@kube-master ~]# systemctl daemon-reload [root@kube-master ~]# systemctl restart docker [root@kube-master ~]# docker info | grep -i driver Storage Driver: overlay2 Logging Driver: json-file Cgroup Driver: systemdkubernetesインストール
- Kubernetesのリポジトリ登録
- kubelet/kubeadm/kubectlインストール
- kubeadm init
- CNI構築
- all-in-one化
Kubernetesのリポジトリ登録
公式のものを参考に
[root@kube-master ~]# cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOFkubelet/kubeadm/kubectlインストール
[root@kube-master ~]# yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes [root@kube-master ~]# systemctl enable kubelet && systemctl start kubelet Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /usr/lib/systemd/system/kubelet.service.kubeadm実行
公式サイトを参考に実行していく
CNIにはCalicoを選択[root@kube-master ~]# kubeadm init --pod-network-cidr=192.168.0.0/16 [root@kube-master ~]# kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yamlinitが成功したらkubeadmの指示に従う
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config[root@kube-master ~]# mkdir -p $HOME/.kube [root@kube-master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@kube-master ~]# chown $(id -u):$(id -g) $HOME/.kube/config※
kubeadm join --token ~~
はall-in-one構成では必要ないらしいのでやらないcalicoネットワーク構築
[root@kube-master ~]# kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yamlkubernetesのall-in-one構築
kubectl taint nodes --all node-role.kubernetes.io/master-
動作確認
[root@kube-master ~]# kubectl get all --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system pod/calico-kube-controllers-5c45f5bd9f-74f4h 1/1 Running 0 4m32s kube-system pod/calico-node-mmvqh 1/1 Running 0 4m33s kube-system pod/coredns-6955765f44-45mkb 1/1 Running 0 16m kube-system pod/coredns-6955765f44-xntv5 1/1 Running 0 16m kube-system pod/etcd-kube-master 1/1 Running 0 16m kube-system pod/kube-apiserver-kube-master 1/1 Running 0 16m kube-system pod/kube-controller-manager-kube-master 1/1 Running 0 16m kube-system pod/kube-proxy-d2qmc 1/1 Running 0 16m kube-system pod/kube-scheduler-kube-master 1/1 Running 0 16m NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16m kube-system service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 16m NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system daemonset.apps/calico-node 1 1 1 1 1 beta.kubernetes.io/os=linux 4m34s kube-system daemonset.apps/kube-proxy 1 1 1 1 1 beta.kubernetes.io/os=linux 16m NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE kube-system deployment.apps/calico-kube-controllers 1/1 1 1 4m34s kube-system deployment.apps/coredns 2/2 2 2 16m NAMESPACE NAME DESIRED CURRENT READY AGE kube-system replicaset.apps/calico-kube-controllers-5c45f5bd9f 1 1 1 4m34s kube-system replicaset.apps/coredns-6955765f44 2 2 2 16m参考文献
- 投稿日:2020-03-16T06:50:38+09:00
DockerのDの字も分からない状態を抜け出すためにやって良かったことをまとめてみる
概要
Dockerを触っていく上で、何を勉強したら良いかで行き詰まることが多かったので、勉強していて特に役に立ったな、と思ったものを備忘録がてら整理してみます。
対象読者
Dockerに入門したはいいけれど、インフラもLinuxも全然わからん、でも何とかしたい、というレベルの話が中心となっています。
k8sまで踏み込んだり、Dockerをバリバリ実務で使いこなすためのベストプラクティスなどなど、深い部分は対象外としています。むしろ、そういうのがあったら読みたいです。また、本記事では、Webアプリの実行環境をDockerで構築できるようになるために必要な知識にフォーカスしています。そのため、データベースを利用した簡単なWebアプリをつくった経験があると、Dockerを勉強するモチベーションが高まるかもしれません。
前置き
1年ほど前に、ふとしたきっかけで、Dockerやるかと思い立ちます。Dockerは入門記事が充実しており、見よう見まねでとりあえず動かせないこともないところまでは、サクッと進みました。
しかし、当時はLinuxやインフラ系の知識が皆無だったこともあり、動作原理どころか、そもそも自分が何をやっているのかも曖昧で、入門から先は手も足も出ませんでした。Dockerそのものの入門記事は数多くありましたが、
Dockerを理解するためにどんな知識が必要か
の全体像がまとまっているものは、中々見つけられませんでした。
Dockerは私にはまだ早いなぁ...と思い、でもやっぱりDockerわかるようになりたいなぁ...と気にかけながら、あれこれ色々手を出し、勉強していました。まだまだDocker完全に理解した状態には程遠いですが、基本部分の理解に必要な前提知識はそれなりに補強できたのか、Dockerの動作が全くイメージできていない状態からは、なんとか脱出できた...はずです。
Dockerなんもわからん状態を辛うじて抜け出せたとはいえ、何をどこまでやれば、Dockerの苦手意識をなくせるかが分からず、手探りの状態が続くのは中々にしんどかったです。
ですので、備忘録がてら、これはやっておいて良かったな、と思ったものをまとめておこうと思います。
これさえやれば、Dockerはもう完璧!!...なんてことはありませんが、なにかの参考になれば幸いです。以下では、本を中心に紹介していきます。このとき、それぞれについて、
何を学ぶことを目的とするか
を意識しておくとよいかもしれません。
目安となるかは分かりませんが、以下はやって良かったことの紹介に加え、何を学ぶことを目指して取り組んだかも、あわせて記述していきます。Linux
コンテナ内での操作はもちろんのこと、Dockerの仕組みを学ぶ上では、何よりLinuxの理解が欠かせません。
とは言え、Linux単体だけを見ても勉強する内容は非常に幅広く、何から手をつけるべきか、悩みやすい部分でもあります。
以下では、基礎的なコマンドや、コンテナ内の操作、そして、Dockerの動作原理を理解する上で、助けられた書籍を挙げていきます。新しいLinuxの教科書
- 学べること: シェルを中心としたLinuxの基本知識・コマンド
元々Linuxを扱う機会はぽつぽつとありましたが、書籍を利用してじっくり学ぶのは、これが初めてとなりました。
結論から言うと、最初にこの書籍から始めたのは、大正解だったと思っています。シェルとはなんぞやから始まり、雰囲気でなんとなく使っていたコマンドについて、一つ一つ丁寧に知識を積み上げるような形で紹介されているため、とても読みやすいです。コンテナの中での操作は、大抵の場合、Linuxのシェル操作が前提知識として必須になります。まずはここからスタートすれば、コンテナに入っても何をしたらいいか分からず、しんどい思いをすることもなくなるかと思います。
Linuxの基礎がぎゅっと詰まっているので、これからも定期的に読み返していきたいと思います。
ゼロからはじめるLinuxサーバー構築・運用ガイド 動かしながら学ぶWebサーバーの作り方
- 学べること: シェル操作によるアプリケーション実行環境の構築方法
Dockerを学習するメリットとして、環境構築が容易になることがよく挙げられます。これを実感してこそ、Dockerを学ぶモチベーションも高まってきます。
そこで、シェル操作に慣れてきたところで、実際に本をベースに、手を動かしながら環境構築をやってみました。今のご時世なら、VPSやクラウドサービスなどを活用すれば、安価にサーバを構築することができます。
勉強がてら、まずはコンテナではなく、実際にサーバとして構築してみるとよいかと思います。
セキュリティ面で不安がある場合は、VMを利用してみるのもよいかもしれません。この本は、サーバ構築に必要な知識を補強しながら、LAMP環境をつくり上げるまでを学べる構成になっています。あいだにネットワークの話が入り、そこでも説明はされていますが、もし詰まった場合は、先にネットワークを勉強してから再挑戦すると、つらくないかもしれません。
試して理解Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識
- 学べること: カーネルを中心とした、Linuxの各種機能の基本動作原理
Dockerはkernelを共有する
なんて言葉があるように、Dockerを深く知るには、カーネルの理解が重要です。しかし、カーネルを理解するためには、幅広い分野の深い知識・経験が必要となります。
カーネルをしっかり学習するのであれば、難しくて分厚い本に立ち向かう覚悟を持たなければなりませんが、Dockerに入門する段階であれば、こういった入門書1冊でも十分だと思います、きっと...。少し話は逸れましたが、この本は、難しい概念を、豊富な図で分かりやすく説明されています。文章で少し迷子になっても、すぐにイメージを補強するための図で補ってくれるため、難しい本でよくある途中リタイアを防いでくれることでしょう。
更に、図解だけにとどまらず、プロセス管理やメモリ管理などを、実際にC言語で書かれたサンプルコードによって、イメージをコードと結びつけながら学ぶことができます。
この結びつきは、時間の掛かることではありますが、ただ字面を追っただけでは得られないレベルまで、理解を深めてくれます。実際にこの本を読んだあとでは、Dockerの動作原理がかなりイメージしやすくなりました。メモリ管理の辺りからぐんぐん難易度が上がっていきますが、じっくり取り組む価値はおおいにあると思います。
※1 C言語自体の勉強は、苦しんで覚えるC言語がわかりやすくておすすめです。
※2 前半部分で既に難易度が高いと感じる場合は、「プログラムはなぜ動くのか」・「コンピュータはなぜ動くのか」を読んでおくと、立ち向かいやすくなるかもしれません
ネットワーク
Dockerを扱う際、コンテナ間通信のイメージが掴みづらく、最初の頃は理解に苦戦していました。
当時はネットワーク関連の知識が非常に浅く、また、業務で携わる機会もほとんどなかったため、個人的に一番つまずいた部分だと感じています。ネットワークそのものは言わずもがな、勉強する範囲が非常に広いです。ですが、Dockerのネットワークまわりを理解するのが目的であれば、レイヤー2とレイヤー3を中心に勉強すると、とっつきやすくなるかもしれません。
3分間ネットワーク基礎講座
- 学べること: レイヤー1~3を中心とした、ネットワーク関連の各用語の概要
ウェブサイトで公開されているものの書籍版です。レイヤー1〜レイヤー3を中心に、対話形式で各種用語について、図を交えながら書かれています。
ネットワーク関連の書籍を読んでいて、この辺りのレイヤーは、業務や趣味でも触る機会が中々なく、概要を理解するのに苦労していました。特に、最初の頃は、イーサネットの規格や、物理学のあれこれの話など、深く踏み入った話とあわせて解説されると、戸惑ってしまうことがよくありました。対して、この書籍は、踏み込み過ぎず、かつ、浅すぎず、丁度いい塩梅で各用語について書かれているので、最初の一歩におすすめです。サクッと読める文量なので、まずはネットワーク関連の用語に慣れるためにも、数回繰り返し読んでみるのもありかもしれません。また、ウェブサイト版も書籍版とは色々異なる部分があるので、興味があったら目を通してみてください。
パケットキャプチャの教科書
- 学べること: パケットと、図解による、ネットワーク通信の流れの具体的なイメージ
たとえばプログラムであれば、文法を学んだ後、実際にソースコードを書くことで、経験を通じて知識を定着させることができます。しかし、ネットワークに関しては、実際の通信を覗いたり、操作するための道程は、プログラムを書くときほど情報が充実しているとは言えません。
そんな中、この書籍に出会うことで、ネットワークへの苦手意識も少しだけマシになりました。構成自体はよくある各レイヤーについて解説したものではありますが、何と言っても、各レイヤーについて、実際のパケットの様子を、流れを丁寧に記述した図もあわせ、事細かに解説してくれている点がありがたいです。
各レイヤーのざっくりとした知識は前提として必要にはなりますが、繰り返し読むことで、ネットワークに関する知識を教科書的な段階から一歩先へ引き上げてくれるはずです。また、本番サーバとしてDockerを利用する際には、HTTPS対応や、DNSなど、レイヤー1~3以外の知識も必要となるため、都度読み返すと、応用の際にもスムーズに学べるかもしれません。
※用語についていくのがしんどいと感じた場合は、「TCP/IPの絵本」から入るのもアリだと思います。
Linuxで動かしながら学ぶTCP/IPネットワーク入門
- 学べること network namespaceの概要と、TCP/IPの各レイヤーの実際の通信の様子のイメージ
最近出た本ではありますが、読んでいてとても面白かったので、ここで紹介します。
Dockerではnetwork namespaceなるものを使うことで、仮想的なネットワークを設定することができる、といった感じの説明をよく見ますが、実際のところ、これだけでは、いまいちピンと来ません。この書籍では、実際にnetwork namespaceで仮想的なネットワークを作成するだけにとどまらず、イーサネットや、IPでの通信を、ネットワークインタフェースを設定するところから丁寧に解説してくれています。
TCP/IPの各レイヤについて、network namespaceで通信に必要な設定・インタフェースを構築し、tcpdumpで実際の通信を確認しながら、
通信ができるようになるまで
を段階的に見ることができます。
Linuxの基礎を学び、上で挙げたネットワークの書籍に目を通したあとで取り組んでみると、ネットワークによってコンピュータ同士が通信できるようになるまでの流れがより深く学べることでしょう。また、network namespaceで実際にインタフェースを設定することで、Dockerのネットワーク周りの理解も、更に進むかと思います。
(余談)
ネットワークの入門書と言えば、「ネットワークはなぜつながるのか」や「マスタリングTCP/IP 入門編」が定番として挙げられています。これらの書籍は確かに分かりやすく書かれていますが、ネットワークの知識がほとんど無い状態で挑むとかなり苦労することになります。(私はここから入ってめちゃくちゃ苦労しました)まずは上記で挙げた入門書に目を通し、何らかの形で実際にネットワーク関連の知識が必要となった際、取り組んでみると、十分に楽しめるのではないかと思います。
Docker
Dockerの使い方を学ぶには、当然、Dockerそのものを勉強することも必要です。Dockerの入門情報は、Qiitaを始めとし、ネット上にたくさんの優れたものがあります。
Docker 入門
で検索し、良さそうだと思ったものをいくつか触っていけば、雰囲気はつかめるかと思います。
このとき、ただ読むだけでなく、実際に手を動かしながら、Dockerfileを書いてみたり、Docker Composeを使ってみたり、あれこれ試しながら、失敗したり、成功したり、といったことを経験するのが重要です。最初のうちは各コマンドや、設定の記述が、なぜ必要なのかイメージが掴めず、苦労するかと思います。ですが、これまで挙げてきたもので基礎知識を身につけていれば、前提知識が足りず手も足も出ないということにはならないはずですので、少しずつでも理解を進められるはずです。
以下に、いくつか私が取り組んできたものを挙げますので、何から始めたら良いか迷っている場合は、練習問題がてら、触ってみるとよいかもしれません。
- C言語の実行環境
- Python + Pytestの実行環境
- create-react-appを利用したReactの実行環境
- デプロイされたWarファイルを実行するTomcat環境
- Django + RDBMSそれぞれをコンテナ化し、DjangoアプリのデータをDBに保存可能とする環境
このとき、大抵のものは便利なイメージとして、既に公開されていたりしますが、最初のうちは、勉強も兼ねて、好きなLinuxディストリビューションをベースイメージとして構築してみると、理解が深まるかと思います。
ただ、やはり体系的に学ぶ上では、本を活用したいものです。
以下では、Dockerの入門書について、いくつか読んできた中で、特に良かったものを紹介します。マンガでわかるDocker
- 学べること: Dockerとはなんぞや~Dockerfileの基本あたりまで
全3冊ありますが、入門段階では、1巻・2巻だけでも十分だと思います。漫画形式でDockerの用語について解説されているので、「イメージ」や「コンテナ」などの言葉の意味は分かっていても、頭の中でイメージしづらい状態から脱するのに適しています。
ネット上の入門記事とあわせて読めば、最初の一歩として十分な理解が得られるでしょう。Docker Deep Dive
- 学べること: Dockerの基本的な概念の網羅・動作原理のさわり部分の理解
英語の書籍なので、一見難しそうに感じてしまいますが、難しい英単語や表現は使われていないので、英語がどうしようもないほど苦手でもなければ、ぜひ読んでみて頂きたいです。
Dockerの各種要素について、「概要」・「詳解」・「コマンド」形式で章立てて解説されており、ある章でいきなり難易度が跳ね上がることもないので、一歩ずつ確実に学ぶことができます。ある程度手を動かした後に読んでみると、断片的に散らばっていた知識が明快な章立てにより、繋がることで、「Dockerなんも分からん」状態を抜け出せるはずです。
しっかりと内容を理解するには、Linuxやネットワークなど、幅広い知識が必要にはなりますが、これまで紹介したものを積み上げていけば、きっと立ち向かえることでしょう。その他
Dockerそのものの理解とは少しずれますが、これもやって良かったな、と思ったことを以下にいくつか紹介します。
Vim
- 学べること: コンテナ内のファイル編集を手軽に行うための知識
コンテナに入ってちょっと設定ファイルなどを操作するとき、ホストからあれこれしたり、エディタの拡張機能などでも対応はできます。ですが、こういうときにサクッと操作できるツールがあればとても便利です。
そんなときに、Vimを勉強しておくと、コンテナの中でも快適に過ごせます。Vimそのものについては、随所で熱く語られているため、詳細は割愛します。拡張機能ましましでカスタマイズするのでもなければ、上記のUdemyのコースで勉強すると、数時間で簡単な使い方を理解することができます。
英語ではありますが、字幕機能もありますし、何より練習問題がVimの基本操作を学ぶのに丁度いい形でつくられているので、Vimの良さを飽きることなく学べることでしょう。Git
エンジニアのためのGitの教科書[上級編] Git内部の仕組みを理解する
- 学べること: Gitの基本コマンドとその仕組み
Gitそのものを知らなくてもDockerは理解できるかとは思います。しかし、Dockerで構築した環境で管理するアプリのソースコードは基本Gitで管理することとなるので、あわせて学んでおいて損はないです。
Gitはネット上はもちろんのこと、書籍もここに挙げた以外にも、素晴らしいものが充実しているので、迷子になるようなこともないかと思います。
まとめ
ちょっと整理するか、ぐらいの軽い気持ちで書き始めたら、思ったよりも長くなってしまいました。
Dockerを単なるツールとして使うためであれば、ここまでやらなくても、このコマンドを叩けばこうなる、と暗記し、用意されている素敵なイメージを使うことで、それなりのことはできてしまいます。ですが、個人的には、多少遠回りにはなっても、基礎からしっかり学んで、なぜを追求していく方が良いと考えています。
これは優劣としてではなく、ただ単に、その方が楽しいからです。Dockerをきっかけに、ネットワークやLinuxに手を伸ばすようになり、1年ほど前よりもDockerはもちろんのこと、インフラ周り、Linuxのことが好きになりました。好きなものが増え、そこから更に深く学ぶと、知的好奇心が刺激され、それはそれは楽しいものです。
これ以上書くと脱線してしまうので、割愛しますが、この記事が少しでも楽しい学びの一助となれば幸いです。