- 投稿日:2020-03-18T23:56:25+09:00
WSL2,Docker,Studio 3tではまったところ
win10で、WSL2,Docker,Studio 3Tを使用した時にStudio 3TからDocker上のmongodbに繋げなくて、はまったことについて書きます。
WSL2はlocalhostではない。
基本的なことですが、WSL2をlocalhostだと思っていました。なので、Stdio 3TでCONNECTのhost sererをlocalhost(初期値)に設定して繋げようとしたのですが、「Cnnecting to server」がfalseになって、つながりませんでした。
そこで、下記の事を行いました。
①WSL2のubuntuのipアドレスを知る。
ubuntuで下記コマンドをたたいて、ipアドレスを知ります。$ hostname -I②Studio 3Tのconnectionのseverに①で調べたipアドレス(192.168.0,0みたいなもの)を入力
これでつながりました。
補足ですが、STUDIO 3tでデータをIntelliShellで作成したが、すぐには反映されず、Studio 3Tを再起動しなければ作成したデータが見れませんでした。何かwin10で使用する際に癖があるのでしょうか?
以上です。
- 投稿日:2020-03-18T22:09:46+09:00
Sequel Proに接続できなかったときの備忘録
はじめに
dockerで起動した
mysqlコンテナ
とSequel Pro
の接続が出来なかったので備忘録として記録します。設定
docker-compose.yml#一部抜粋 db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "3306:3306"SequelPro名前:local(任意) ホスト:127.0.0.1 ユーザ名:root パスワード:password ポート:3306接続できずにエラー発生。
ググる。
ポート番号がすでにローカルで使われているかもしれない!という記事にたどり着く。
dockerで起動したmysqlコンテナにsequel proで接続するポートの確認
ポート番号の確認をしてみる。(portscanを実行する)
ローカルで使用されているポート番号の調べ方はこちらの記事を参考にしました。
Macで使用しているポートを調べる方法とポートを使用しているプログラム確認方法以前にローカルで使用した
mysqlですでに3306番が使われていることが発覚!ポート番号の変更
docker-compose.yml#一部抜粋 db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: root ports: - "4306:3306" ←←変更変更後、再度docker-compose buildをやりなおしコンテナを立ち上げ、Sequel Proへの接続が無事に成功しました。
締め
いろいろ調べていくとmysql8.0にするとSequelProへの接続がエラーになったという情報もちらほら見られた。mysql8.0は現時点では情報量も少ないので、mysql5.7の方が扱いやすいかもですね。
- 投稿日:2020-03-18T18:54:41+09:00
Azuriteでローカル環境構築(Docker + PHP + Azure Storage)
目的
Azuriteを利用してDocker + PHP + Azure Storageのローカル環境を構築します。
Dockerによるローカル環境構築を進めてきましたがStorageはAzureプラットフォームのを利用していたので、Azuriteを利用してローカル環境だけで完結させます。Azuriteとは
Azure Storageのエミュレーター。
ローカルでの Azure Storage の開発とテストに Azurite エミュレーターを使用する (プレビュー)
AzuriteかAzure ストレージ エミュレーターか
Azurite は今後のストレージ エミュレーター プラットフォームです。Azurite は Azure ストレージ エミュレーターよりも優先されます。
ということなので今後もこちらを使っていけば良さそうです。
Azuriteのインストール方法
- Azurite Docker イメージをインストールして実行する
今回はDockerを利用するのでこちらを選択します。
Docker環境
docker-compose.yml
version: '3' services: php: # 省略 storage: image: mcr.microsoft.com/azure-storage/azurite prots: - "10000:10000" volumes: - ./docker/storage/data:./dataPHPのコンテナについては割愛します。
公式のPHPライブラリ を利用してAzure Storageを利用できればAzuriteに関しても問題ないと思ってます。また、今回はBlobだけを使用するのでTableとQueueについても割愛します。
Azure Storage Explorerから接続してみる
接続ダイアログから「ローカル エミュレーターにアタッチする」を選択してアタッチします。
AzuriteにBlobを作成する
phpでBlobを作成していきます。
<?php require_once '../vendor/autoload.php'; $connection = '<接続文字列>'; $client = \MicrosoftAzure\Storage\Blob\BlobRestProxy::createBlobService($connection); $container = 'sample'; // 事前に作成しておく $blob = 'example.txt'; $content = 'Hello Azurite!'; $client->createBlockBlob($container, $blob, $content);接続文字列について
$connection = 'UseDevelopmentStorage=true';基本はこのショートカットでOK。
しかしDocker環境だと事情が異なります。
これで先程の処理を実行しようとすると・・・cURL error 7: Failed to connect to 127.0.0.1 port 10000
Dockerコンテナ間で接続する場合、これでは不十分のようです。
先程のショートカットを展開した接続文字列からエンドポイントを変更していきます。
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1
ここのホスト名をコンテナのサービス名に変更します。
BlobEndpoint=http://storage:10000/devstoreaccount1
最終的な接続文字列は次の通りです。
$connection = 'DefaultEndpointsProtocol=http;AccountName=devstoreaccount1; AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==; BlobEndpoint=http://storage:10000/devstoreaccount1;';AccountName、AccountKeyはエミュレーター固定です。
TableEndpoint、QueueEndpointは割愛します。これで先程のBlob作成処理を実行すると・・・
作成されました。
パブリックURLが・・・
ひとつ問題が残りました。
// http://storage:10000/devstoreaccount1/sample/example.txt echo $client->getBlobUrl($container, $blob);接続文字列でホスト名をコンテナのサービス名にしたのはDockerコンテナ間で接続するためでした。
コンテナ外のブラウザからアクセスする場合は「127.0.0.1」にしなければならないです。
(パブリックアクセスの設定を変更して許可するのも忘れずに)Docker + Azurite + ブラウザからアクセスするケース(例えばHTMLのaタグ、imgタグ等)はホスト名を書き換えなければいけません。
まとめ
微妙な部分もありましたがローカル環境としては十分だと思ってます。
「ちょっと動かすだけなのに、AzureプラットフォームにStorage
サービスを作成しないといけない」という点は解消できました。問題等(追記)
使ってるなかで気がついた問題などです。
Append Blob がサポートされていない
リリース「2020.03 Version 3.6.0」時点です。
We will consider Append Blob in the future, but it's still not in the recent release plan.
- 投稿日:2020-03-18T15:51:52+09:00
GitHub ActionsでOpenAPI Generatorを動かす [Docker版]
TL;DR
API定義ファイルが更新されたらGitHub ActionsでOpenAPI Generatorを動かしてPRを作る
用意するもの
- OpenAPI-Specification v3に準拠したAPI定義ファイル
- API定義ファイルを管理するリポジトリ
- 生成したクライアントを管理するリポジトリ
GitHub Actionsで動かすOpenAPI Generator
本編です
1. sample-openapiの用意
- GitHub Actionsを作成
generate.yaml# This is a basic workflow to help you get started with Actions name: generate # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch and petstore.yaml on: push: branches: [ master ] paths: petstore.yaml # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 # clientをcheckout - uses: actions/checkout@v2 with: token: ${{ secrets.GITHUB_TOKEN }} repository: yumemi-nkomiya/github-actions-client-openapi path: client # openapi generate - uses: docker://openapitools/openapi-generator-cli with: args: generate -i ./petstore.yaml -g swift5 -o ./client/ # Create pull request - uses: peter-evans/create-pull-request@v2 with: token: ${{ secrets.REPO_ACCESS_TOKEN }} path: client commit-message: update client title: update client body: update client branch: feature/update_client branch-suffix: short-commit-hash # 同じプルリクは作らない解説
- trigger
ブランチとファイルを条件指定
- clientをcheckout
client-openapiをチェックアウトします。
client-openapiがprivateならPersonal access token
を作ってsample-openapiのsecretsに登録して使います
- openapi generate
mavenビルドしてとか、jarをリポジトリに入れてとかあったんだけど公式にDockerが提供されているので利用する
パラメータはargs
に指定します
- Create pull request
client-openapiの権限がある
Personal access token
が必要2. GitHub Actionsの実行
sample-openapiにpetstore.yamlをpush
- GitHub Actionsの実行結果
https://github.com/yumemi-nkomiya/github-actions-sample-openapi/actions/runs/57991712)
- 作成されたPR
https://github.com/yumemi-nkomiya/github-actions-client-openapi/pull/1
おまけ
generatorがpodspecやPackage.swiftを生成してくれるのでCocoaPodsや、tag打つだけでSwiftPMやCarthageも対応できます
参考記事
- 投稿日:2020-03-18T14:15:21+09:00
Docker + CentOS8でrailsアプリをデプロイするまで
はじめに
CentOS8で自作したrailsアプリをdocker nginx unicornでデプロイするまでを、つまづいたことなど含めて備忘録として書いていきます(時系列順に書いているので少し遠回りな手順になってます)
Dockerについては、動きを把握するためにDockerfileを使わずに動かしてます環境
ruby 2.5.1
(Rails 5.2.3)
CentOS8まずはDockerのところから
% docker run -d -it -p 3000:80 --name myapp centos:8 docker exec -it myapp bashこれでCentOSのコンテナを立ち上げてnginxをインストールして、systemctlで起動しようとしたら、D-Busだのnot permittedみたいなエラーが出て怒られた
どうやら、CentOS7でも同じようなことが起こるみたい。こちらを参照した
コンテナを削除して、もう一度立ち上げる
% docker rm myapp % docker run -d -it -p 3000:80 --privileged --name myapp centos:8 /sbin/init % docker exec -it myapp bash
--privileged
オプションについてはこちらを参照これでsystemctlコマンドが使えているはずです
必要なソフトウェアをインストールしていく
nginxの動作確認
# systemctl # dnf install -y git vim nginx # systemctl start nginx # systemctl status nginx # vim /etc/nginx/nginx.conf # vim /usr/share/nginx/html # vim /usr/share/nginx/html/index.htmlRubyのインストール
anyenv→rbenvから今回使うruby2.5.1をインストールする
anyenvのインストールについては公式のwikiから
# git clone https://github.com/anyenv/anyenv ~/.anyenv # echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile # ~/.anyenv/bin/anyenv init # vim .bash_profile →eval "$(anyenv init -)"を記述 # exec $SHELL -l # anyenv install --init # anyenv -v # anyenv install rbenv # exec $SHELL -lrbenvを入れるところまではできたが、rubyを入れるところから少し躓いた
# rbenv install 2.5.1 Downloading ruby-2.5.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2 /root/.anyenv/envs/rbenv/plugins/ruby-build/bin/ruby-build: line 213: pushd: ruby-2.5.1: No such file or directory BUILD FAILED (CentOS Linux 8 using ruby-build 20200224) Inspect or clean up the working tree at /tmp/ruby-build.20200302084110.884.8HpNM1 Results logged to /tmp/ruby-build.20200302084110.884.log Last 10 log lines: /tmp/ruby-build.20200302084110.884.8HpNM1 ~ warning: bzip2 not found; consider installing `bzip2` package tar (child): bzip2: Cannot exec: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting nowどうやらtarやbzip2が入ってないと言われ怒られたようです
# dnf install tar bzip2 -yもう一回チャレンジ
[root@32a991428119 ~]# rbenv install 2.5.1 Downloading ruby-2.5.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2 Installing ruby-2.5.1... BUILD FAILED (CentOS Linux 8 using ruby-build 20200224) Inspect or clean up the working tree at /tmp/ruby-build.20200302084353.1066.LCm1tD Results logged to /tmp/ruby-build.20200302084353.1066.log Last 10 log lines: checking for ruby... false checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking target system type... x86_64-pc-linux-gnu checking for gcc... no checking for cc... no checking for cl.exe... no configure: error: in `/tmp/ruby-build.20200302084353.1066.LCm1tD/ruby-2.5.1': configure: error: no acceptable C compiler found in $PATH See `config.log' for more details今度はCコンパイラがないと言われてるから、それをインストールしてみる
(この後、makeもなかったようなのでmakeもインストール)# dnf install gcc makeERROR: Ruby install aborted due to missing extensions Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.また怒られた。。。
さらにインストール# dnf install -y openssl-devel readline-devel zlib-devel# rbenv install 2.5.1 Downloading ruby-2.5.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2 Installing ruby-2.5.1... Installed ruby-2.5.1 to /root/.anyenv/envs/rbenv/versions/2.5.1 # ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]できた!
Rails アプリのclone
作ったアプリをgithubリポジトリからクローン
今回は自分が作ったアプリをcloneしていきます。この部分は任意のURLに置き換えてください# git clone https://github.com/xxx/hogehoge.git⚠️Gemfile.lockのbundler のバージョンによっては
gem install bundler
するだけじゃエラーが起こるから注意!こんなエラーが起こることがある
# gem install bundler Fetching: bundler-2.1.4.gem (100%) Successfully installed bundler-2.1.4 Parsing documentation for bundler-2.1.4 Installing ri documentation for bundler-2.1.4 Done installing documentation for bundler after 4 seconds 1 gem installed # bundle install Traceback (most recent call last): 2: from /root/.anyenv/envs/rbenv/versions/2.5.1/bin/bundle:23:in `<main>' 1: from /root/.anyenv/envs/rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path' /root/.anyenv/envs/rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)gemfile.lockのBUNDLED WITHにあるバージョンをインストールする
参考# gem install bundler -v 2.0.1これで
bundle install
コマンドも使えているはずunicornとnginxの設定
unicornの設定についてはこちら
unicorn.rbのlisten, pidと、lib/tasks/unicorn.rbの
def unicorn_pid
は各自の環境で設定しておくことこのまま
rake unicorn:start
コマンドをしてみると、Could not find a JavaScript runtime.
と怒られます(JavaScript入れるの忘れてました)ということでjavaScriptの動作環境を得るためにnode.jsをインストール。これもanyenvからインストール
# anyenv install -l →nodenvがあったからそれを入れます # anyenv install nodenv # exec $SHELL -l # nodenv install 12.16.1 # nodenv global 12.16.1 # exec $SHELL -l # node -v =>v12.16.1また、この時点でsqlite3が入ってないときでもエラーになったから、入れておく
エラーの内容はlog/unicorn.log
で確認できるよ!sqliteのヘッダファイルがなかったらしい?# dnf install -y sqlite # dnf install sqlite-devel.x86_64 →sqliteをインストールするだけじゃgemインストールできず、Development toolsが必要だった(dnf search sqliteしてみた) # gem install sqlite3 -v '1.3.13' --source 'https://rubygems.org/'これでちゃんと
rake unicorn:start
が動いた!あとは参考サイトのnginxの設定通りに進めていく。
・・・が、いざnginxの再起動をすると、正常に画面が出なくなった(403 Forbbidenが出てた)
エラーログをみてみる% tail /var/log/nginx/error.log 2020/03/02 11:04:28 [crit] 54612#0: *2 connect() to unix:/root/Workspace/ikea_stock_finder/tmp/unicorn.sock failed (13: Permission denied) while connecting to upstream, client: 172.17.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://unix:/root/Workspace/ikea_stock_finder/tmp/unicorn.sock:/500.html", host: "localhost:3000"どうやら権限がないらしい。
ps aux | grep unicorn
でプロセスをみてみるとrootで実行されている。nginx.confの設定ではuserはnginxとなっているからここがおかしいのか?と思いrootに変えてみたら、うまくできました最後に
一度コンテナから抜け出した後に再び
% docker exec -it myapp bash
でログインしたら、bash_profileが読み込まれていないらしい?
% docker exec -it myapp bash --login
とすると解決当たり前ですが今の状態で
docker stop
した後にdocker start
すると、nginxやunicornの再起動が必要です
- 投稿日:2020-03-18T13:55:14+09:00
OpenAPIを使ってモックサーバーを起動する
OpenAPIを使ってAPI定義を書いている場合、その定義ファイルからモックのサーバーが起動できれば便利ですよね。
実際にAPIサーバーの実装が完了する前からクライアント側の実装を行うことができるので、とても効率が良いです!調べれば色々と方法が出てきますが、個人的に楽だった方法をまとめておきます。
Prismがめちゃくちゃ便利
stoplight社のprismというOSSのモックサーバーを使います。
今回はこのDockerイメージを使うので、Dockerを入れていない場合は先に入れておいてください。openapi.yamlの準備
まずはAPI定義を行った
openapi.yaml
を準備してください。
今回は、例としてシンプルな内容の定義ファイルを用意しました。openapi.yamlopenapi: 3.0.0 info: version: 1.0.0 title: Swagger Petstore license: name: MIT servers: - url: http://petstore.swagger.io/ paths: /pets: get: summary: List all pets operationId: listPets tags: - pets parameters: - name: limit in: query description: How many items to return at one time (max 100) required: false schema: type: integer format: int32 responses: '200': description: A paged array of pets headers: x-next: description: A link to the next page of responses schema: type: string content: application/json: schema: $ref: "#/components/schemas/Pets" default: description: unexpected error content: application/json: schema: $ref: "#/components/schemas/Error" components: schemas: Pet: required: - id - name properties: id: type: integer format: int64 example: 1 name: type: string example: "pochi" tag: type: string example: "dog" Pets: type: array items: $ref: "#/components/schemas/Pet" Error: required: - code - message properties: code: type: integer format: int32 message: type: stringモックサーバーの起動
先程用意した
openapi.yaml
と同じディレクトリ内で、下記を実行します。
これだけです!docker run --rm -it -p 4010:4010 -v $PWD:/tmp stoplight/prism:3 mock -h 0.0.0.0 /tmp/openapi.yaml実際にAPIを叩いてみます。
curl 'localhost:4010/pets'
レスポンスとして、
openapi.yaml
のexample
で定義した内容が返ってきます。[ { "id": 1, "name": "pochi", "tag": "dog" } ]ちなみに、
-d
オプションを使うと、レスポンスが動的に変わります。docker run --rm -it -p 4010:4010 -v $PWD:/tmp stoplight/prism:3 mock -h 0.0.0.0 -d /tmp/openapi.yamlレスポンスはこの様に、毎回変わります。
[ { "id": 8872624476737700000, "name": "Duis", "tag": "magna in laborum" }, { "id": -6385831628202697000, "name": "veniam in do fugiat irure", "tag": "consequat Ut Excepteur anim tempor" }, { "id": 4943733727999074000, "name": "dolor dolor", "tag": "dolore pariatur ullam" }, { "id": -1524702861247148000, "name": "irure voluptate dolor mollit ex", "tag": "quis" } ]本当に簡単ですね!
- 投稿日:2020-03-18T11:57:13+09:00
Docker環境にSystem Specを導入する
はじめに
Docer環境でRSpecのSystem Specを導入しようとしたところ、結構ハマったので、備忘録としてまとめます。
まず、Docer環境にSystem Specを実行するためには、いくつか方法があるらしい。
調査をしていると、メジャーな方法は以下の二つ(もっとあるかもしれませんが、、、)1. Railsが動いているimageにchromeをインストールする方法
2. chrome用コンテナを立ち上げる方法今回は2の方法でやってみました。
前提
Quickstart: Compose and Railsの通りに、Rails on Dockerの環境構築が済んでいる状態とします。
筆者の環境は
- Ruby 2.5.7
- Rails 5.2.4
です。docker-compose.ymlを編集する
selenium_chromeのコンテナが立ち上がるようdocker-compose.ymlに追加していきます。
Dockerイメージにはselenium/standalone-chromeを使用します。docker-compose.ymlversion: '3' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db #追加 - chrome #追加 chrome: image: selenium/standalone-chrome:3.141.59-dubnium ports: - 4444:4444gemを追加する
Gemfilegroup :development, :test do gem 'rspec-rails' end group :test do gem 'capybara', '>= 2.15' gem 'selenium-webdriver' enddockerをbuildして、bundle installします。
$ docker-compose build $ docker-compose up -drspecの設定
rspecをインストールします。
$ docker-compose run web rails g rspec:installheadless chromeの設定
spec/rails_helper.rbにheadless chromeの設定を追加していきます。
/spec/rails_helper.rbrequire 'capybara/rspec' # headless chrome 設定① Capybara.server_host = Socket.ip_address_list.detect { |addr| addr.ipv4_private? }.ip_address Capybara.server_port = 3001 ※ Capybara.register_driver :selenium_remote do |app| url = "http://chrome:4444/wd/hub" opts = { desired_capabilities: :chrome, browser: :remote, url: url } Capybara::Selenium::Driver.new(app, opts) end # headless chrome 設定② RSpec.configure do |config| config.before(:each, type: :system) do driven_by :rack_test end config.before(:each, type: :system, js: true) do driven_by :selenium_remote host! "http://#{Capybara.server_host}:#{Capybara.server_port}" end endポイント:
後半部分(# headless chrome 設定②)で、
js: true
を記述した場合のみ、seleniumドライバーが立ち上がるように設定しています。ハマったポイント:
js: true
のテストを走らせたとき、Capybaraがseleniumサーバーを立ち上げて、先ほど設定したchromeコンテナで起動しているchromeを操作します。
しかし、Capybara.server_portを指定する部分(*)で、webコンテナで指定したポートと同じ3000を指定してしまうと、js: true
のテストを走らせたときに、webコンテナで指定したポートと競合してseleniumサーバーが立ち上がらずエラーとなってしまいます。
そこで、Capybara.server_port =30003001
とすることで、競合することなく、無事サーバーが立ち上がり、テストが通るようになりました。これで準備は整いました。
あとは、テストを実際に走らせるだけです。実際にテストを走らせてみる
spec/system/test_spec.rbrequire "rails_helper" RSpec.describe 'Test', type: :system, js: true do example 'サンプルテスト' do #ここにテスト内容を記述 end end$ docker-compose exec web bundle exec rpsecこれで、テストが通るはずです。
参考記事
下記の記事を参考にさせていただきました。
ありがとうございます。
- Docker で RSpec の System Spec を実行するための設定メモ
- Rails + Selenium + DockerでSystemSpecの環境構築
- Rails on Dockerにて、Headless ChromeでSystem Testをやってみた。
- 投稿日:2020-03-18T10:50:23+09:00
laravel on dockerのimage別速度比較
目的
php:fpm-alpineイメージを使ってlaravelを動かしていましたところ、異様にレスポンスが遅かったので調べてみたところこんな話がありました。
https://qiita.com/yoshiken/items/93d170b69d8cb8520badどうやらalpineが遅いと。
そこでイメージの選択でどれくらい違いが出るのかを試してみました。比較対象
- alpine
- debian
- centos
比較方法
laravel new
した直後のプロジェクトをphp artisan serve
で起動し、以下の2パターンで比較してみました。
/
(Welcomページ)へリクエスト/items
(itemモデルとレコード100件を作って一覧をjsonで返す)へリクエスト測定にはsiegeを利用しています。
比較結果
$ siege --no-follow -r 10 -c 1 http://localhost:8000
image response time(s) debian 0.31 alpine 0.77 centos 0.81 $ siege --no-follow -r 10 -c 1 http://localhost:8000/items
image response time(s) debian 0.19 alpine 1.90 centos 1.67 意外とcentosでも遅い結果になりました。
原因は何なのでしょうね?alpineとcentosでは動かすためにインストールしたExtensionが似ていたので、Extensionの違いだったりするんでしょうか。。参考
Dockerfile
debianFROM debian RUN apt-get update RUN apt-get install -y php RUN apt-get install -y php-zip RUN apt-get install -y php-mbstring RUN apt-get install -y php-dom RUN apt-get install -y php-mysql WORKDIR /appalpineFROM alpine RUN apk update RUN apk add php RUN apk add php-zip RUN apk add php-mbstring RUN apk add php-dom RUN apk add php-phar RUN apk add php-json RUN apk add php-openssl RUN apk add php-session RUN apk add php-mysqlnd RUN apk add php-pdo RUN apk add php-pdo_mysql COPY php.ini /etc/php7/php.ini WORKDIR /appcentosFROM centos RUN yum update -y RUN yum install -y php RUN yum install -y php-mbstring RUN yum install -y php-dom RUN yum install -y php-json RUN yum install -y php-session RUN yum install -y php-mysqlnd RUN yum install -y php-pdo RUN yum install -y php-pdo_mysql COPY php.ini /etc/php.ini WORKDIR /app
- 投稿日:2020-03-18T10:50:23+09:00
alpine + laravel on dockerのimage別速度比較
目的
php:fpm-alpineイメージを使ってlaravelを動かしていましたところ、異様にレスポンスが遅かったので調べてみたところこんな話がありました。
https://qiita.com/yoshiken/items/93d170b69d8cb8520badどうやらalpineが遅いと。
そこでイメージの選択でどれくらい違いが出るのかを試してみました。比較対象
- alpine
- debian
- centos
比較方法
laravel new
した直後のプロジェクトをphp artisan serve
で起動し、以下の2パターンで比較してみました。
/
(Welcomページ)へリクエスト/items
(itemモデルとレコード100件を作って一覧をjsonで返す)へリクエスト測定にはsiegeを利用しています。
比較結果
$ siege --no-follow -r 10 -c 1 http://localhost:8000
image response time(s) debian 0.31 alpine 0.77 centos 0.81 $ siege --no-follow -r 10 -c 1 http://localhost:8000/items
image response time(s) debian 0.19 alpine 1.90 centos 1.67 意外とcentosでも遅い結果になりました。
原因は何なのでしょうね?alpineとcentosでは動かすためにインストールしたExtensionが似ていたので、Extensionの違いだったりするんでしょうか。。参考
Dockerfile
debianFROM debian RUN apt-get update RUN apt-get install -y php RUN apt-get install -y php-zip RUN apt-get install -y php-mbstring RUN apt-get install -y php-dom RUN apt-get install -y php-mysql WORKDIR /appalpineFROM alpine RUN apk update RUN apk add php RUN apk add php-zip RUN apk add php-mbstring RUN apk add php-dom RUN apk add php-phar RUN apk add php-json RUN apk add php-openssl RUN apk add php-session RUN apk add php-mysqlnd RUN apk add php-pdo RUN apk add php-pdo_mysql COPY php.ini /etc/php7/php.ini WORKDIR /appcentosFROM centos RUN yum update -y RUN yum install -y php RUN yum install -y php-mbstring RUN yum install -y php-dom RUN yum install -y php-json RUN yum install -y php-session RUN yum install -y php-mysqlnd RUN yum install -y php-pdo RUN yum install -y php-pdo_mysql COPY php.ini /etc/php.ini WORKDIR /app
- 投稿日:2020-03-18T09:18:23+09:00
DockerのMySQLコンテナが、永遠に再起動を繰り返すエラーの対処法
概要
事象
MySQLが動くDockerコンテナを、docker-composeで立ち上げようとしたところ、コンテナが永遠に再起動を繰り返す事象が起こりました。この問題の解決方法を、ここにメモしておきます。
ちなみに、私はWindows上でDocker Toolboxを用いていた時にこの問題が起こりましたが、それ以外の環境だとこの問題は起こらなさそうです(おそらく)。
docker-compose.ymlの設定
docker-compose.ymlのうち、この問題が起こる部分の設定は以下のようになっています。
db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306特別な設定は何もしておらず、単純に
mysql:5.7
のイメージをベースに必要最低限の設定をしているのみです。対処法
立ち上がったコンテナ内で、
--innodb-use-native-aio=0
を実行させます。なので、docker-compose.ymlは以下のようになります。db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306 command: --innodb-use-native-aio=0 # <- これ!なぜこれで解決するのか
MySQLの公式ドキュメントには、以下のような記述があります。
InnoDB uses the asynchronous I/O subsystem (native AIO) on Linux to perform read-ahead and write requests for data file pages. This behavior is controlled by the innodb_use_native_aio configuration option, which applies to Linux systems only and is enabled by default.
InnoDB(MySQLのためのデータベースエンジン)はデフォルトでLinuxの非同期I/O(native AIO)を用いるように設定されていますが、この挙動は
innodb_use_native_aio
オプションで変更できます。今回私はWindows上でDocker Toolboxを用いてコンテナを動かしていたのですが、その場合だとこの非同期I/Oが利用できないため、エラーが起こり再起動が繰り返されていたようです。そのため、公式ドキュメントの上に引用した部分に書いてある通り、
innodb_use_native_aio
オプションで非同期I/Oを用いないように設定して、この問題を回避する必要があります。
- 投稿日:2020-03-18T09:18:23+09:00
DockerのMySQLコンテナが、Docker Toolbox上で起動に失敗するエラーの対処法
概要
事象
MySQLが動くDockerコンテナを、docker-composeで立ち上げようとしたところ、コンテナが永遠に再起動(restart)を繰り返す事象が起こりました。この問題の解決方法を、ここにメモしておきます。
ちなみに、私はWindows上でDocker Toolboxを用いていた時にこの問題が起こりましたが、それ以外の環境だとこの問題は起こらなさそうです(おそらく)。
docker-compose.ymlの設定
docker-compose.ymlのうち、この問題が起こる部分の設定は以下のようになっています。
db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306特別な設定は何もしておらず、単純に
mysql:5.7
のイメージをベースに必要最低限の設定をしているのみです。対処法
立ち上がったコンテナ内で、
--innodb-use-native-aio=0
を実行させます。なので、docker-compose.ymlは以下のようになります。db: image: mysql:5.7 volumes: - "/tmp/db/data:/var/lib/mysql" - "./db:/usr/src/db" restart: always environment: MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $MYSQL_DATABASE MYSQL_USER: $MYSQL_USER MYSQL_PASSWORD: $MYSQL_PASSWORD ports: - 3306:3306 command: --innodb-use-native-aio=0 # <- これ!なぜこれで解決するのか
MySQLの公式ドキュメントには、以下のような記述があります。
InnoDB uses the asynchronous I/O subsystem (native AIO) on Linux to perform read-ahead and write requests for data file pages. This behavior is controlled by the innodb_use_native_aio configuration option, which applies to Linux systems only and is enabled by default.
InnoDB(MySQLのためのデータベースエンジン)はデフォルトでLinuxの非同期I/O(native AIO)を用いるように設定されていますが、この挙動は
innodb_use_native_aio
オプションで変更できます。今回私はWindows上でDocker Toolboxを用いてコンテナを動かしていたのですが、その場合だとこの非同期I/Oが利用できないため、エラーが起こり再起動が繰り返されていたようです。そのため、公式ドキュメントの上に引用した部分に書いてある通り、
innodb_use_native_aio
オプションで非同期I/Oを用いないように設定して、この問題を回避する必要があります。コンテナの再起動について
コンテナが再起動するのは、私がdocker-compose.ymlに
restart:always
を書いているからです。それ以外の場合は、普通にコンテナが落ちると思われます。
- 投稿日:2020-03-18T02:42:09+09:00
dockerコンテナにサブドメインなどもまとめて1つのIPに名前解決する
やりたいこと
- docker-composeで立ち上げたコンテナから任意のホストに名前解決したい
- docker-networkには参加させない(E2EテストやブラウザでURLを打ってアクセスさせるなど)
- かつ、サブドメインで同じIPに名前解決したい
// TODO: つまりどういうことだってばよ (説明する)
2までの場合
例として、
uyu.pun
ドメインを192.168.1.11に受け流すように変更してみます。// TODO: extra_hostsが何をしているのか
docker-compose.ymlversion: '3' services: app: image: node:13.10.1 ports: - 3000:3000 # ↓ 足す extra_hosts: - 'uyu.pun:192.168.1.11' command: "node app.js" volumes: - ./:/src working_dir: /src参考: Docker で Node.js 開発環境を簡単に用意する
ポートについては固定値に変更させていただきました。↓コンテナ立ち上げ後、シェルで
/etc/hosts
ファイルを参照した結果です。(他の項目は省いています)/etc/hosts192.168.1.11 uyu.pun鬼の仕様変更
…ではないと思いますが、サブドメインで同じホストの別ポートにマッピングしたい、といった状況になったとします。
例として、
admin.uyu.pun
も192.168.1.11に向けてみます。docker-compose.ymlversion: '3' services: app: image: node:13.10.1 ports: - 3000:3000 # 失敗する extra_hosts: - 'uyu.pun:192.168.1.11' - 'admin.uyu.pun:192.168.1.11' command: 'node app.js' volumes: - ./:/src working_dir: /src↓出力後
/etc/hosts192.168.1.11 uyu.pun 192.168.1.11 admin.uyu.punこの状態でpingを打つと失敗します。どうもhostsファイルの仕様っぽいです。
参考: Hostsファイル:複数の行に同じIPアドレスがあるのは間違っていますか?
ざっくりとしか読んでいませんが、先に書いたほうが優先される?模様。対策 : コロンより前をスペース区切りで記述する
docker-compose.ymlversion: '3' services: app: image: node:13.10.1 ports: - 3000:3000 # コロンより前をスペース区切りで記述する extra_hosts: - 'uyu.pun admin.uyu.pun:192.168.1.11' command: 'node app.js' volumes: - ./:/src working_dir: /src↓起動後の
/etc/hosts
ファイルの確認/etc/hosts192.168.1.11 uyu.pun admin.uyu.punpingを打ってみます。
# ping uyu.pun PING uyu.pun (192.168.1.11) 56(84) bytes of data. From 192.168.1.22 (192.168.1.22) icmp_seq=1 Destination Host Unreachable ^c # ping admin.uyu.pun PING uyu.pun (192.168.1.11) 56(84) bytes of data. From 192.168.1.22 (192.168.1.22) icmp_seq=1 Destination Host Unreachable無事、2つのドメインを同じIPに名前解決できた。(IPアドレスは適当にしたので疎通できていませんが、期待したIPにpingを投げていることがわかると思います。)
応用
今回これを試したのは、なるべく実運用に近い環境でE2Eテストの実行をしたいという背景でした。
各自のローカルマシンのdockerコンテナ上にあるサーバーにリクエストを向けるために、IPアドレスの部分は変数にし、参照元の.env
ファイルは以下のようにし .gitignoreしています。
ちなみに、.envの環境変数を展開する場合は"で囲うようです。docker-compose.yml... extra_hosts: - "uyu.pun admin.uyu.pun:${HOST_MACHINE_IP}" ....envHOST_MACHINE_IP=192.168.1.11課題
記入するドメインが増えると横に長くなっていってしまうので、ymlファイル上では改行してきれいに表示したい。。
おわりに
uyu.punって何?うゆぷん?って方へ
こちら
- 投稿日:2020-03-18T01:22:41+09:00
Linux(Ubuntu,CentOSなど)にDockerを入れる便利なスクリプト
Docker公式が便利なスクリプトを用意してくれている。
毎回インストール後に思い出すのでメモ。https://docs.docker.com/install/linux/docker-ce/ubuntu/
の下のほうに書いてある。# インストールスクリプトをダウンロードして実行 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # 非rootユーザーで実行したい場合に # 一回ログアウトしないと反映されない sudo usermod -aG docker your-user # docker-composeも使う場合に sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-composeまた、公式のドキュメントには、
- プロダクション環境で使うのはお勧めしない
- sudo権限で動くスクリプトのため、実行前に内容を確認しておくこと
などと書かれてある。