- 投稿日:2020-02-16T21:38:44+09:00
React のチュートリアルを Typescript でやってみた【環境構築編】
背景
React 触ってみたい。
Typescript もやってみたい。作業環境
今回は docker を使用し環境を作る。
- macOS Catalina 10.15.3
- Docker version 19.03.5, build 633a0ea
- docker-compose version 1.25.3, build d4d1b42b
- webpack@4.41.6
- typescript@3.7.5
- react@16.12.0
開発環境の準備
プロジェクトのディレクトリーを作成
作業するディレクトリを作成します。
ここではreact-tutorial
としておきます。mkdir react-tutorial cd react-tutorialディレクトリの中に以下のファイルを作成します。
- Dockerfile
- docker-compose.yml
以下それぞれのファイルの内容
Dockerfile
DockerfileFROM node:13.8.0-alpine3.11 ENV NODE_ENV=development WORKDIR /appdocker-compose.yml
docker-compose.ymlversion: "3" services: webserver: container_name: react-tutorial image: react build: . volumes: - ./:/app tty: true ports: - 8080:8080tree はこんな感じ
react-tutorial $tree . ├── Dockerfile └── docker-compose.yml開発環境の作成
とりあえずビルドします。
docker-compose up --build -d以下のコマンドでコンテナが起動していれば OK
react-tutorial $docker-compose ps起動している場合以下のように表示される。
react-tutorial $docker-compose ps Name Command State Ports --------------------------------------------------------------------------- react-tutorial docker-entrypoint.sh node Up 0.0.0.0:8080->8080/tcpコンテナ内に移動する場合は以下
docker exec -it react-tutorial /bin/shpackage.json の作成
まずはコンテナ内に移動
docker exec -it react-tutorial /bin/sh以下のコマンドで package.json を作成します。
npm init設定は以下のように設定しました。
package name: (app) react-tutorial version: (1.0.0) description: entry point: (index.js) webpack.config.js test command: git repository: keywords: author:humi3 license: (ISC) About to write to /app/package.json:ワークディレクトリに以下の package.json が以下の内容でされたと思います。
package.json{ "name": "react-tutorial", "version": "1.0.0", "description": "## コンテナビルド `docker-compose up --build`", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "humi", "license": "ISC" }※今回は 1 から環境を構築しますが、以下のコマンドで React + Typescript の環境できます。
my-app
の箇所にプロジェクト名npx create-react-app my-app --typescript必要なライブラリのインストール
Webpack
npm install --save-dev webpack webpack-cliTypescript で必要なライブラリ
npm install --save-dev typescript awesome-typescript-loader source-map-loaderreact & react-dom
npm install --save-dev react react-dom @types/react @types/react-domディレクトリとファイルの準備
以下のディレクトリの構成になるようにファイルを作成します。
react-tutorial ├── dist │ ├── index.html │ └── bundle.js ├── node_modules ├── src │ └──index.tsx ├── Dockerfile ├── docker-compose.yml ├── package-lock.json └── package.jsonbundle.js 及び index.tsx はファイル作成だけでいいです。
index.html だけ以下のような内容にしておきます。index.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>TypeScript HelloWorld</title> </head> <body> <div id="root"></div> <script src="bundle.js"></script> </body> </html>tsconfig.json の作成
以下のコマンドで
tsconfig.json
を作成します。npx tsc --init設定は以下のようにしました。
tsconfig.json{ "compilerOptions": { "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, "outDir": "./dist/" /* Redirect output structure to the directory. */, "strict": true /* Enable all strict type-checking options. */, "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, "sourceMap": true /* Emit a single file with source maps instead of having a separate file. */, "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "jsx": "react", "lib": ["es2015", "dom"] } }現在のディレクトリ
react-tutorial ├── dist │ ├── index.html │ └── bundle.js ├── node_modules ├── src │ └──index.tsx ├── Dockerfile ├── docker-compose.yml ├── package-lock.json ├── package.json └── tsconfig.jsonwebpack.config.js の作成
webpack.config.js
を作成します。react-tutorial ├── dist │ ├── index.html │ └── bundle.js ├── node_modules ├── src │ └──index.tsx ├── Dockerfile ├── docker-compose.yml ├── package-lock.json ├── package.json ├── tsconfig.json └── webpack.config.json
webpack.config.js
の内容webpack.config.jsconst path = require("path"); module.exports = { entry: path.resolve(__dirname, "./src/index.tsx"), output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js" }, devtool: "source-map", target: "node", resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }, module: { rules: [ { test: /\.tsx?$/, loader: "awesome-typescript-loader" }, { enforce: "pre", test: /\.tsx?$/, loader: "source-map-loader" } ] } };以上でファイルの準備が完成しました。
動作確認
index.tsx の内容を以下へ
index.tsximport * as React from "react"; import * as ReactDOM from "react-dom"; export default class App extends React.Component<{}, {}> { render(): JSX.Element { return <div>HelloWorld!</div>; } } ReactDOM.render(<App />, document.getElementById("root"));package.json に build 用の script を追加
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build":"webpack" },以下のコマンドで build を行います。
npm run buildindex.html をブラウザで開き
HelloWorld!
が表示されたら OK です。
今回は、環境構築の部分をやってみました。
次回は、公式のチュートリアルを Typescript にしてやっていきたいと思います。参考
https://speakerdeck.com/takepo/reactxreduxniokerutypescriptru-men
https://qiita.com/soarflat/items/28bf799f7e0335b68186
https://qiita.com/one-kelvin/items/b810aafb6b5ef90789a3
- 投稿日:2020-02-16T20:55:14+09:00
【Kubernetes】OperatorSDKにサクッと入門
概要
- 本記事では、operator-sdkを利用して、deploymentのimageが変更されるたびに、slackに通知する仕組みを作成します。
- サンプルコード: https://github.com/solt9029/deployment-image-watcher
- 挙動: https://www.youtube.com/watch?v=eknVJj8E-HE&feature=youtu.be
対象読者
- 基本的なkubernetesの知識がある人
- operatorとは何か、なんとなく把握しているが、開発を行なったことがない人
- go言語の基本的な文法が読める人
はじめに
kubernetesの拡張機能の1つに、operatorが存在します。
operatorを利用すれば、運用の自動化を行うことができます。
operatorに関する詳しい説明は、下記リンクをご覧ください。
https://qiita.com/MahoTakara/items/af4ad8ab69c24102bd72複数人で同一のclusterやnamespace上で開発を行なっている場合に、
誰がいつdeploymentのimageを変更したか分からず困る状況を想定し、
本記事では、deploymentのimageが変更されるたびに、slackに通知する仕組みを作成していきます。なお、本記事で作成するものは、本来のoperator-sdkの使い方とは言えないため、
あくまでoperator-sdkに触れる目的であることをご留意ください。環境構築
以下の環境が必要です。
- go
- operator-sdk
- docker
- kubectl
dockerやkubectlのインストールについては説明を省きます。
下記手順により、goおよびoperator-sdkをインストールします。brew install go go version # 筆者はv1.13.3を使用 export Go111MODULE=on # Go Modulesを使用するため brew install operator-sdk operator-sdk version # 筆者はv0.15.2を使用また、kubernetesクラスタやdockerhub、slackapi(botによるメッセージ送信)が利用できる状態としてください。
開発
テンプレート生成
下記手順によりテンプレートを生成します。
operator-sdk new deployment-image-watcher --repo=github.com/<username>/deployment-image-watcher cd deployment-image-watcher operator-sdk add controller --api-version=deployment.k8s.io/v1alpha1 --kind=Deployment通常、operator-sdkを使用する場合、CRD(Custom Resource Definition)を利用するのが一般的ですが、
今回はdeploymentのimageの変更を検知したいだけなので、CRDは生成しません。controller
さっそく、根幹となるcontrollerを編集していきます。
controllerはpkg/controller/deployment/deployment_controller.go
に存在します。
重要な部分は以下の通りです。
またファイル全体は https://github.com/solt9029/deployment-image-watcher/blob/master/pkg/controller/deployment/deployment_controller.go から確認できます。func add(mgr manager.Manager, r reconcile.Reconciler) error { c, err := controller.New("deployment-controller", mgr, controller.Options{Reconciler: r}) if err != nil { return err } slackClient := slack.New(os.Getenv("SLACK_TOKEN")) source := &source.Kind{Type: &appsv1.Deployment{}} handler := &handler.EnqueueRequestForObject{} predicate := predicate.Funcs{ UpdateFunc: func(e event.UpdateEvent) bool { for _, oldContainer := range e.MetaOld.(*appsv1.Deployment).Spec.Template.Spec.Containers { for _, newContainer := range e.MetaNew.(*appsv1.Deployment).Spec.Template.Spec.Containers { if oldContainer.Name == newContainer.Name && oldContainer.Image != newContainer.Image { messageText := createMessage(newContainer.Name, newContainer.Image, oldContainer.Image) slackClient.PostMessage(os.Getenv("SLACK_CHANNEL"), slack.MsgOptionText(messageText, true)) } } } return true }, } err = c.Watch(source, handler, predicate) if err != nil { return err } return nil }watch関数のsourceの引数によって、監視対象としてdeploymentを設定します。
predicateは本来、deploymentの変更や追加、削除などのイベントに対して、
reconcileを行うべきかフィルタリングする役割を担っています。
このpredicate内では変更前の状態と変更後の状態を両方取得することができるため、
今回はこの部分でimageが変更されたかどうかを判定し、slack通知を行うロジックを書いています。
e.MetaOld.(*appsv1.Deployment).Spec.Template.Spec.Containers
によって変更前のdeployment.spec.template.containersを取得できます。
同様に、変更後のdeployment.spec.template.containersも取得できます。
それらを用いて、imageを比較し、変更があればslack通知を行なっています。ビルド
これだけで開発は終了です。
下記手順でビルドし、イメージをdocker registryにpushします。operator-sdk build <username>/deployment-image-watcher:latest docker push <username>/deployment-image-watcher:latestマニフェスト
deploy/secret.yaml
を追加し、以下のようなsecretのマニフェストを記述します。
SLACK_TOKEN
にはslackapiのtokenをbase64化した値を入れてください。echo -n "<your slack token>" | base64apiVersion: v1 kind: Secret metadata: name: deployment-image-watcher type: Opaque data: SLACK_TOKEN: <YOUR_SLACK_TOKEN_BASE64_ENCODED>次に、
deploy/operator.yaml
を編集します。
以下の2つの環境変数を追加してください。- name: SLACK_TOKEN valueFrom: secretKeyRef: name: deployment-image-watcher key: SLACK_TOKEN - name: SLACK_CHANNEL value: "general"動作確認
下記手順により、deployment-image-watcherをデプロイします。
kubectl apply -f deploy/
なんらかのdeploymentをapplyし、imageを変更してみてください。
slackに通知が届くはずです。おわりに
本記事では、operator-sdkを利用して、deploymentのimageが変更されるたびに、slackに通知する仕組みを作成しました。
operator-sdkを手軽に使うために、CRDを用いずに簡易的なサンプルを実装しました。
本来のoperator-sdkの利用目的とは若干ずれていましたが、本記事によって基本的な使い方がわかれば幸いです。
ありがとうございました。
- 投稿日:2020-02-16T18:08:09+09:00
雑に知ってしまったDockerを知り直す ~アプリケーション持ち込み編~
おさらい
第2回です。
前回の投稿はこちら
前回はnginxのイメージをpullして来てコンテナ起動。
ポートフォワードしてウェルカムページを表示させるまでやりました。今回やりたいこと
- ローカルで適当にアプリケーションを用意する
- どうにかしてそのアプリケーションをコンテナの中にぶちこむ
- ホスト側から起動したアプリケーションへアクセスできるようにする
アプリケーションを用意
Nodeとgithubを勉強したときに作った、first-stepっていうオシャレ気取った名前のリポジトリが放置されていたので、これを再利用します。
せっかくなので触ったこと無いReactへ転生。この辺のステップは本題と外れてしまうので割愛。
$ npm start
これをどうにかしてコンテナへ持っていきたい。
コンテナを用意
前回はnginxのイメージを利用しましたが、今回はnodeのイメージを利用します。
現在のnodeの最新バージョンはv13.8.0
なんですが、ホストにインストールしてるのは安定版のv12.16.0
なのでこれをインストールしたい。バージョン指定してイメージをpullするのどうやるんだろう・・と思いつつとりあえずイメージを探します。
コマンドでも探せるみたいなんですが、初めてなのでGUIに頼ります。なるほどなるほど、なんかそれっぽいですね。
調べてみるとこれはTagと呼ばれるもので、古いのバージョンのイメージが欲しい場合はこのTagを指定してpullする必要があると。ただ、同じバージョン(v12.16.0)でもstretchとかslimとか更に違いがあるのが気になる。。
で更に調べると、例えばnodeの場合だとバージョンは同じでも無駄なファイルを省いて最適化されたslimバージョンがあったり、Debianのバージョンが異なるもの(stretchとかbusterとかはDebianのコードネーム)があったりと結構細かい違いがあるということが判明。
このあたりもちゃんと意識して適切なイメージを選択する必要があるってことか・・
で、更に気になったのがTag指定しない場合はどうなるんだ?とかlatest指定すると結局どれを引っ張ってくるのよとか、そもそもこれ誰が作ったイメージなん?安全なん?とか・・
TODO: これも色々調べてみたんですけど、今回の趣旨からは外れそうなのとボリューム膨らみそうなので別記事でまたやります。今回はとりあえず名前がかっこいいのでbusterでやります。
$ docker pull node:12.16.0-buster 12.16.0-buster: Pulling from library/node dc65f448a2e2: Pull complete 346ffb2b67d7: Pull complete dea4ecac934f: Pull complete 8ac92ddf84b3: Pull complete a3ca60abc08a: Pull complete ab849ba5abe0: Pull complete b9e0c215e971: Pull complete 766774022603: Pull complete f199c0426b2a: Pull complete Digest: sha256:66d5994de29952fe982729ef7c7f8d4c50d528279db386efbf373451f534fa16 Status: Downloaded newer image for node:12.16.0-buster $ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE node 12.16.0-buster ce43ce61c1de 28 hours ago 882MB $ docker run [イメージ名:TAG] $ docker run -d --name node-react node:12.16.0-buster 505ba1fdefd2f705f90b083cee3653445256a0917e054147f8251d4e0eeef122 #前回はrunする前にイメージをpullしてなかったのでこのタイミングで色々ダウンロードしてましたが、 今回は事前にpull済なのでローカルのイメージを利用。カシコイ $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8a126cad2450 node:12.16.0-buster "docker-entrypoint.s…" 5 seconds ago Exited (0) 4 seconds ago node-reactで、ここで作成したコンテナのSTATUSを見るとUp(起動中)ではなく、Exitedになっちゃってる。
前回のnginxの場合サーバを立ち上げてUp状態になっていたけど、今回のイメージはあくまでnodeの実行環境を用意するだけなのでコンテナが立ち上がりっぱなしにはならないのかな、となんとなく推測。
環境を構築して後続の命令が無いと、プロセスが死ぬようになっているらしい。起動するアプリケーションも無いのに立ち上げておく意味ないもんね。
-itd
ってオプションつけるとコンテナが立ち上がりっぱなしになるらしいのでお試し。$ docker run -itd -i ホストの入力をコンテナの標準出力につなげる。コンテナ側へ正しくコマンドを渡せるようにする。 -t コンテナの標準出力をホストの標準出力につなげる。ttyをコンテナに割り当てて、対話できるようにする。 -d コンテナに入らずバックグランドで起動する $ docker run -itd --name node-react node:12.16.0-buster 10235f0996b7c1b1e5f47c5b1c36651ff4fe20cd72b14f47dc5a11f0e8607780 $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 10235f0996b7 node:12.16.0-buster "docker-entrypoint.s…" 3 seconds ago Up 2 seconds node-reactうんうん、STATUSがUpになってる。
コンテナに入って作業したい場合は、とりあえず-itdって覚えても良いかもしれない。
TODO: 1個づつオプション外して試してみたけど、ここの挙動が上手く理解できていないので別の機会にちゃんと調べる。# コンテナの中に入る $ docker exec -it node-react /bin/bash root@8bf7a6704bb9:/# node -v v12.16.0ちゃんと指定したバージョンで入ってますね
コンテナにアプリケーションをぶちこむ
最初は「ファイル転送でもすれば良いんかなぁ」とかかなり脳筋なこと考えていたんですけど、考えてみたらgithubからcloneしてきて起動すれば良いんじゃね?と思ったのでお試し。
root@8bf7a6704bb9:/# git --version git version 2.20.1git入ってる!勝った
# 適当なディレクトリへ移動して root@8bf7a6704bb9:/# cd /usr/src/ # cloneして root@8bf7a6704bb9:/usr/src# git clone https://github.com/wol-827/first-step.git Cloning into 'first-step'... remote: Enumerating objects: 22, done. remote: Total 22 (delta 0), reused 0 (delta 0), pack-reused 22 Unpacking objects: 100% (22/22), done. root@8bf7a6704bb9:/usr/src# cd first-step/ # アプリ起動に必要なモジュールインストールして root@8bf7a6704bb9:/usr/src/first-step# npm i found 0 vulnerabilities # アプリケーション起動 root@8bf7a6704bb9:/usr/src/first-step# npm start Compiled successfully! You can now view sample-app in the browser. Local: http://localhost:3000/ On Your Network: http://172.17.0.2:3000/ Note that the development build is not optimized. To create a production build, use npm run build.起動できてそう!良い感じ
コンテナ起動時にポートフォワード設定し忘れてしまったので、改めて設定。
アプリケーションは3000番で起動していて、8080へ飛ばしたいのでこんな感じ。$ docker run -itd -p 8080:3000 --name node-react node:12.16.0-busterできた。ウレシイ。
まとめ
Dockerについて調べていると、環境を汚すことなくアプリケーションの実行環境を用意できる、なんでことが書かれているのをよく見るんですが身を持ってそれを実感しました。
ホスト側にDockerイメージだけ用意してあれば、nodeやらReact用のモジュールやらはコンテナの中にだけ入れるのでホスト側はキレイな体を保てると。専用のコンテナを立てるのでnodeのバージョンの切り替えも不要。
イメージはこれで、githubのリポジトリはこれ、コマンド実行手順はこれ、っていう風に準備すれば、とりあえず環境は手に入る。便利便利。とはいえ今回の場合、コンテナの中に入ってcloneしたり色々コマンド実行しているのが冗長。
次はこの辺りをコマンド1発で出来るようにしたいと思います。たぶん出来る。出来ろ。
- 投稿日:2020-02-16T17:51:56+09:00
WSL1を残したまま、WSL2のUbuntuでdockerを動かすまで
tl;dr
WSL1のUbuntu18.04を消したくないので、ストアを使わずにWSL2へUbuntu18.04を手動インストールし、そこにdockerをインストールします。
Windows Insider Program への参加
公式の通りに参加します。
- サイトにてWindows Insider Programへ参加する
- 参加したアカウントとWindows10への紐付けWSL2の準備
windows update
より、新しいwindowsのビルドを取得します。新しいビルドがインストールされたら、管理者として起動したpowershell上で以下のコマンドを実行します。
ちなみにWSL1を既に実行している場合は、2行目は不要です。Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-LinuxUbuntuパッケージのダウンロード
microsoftストアのUbuntu18.04は、既にWSL1にセットアップされているため使えません。
そのため、Ubuntu18.04パッケージをここからダウンロード。
ubuntu-bionic-core-cloudimg-amd64-root.tar.gz
というファイルがダウンロードされます。LxRunOfflineのダウンロード
WSLを管理するためのフル機能のユーティリティである
LxRunOffline
を、ここからダウンロード。LxRunOffline-v3.4.1-msvc.zip
ですUbuntuをインストール
ダウンロードした
LxRunOffline
を適当な場所に解凍します。
ついでにダウンロードしたUbuntuパッケージも同じ場所に配置します。
powsershellを管理者として起動し、カレントをLxRunOffline
に移動後、以下のWSLインストールコマンドを実行します。LxRunOffline i -n {任意のディストリビューション名} -d {インストールしたい任意のディレクトリ} {パッケージファイル}私の場合は、「D:\WSL\Ubuntu-18-wsl2」にインストールし、ディストリビューション名(今後、WSLの操作に使用する)を「Ubuntu-18-wsl2」としました。
> .\LxRunOffline i -n Ubuntu-18-wsl2 -d D:\WSL\Ubuntu-18-wsl2 -f ubuntu-bionic-core-cloudimg-amd64-root.tar.gzUbuntuの準備
引き続きの
LxRunOffline
コマンドを使って、Ubuntuを起動します。まだ、この時点ではWSL2になっていません。
ディストリビューション名は「Ubuntu-18-wsl2」になっていますが、そこは、ご自分のつけたディストリビューション名に読み替えてください。> .\LxRunOffline run -n {作成したディストリビューション名}私の場合は、以下のコマンドを実行しました。
> .\LxRunOffline run -n Ubuntu-18-wsl2起動したUbuntuに対し、以下のコマンドを実行します。
途中で「myuser」というユーザーを作成していますが、そこは任意に変えてください。# apt update # apt upgrade # adduser myuser # apt install sudo # gpasswd -a myuser sudo # login myuser最後のコマンドで、作成したユーザーでログインしたので、
id
コマンドを使い、作成したユーザーのuidを確認します。$ id uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),27(sudo)uid(私の場合は1000)を確認したら、一旦Ubuntuからログアウトします。
WSLのデフォルトユーザーの設定
管理者として起動したpowershell上で以下のコマンドを実行します。
> .\LxRunOffline su -n {作成したディストリビューション名} -v {上記で確認したuid}私の場合は、以下のコマンドを実行しました。
> .\LxRunOffline su -n Ubuntu-18-wsl2 -v 1000WSL1 から WSL2 へのアップグレード
管理者として起動したpowershell上で以下のコマンドを実行します。
> wsl --set-version {作成したディストリビューション名} 2私の場合は、以下のコマンドを実行しました。
> wsl --set-version Ubuntu-18-wsl2 2以下のコマンドで正しくアップグレードされたか確認します。
> wsl -l -v NAME STATE VERSION * Ubuntu-18.04 Running 1 Ubuntu-18-wsl2 Running 2Ubuntu-18.04がWSL1で実行中であり、Ubuntu-18-wsl2がWSL2で実行中であるのがわかります。
dockerのインストールと確認
powershell上で以下のコマンドを実行し、WSL2のUbuntuにログインします。
> .\LxRunOffline run -n {作成したディストリビューション名}Ubuntuにログイン後、公式通りの手順でdockerをインストール。
$ sudo apt-get update $ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io? 動作確認
dockerサービスの起動
$ sudo service docker starthello-world実行
$ sudo docker run hello-world 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/以上。
- 投稿日:2020-02-16T17:43:21+09:00
docker-compose run web rake db:createできないときにやったこと
エラー文
Starting myapp_db_1 ... done warning Integrity check: System parameters don't match error Integrity check failed error Found 1 errors. ======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ======================================== #ここの文章を参照した To disable this check, please change `check_yarn_integrity` to `false` in your webpacker config file (config/webpacker.yml). yarn check v1.21.1 info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.解決策
「config/webpacker.yml」ファイルのcheck_yarn_integrity: trueの箇所をfalseに変更したら解決した。
check_yarn_integrityって何?
JavaScriptのパッケージをチェックしたり、保全したりする役割があるらしい。。。
参考記事
webpacker の check_yarn_integrity オプションについて調べてみた
yarnが原因でdocker-compose runが実行できないときの対処法
上記記事を参考にしたらできたので執筆者には感謝です。
- 投稿日:2020-02-16T16:38:58+09:00
Railsチュートリアルの開発環境を Docker にしてみなイカ?
【概要】
Railsチュートリアルで作成する Sample App の開発環境を Docker でコンテナ化しました。
細かい用語の勉強はおいといて、とりあえず動くものを作ってみましょう。
- 開発環境
- macOS Mojave: 10.14.6
- Docker Engine: 19.03.5
- Docker Compose: 1.25.4
- コンテナ環境
- Alpine Linux: 3.11.3
- Ruby: 2.4.9 1
- Rails: 5.1.2
- 参考: 学習情報 URL
【本文】
□ 事前準備
※ 準備済みの場合は省略可能
■ Docker 準備
インストール方法については、検索したら大量に出てくることから、本記事では詳細を記述しないため、ご了承ください。以下のURLが参考になるかと思います。
- Mac OS X に Docker Toolbox のインストール — Docker-docs-ja 1.10.0 ドキュメント■ Sample App 準備
ご存知の通り、Railsチュートリアルでは、Ruby on Rails を使用してSample App という名称のアプリケーションを作成します。しかし、一から作成するのは手間でしたので、本記事では、YassLab(株)がGitHubに公開しているサンプルコードを使用しました。
なお、サンプルコードを使用する手順は、以下の通りです。○ 1: GitHubから自分のPCにダウンロード
bash$ git clone https://github.com/yasslab/sample_apps.git
○ 2: 使用するプロジェクトのディレクトリ準備
bash$ mkdir sample_app $ cp -rp sample_apps/5_1_2/ch14/* sample_app/ $ cd sample_app□ 1: Dockerfile
- プロジェクトのルートディレクトリからの操作を想定します。
○ 1: Dockerfile生成
bash$ mkdir docker $ touch docker/Dockerfile○ 2: Dockerfileの編集
DockerfileFROM ruby:2.4.9-alpine3.11 ENV LANG C.UTF-8 \ TZ Asia/Tokyo ENV BUILD_PACKAGES="build-base" \ DB_PACKAGES="sqlite-dev postgresql-dev" \ RAILS_PACKAGES="tzdata nodejs imagemagick" \ FAVORITE_PACKAGES="less" RUN apk update && \ apk upgrade && \ apk --update --no-cache add \ ${BUILD_PACKAGES} \ ${DB_PACKAGES} \ ${RAILS_PACKAGES} \ ${FAVORITE_PACKAGES} WORKDIR /app COPY Gemfile \ Gemfile.lock \ /app/ RUN bundle install --jobs=4 # 下記のコードは、頻繁に Gemfile を変更する場合、コメントアウトを推奨します。 # RUN apk del ${BUILD_PACKAGES} # https://github.com/bundler/bundler/issues/6154 ENV BUNDLE_GEMFILE='/app/Gemfile'□ 2: docker-compose.yml
○ 1: Dockerfile生成
bash$ touch docker-compose.yml○ 2: docker-compose.ymlの編集
docker-compose.ymlversion: '3' services: app: build: context: . dockerfile: ./docker/Dockerfile ports: - 3000:3000 command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - ./:/app:cached stdin_open: true tty: true□ 3: コンテナ生成
○ 1: docker-compose.yml を元にコンテナに必要なイメージを構築
bash$ docker-compose build
○ 2: 構築したイメージを元にコンテナを構築して起動
bash$ docker-compose up -d□ 4: Sample App の準備
- ここまでの操作により、Docker によるコンテナ化は終了といって差し支えありません。
- ここからは、通常の Rails アプリケーションに必要な操作と同じです(Heroku の操作感に似てるかと)。
○ 1: コンテナ環境に入る
- Alpine Linux のデフォルトのログインシェルは、
ash
になります。bash
で操作したい方は、拡張機能に適宜追加してください。bash$ docker-compose exec app ash○ 2: データベース関係の準備
- ご存知の通りデータベースがない状態では、 http://localhost:3000 にアクセスしてもアプリケーションは動きません。
- コンテナ内で rails コマンドを試してみましょう。
ash(コンテナ内)$ rails db:create $ rails db:migrate $ rails db:seed○ 3: 作業完了
- これで、開発環境のコンテナ化が完了しました。
- http://localhost:3000 にアクセスして、試しに操作してみてください。
- 終了時は、以下のコマンドとなります。
bash# 一時停止 $ docker-compose stop # 再起動 $ docker-compose start # コンテナ削除 $ docker-compose down□ ※ 注意事項等
■ 注意事項
※ 1: 新たにGemを追加する場合
- bundle install が以下のように失敗する可能性があります。
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
- 原因として、コンテナ環境の OS である Alpine Linux において、導入したい Gem に必要となる OS の拡張機能(=package)がインストールされていないことが多くの理由になるかと思われます。
- 解決策として、エラー文中に記載されているログを
$ cat 〜色々path〜/mkmf.log
で内容を確認して、必要な拡張機能を$ apk add 〜拡張機能〜
で逐一インストールしていけば、解決されるはずです。- 本法で解決した場合は、
$ docker-compose build --no-cache
の際に追加でインストールした拡張機能がリセットされるため、 Dockerfile にも必ず追加しておいてください。- 大元の原因は、本記事で使用した Dockerfile は、限られた拡張機能しかインストールしていないことです。もし、不便に感じる場合は、別のイメージを使用して、自分だけのコンテナ環境の作成に挑戦してみると良いでしょう。Docker 及び Linux の学習に繋がります。
- また、他のエラーとして、 Gem はインストールされるが正常に動作しないこともあります。気が向いたら別記事で簡単に説明します。
※ 思いつき次第追加
■ あとがき
プログラマへの転職前、駆け出しエンジニアで Docker を勉強してる人を散見して、正直焦ってました。入門用の記事や動画を見ても、訳の分からない Dockerfile にコマンドの数々...しかし、実際に転職してからDockerfile の中身を理解してなくても、コンテナ作って作業ができれば十分でした。
この経験から、初期段階ではコマンドが扱えてコンテナを立ち上げられる程度の理解で十分と考えたため、コピペでファイルを作成して、コマンド打つだけの構成にして、簡単に Docker の世界を体験できるようにしてみました。
もちろん、Dockerfile から考えて作成するのも良い勉強になりますが、入社初期にインフラ周りを触らせることも少ないと思うので、コーディングに直接関係する学習を優先した方がよいでしょう(DBとかSQLとかActiveRecordとか...)。
Docker への入門にあたり参考になりましたら幸いです。
Railsチュートリアル公式では、Rubyのバージョンが
2.4.0
でしたが、当該バージョンのDockerfileがサポートされていないため、サポート中で同じマイナーバージョンである2.4.9
を選択しています。2.4.0
を使用したい場合は、Dockerfile中の FROM部分をFROM ruby:2.4.0-alpine
に置換してください。 ↩
- 投稿日:2020-02-16T16:04:14+09:00
Docker Desktop for Mac/Win (Docker for Mac/Win) が遅くて困っているあなたへ
はじめに
Docker Desktopを使用していて動作が重い、CPU負荷が凄いことになっている、volume mountするとIOがとても遅いといった事象で困っている方は沢山いらっしゃるかと思います。
私も同じく、Docker for Macを使用していてDocker(Daemon)の立ち上がりが遅かったり、暴走してDockerのプロセスをkillしたりすることが多々ありました。
しかし、諸々の事情でDockerで開発しなければならない場合もあると思います。
そんな方は是非、こちらの記事を参考にVagrant on Docker
への乗り換えを検討してみてください!メリット
- Docker Desktop特有のVolume mount遅い問題が解決できる
- Windows 10ユーザーはProじゃなくても大丈夫
- CPU暴走しなくなる?(体感の問題かも)
- ローカルに複数のDocker Daemonを建てられる
- Kubernetesのクラスタも作れます
- VMのイメージを他の人に渡せば開発環境ごと共有できる
- ホストOSが変わってもそのまま使える
- PCのお引っ越しも楽々!
- 開発ツールのインストール用shell(tigなど)を作ってしまえば開発環境も一発で構築!
デメリット
- Linuxの知識が必要(Docker使いなら大丈夫かと思います)
- コンテナ内で生成したファイルはPermission変更が必要
→rails generate
やphp artisan
のようなコマンドでソースの雛形を生成する際には毎回権限付与が必要Permissionは以下のコマンドで対応可能です。
LinuxでDocker運用している方で簡単な回避方法があれば教えていただきたいです。
(Dockerfileでadduserする方法以外)# ホストではなく、VM上で実行(Dockerコンテナ外) sudo chmod 777 <対象のファイル> # または sudo chmod -R 777 <対象のディレクトリ>開発環境
- macOS (Windowsでも大丈夫なはず)
- VirtualBox
- Vagrant
- Ubuntu 18.04 LTS
- Docker
- Docker Compose
※階層で仮想環境の中身を表現しています
セットアップ
VirtualBox/Vagrantインストール
以下、Macの場合で記載します。
Windowsの方は以下からダウンロードしてください。
https://www.vagrantup.com/downloads.html# 前提:Homebrew, hobebrew-caskが使用できること brew cask install virtualbox brew cask install vagrantVMのセットアップ
私はUbuntu大好きっ子なので、Ubuntuを対象に構築します。
楽をしたい方は以下のリポジトリを
git clone
してください。
https://github.com/MasanoriIwakura/vagrant-docker.git# Vagrantの設置を保持するディレクトリを作成 mkdir vagrant-docker cd vagrant-docker # Vagrantfile作成 vagrant init ubuntu/bionic64VM内にDockerをインストール
Vagrantfile
を編集し、初期起動時に自動でDockerをインストールされるようにします。今回は記載しませんが、vimを使用されている方はvimrcの設定、
gitの初期設定、tigのインストールなど、開発で使用するツールの設定もこのタイミングで行っておくと便利です。# インストール用のshellを作成 touch dockerinstall.sh中身はこんなかんじです。
#!/bin/bash sudo apt update sudo apt -y install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" sudo apt update sudo apt -y install docker-ce docker-ce-cli containerd.io # permission settings(sudoなしでdockerコマンドを使用する設定) sudo usermod -aG docker vagrant sudo systemctl restart docker exit 0直接Vagrantfileにインストール用のコマンドを記載することもできますが、
可読性と管理のし易さを考慮してshellに分けました。Vagrantfileの修正
上記のshellを実行したり、開発環境を整えるためにVagrantfileに修正を加えます。
# config.vm.box = "ubuntu/bionic64" の下あたりに追記 config.vm.provision :shell, path: "dockerinstall.sh" # docker-compose.ymlでportsを記載する場合、ホストとポートフォワードするには以下を追記 # これを記載するとhttp://localhost:8080 でアクセスできる config.vm.network "forwarded_port", guest: 8080, host: 8080 # ホストのフォルダをマウントしたい場合 # 注意:docker, docker-composeのvolumeと同じにすると遅くなるのであくまでもホストからデータを移動したい時用 config.vm.synced_folder "./mnt", "/host_data" # VMのスペック調整 # config.vm.provider "virtualbox" do |vb| のコメントを解除 # 対応するend のコメントも解除 config.vm.provider "virtualbox" do |vb| # CPUのコア数設定 vb.cpus = "2" # メモリ設定 # 私はホストが16GBなので8192に設定しています vb.memory = "4096" endいざ、実行
# config.vm.synced_folderを設定している場合は先にフォルダを作成しないとエラーになります mkir ./mnt # VM立ち上げ vagrant up # VMにssh # VMから抜ける時はexit vagrant ssh # VM終了(ホスト側で実行) vagrant haltここで一点注意
vagrant halt
をすると起動中のコンテナも問答無用で停止します。(シャットダウンと同じイメージ)その他
私はVisual Studio Code(VSCode)を使用して開発しているのですが、Intellij IDEAやVSCodeを使用している場合は
リモート設定を行うとローカルで開発している感覚でコーディングができるのでおすすめです!VimやEmacs派の方はそのままsshで開発できちゃいますね。
VSCodeでの設定例は割愛しますが、私は以下のリンクを参考に設定しました。
Remote-SSH
という拡張機能を使用します。
https://qiita.com/hppRC/items/9a46fdb4af792a454921Intellij IDEAはこのへん??
https://pleiades.io/help/idea/editing-individual-files-on-remote-hosts.html
- 投稿日:2020-02-16T15:50:04+09:00
reCAPTCHAのサイトを毎日自動スクレイピングする (6/7: コンテナ化)
- 要件定義〜python環境構築
- サイトのスクレイピング機構を作る
- ダウンロードしたファイル(xls)を加工し、最終成果物(csv)を作成するようにする
- S3からのファイルダウンロード / S3へのファイルアップロードをつくる
- 2captchaを実装
- Dockerコンテナで起動できるようにする
- AWS batchに登録
サーバ上で動くようにする
前回までで、一度起動させれば、あとは何もせず自動で動くようになりました。
cronでも設定すれば毎日の実行でもできますが、このままだと 自分のPCをずっと起動させることになってしまいます。
なんとかサーバ上で起動するようにしたいところです。ここで壁になるのが、今回のスクレイピングは、Displayが必須になること。
Chromeのheadlessモードなども試したのですが、うまくいきませんでした。というわけで今回は、少し古い技術ではあるものの
Xvfb
という仮想ディスプレイを作成できる仕組みを使って実装することに。Xvfbは、Linux上で動くアプリケーションです。
ので、LinuxのDockerコンテナを使って実装し、最終的に AWS batchを使ってバッチ実行する方針でいくことにしました。Docker image作成
作成のための検証
※Dockerのダウンロードやインストールは割愛します
まずは、自分の使う
Docker image
を作っていきます。
Xvfbを調べていたら利用実績が多そうだった、CentOSを使っていきます。まずは既存のcentOS imageから起動させ、必要なアプリケーションを実際にインストールしてみます。
mac(host)docker pull centos #DockerHubからcentOSのimageを引っ張ってくる docker run -it -d centos #起動させる docker ps #起動を確認&コンテナIDを取得 docker exec -it b7948c7802eb /bin/bash #コンテナ側のターミナルに入る必要なのは
- python
- pythonパッケージそれぞれ
- Xvfb
- firefox
なのでそれぞれインストールしてみます。
container内でいろいろ試すyum install -y python36 #python入れる python3 -m pip install --upgrade pip #pip入れる pip install requests #必要なパッケージ入れてみる ... yum -y install xorg-x11-server-Xvfb #Xvfbのインストール yum -y install firefox #firefoxのインストール Xvfb :1 -screen 0 1600x1200x16 & #Xvfbの起動 export DISPLAY=:1 #:1と定義したディスプレイを使う firefox #firefoxを起動お。画面がよく見えないのですが、firefox起動してるぽい…?
というわけで次は、ここで自分のプログラムを実行させてみます。ここで私はDockerfileの作成に入りました。
本当はdocker cp
コマンドとかを使って入れてみて試すほうが効率がいいのかも。Dockerfileの作成
FROM centos ENV TZ JST-9 #(1) #ホームディレクトリを設定 ENV HOME=/home WORKDIR $HOME #自分のアプリ(app以下)をhome以下に移す COPY . $HOME/ RUN yum install -y python36 RUN python3 -m pip install --upgrade pip RUN pip install -r app/requirements.txt #(2) RUN yum -y install xorg-x11-server-Xvfb RUN yum -y install firefox RUN chmod 744 startup.sh CMD ["./startup.sh"] #(3)(1) どうやらタイムゾーンはUTCになってしまう模様。今回のバッチは時間が重要なのでタイムゾーンを変更しています
(2) 最初は一行ずつ書いていたのですが、まとめたほうがきれいだったのでrequirements.txtに必要パッケージをまとめました。必要パッケージはpip freeze
コマンドで出てきたものをそのまま記載。
(3) Xvfbの起動コマンドは、docker run
のタイミングですることが必要だとわかったので、shellを作成してまとめました。startup.sh#!/usr/bin/env bash Xvfb :1 -screen 0 1600x1200x16 & export DISPLAY=:1 python3 app/source/run.py --run_mode test #最後はnormalにするがlinuxで動くために少々変更
- geckodriverはlinux用のものをダウンロード
- OSを判断し、どのdriverを使うのか、で分岐するように変更
最終的なファイル構成はこうなります。
├── Dockerfile ├── README.md ├── app │ ├── drivers │ │ ├── geckodriver │ │ └── geckodriver_linux │ ├── requirements.txt │ └── source │ ├── run.py │ ├── scraping.py │ ├── make_outputs.py │ ├── s3_operator.py │ └── configs.py ├── startup.sh └── tmp ├── files │ ├── download │ ├── fromS3 │ └── toS3 └── logs起動してみる
下記のコマンドで実行できます。
docker build -t myapp . docker run -it myapp本当はこんなスラスラといかなかったですけどね…。上のコマンドは40回くらい打った気がします。
しかし、うまく行ったときは感動モノです!
画面は全く見えないけど、コンソールは出ているし、S3にファイルができているのですから。最後は、AWS上で実行させるだけ…。ゴールが見えてきました。
- 投稿日:2020-02-16T15:48:25+09:00
Swaggerを管理しつつ、スタブを自動生成する環境をDockerを使って構築する
APIドキュメントとスタブをまとめて管理できる環境を作りました。
やりたいこと
フロントエンドとバックエンドの認識合わせ、及び開発のため、APIの定義が存在するファイルはフロントエンドとバックエンドが共有するリポジトリに載せておきたいです。
そこで、APIの定義にはSwaggerを使うとします。
この場合、下記を全て実現できると幸せになれると感じました。
- SwaggerをSwagger Editorを使ってAPI定義を書きたい
- Swagger UIでAPI定義を見たい
- 作ったSwaggerファイルから、自動生成されたレスポンスを返してくれるスタブが欲しい
ということで、これらを実現する環境をDockerを使って構築していきたいと思います。
Dockerを使えば環境構築も一瞬で終わりますし、スタブの再生成もコンテナをビルドするだけで行えるので、それぞれ相性が良いです。構成
- API作成 & 編集: Swagger Editor
公式ページ: https://swagger.io/docs/open-source-tools/swagger-editor/- APIドキュメント閲覧: Swagger UI
公式ページ: https://swagger.io/docs/open-source-tools/swagger-ui- スタブサーバー生成: Swagger Codegen
公式ページ: https://swagger.io/docs/open-source-tools/swagger-codegen/ソース
ディレクトリ構成
. ├── docker/ │ └── stub/ │ └── Dockerfile # スタブ用Dockerfile ├── swagger/ # swagger関連のソース用ディレクトリ │ ├── stub/ # swagger.yamlから自動生成されたスタブのソース │ │ ├── index.js │ │ ├── ... │ │ └── ... │ └── swagger.yaml # API定義ファイル └── Makefile # 各種コマンド管理Swagger Editorを使ってAPI定義ファイルであるswagger.yamlを生成し、そのファイルを元にスタブに設置するファイル及び、スタブコンテナをビルドします。
Makefile
ビルドコマンドや各種サーバー起動コマンドの定義です。
IMAGE_STUB=api_stub PORT_SWAGGER_EDITOR=8081 PORT_SWAGGER_UI=8082 PORT_STUB=8080 SWAGGER_DIR_PATH=$(PWD)/swagger SWAGGER_YAML_PATH=${SWAGGER_DIR_PATH}/swagger.yaml # swagger.yamlからスタブ用ソース及びスタブコンテナをビルドする .PHONY: build_stub build_stub: @echo "=== Generating stub file from swagger.yaml is running... ===" docker run --rm \ -v ${SWAGGER_DIR_PATH}:/swagger \ swaggerapi/swagger-codegen-cli generate \ -l nodejs-server \ -i /swagger/swagger.yaml \ -o /swagger/stub @echo "=== Generating stub file is completed. ===\n" @echo "=== Building new container... ===" docker build -f docker/stub/Dockerfile -t ${IMAGE_STUB} . @echo "=== Building container is completed. ===" # スタブを起動 .PHONY: run_stub run_stub: docker run --rm -p ${PORT_STUB}:8000 ${IMAGE_STUB} # Swagger Editor用サーバーを起動 .PHONY: run_swagger_editor run_swagger_editor: docker run --rm -p ${PORT_SWAGGER_EDITOR}:8080 swaggerapi/swagger-editor # Swagger UI用サーバーを起動 .PHONY: run_swagger_ui run_swagger_ui: docker run --rm -p ${PORT_SWAGGER_UI}:8080 \ -v ${SWAGGER_YAML_PATH}:/usr/share/nginx/html/api/swagger.yaml \ -e API_URL=http://localhost:${PORT_SWAGGER_UI}/api/swagger.yaml \ swaggerapi/swagger-uidocker/stub/Dockerfile
Node.jsでホスティングをするだけのシンプルなサーバーです。
FROM node:13.7.0-alpine3.10 ENV APP_HOME /usr/src/app RUN mkdir -p $APP_HOME WORKDIR $APP_HOME # スタブ用ソースをコンテナにコピー COPY swagger/stub/ $APP_HOME EXPOSE 8000 RUN npm install ENTRYPOINT ["npm", "start"]使ってみる
ステップ1: Swagger Editor
まずは、
$ make run_swagger_editor
コマンドでSwagger Editorを起動します。
http://localhost:8081
にアクセス。
Swagger Editor上で、
GET /persons
APIを定義。swagger.yamlswagger: '2.0' info: version: 1.0.0 title: Swagger-sample description: | #### サンプル schemes: - http host: localhost:8080 basePath: /api/v1 paths: /persons: get: summary: Get all persons. parameters: [] responses: 200: description: A JSON array of person model schema: type: array items: $ref: '#/definitions/Person' example: - id: 1 name: Mike age: 23 - id: 2 name: Jun age: 20 - id: 3 name: Jack age: 26 definitions: Person: type: object properties: id: type: integer name: type: string age: type: integerSwagger Editor上の
Save as YAML
をクリックし、ダウンロードされたswagger.yamlをswaggerディレクトリ配下へ移動。
$ cp ~/Download/swagger.yaml ./swaggerステープ2: Swagger UIでAPIを確認
$ make run_swagger_ui
コマンドで、Swagger UIを起動します。
http://localhost:8082
にアクセス。
すると、先ほど作成したAPIがSwagger UI上で表示されることを確認できます。
ここまでで、Swaggerを管理する環境はできました。
それでは、本題のスタブの用意へと移りましょう。ステップ3: スタブコンテナビルド
$ make build_stub
でスタブコンテナをビルド。
Building container is completed.
が表示されれば完了です。なお、ここでは下記の順でビルドが行われます。
1. スタブ用ソースを自動生成
2. 自動生成されたソースがパッケージングされたコンテナをビルドステップ4: スタブを使用してAPIを呼び出す
$ make run_stub
でスタブコンテナを起動。
まず、http://localhost:8080/docs
へアクセスすると、先ほど定義したAPIがドキュメントとして表示されます。
では、
http://localhost:8080/api/v1/persons
へアクセスしてみましょう。
すると、SwaggerファイルにてExampleで定義したレスポンスが返ってくることが確認できます。
これで、Swaggerファイルで定義したレスポンスからスタブを自動生成し、呼び出せることが確認できました!
まとめ
Swagger Editorでswagger.yamlを作成し、それをSwagger UIで確認、及び定義したAPIのレスポンスを返すスタブに変換し呼び出せる環境を構築しました。
APIを開発するのであればAPIドキュメントは必須ですし、さらにそのAPIを開発中にフロントエンド側で使いたいとなるとスタブの開発は不可欠です。
スタブの自動生成を使用すれば、APIとスタブの二重管理などの手間も省けます。しばらく使ってみて、また知見があれば記録を残そうと思います。
補足
Swagger Editorで編集したファイルをダウンロードしてswaggerディレクトリ配下に設置するところのみ、手動のオペレーションが発生してしまっています。
ここに関して自動化させられるやり方をご存じの方がいらっしゃいましたら、アドバイスをいただけますと嬉しいです m(__)m
- 投稿日:2020-02-16T14:46:00+09:00
コンテナからイメージを作成してdocker hubにpushする
目的
dockerコンテナにriscvのクロスコンパイラ環境を構築する際にriscv-toolchainのbuildに想像以上に時間が掛かり、また同じように環境作成を行うのはしんどいと思ったので環境作成中に一旦commitしてイメージを作成しようと考えた。ついでにdocker hubへのpushも行っておく。
参考記事
https://qiita.com/tubone/items/a3bad04abf4c700cae3d
https://www.memotansu.jp/docker/626/
http://docs.docker.jp/engine/reference/commandline/commit.html作業環境
- Windows10 Home Insider Preview
- バージョン:2004
- OSビルドバージョン:19564
- WSL2 Ubuntu18.04
- Remote-WSL(VSCode)
手順
稼働中のコンテナの停止
まずは稼働中のコンテナを停止するので、停止するコンテナを調べる。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e21a09577ff9 rust-env "/bin/bash" 10 hours ago Up 10 minutes rust-env調べて停止したいコンテナがあったら停止する。
(commitする際にコンテナが一時停止するようなのでこの手順はなくていいかも)$ sudo docker stopdockerコンテナのイメージ作成
docker commitで以下のように作成する。
docker commit [コンテナ名] [リポジトリ名]:[tag名]
$ sudo docker commit rust-env chilchil/rust-env:latest sha256:1cd5668d157123abe7b3422623c21f96766df0df7e9c2a850e1d28aa488dd1feイメージが作成されたかどうか確認する。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE chilchil/rust-env latest 1cd5668d1571 53 seconds ago 14.3GBdocker hubにpush
作成したイメージをdocker hubにpushする。docker hubへのリポジトリの作成とかは以下を参照。
https://qiita.com/umi/items/d4b5a68263ad0444693b$ sudo docker login Authenticating with existing credentials... ~省略~ Login Succeeded $ sudo docker push chilchil/rust-env The push refers to repository [docker.io/chilchil/rust-env] ~省略~ latest: digest: sha256:175c3dadc63c15f5a3c369078999722553b9200158028cf97685baa911d0e168 size: 2624pushしたdockerイメージを確認する。(publicである場合)
takayama@DESKTOP-MO8SE8A:~$ sudo docker search chilchil NAME DESCRIPTION STARS OFFICIAL AUTOMATED chilchil/rust-env 0以上になります。
- 投稿日:2020-02-16T13:31:50+09:00
docker runがエラー(Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use)
docker run -p 80:80 -p 443:443 -d --privileged centos:latest /sbin/initを行うと下記エラーとなる。
docker: Error response from daemon: driver failed programming external connectivity on endpoint amazing_proskuriakova (65b0d6d847914cee8f6129bd36fed4d0a1c67843be6413d238f0c376af150950): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use結論
80番ポートであるapacheが起動していたから起こったエラー
解決策
1.ポート番号をずらしてコマンドを実行してみる。
(sudo)docker run -p 88:88 -p 443:443 -d --privileged centos:latest /sbin/init
このようにポート番号を80ではなく88にずらして実行
2.すでに80番ポートで起動しているプロセスを終了する
sudo lsof -i -P | grep "LISTEN"
[root@ip-172-31-28-29 ~]# lsof -i -P | grep "LISTEN" rpcbind 2677 rpc 8u IPv4 16507 0t0 TCP *:111 (LISTEN) rpcbind 2677 rpc 11u IPv6 16510 0t0 TCP *:111 (LISTEN) httpd 3057 root 4u IPv6 18359 0t0 TCP *:80 (LISTEN) httpd 3093 apache 4u IPv6 18359 0t0 TCP *:80 (LISTEN) httpd 3094 apache 4u IPv6 18359 0t0 TCP *:80 (LISTEN) httpd 3095 apache 4u IPv6 18359 0t0 TCP *:80 (LISTEN) httpd 3096 apache 4u IPv6 18359 0t0 TCP *:80 (LISTEN) httpd 3097 apache 4u IPv6 18359 0t0 TCP *:80 (LISTEN) master 3200 root 13u IPv4 18805 0t0 TCP localhost:25 (LISTEN) sshd 3364 root 3u IPv4 20172 0t0 TCP *:22 (LISTEN) sshd 3364 root 4u IPv6 20174 0t0 TCP *:22 (LISTEN) container 3502 root 7u IPv4 21589 0t0 TCP localhost:34781 (LISTE )apacheが起動していました。
さっそく終了させます。
sudo apachectl stop今思えば、以前にシステムがブートするたびに Apache ウェブサーバーが起動するように下記コマンドで設定していました。
sudo chkconfig httpd on
- 投稿日:2020-02-16T10:44:32+09:00
Dockerで起動したJupyter Notebookでvimキーバインドを使う
概要
最近はデータサイエンスの勉強で統計学の本を読んでいるのですが、本を読んでいるだけだとなかなかイメージしにくいこともあるので、Jupyter Notebookを使って手元でコードを書きながらやりたいなと思いました。
Jupyter Notebookでコード書くならvimのキーバインドが使えないとテンションが上がらないのでvimが使えるようにしたいと思いましたが、多少ハマった部分などあったのでやり方をまとめました。環境
バージョン Mac 10.15.3 Docker 19.03.4 docker-compose 1.24.1 環境構築手順
Dockerfileとdocker-composeを使ってvimのキーバインドが使えるJupyter Notebookを起動します。
※以下ファイルはGitHubにもまとめているのでご参考ください。
https://github.com/hikarut/Data-Science1. notebook保存用のディレクトリ作成
$ mkdir notebooks2. Dockerfileの作成
DockerfileFROM jupyter/minimal-notebook:latest USER root RUN pip install jupyter_contrib_nbextensions && \ jupyter contrib nbextension install --user && \ git clone https://github.com/lambdalisue/jupyter-vim-binding /home/jovyan/.local/share/jupyter/nbextensions/vim_binding && \ jupyter nbextension enable vim_binding/vim_binding EXPOSE 10000 CMD ["bash"]※
jupyter-vim-binding
レポジトリのクローン先はコマンドjupyterのpathと合わせる必要があります。(jupyter --path
コマンドで確認出来ます)3. docker-compose.ymlの作成
docker-compose.ymlversion: '3' services: data-science: restart: always build: . container_name: 'data-science' ports: - "10000:10000" working_dir: '/root/' tty: true volumes: - ./notebooks:/root/notebooks/4. コンテナのビルド
$ docker-compose up -d --build5. コンテナにログイン
$ docker-compose exec data-science bash6. Jupyter Notebookの起動
/root# jupyter notebook --port 10000 --allow-root表示される
http://127.0.0.1:10000/?token=xxxxxxxxxxxxxxxx
にアクセスします。7. VIM bindingのエクステンションを有効にする
デフォルトだとエクステンションの設定に
disable
にチェックが入っているのでチェックを外して有効にします。
最後に
Jupyter Notebookでvimのキーバインドを使えるようにするやり方は結構まとまっていたのですが、色々試していたら以外とハマった部分もあったので自分なりにまとめてみました。
これで快適なNotebookが書けそうです!
(ただ今回はユーザーを全てrootにしちゃったのでその辺は変えた方が良いかもです。。)参考
- 投稿日:2020-02-16T09:49:21+09:00
【Docker入門①】そもそも『Docker』とは…?
この記事では、《Docker や コンテナ》について、
僕が学習した内容をまとめています。
- 『Docker』とは…?
- 『Docker』って何が良いの…?
- 『Docker』のアーキテクチャ(構成)
こういった疑問についてまとめています。
※本記事は、自分で学習したことのまとめ用として書いています。
尚、解説で誤った点があれば、スローして頂ければ喜んでキャッチしますのでお願い致します。『Docker』とは…?
『Docker』とは・・・
Linux上でコンテナを作成・管理・実行するためのプラットフォームです。
Docker社(旧dotCloud社)によって、2013年3月に初版がリリースされ、現在ではインフラ関係やDevOps界隈で注目されている技術の一つです。
Windowでも・・・
Windows Server 2016 からはWindowsコンテナが利用できるようになりました。
※Windowsコンテナは、Windows上でのみ実行可能です『Docker』を利用すると何がメリットなの…?
『Docker』はLinuxのコンテナ技術を使ったもので、よく『仮想マシン』と比較されます。
なので、まずは・・・
『仮想マシン』と『コンテナ』の違い
について簡単に見ていきましょう。
『仮想マシン』と『コンテナ』について
『仮想マシン』は・・・
ホストOS上で『VirtualBox』や『VMware』などのハイパーバイザー(仮想化ソフトウェア)を利用して仮想マシンを作成し、その仮想マシンのゲストOS上でアプリやミドルウェアを動かします。
そのため・・・
起動に時間がかかるというデメリットがあります。
(もちろん、完璧に環境を分離できるというメリットもありますが…)それに対し、『Docker』は・・・
ホストOSのみの使用でプロセスやユーザなどを隔離することで、ホストOS上にあたかも別のマシンが動いているかのような環境を作ります。
そのため・・・
軽量で、且つ高速に起動・停止することが可能になります。
『Docker』を利用するメリット【5つ紹介】
『Docker』では、開発環境の構築(ミドルウェアのインストールや各種環境設定)をコード化して管理します。
そのため・・・
『Docker』を利用することで、以下のようなメリットがあります。
- コード化して管理することで、
誰でも、どこでも同じ開発環境が構築できる- 構築した開発環境を簡単に配布できる
例えば・・・
"開発環境(Windows上)では正常に動作したけど、Linuxでは動作しなかった"
なんて経験がある方もいるかと思いますが…
このケースの場合、開発工程から『Docker』を利用することで防ぐことができます。
さらには・・・
『開発工程の中で使っていた環境をそのまま本番環境に持っていく』
なんてことも可能なので、差分の発生がなくなり、環境差分によるトラブルも防ぐことができます。
また・・・
作成した
Docker イメージ
は他の開発メンバーにも渡せるので、それを使ってもらうことで…
- メンバー間での開発環境のバージョンずれ防止
- 準備時間(開発環境を準備する時間)の短縮
にもつながります。
実際・・・
"資料の不備や手順ミスが原因で、開発環境の準備に丸一日かかってしまった"
なんて経験がある方も多いんではないでしょうか…苦笑
そんなところで、メリットをまとめると下記の5つのようなモノが挙げられます。
- 起動が速い
- コード化して管理することで、
誰でも、どこでも同じ開発環境が構築できる- 構築した開発環境を簡単に配布できる
- メンバー間での開発環境のバージョンずれ防止
- 準備時間(開発環境を準備する時間)を短縮できる
※あくまで一部なので、他にもたくさんあると思います
『Docker』のアーキテクチャ(構成)
『Docker』のシステム構成に関してのお話で、要は…
『コンテナをどうやって動かすか』
ってことについてです。
具体的には、『Docker』は下記の4つで構成され、サービスを提供しています。
- Docker デーモン
- Docker クライアント
- Docker イメージ
- Docker コンテナ
それでは、ひとつずつ見ていきましょう。
①:Docker デーモン
Docker デーモン
は・・・コンテナの管理・実行を行います。
Docker デーモン
はイメージからコンテナを作成したり、実行したりするだけの存在なので・・・実際は、
Docker デーモン
に対して指示を出すシステムが必要です。それが、お次に紹介する『Docker クライアント』です。
②:Docker クライアント
Docker クライアント
は・・・『Docker』を操作するためのアプリケーションです。
管理者からのコマンドを受け付けたら、その先にある
Docker デーモン
へ指示を飛ばし、それによってコンテナが動いたり止まったりする訳です。③:Docker イメージ
Docker イメージ
は・・・コンテナの元になるひな形で、
Docker レジストリ
に保管されます。
Docker レジストリ
としては、Docker Hubと呼ばれるオンラインサービスが提供されており、そこではイメージの共有やダウンロードが可能です。④:Docker コンテナ
Docker コンテナ
は・・・Docker イメージを元にして実行されたプロセスです。
各コンテナは分離されているので、独立したホストの同じように扱うことが可能です。
まとめ・感想
『Docker』に関しても『業務のなかでもやってみたい!』と思ってますが、なかなかチャンスがなさそう…。
(待っててもチャンス来ないので、行動するしかないですね笑)今後は…
『Dockernのセットアップやコンテナの起動方法』
についてもまとめる予定です。
- 投稿日:2020-02-16T09:19:52+09:00
Rails Tutorialの知識から【ポートフォリオ】を作って勉強する話 #19 Docker編
こんな人におすすめ
- プログラミング初心者でポートフォリオの作り方が分からない
- Rails Tutorialをやってみたが理解することが難しい
前回:#18 EC2環境構築, Nginx+Puma+Capistrano編
番外:#18.5 環境変数, Gmail送信設定編
次回:準備中今回の流れ
- 完成のイメージを理解する
- Dockerを導入する理由を知る
- RailsアプリをGitHubからクローンする
- ローカルの開発環境を整える
- Dockerをインストールする
- Dockerの仕組みを理解する
- Dockerのファイルを作成する
- Dockerを起動する
- トラブルシューティング
この記事は、動画を観た時間を記録するアプリのポートフォリオです。
今回は、Railsアプリの開発環境にDockerを組み込みます。
ローカル(ホスト)にはMacを使います。完成のイメージを理解する
はじめにDockerの必要性を知ります。
ローカル(Mac)にRailsアプリがない、動く環境にない方は先に環境を整えます。次にDockerを構成します。
具体的には、プロセスをapp(RailsやPumaなど)db(MySQL)nginx(Nginx)の3つに分け、Docker Composeで定義します。
ここでDockerを構成しながら、Dockerの理解を深めます。最後にDockerを起動します。
起動がスムーズに行くことは稀で、何らかのエラーが発生します。
トラブルシューティングを活用しながら、起動を成功させます。以上です。
Dockerを導入する理由を知る
Dockerは、軽くてポータビリティのある開発環境ツールです。
Dockerは、モダンな企業のほとんどが使うツールです。
Dockerを、ポートフォリオに組み込むことで、転職先の企業とのマッチング率を高めるという狙いがあります。さてDockerの動作については、こちらの記事が分かりやすいので、一読します。
いまさらだけどDockerに入門したので分かりやすくまとめてみたRailsアプリをGitHubからクローンする
RailsアプリをローカルであるMacにクローンします。
※ すでにローカルでRailsアプリを開発している方は飛ばしてください。local(自分のMacターミナル)$ vi ~/.gitconfig
.gitconfig[user] name = Gitに登録している名前 email = Gitに登録しているメールアドレス [url "github:"] InsteadOf = https://github.com/ InsteadOf = git@github.com:local$ cd ~/.ssh $ ssh-keygen -t rsa Enter file in which to save the key ():git_rsa Enter passphrase (empty for no passphrase): # 何もせずエンター Enter same passphrase again: # 何もせずエンター $ vi config.ssh/config# 以下を追加 Host github Hostname github.com User git IdentityFile ~/.ssh/git_rsalocal$ cat git_rsa.pub # 中身をコピーGitHubにログイン
右上アイコン『Settings』 → 『SSH and GPG keys』 → 『New SSH key』Title:任意 Key:コピーした公開鍵をペーストlocal$ cd ~ $ git clone -b ブランチ名 git@ github.com:GitHubのユーザー名/アプリ名.git以上でRailsアプリのクローンは完了です。
参考になりました↓
リモートから特定のブランチを指定してcloneするローカルの開発環境を整える
ローカル(Mac)の開発環境を整えます。
ここでの手順は以下の通りです。
※ すでにローカルでRailsアプリを開発している方は飛ばしてください。
- Homebrewをインストールする
- Rubyをインストールする
- Bundlerをインストールする
- MySQLをインストールする
Homebrewをインストールする
Homebrew(公式)をインストールします。
HomebrewはMacでよく利用されるパッケージ管理です。local(Mac)/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"Rubyをインストールする
Rubyをインストールします。
RubyはMacに標準で入っていますが、バージョン管理のためにrbenvを使います。local(Mac)$ brew install rbenv ruby-build $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile $ source .bash_profile $ rbenv install 使いたいバージョン $ rbenv global 使いたいバージョン $ rbenv rehashBundlerをインストールする
Bundlerをインストールします。
$ gem install bundlerMySQLをインストールする
MySQLをインストールします。
$ brew install mysql参考になりました↓
Ruby初学者のRuby On Rails 環境構築【Mac】Dockerをインストールする
Docker Desktop for Macからアカウントを作成し、インストールします。
手順は以下の通りです。
- 『Get Started』からDcokerHubアカウントを作成する
- 『Get Docker』からDockerをインストールする
参考になりました↓
DockerをMacにインストールするDockerの仕組みを理解する
それではDockerを使って、環境を構築します。
仕組みとしては、app(RailsとPuma)db(MySQL)nginx(Nginx)のイメージをDockerfileなどで用意し、Docker Composeでプロセスを起動させます。早速、以下のようにホスト側のディレクトリを構成します。
Dockerの各ファイル、用語は後述します。lantern_app ├── config │ ├── database.yml(既存) │ └── puma.rb(既存) ├── containers │ └── nginx │ ├── Dockerfile │ └── nginx.conf ├── docker-compose.yml ├── Dockerfile ├── environments │ └── db.env ├── Gemfile(既存) ├── Gemfile.lock(既存) └── 他用語を説明します。
Image
色々な環境を提供してくれる入れ物のことです。
イメージからRubyやNginxなどを取得します。Dockerfile
イメージを作るためのファイルです。
イメージを元に機能を拡張するなどの用途があります。Volume
データ永続のための保存場所です。
Dockerのデータはコンテナの終了とともに消えるため、必要に応じて設定します。Container
イメージを元に作られたプロセスのことです。
イメージを起動すると、環境がプロセスとしてコンテナに隔離されます。Docker Compose
複数のコンテナを定義・実行するツールです。Dockerのファイルを作成する
それではDockerのディレクトリとファイルを作成します。
local(Mac)$ touch Dockerfile docker-compose.yml $ mkdir containers containers/nginx environments $ cd containers/nginx $ touch Dockerfile nginx.conf $ cd ../.. $ touch environments/db.env各ファイルを編集します。
各ファイルの詳細は、後述します。Dockerfile# 元にするイメージ FROM ruby:2.6.3 # コンテナを機能させるまでの準備のコマンドを実行する RUN apt update -qq && \ apt install -y build-essential nodejs RUN mkdir /lantern_docker # 環境変数を設定する ENV APP_ROOT /lantern_docker # コマンドを実行するディレクトリを設定する WORKDIR $APP_ROOT # ホストのファイルをコンテナにコピーする ADD Gemfile $APP_ROOT/Gemfile ADD Gemfile.lock $APP_ROOT/Gemfile.lock # 既出 RUN gem install bundler RUN bundle install ADD . $APP_ROOT RUN mkdir -p tmp/sockets # コンテナ起動時のポートを設定する EXPOSE 3000RailsアプリはRubyイメージを元にして作成します。
RUN apt ...でRailsが動く環境をインストールし、ADD . $APP_ROOTでGemfileなどをコンテナにコピーし、RailsやPumaなどを動作させます。docker-compose.yml# Docker Composeのバージョン version: '3' # Docker Composeではコンテナをサービスとして扱う services: # サービス名をappとして定義 app: # 参照するDockerfileを指定(docker-compose.ymlから基準) build: . # 環境変数が設定されているファイルを指定 env_file: - ./environments/db.env # ボリュームをマウント(後述) volumes: - .:/lantern_docker # サービス名dbが作成されたらappを作成 depends_on: - db # コンテナを起動させ続ける際に使用 tty: true # コマンドを実行 command: bundle exec puma -C config/puma.rb db: # イメージを指定(後述) image: mysql env_file: - ./environments/db.env # ボリュームをマウント(後述) volumes: - db-data:/var/lib/mysql nginx: build: containers/nginx # ホスト:コンテナのポートを指定 ports: - "80:80" depends_on: - app # ボリュームとして扱うボリューム名 volumes: db-data:Docker Composeの各サービスは、DockerfileまたはDockerHubのイメージを参照します。
ここでは、appとnginxがDockerfile、dbがイメージを参照しています。appのボリュームは、ホスト側のホームディレクトリ全てをボリューム化しています。
dbのボリュームは、コンテナ側のディレクトリ/var/lib/mysqlをdb-dataというボリューム名でボリュームをマウントしています。この辺りはややこしく、参考記事を読むことをおすすめします。
参考になりました↓
Docker、ボリューム(Volume)について真面目に調べた
Dockerの-vや--volumeオプションはわかりづらいから、--mountを使おう
バインドマウント | Docker docs(日本語)
Pumaの起動におけるpumaコマンドとpumactlコマンドの違いcontainers/nginx/DockerfileFROM nginx RUN rm -f /etc/nginx/conf.d/* ADD nginx.conf /etc/nginx/conf.d/lantern_docker.conf CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.confNginxはフォアグラウンドでの動作を期待しているので、'deamon off;'とします。
フォアグラウンドとバックグラウンドの違いは、PCで表すとこんな感じです。
- フォアグラウンド:一番上のウインドウ
- バックグラウンド:それ以外のウインドウ
参考になりました↓
フォアグラウンド(foreground)とは | 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典containers/nginx/nginx.conf# Pumaとやり取りするための通信路 upstream lantern_docker { server unix:///lantern_docker/tmp/sockets/puma.sock; } # サーバーに関する情報 server { # ポート listen 80; # 処理するサーバー名 server_name localhost; # ログに関するファイルの場所 access_log /var/log/nginx/access_log; error_log /var/log/nginx/error_log; # ドキュメントルートの設定 root /lantern_docker/public; try_files $uri/index.html $uri @app; # 内部リダイレクトの処理 location @app { # バックエンドサーバーに送信するヘッダーを定義し直す proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; # プロキシのパス(Pumaに渡す) proxy_pass http://lantern_docker; proxy_redirect off; } }アプリ名を自分のものに変更します。
Nginxの設定は#18で説明済みなので、省略します。environments/db.envMYSQL_USER=ユーザー名 MYSQL_ROOT_PASSWORD=パスワード MYSQL_HOST=エンドポイント環境変数の設定です。
エンドポイントが分からない場合、#17.5をご覧ください。config/database.ymldefault: &default adapter: mysql2 encoding: utf8 timeout: 5000 reconnect: false pool: 5 socket: /var/lib/mysql/mysql.sock username: <%= Rails.application.credentials.mysql[:user_name] %> password: <%= Rails.application.credentials.mysql[:password] %> host: <%= Rails.application.credentials.mysql[:host] %> development: <<: *default database: lantern_development test: <<: *default database: lantern_test production: <<: *default database: lantern_productionMySQLの設定です。
credentailsが未設定の場合は、#18.5をご覧ください。config/puma.rbworkers Integer(ENV['WEB_CONCURRENCY'] || 2) threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5) threads threads_count, threads_count preload_app! rackup DefaultRackup port ENV['PORT'] || 3000 environment ENV['RACK_ENV'] || 'development' on_worker_boot do ActiveRecord::Base.establish_connection end plugin :tmp_restart app_dir = File.expand_path("../..", __FILE__) bind "unix://#{app_dir}/tmp/sockets/puma.sock" pidfile "#{app_dir}/tmp/pids/puma.pid" stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", truePumaの設定です。
ここも#18で説明済みなので、省略します。以上で、Dockerのファイル編集は完了です。
Dockerを起動する
Docker Composeを使ってDockerコンテナを起動します。
local(Mac)# Dockerfileからイメージをビルド $ docker-compose build # Docker Composeのコンテナを起動(-dでバックグラウンド起動) $ docker-compose up -d # Docker Composeのコンテナのプロセスを確認 $ docker-compose ps以上でDockerの組み込みは完了です。
後は各コンテナに入り、開発を進めてください。shell# appのbashに入る $ docker-compose exec app bash # 例 $ rails db:migrate参考になりました↓
Docker + Rails + Puma + Nginx + MySQL
丁寧すぎるDocker-composeによるrails5 + MySQL on Dockerの環境構築(Docker for Mac)
既存のRailsアプリにDockerを導入する手順
Nginx + Rails (Puma) on Docker のいくつかの実用パターン
Docker + Rails + Puma + Nginx + Postgres
Docker ComposeでNginx Rails MySQL環境を構築してみるトラブルシューティング
Dockerで起動する際、様々なエラーが発生します。
一例ですが、私が見舞ったトラブルの解決策を書き残します。よく使うスクリプトを確認する
先によく使うスクリプトを紹介します。
まずはDockerやDocker Composeのコマンドを紹介します。shell# ログの確認 $ docker-compose logs # サービスの確認 $ docker-compose ps -a # コンテナの確認 $ docker ps -a # コンテナとネットワークの停止と削除 $ docker-compose down --rmi all # コンテナの削除 $ docker rm ID名 # イメージの削除 $ docker rmi ID名 # コンテナのbash内に入る $ docker-compose exec サービス名 bash続いてbashを紹介します。
bash# ディレクトリの有無を確認する(出力0=有、出力1=無) $ test -f パス;echo $? # プロセスが使用しているポートを確認する $ lsof -i # ポートを指定してプロセスを確認する $ lsof -i:ポート番号以上です。
以降から、具体的なトラブルシューティングに入ります。参考になりました↓
Docker実践〜dockerのコンテナ環境をきれいに消す
docker-compose up したコンテナを起動させ続ける方法
Linux/UNIXでファイル・ディレクトリの存在確認をする
Linuxでプロセスが何のポート使っているかを調べる/usr/local/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.1.4) (Gem::GemNotFoundException)
Bundlerが見当たらないのでエラーが発生します。
GemからBundlerをインストールします。Dockerfile# 以下を追加 RUN gem install bundler参考になりました↓
Docker + Rails のdocker-compose build でGemNotFoundExceptionの時の対処mysql client is missing.
MacにMySQLがないためにエラーが発生します。
HomebrewでMySQLをインストールします。local(Mac)$ brew install mysql参考になりました↓
mysql2 が原因でbundle installにてエラーを吐く(Mac OS X)uses an image, skipping
こちらはエラーではありません。
すでにビルドが済んだイメージをリモートで取得するので、upすれば問題ありません。local(Mac)$ docker-compose up -d参考になりました↓
docker-compose.yml起動時にuses an image, skippingされる現象
docker-compose `up` とか `build` とか `start` とかの違いを理解できていなかったのでまとめてみた。error: database is uninitialized and password option is not specified
データベースのエラーです。
データベースが初期化されていない、パスワードがないため発生します。
環境変数のあたりを確認します。environments/db.envMYSQL_USER=ユーザー名 MYSQL_ROOT_PASSWORD=パスワード MYSQL_HOST=エンドポイントdocker-compose.yml# 中略 db: image: mysql env_file: - ./environments/db.env # 中略参考になりました↓
docker, docker-composeでmysqlが起動しない
docker-compose.ymlで.envファイルに定義した環境変数を使う
How to link MySQL RDS in docker-compose.yml file?NoMethodError: Cannot load database configuration:
データベースのエラーです。
データベースに関する設定に問題があります。解決策1:ttyをtrueにする
ttyをtrueにすると解決するかもしれません。
docker-compose.ymlapp: # 中略 tty: true # 中略参考になりました↓
docker-compose up したコンテナを起動させ続ける方法
docker-composで起動したコンテナがすぐに停止する解決策2:database.ymlのERbを削除する
コメントアウトしていてもERbは評価されます(恐らく)。
database.yml内のERbは削除します。config/database.yml# 以下で書かれた必要ない箇所を削除する <%= %>参考になりました↓
Rails を起動したら Cannot load `Rails.application.database_configuration`: (NoMethodError) が出てハマった502 Bad Gateway
何らかのサーバーに関するエラーです。
私の場合は、以下のように変更すると解決しました。nginx.confupstream lantern_docker { # ソケットからサービス名に変更 # server unix:///lantern_docker/tmp/sockets/puma.sock; server app:3000; } # 中略参考になりました↓
Docker Compose と nginx でリバースプロキシを作ろうとしたお話(出題編)
前回:#18 EC2環境構築, Nginx+Puma+Capistrano編
番外:#18.5 環境変数, Gmail送信設定編
次回:準備中
- 投稿日:2020-02-16T09:18:39+09:00
(ドラフト/メモ)Dockerコンテナベースで動作するメールサーバ
1.Mailu
https://github.com/Mailu/Mailu・Mailuで簡単にWebUI付きのメールサーバを立てる
https://qiita.com/kter/items/7cad987794b6610e49832.mailcow
https://mailcow.email/3.tomav/docker-mailserver
https://github.com/tomav/docker-mailserverPostfix with smtp or ldap auth Dovecot for sasl, imap (and optional pop3) with ssl support, with ldap auth Dovecot is installed from the Dovecot Community Repo saslauthd with ldap auth Amavis Spamassasin supporting custom rules ClamAV with automatic updates OpenDKIM OpenDMARC Fail2ban Fetchmail Postscreen Postgrey basic Sieve support using dovecot LetsEncrypt and self-signed certificates Setup script to easily configure and maintain your mailserver persistent data and state (but think about backups!) Integration tests Automated builds on docker hub Plus addressing (a.k.a. extension delimiters) works out of the box: email for you+extension@example.com go to you@example.com Why I created this image: Simple mail server with Docker Before you open an issue, please have a look this README, the Wiki and Postfix/Dovecot documentation. Requirements Recommended: 1 CPU 1-2GB RAM Swap enabled for the container Minimum: 1 CPU 512MB RAM Note: You'll need to deactivate some services like ClamAV to be able to run on a host with 512MB of RAM. Even with 1G RAM you may run into problems without swap, see FAQ.・Dockerでメールサーバーを建てたときのメモ
https://blog.netaka.net/mailserver_on_docker/