- 投稿日:2020-01-12T21:52:42+09:00
Ruby on Rails APIモードのCRUD実装 【初学者のReact✗Railsアプリ開発 第5回】
やったこと
- Ruby on RailsのAPIモードでCRUDを実装する(ただし、更新(U)はなし)
前回の記事
Reactのreduxを用いたログイン処理周りの実装【初学者のReact✗Railsアプリ開発第4回】
参考にさせていただいた記事
https://qiita.com/k-penguin-sato/items/adba7a1a1ecc3582a9c9
実装手順
モデルとコントローラーの作成
$ docker-compose run api rails g model post content:string $ docker-compose run api rails g controller api/v1/posts生成されたマイグレーションファイルを編集します。
db/migrate/XXX_create_posts.rbclass CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.string :content t.references :user, foreign_key: true t.timestamps end add_index :posts, [:user_id, :created_at] end end$ docker-compose run api rake db:migrateroute.rb
route.rbRails.application.routes.draw do namespace :api, defaults: { format: :json } do namespace :v1 do ##省略## resources :posts end end end
- resourcesで、GET, POSTなど複数のルーティングを一気に設定できる。resourceとの違いに注意。
posts_controller
posts_controllermodule Api module V1 class PostsController < ApplicationController before_action :set_post, only: [:index, :show, :update, :destroy] before_action :authenticate_api_v1_user! def index posts = Post.all render json: { status: 'SUCCESS', message: 'Loaded posts', data: posts} end def show @user = @post.user json_data = { 'post': @post, 'user': { 'name': @user.name, 'nickname': @user.nickname, 'image': @user.image } } render json: { status: 'SUCCESS', message: 'Loaded the post', data: json_data} end def create post = Post.new(post_params) if post.save render json: { status: 'SUCCESS', data: post} else render json: { status: 'ERROR', data: post.errors } end end def destroy @post.destroy render json: { status: 'SUCCESS', message: 'Delete the post', data: @post} end def update end private def set_post @post = Post.find(params[:id]) end def post_params params.require(:post).permit(:content, :user_id) end end end endmodels/post.rb
post.rbclass Post < ApplicationRecord belongs_to :user endPostmanを用いてAPIの動作確認をする
create
chromeのデベロッパーツール->Application->Local Storageからauth_tokenとかをコピーして、
Postmanに貼り付ける。
そしてlocalhost:3000/api/v1/postsにPOSTすると
postが作成されたことが確認できます。index
localhost:3000/api/v1/postsにGETすると
show
localhost:3000/api/v1/posts/1にGETすると、idが1のpostが返されます。
destroy
localhost:3000/api/v1/posts/1にDELETEすると、idが1のpostが消えます。
indexで確認すると、消えています。
- 投稿日:2020-01-12T21:39:02+09:00
Dockerで開発環境を構築する
はじめに
前回の記事でDockerってどんなものなんだろうってことを軽く調べて書かせて頂きました。
今回は実際にDockerを使用して開発環境を構築してみよう!って内容を書きたいと思います。
まずは操作に慣れたいのでイメージを取得してコンテナを作成して起動までをやってみたいと思います。主なコマンド
- docker pull リポジトリ:タグ (イメージの取得)
- docker run イメージ名 (コンテナの生成から起動)
- docker start コンテナID(もしくはコンテナ名)
- docker stop コンテナID(もしくはコンテナ名)
- docker rm コンテナID(もしくはコンテナ名)
- docker ps (起動中のコンテナ表示)
- docker ps -a (状態に関係なくすべてのコンテナを表示)
- docker ps -aq (コンテナIDのみ表示)
- docker commit コンテナID(もしくはコンテナ名) イメージ名:タグ (コンテナからイメージ作成)
イメージの取得
まずcentosのイメージを取得します。
centos7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:centos7 docker.io/library/centos:centos7イメージ一覧を表示して確認。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos centos7 5e35e350aded 2 months ago 203MBこれでイメージの取得は完了です。めっちゃ簡単!!
イメージからコンテナを作成、起動
$ docker run -it -d --name centos7 centos:centos7 Unable to find image 'centos:centos7' locally centos7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:centos7 9ac1b47222b99cb76f33837836e30859d7a0420fdccb694d0deb795a5da7b7b7起動できているか確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ac1b47222b9 centos:centos7 "/bin/bash" 2 minutes ago Up 2 minutes centos7STATUSの欄を見るとUp 2となっているので起動できているかと思います。
実際にコンテナを操作してみる
$ docker exec -it centos7 /bin/bash [root@9ac1b47222b9 /]#これでコンテナ内に入れたのでコマンド操作が可能になります。
コンテナから抜けるにはexitで抜けれました。コンテナの停止
docker stop コンテナID(またはコンテナ名)
上記でコンテナを停止できます。$ docker stop centos7 centos7停止しているか確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESプロセスが表示されていないので正しく停止してそうです。
意外と直感的に操作できた
linux環境を触ったことある人なら意外と簡単に操作できるなって感じました。
これからは自分でイメージを作成したりdockerfileについても勉強して記事にしていきたいと思います。
- 投稿日:2020-01-12T21:39:02+09:00
Dockerを触ってみる
はじめに
前回の記事でDockerってどんなものなんだろうってことを軽く調べて書かせて頂きました。
今回は実際にDockerを使用して開発環境を構築してみよう!って内容を書きたいと思います。
まずは操作に慣れたいのでイメージを取得してコンテナを作成して起動までをやってみたいと思います。主なコマンド
- docker pull リポジトリ:タグ (イメージの取得)
- docker run イメージ名 (コンテナの生成から起動)
- docker start コンテナID(もしくはコンテナ名)
- docker stop コンテナID(もしくはコンテナ名)
- docker rm コンテナID(もしくはコンテナ名)
- docker ps (起動中のコンテナ表示)
- docker ps -a (状態に関係なくすべてのコンテナを表示)
- docker ps -aq (コンテナIDのみ表示)
- docker commit コンテナID(もしくはコンテナ名) イメージ名:タグ (コンテナからイメージ作成)
イメージの取得
まずcentosのイメージを取得します。
centos7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:centos7 docker.io/library/centos:centos7イメージ一覧を表示して確認。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos centos7 5e35e350aded 2 months ago 203MBこれでイメージの取得は完了です。めっちゃ簡単!!
イメージからコンテナを作成、起動
$ docker run -it -d --name centos7 centos:centos7 Unable to find image 'centos:centos7' locally centos7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:centos7 9ac1b47222b99cb76f33837836e30859d7a0420fdccb694d0deb795a5da7b7b7起動できているか確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ac1b47222b9 centos:centos7 "/bin/bash" 2 minutes ago Up 2 minutes centos7STATUSの欄を見るとUp 2となっているので起動できているかと思います。
実際にコンテナを操作してみる
$ docker exec -it centos7 /bin/bash [root@9ac1b47222b9 /]#これでコンテナ内に入れたのでコマンド操作が可能になります。
コンテナから抜けるにはexitで抜けれました。コンテナの停止
docker stop コンテナID(またはコンテナ名)
上記でコンテナを停止できます。$ docker stop centos7 centos7停止しているか確認
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESプロセスが表示されていないので正しく停止してそうです。
意外と直感的に操作できた
linux環境を触ったことある人なら意外と簡単に操作できるなって感じました。
これからは自分でイメージを作成したりdockerfileについても勉強して記事にしていきたいと思います。
- 投稿日:2020-01-12T19:37:52+09:00
Docker で pygments 環境を用意して minted パッケージを試す
LaTeX でソースコードをいい感じにシンタックスハイライトしてくれる minted パッケージを,Docker を使って試してみたときのメモです。手元の Python 環境に手を加えずに Docker コンテナを利用して minted パッケージを動かすことを目指します。この方法は,minted に限らず,外部ツールを呼び出す系の LaTeX パッケージを,手元の環境を汚さずに試す方法の一例として参考になると思います。
minted パッケージの使用例
- mintedでLaTeXドキュメントにソースコードを載せる
- ソースコードの貼り付けができるmintedをpLaTeXで使ってみた
- [LaTeX] minted --- プログラムソースコードのハイライト表示
minted パッケージの動作要件
minted.sty
(TeX Live ならば初めからインストールされている)pygments
がインストールされた Python 環境minted.sty
からpygmentize
コマンドを呼び出すために LaTeX エンジンに-shell-escape
を与えることが必須pygments の準備
pygments
のインストールは,pip
が使える Python 環境であれば$ pip install pygmentsとすればOKです。
ただし,今回はあくまでお試しということで,手元の Python 環境を汚さずに minted パッケージを試したいと思います。そこで
pygments
を搭載した Docker コンテナを用意します。pygments 入り Docker コンテナイメージのビルド
Alpine Linux + Python のベースイメージに対し,
pygments
を追加インストールして,自動でpygmentize
コマンドが起動するように設定した Docker コンテナです。DockerfileFROM python:alpine WORKDIR /workdir RUN pip install pygments ENTRYPOINT ["pygmentize"]この Dockerfile をビルドし,ここでは仮に
pygmentize-wrapper
という名前のイメージとして保存します。$ docker build -t pygmentize-wrapper .pygmentize コマンドのラッパースクリプトの準備
次に,テスト用ディレクトリ(たとえば
/tmp/minted-test
)に次のスクリプトを用意し,pygmentize
という名前で保存して,実行権限を与えて(chmod +x
)おきます。pygmentize#!/bin/sh docker run --rm \ --mount type=bind,src="$(pwd)",dst=/workdir \ pygmentize-wrapper "$@"発想としては,
minted.sty
から\ShellEscape
で呼び出されるpygmentize
コマンドを,本物のpygmentize
コマンドではなく,Docker コンテナ内のpygmentize
を呼び出すこのラッパースクリプトに差し替えて偽装しようというわけです。サンプル文書の用意
次のようなサンプル文書を用意します。minted パッケージが提供する
minted
環境のみならず,tcolorbox パッケージが提供するtcblisting
環境のシンタックスハイライトエンジンを minted に設定したものも試します。(このサンプル文書は upLaTeX 文書となっていますが,そこは特に深い意味はありません。pLaTeX や pdfLaTeX 等でもOKです。)sample.tex%#!uplatex \documentclass[uplatex,dvipdfmx,papersize]{jsarticle} \usepackage{graphicx,xcolor} \usepackage[cache=false]{minted} \usepackage{tcolorbox} \tcbuselibrary{minted} \tcbset{listing engine=minted} \pagestyle{empty} \begin{document} \begin{minted}{c} #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; } \end{minted} \begin{tcblisting}{colback=red!5!white,colframe=red!75!black,left=1cm,minted options={fontsize=\small,linenos,firstnumber=1100,numbersep=3mm}} This is a \LaTeX\ example which displays the text as source code and in compiled form. \end{tcblisting} \begin{tcblisting}{listing only,title=another language listing only example,fonttitle=\bfseries,colback=red!5!white,colframe=red!75!black,minted language=xml} <?xml version="1.0"?> <project name="Package tcolorbox" default="documentation" basedir="."> <description> Sample </description> </project> \end{tcblisting} \end{document}サンプル文書のコンパイル
コンパイル実行の仕方
現状,次のようなファイル構成になっています。
/tmp/minted-test (実験用ディレクトリ) ├── pygmentize (ラッパースクリプト) └── sample.tex (サンプル文書)LaTeX コンパイルのコマンド実行に前置して,
PATH=.:$PATH
を加えておきます。これにより,PATH
の設定に一時的にカレントディレクトリが加わります。こうすることで,minted.sty
から\ShellEscape
で呼び出されるpygmentize
コマンドを,カレントディレクトリのラッパースクリプトに差し替えることができます。$ PATH=.:$PATH ptex2pdf -u -l -ot -shell-escape sample.tex
-ot
で TeX エンジンに対して-shell-escape
を渡しています。コンパイル結果
無事にホスト側の LaTeX エンジンから Docker コンテナ内の
pygmentize
コマンドが呼び出され,綺麗に色分けされました!
- 投稿日:2020-01-12T19:37:52+09:00
Docker で Pygments 環境を用意して minted パッケージを試す
様々な言語のソースコードをいい感じにシンタックスハイライトして,LaTeX 文書内に貼り込んでくれる minted パッケージを,Docker を使って試してみたときのメモです。手元の Python 環境に手を加えずに Docker コンテナを利用して minted パッケージを動かすことを目指します。この手法は,minted に限らず,別途インストールする必要のある外部ツールを呼び出す系の LaTeX パッケージを,手元の環境を汚さずに試す方法の一例として参考になるのではないでしょうか。
minted パッケージの使用例
- mintedでLaTeXドキュメントにソースコードを載せる
- ソースコードの貼り付けができるmintedをpLaTeXで使ってみた
- [LaTeX] minted --- プログラムソースコードのハイライト表示
minted パッケージの動作要件
minted.sty
(TeX Live ならば初めからインストールされている)- Pygments がインストールされた Python 環境
minted.sty
からpygmentize
コマンドを呼び出すために LaTeX エンジンに-shell-escape
を与えることが必須Pygments の準備
Pygments のインストールは,
pip
が使える Python 環境であれば$ pip install pygmentsとすればOKです。
ただし,今回はあくまでお試しということで,手元の Python 環境を汚さずに minted パッケージを試したいと思います。Python の
venv
やvirtualenv
を使ってもよいのですが,ここでは,(Python に限らず使える手法という意味で)より一般的で,より環境の分離がしっかりできる,Docker によるコンテナ化の方針でゆくことにします。つまり,Pygments を搭載した Docker コンテナを用意します。Pygments 入り Docker コンテナイメージのビルド
Alpine Linux + Python のベースイメージに対し,Pygments を追加インストールして,自動で
pygmentize
コマンドが起動するように設定した Docker コンテナです。DockerfileFROM python:alpine WORKDIR /workdir RUN pip install pygments ENTRYPOINT ["pygmentize"]この Dockerfile をビルドし,ここでは仮に
pygmentize-wrapper
という名前のイメージとして保存します。$ docker build -t pygmentize-wrapper .pygmentize コマンドのラッパースクリプトの準備
次に,テスト用ディレクトリ(たとえば
/tmp/minted-test
)に次のスクリプトを用意し,pygmentize
という名前で保存して,実行権限を与えて(chmod +x
)おきます。pygmentize#!/bin/sh docker run --rm \ --mount type=bind,src="$(pwd)",dst=/workdir \ pygmentize-wrapper "$@"発想としては,
minted.sty
から\ShellEscape
で呼び出されるpygmentize
コマンドを,本物のpygmentize
ではなく,Docker コンテナ内のpygmentize
を呼び出すこのラッパースクリプトに差し替えて偽装しようというわけです。サンプル文書の用意
次のようなサンプル文書を用意します。minted パッケージが提供する
minted
環境のみならず,tcolorbox パッケージが提供するtcblisting
環境のシンタックスハイライトエンジンを minted に設定したものも試します。(このサンプル文書は upLaTeX 文書となっていますが,そこは特に深い意味はありません。pLaTeX や pdfLaTeX 等でもOKです。)sample.tex%#!uplatex \documentclass[uplatex,dvipdfmx,papersize]{jsarticle} \usepackage{graphicx,xcolor} \usepackage[cache=false]{minted} \usepackage{tcolorbox} \tcbuselibrary{minted} \tcbset{listing engine=minted} \pagestyle{empty} \begin{document} \begin{minted}{c} #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; } \end{minted} \begin{tcblisting} {colback=red!5!white, colframe=red!75!black, left=1cm, minted options={fontsize=\small,linenos,firstnumber=1100,numbersep=3mm}} This is a \LaTeX\ example which displays the text as source code and in compiled form. \end{tcblisting} \begin{tcblisting} {listing only, title=another language listing only example, fonttitle=\bfseries, colback=red!5!white, colframe=red!75!black, minted language=xml} <?xml version="1.0"?> <project name="Package tcolorbox" default="documentation" basedir="."> <description> Sample </description> </project> \end{tcblisting} \end{document}サンプル文書のコンパイル
コンパイル実行の仕方
現状,次のようなファイル構成になっています。
/tmp/minted-test (実験用ディレクトリ) ├── pygmentize (ラッパースクリプト) └── sample.tex (サンプル文書)LaTeX コンパイルのコマンド実行に前置して,
PATH=.:$PATH
を加えておきます(sh系シェルの場合,コマンド実行に前置してスペース区切りで環境変数の定義を書くことで,そのコマンド呼び出し時のみ一時的に環境変数の値を変更して実行できます)。これにより,PATH
の設定の先頭に一時的にカレントディレクトリが加わった状態で LaTeX エンジンを呼び出せます。その結果,minted.sty
から\ShellEscape
で呼び出されるpygmentize
コマンドを,カレントディレクトリのラッパースクリプトに差し替えることができます。$ PATH=.:$PATH ptex2pdf -u -l -ot -shell-escape sample.tex
-ot
オプション(options for TeX の意)で TeX エンジンに対して-shell-escape
を渡しています。コンパイル結果
無事にホスト側の LaTeX エンジンから Docker コンテナ内の
pygmentize
コマンドが呼び出され,綺麗に色分けされました!
- 投稿日:2020-01-12T18:24:06+09:00
GitHub Package RegistryのDockerイメージは認証無しではPullできない (2020/01/12時点)
ハマる人がいるかもしれないのでMEMOです。
2020/01/12時点ではGitHub PackagesのDockerレジストリ(docker.pkg.github.com)に登録されているDockerイメージはdocker loginによる認証が必須となります。レポジトリがPublicかPrivateに関わらず認証が必須です。
このため例えばGKE等でDocker Hub上のDockerイメージと同じようにPullをしようとすると
no basic auth credentials
というエラーが発生してPullに失敗します。以下はGKE上でエラーが発生した時のPodのエラーメッセージ例です。
Warning Failed 58s (x3 over 100s) kubelet, gke-cluster-xxx Failed to pull image "docker.pkg.github.com/xxx/xxx/xxx:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://docker.pkg.github.com/v2/xxx/xxx/xxx/manifests/latest: no basic auth credentials Warning Failed 58s (x3 over 100s) kubelet, gke-cluster-xxx Error: ErrImagePull今後の対応予定
ちなみに本件についてはGitHub側は仕様であると回答してますが、認証無しの要望についてはGitHub Package Registryチームに展開したと述べています。このため将来的にはPublicレポジトリについては認証無しでもPullできるようになるかもしれません。
- 投稿日:2020-01-12T17:06:54+09:00
Raspberry PI(Raspbian)開発環境をx86_64マシン上に構築する
はじめに
2019年の年末に、年末だからという理由だけでラズパイ(Raspberry PI Zero W)を購入しました。で、冬休みにいろいろ触ってみたのですが、やっぱり動作が重たいんですよねぇ。さらに、SDカードも32GBでそれほど余裕もなく。なので、ラズパイ上に開発環境を構築してアプリを開発しようという夢は諦めて、x86_64マシンに開発環境を構築して、アプリ開発を行うことにしました。
本記事は、開発環境をx86_64マシン上に構築するための手順やその時ハマった内容などを、備忘録として記載したものです。開発環境概要
開発環境構築作業は、以下のホスト上で行いました。
- ホスト:Ubuntu 18.04LTS
また、開発環境はDockerを使ってコンテナ上に構築しています。コンテナを利用することで、ホストの環境を汚すことなく開発環境構築が行えます。
- Docker Version:19.03.5
ラズパイ用OSは、Raspbian Liteを使用しました。
- Raspbian Buster Lite(Minimal image based on Debian Buster)
- Version:September 2019
- Release date:2019-09-26
- Kernel version:4.19
つまり、Raspbian(buster)コンテナイメージを作成し、そのイメージを使って開発環境を構築するということです。
但し、RaspbianはARM系アーキテクチャマシンで動作するバイナリですので、単純にDockerで立ち上げても動作しませんので、QEMUエミュレータを使用して動作させることになります。構築手順
実際の手順については、こちらの記事がわかりやすいので、そちらを参照してください。手順概要は以下です。
1. Dockerでベースコンテナの準備
開発環境構築作業用コンテナを立ち上げます。
2. Raspbian Buster Liteのイメージファイルのマウント
立ち上げたコンテナ内で、Raspbian Buster Liteイメージファイルをマウントします。
3. Raspbian Buster Liteのファイル群の取得(tarで固める)
イメージをマウントすることで、OSファイルが参照出来ますので、tarで固めて取得します。
また、QEMUを利用してARM系の実行ファイルをx86_64で動作させるため、qemu-arm-staticツールを格納しておきます。
4. 取得したファイル群で、コンテナイメージを作成
作成したtarファイルを利用して、コンテナイメージを作成します。
5. 作成したコンテナイメージで、コンテナを作成・起動
作成したコンテナイメージでコンテナを立ち上げます。これで、RaspbianOSのコンテナが立ち上がります。上記で、コンテナは問題なく立ち上がり、ラズパイ用アプリの開発は行えるのですが、ホストPCを再起動した後にコンテナを立ち上げようとすると、以下のようになって、コンテナが立ち上がらなくなります。
container$ docker start -i 8d1086983af8 standard_init_linux.go:211: exec user process caused "exec format error"いろいろ調べたら、x86_64環境で他のアーキテクチャのバイナリ(コンテナ)を実行する方法について紹介されていた資料を見つけました。
その中で、x86_64環境で他のアーキテクチャのバイナリ(コンテナ)を実行する場合は、事前に以下のコマンドを実行する必要があるとのこと。
hostdocker run --rm --privileged multiarch/qemu-user-static --resetこれで異なるアーキテクチャのバイナリ(コンテナ)を実行することが出来ます。
host$ docker run --rm --privileged multiarch/qemu-user-static --reset Unable to find image 'multiarch/qemu-user-static:latest' locally latest: Pulling from multiarch/qemu-user-static bdbbaa22dec6: Pull complete 42399a41a764: Pull complete ed8a5179ae11: Pull complete 1ec39da9c97d: Pull complete df7dd9470aac: Pull complete Digest: sha256:25d6e8bb037094525cd70da43edc06a62122028cb9ad434605affbd4fffb3a4f Status: Downloaded newer image for multiarch/qemu-user-static:latest Setting /usr/bin/qemu-alpha-static as binfmt interpreter for alpha Setting /usr/bin/qemu-arm-static as binfmt interpreter for arm Setting /usr/bin/qemu-armeb-static as binfmt interpreter for armeb Setting /usr/bin/qemu-sparc-static as binfmt interpreter for sparc Setting /usr/bin/qemu-sparc32plus-static as binfmt interpreter for sparc32plus Setting /usr/bin/qemu-sparc64-static as binfmt interpreter for sparc64 Setting /usr/bin/qemu-ppc-static as binfmt interpreter for ppc Setting /usr/bin/qemu-ppc64-static as binfmt interpreter for ppc64 Setting /usr/bin/qemu-ppc64le-static as binfmt interpreter for ppc64le Setting /usr/bin/qemu-m68k-static as binfmt interpreter for m68k Setting /usr/bin/qemu-mips-static as binfmt interpreter for mips Setting /usr/bin/qemu-mipsel-static as binfmt interpreter for mipsel Setting /usr/bin/qemu-mipsn32-static as binfmt interpreter for mipsn32 Setting /usr/bin/qemu-mipsn32el-static as binfmt interpreter for mipsn32el Setting /usr/bin/qemu-mips64-static as binfmt interpreter for mips64 Setting /usr/bin/qemu-mips64el-static as binfmt interpreter for mips64el Setting /usr/bin/qemu-sh4-static as binfmt interpreter for sh4 Setting /usr/bin/qemu-sh4eb-static as binfmt interpreter for sh4eb Setting /usr/bin/qemu-s390x-static as binfmt interpreter for s390x Setting /usr/bin/qemu-aarch64-static as binfmt interpreter for aarch64 Setting /usr/bin/qemu-aarch64_be-static as binfmt interpreter for aarch64_be Setting /usr/bin/qemu-hppa-static as binfmt interpreter for hppa Setting /usr/bin/qemu-riscv32-static as binfmt interpreter for riscv32 Setting /usr/bin/qemu-riscv64-static as binfmt interpreter for riscv64 Setting /usr/bin/qemu-xtensa-static as binfmt interpreter for xtensa Setting /usr/bin/qemu-xtensaeb-static as binfmt interpreter for xtensaeb Setting /usr/bin/qemu-microblaze-static as binfmt interpreter for microblaze Setting /usr/bin/qemu-microblazeel-static as binfmt interpreter for microblazeel Setting /usr/bin/qemu-or1k-static as binfmt interpreter for or1k fujita@Inspiron-11-3162:~$ docker start -i 8d1086983af8 root@8d1086983af8:/#makeやgccなどはすでにインストール済みなので、C言語での開発ならすぐに始めることができます。
おまけ
マルチアーキテクチャのコンテナイメージがGitHubで公開されています。
- 投稿日:2020-01-12T15:06:22+09:00
dockerのscratchイメージ上でgolangのWebアプリを動かす際は、スタティックリンクが必要
Best practices for writing Dockerfiles (参考訳v18.09ベース)を参考に、golangで書いたWebアプリを動かそうとしたらハマったので、その記録を残します。
ざっくりいうと
- golangで書いたwebアプリ(サンプル)を、dockerのscratchイメージ上で動かそうとしたら起動で失敗
- 調べたらダイナミックリンクでビルドされており、scratchイメージではファイルが足りなかったのが原因
- スタティックリンクでビルドし直したら解決した
環境
- go 1.13.5
- docker 19.03.5
ハマるまでの流れ
"Use multi-stage builds"にマルチステージビルドを使うgolangのサンプルがあります。ビルドするときに使うイメージとリリースするイメージを分けることで、リリースイメージに余計なもの入れなくてすみ、イメージのサイズも小さくできます。
それはよさそうだと言うことで、手元にあったWebアプリをサンプルにして次のようなDockerfileを用意しました。
FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]sample-go-serverは、
hello world
を返す簡単なものです。package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintf(w, "hello world") }) log.Fatal(http.ListenAndServe(":8080", nil)) }このDockerfileをビルドします。
❯ docker build -t sample-go-server . ❯ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sample-go-server latest 0acf7d1e1ed7 42 minutes ago 7.45MBrunで起動すると思いきや次のようなエラーで失敗します。
❯ docker run -d -p 8080:8080 --name sample sample-go-server 1e097919ec5ac31839228646e2b14bd0434f56d74787d73b6afa172154829250 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ❯ docker logs sample standard_init_linux.go:211: exec user process caused "no such file or directory"
"no such file or directory"
と言われましても…。何が足りないかを言ってくれ〜?解決方法
ググったところ以下が見つかりました。ありがとうインターネッツ。
- Docker + Goバイナリでstandard_init_linux.go:178: exec user process caused "no such file or directory"と出た時の対処 - Qiita
- golangで書いたアプリケーションのstatic link化 - okzkメモ
netパッケージを含む場合はダイナミックリンクでビルドされ、それが原因でno such fileになるらしいです。
なので、さっそくこれに該当しているかを確認してみます。
ビルドで使ったalpineイメージにはfile
コマンドが入っていないため、まずそれを入れます。パッケージは Alpine Linux packagesで探せます。/bin # apk update && apk add file fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz v3.11.2-25-g58afcd742e [http://dl-cdn.alpinelinux.org/alpine/v3.11/main] v3.11.2-24-g7cfe3a1534 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community] OK: 11261 distinct packages available (1/2) Installing libmagic (5.37-r1) (2/2) Installing file (5.37-r1) Executing busybox-1.31.1-r8.trigger OK: 12 MiB in 17 packages /bin # which file /usr/bin/file
file
コマンドで確認してみると、たしかにdinamically linked
となっていました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=5E6Qy3Li7DELFoSZUyv5/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/wYNglNx2pwV9Z_45IRLn, not stripped参考サイトにあった
CGO_ENABLED=0
でビルドをし直してみます。FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN CGO_ENABLED=0 go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]たしかに
statically linked
に変わりました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=cD81ASWTt8bngTyIxfpe/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/rmgAW8vnYv0XAugzIkMj, not strippeddocker runでも無事起動できました。
❯ docker run -d -p 8080:8080 --name sample sample-go-server c27e29aaa697ac7131995472377bb2ff58e6a6ebe6a8174fb8a9de64efc767d5 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c27e29aaa697 sample-go-server "/bin/sample-go-serv…" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp sample ❯ curl http://localhost:8080 hello world参考
- 投稿日:2020-01-12T15:06:22+09:00
dockerのscratchイメージでgolangのWebアプリを動かすときは、スタティックリンクしてるかを確認
Best practices for writing Dockerfiles (参考訳v18.09ベース)を参考に、golangで書いたWebアプリを動かそうとしたらハマったので、その記録を残します。
ざっくりいうと
- golangで書いたwebアプリ(サンプル)を、dockerのscratchイメージ上で動かそうとしたら起動で失敗
- 調べたらダイナミックリンクでビルドされており、scratchイメージではファイルが足りなかったのが原因
- スタティックリンクでビルドし直したら解決した
環境
- go 1.13.5
- docker 19.03.5
ハマるまでの流れ
"Use multi-stage builds"にマルチステージビルドを使うgolangのサンプルがあります。ビルドするときに使うイメージとリリースするイメージを分けることで、リリースイメージに余計なもの入れなくてすみ、イメージのサイズも小さくできます。
それはよさそうだと言うことで、手元にあったWebアプリをサンプルにして次のようなDockerfileを用意しました。
FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]sample-go-serverは、
hello world
を返す簡単なものです。package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintf(w, "hello world") }) log.Fatal(http.ListenAndServe(":8080", nil)) }このDockerfileをビルドします。
❯ docker build -t sample-go-server . ❯ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sample-go-server latest 0acf7d1e1ed7 42 minutes ago 7.45MBrunで起動すると思いきや次のようなエラーで失敗します。
❯ docker run -d -p 8080:8080 --name sample sample-go-server 1e097919ec5ac31839228646e2b14bd0434f56d74787d73b6afa172154829250 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ❯ docker logs sample standard_init_linux.go:211: exec user process caused "no such file or directory"
"no such file or directory"
と言われましても…。何が足りないかを言ってくれ〜?解決方法
ググったところ以下が見つかりました。ありがとうインターネッツ。
- Docker + Goバイナリでstandard_init_linux.go:178: exec user process caused "no such file or directory"と出た時の対処 - Qiita
- golangで書いたアプリケーションのstatic link化 - okzkメモ
netパッケージを含む場合はダイナミックリンクでビルドされ、それが原因でno such fileになるらしいです。
なので、さっそくこれに該当しているかを確認してみます。
ビルドで使ったalpineイメージにはfile
コマンドが入っていないため、まずそれを入れます。パッケージは Alpine Linux packagesで探せます。/bin # apk update && apk add file fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz v3.11.2-25-g58afcd742e [http://dl-cdn.alpinelinux.org/alpine/v3.11/main] v3.11.2-24-g7cfe3a1534 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community] OK: 11261 distinct packages available (1/2) Installing libmagic (5.37-r1) (2/2) Installing file (5.37-r1) Executing busybox-1.31.1-r8.trigger OK: 12 MiB in 17 packages /bin # which file /usr/bin/file
file
コマンドで確認してみると、たしかにdinamically linked
となっていました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=5E6Qy3Li7DELFoSZUyv5/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/wYNglNx2pwV9Z_45IRLn, not stripped参考サイトにあった
CGO_ENABLED=0
でビルドをし直してみます。FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN CGO_ENABLED=0 go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]たしかに
statically linked
に変わりました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=cD81ASWTt8bngTyIxfpe/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/rmgAW8vnYv0XAugzIkMj, not strippeddocker runでも無事起動できました。
❯ docker run -d -p 8080:8080 --name sample sample-go-server c27e29aaa697ac7131995472377bb2ff58e6a6ebe6a8174fb8a9de64efc767d5 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c27e29aaa697 sample-go-server "/bin/sample-go-serv…" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp sample ❯ curl http://localhost:8080 hello world参考
- 投稿日:2020-01-12T15:06:22+09:00
dockerのscratchイメージでgolangのWebアプリを動かす
Best practices for writing Dockerfiles (参考訳v18.09ベース)を参考に、golangで書いたWebアプリを動かそうとしたらハマったので、その記録を残します。
ざっくりいうと
- golangで書いたwebアプリ(サンプル)を、dockerのscratchイメージ上で動かそうとしたら起動で失敗
- 調べたらダイナミックリンクでビルドされており、scratchイメージではファイルが足りなかったのが原因
- スタティックリンクでビルドし直したら解決した
環境
- go 1.13.5
- docker 19.03.5
ハマるまでの流れ
"Use multi-stage builds"にマルチステージビルドを使うgolangのサンプルがあります。ビルドするときに使うイメージとリリースするイメージを分けることで、リリースイメージに余計なもの入れなくてすみ、イメージのサイズも小さくできます。
それはよさそうだと言うことで、手元にあったWebアプリをサンプルにして次のようなDockerfileを用意しました。
FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]sample-go-serverは、
hello world
を返す簡単なものです。package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintf(w, "hello world") }) log.Fatal(http.ListenAndServe(":8080", nil)) }このDockerfileをビルドします。
❯ docker build -t sample-go-server . ❯ docker images REPOSITORY TAG IMAGE ID CREATED SIZE sample-go-server latest 0acf7d1e1ed7 42 minutes ago 7.45MBrunで起動すると思いきや次のようなエラーで失敗します。
❯ docker run -d -p 8080:8080 --name sample sample-go-server 1e097919ec5ac31839228646e2b14bd0434f56d74787d73b6afa172154829250 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ❯ docker logs sample standard_init_linux.go:211: exec user process caused "no such file or directory"
"no such file or directory"
と言われましても…。何が足りないかを言ってくれ〜?解決方法
ググったところ以下が見つかりました。ありがとうインターネッツ。
- Docker + Goバイナリでstandard_init_linux.go:178: exec user process caused "no such file or directory"と出た時の対処 - Qiita
- golangで書いたアプリケーションのstatic link化 - okzkメモ
netパッケージを含む場合はダイナミックリンクでビルドされ、それが原因でno such fileになるらしいです。
なので、さっそくこれに該当しているかを確認してみます。
ビルドで使ったalpineイメージにはfile
コマンドが入っていないため、まずそれを入れます。パッケージは Alpine Linux packagesで探せます。/bin # apk update && apk add file fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz v3.11.2-25-g58afcd742e [http://dl-cdn.alpinelinux.org/alpine/v3.11/main] v3.11.2-24-g7cfe3a1534 [http://dl-cdn.alpinelinux.org/alpine/v3.11/community] OK: 11261 distinct packages available (1/2) Installing libmagic (5.37-r1) (2/2) Installing file (5.37-r1) Executing busybox-1.31.1-r8.trigger OK: 12 MiB in 17 packages /bin # which file /usr/bin/file
file
コマンドで確認してみると、たしかにdinamically linked
となっていました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=5E6Qy3Li7DELFoSZUyv5/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/wYNglNx2pwV9Z_45IRLn, not stripped参考サイトにあった
CGO_ENABLED=0
でビルドをし直してみます。FROM golang:1.13.5-alpine AS build WORKDIR /go/src/sample-go-server COPY ./app /go/src/sample-go-server RUN CGO_ENABLED=0 go build -o /bin/sample-go-server FROM scratch COPY --from=build /bin/sample-go-server /bin/sample-go-server EXPOSE 8080 ENTRYPOINT ["/bin/sample-go-server"]たしかに
statically linked
に変わりました。/bin # file sample-go-server sample-go-server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=cD81ASWTt8bngTyIxfpe/TdC1EDiTsXrg0i0ta2Xx/49v4RWXcyEm12mEJPV8f/rmgAW8vnYv0XAugzIkMj, not strippeddocker runでも無事起動できました。
❯ docker run -d -p 8080:8080 --name sample sample-go-server c27e29aaa697ac7131995472377bb2ff58e6a6ebe6a8174fb8a9de64efc767d5 ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c27e29aaa697 sample-go-server "/bin/sample-go-serv…" 2 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp sample ❯ curl http://localhost:8080 hello world参考
- 投稿日:2020-01-12T13:03:23+09:00
軽量なDocker Imageを作成する
目的
この記事では、軽量のDocker Imageを生成するDockerfileを作成する手順を書いていきます。
余談
有名な仮想化ソフトとして、Virtual Box(+ Vagrant)がありますが、以下のような問題点があります。
- 仮想マシン起動が遅い
- イメージの容量が大きい
- 2GBとか
勿論、Virtual Boxは、ホストOS(PC)の中にそのままOSを立ち上げるため、ネットワーク周り等扱いやすいと言えば扱いやすいのですが、仮想マシン立ち上げ時に時間がかかったり、ほかの人と同じ環境を共有する際、2GBのイメージを交換したりするのは大変です。
そこで、Dockerという仮想化ソフトの出番ですが、実際に使ってみると初心者は特に、以下の課題が発生するかと思います。
- Docker Imageが1GBを超える
仮想環境のイメージを共有する際、Virtual Boxとは異なり、Imageを生成するためのテキストで記述されたDockerfileを使用することに関しては、イメージ共有を効率化するのですが、何も考えずイメージを作成していしまうと、1GBのイメージになってしまい、それなりにリソースを食います。
やはり、かっこいいのは、軽量化されたイメージだと思うので、今回は自分で目的に沿ったイメージを作成したいと思います。
開発環境
今回のDocker Imageは、以下の環境で作成/テストを行います。
- OS: Windows 10
- Docker: Docker Toolbox version 19.03.1
Dockerfileの作成
ゴール
Ruby on RailsのWebアプリケーション(rails newした初期アプリ)が入っているDocker Imageを生成するDockerfileを作成します。
ハードウェア容量が少ないサーバー等に需要があるかと思います。
また、Docker Imageを共有するときも、軽い方がImageの生成が素早くていいと思います。作成するDocker Image
Ruby公式の軽量イメージの
alpineイメージ
を使用します。
このalpineイメージ、最小のソフトしかインストールされていない為、Ruby on Railsのアプリケーション起動に必要なソフトをインストールしながらDockerfileを作成します。
インストールするアプリケーションのバージョンは、以下です。
- Ruby: 2.6.5
- Ruby on Rails: 6.0.1
Dockerfileの作成手順
Dockerfileを作成するの手順は以下の様に行います。
- ベースイメージのPull
- ベースコンテナの立ち上げ
- コンテナ内で必要ソフトのインストール
- Dockerfileの作成
- Dockerfileの実行
地道な作業になりますが、やる気をそがれず、後戻りせず行うためには、上記のような手順になるかと思います。
それでは、実際にイメージを作成していきます。
Dockerはインストールするされていることが前提で解説をします。1.ベースイメージのPull
以下のコマンドでベースとなるDocker Imageをローカルにダウンロードします。
どのバージョンのRubyイメージがあるかは、公式HPのDescription
タブに記述があります。docker pull ruby:2.6.5-alpine3.102.ベースコンテナの立ち上げ
以下のコマンドで、Pullしたイメージを使用し、コンテナを立ち上げます。
docker run -it ruby:2.6.5-alpine3.10 /bin/ashalpineイメージでは、
bash
は使用できないため、/bin/ash
を指定して実行します。3.コンテナ内で必要ソフトのインストール
コンテナ内でRailsアプリケーションを立ち上げるために必要なソフトをインストールします。
インストールしたソフトやコマンドに関しては、Dockerfileまたはメモに書き残します。
エラーが発生した場合、エラー文を読んだり、検索したりして対処を行います。
また、コマンド実行後に、y/n
の選択肢が出る場合は、記録を行い、Dockerfileでは-y
などのオプションをつけて記述していきます。今回は、railsをインストールして、必要なパッケージをインストールする方法をとりました。
コンテナ内で実行したコマンド/ # apk update / # apk add yarn nodejs / # gem install bundler / # gem install rails <- C compilerなどがなく エラー / # apk add gcc / # apk add g++ / # apk add make / # gem install rails <- 成功 / # mkdir app / # cd app / # rails new . <- sqlite3がなくエラー / # apk add sqlite-dev / # rails s ... <- rails sができるまで試すメモapk update apk add yarn nodejs gem install bundler apk gcc g++ make apk add sqlite-dev ...4.Dockerfileの作成
3でメモしたコマンドを元に、Dockerfileを作成します。
作成したDockerfileが以下です。
DockerfileFROM ruby:2.6.5-alpine3.10 ENV APP_HOME /app RUN mkdir -p $APP_HOME WORKDIR $APP_HOME ADD . $APP_HOME RUN apk update \ && apk add --no-cache gcc g++ make sqlite-dev yarn nodejs \ && gem install bundler \ && bundle install \ && yarn install EXPOSE 3000 CMD ["rails", "s", "-b", "0.0.0.0"]5.Dockerfileの実行
4.で作成したDockerfileを実行します。
railsのアプリケーションディレクトリの中に、Dockerfileを置き、イメージを生成します。
ディレクトリは以下のような構成になります。app/ ├ Dockerfile ├ bin/ ├ config.ru ├ Gemfile ├ Gemfile.lock ├ lib/ ├ node_modules/ ├ postcss.config.js ├ Rakefile ├ storage/ ├ tmp/ ├ yarn.lock ├ babel.config.js ├ config/ ├ db/ ├ log/ ├ package.json ├ public/ ├ README.md ├ test/ └ vendor/また、4.で
rails s
を実行した際に、Please add gem 'tzinfo-data' to your Gemfile and run bundle install
といったエラーが出たので、ホストOSのGemfileを変更します。- (修正前) gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + (修正後) gem 'tzinfo-data'以下のコマンドでDockerfileをビルドします。
docker build -t rails-app .
作成したイメージを使用して上手くコンテナが起動できない場合は、以下のコマンドを使用して、ログを確認しつつ、エラーを解消していきます。
docker logs <コンテナID>
作成したイメージからコンテナを立ち上げ、ブラウザなどから、Railsアプリケーションの起動が確認できれば終了です。
docker run -d -p 3000:3000 rails-app
curl http://192.168.99.100:3000
公式イメージとの比較
Rubyの公式イメージにrailsをインストールしたDocker Imageと比較しました。
イメージ名 容量 rails-app 649MB ruby(公式) 1.29GB 容量はあくまでも参考にしてください。
そもそも、Rubyの公式イメージ自体、840MBあるので、今回作成したイメージが軽量化されていることがわかります。docker-composeを使用して、ホストOS側のアプリケーションディレクトリをマウントすると、もっとイメージ自体の容量が少なくなります。
Macを使用して、ホストOSからエディタで開発をする場合はdocker-composeを使用した方がいいかもしれません。ポイントとしては、
rails new .
をするまでの過程の中で、必要最低限のものしかインストールしない事だと思います。
例えば、alpine-sdk
をインストールすれば、gccやmakeがインストールできるのですが、その他gitやcurlなど必要のない物もインストールされてしまいます。
なので、gem install rails
やbundle install
した際にエラーが出て、インストールが必要なものだけ入れるのが良いと思います。また、今回使用した
ruby:2.6.5-alpine3.10
には、vi
が入っていたので、この辺りも削除するとよいと思います。
- 投稿日:2020-01-12T11:40:41+09:00
dockerでbrowser-syncを導入して令和のWordPress環境に
概要
2017年ぐらいまではほぼWPに食わせてもらっていたというぐらいにWP案件をやりまくっていたものの、そこからSPAなどを触るようになりブラウザシンクやローカル構築に甘やかされまくった結果、WPの仕事が辛くて仕方なくなる
クリアライン
・ブラウザシンクを入れてローカルのthemeを変更したらブラウザシンクでブラウザをオートリロードさせて開発スピードをアップしたい
問題解決に向けて
docker-comopseを導入する
docker-compose.ymlversion: "3" services: db: image: mysql:5.7 volumes: - ./db_data:/var/lib/mysql - ./localhost.sql:/docker-entrypoint-initdb.d/install_wordpress.sql environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: main_db MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: image: wordpress:latest depends_on: - db ports: - "8000:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_NAME: main_db WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_TABLE_PREFIX: wp_ volumes: - ./themes:/var/www/html/wp-content/themes - ./plugins:/var/www/html/wp-content/plugins - ./languages:/var/www/html/wp-content/languages phpmyadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=db:3306 - PMA_USER=wordpress - PMA_PASSWORD=wordpress depends_on: - db ports: - 8080:80 volumes: - /sessions bs-wordpress: image: ustwo/browser-sync command: start --proxy "wordpress:80" --files "themes/**/*.php,themes/**/*.css" volumes: - ./themes:/source/themes depends_on: - wordpress ports: - "3000:3000" - "3001:3001"docker-compose up後に
bs-wordpress_1 | [Browsersync] Proxying: http://wordpress:80 bs-wordpress_1 | [Browsersync] Access URLs: bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | Local: http://localhost:3000 bs-wordpress_1 | External: http://172.21.0.5:3000 bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | UI: http://localhost:3001 bs-wordpress_1 | UI External: http://172.21.0.5:3001 bs-wordpress_1 | -----------------------------------というメッセージが出てきてlocalhost:3000でブラウザシンクが立ち上がり
themes配下のphpファイルとcssをを更新するとブラウザシンクが走りリロードされます。何をやっているのか
ついでに
普段のWP環境はこれに
・localhost.sqlを利用してサーバーのDBをローカルにpullする
・WP Offload Mediaを利用して画像ファイルの管理をすべてS3にぶん投げてローカルとサーバーのズレを最小限にする
・AWS code deployを利用して特定のgitブランチにアップすると自動でサーバーにデプロイを行う
ということを組み合わせて行いPRベースでの開発を徹底しています。
そのあたりもまた機会があれば記事にしたいと思います。
- 投稿日:2020-01-12T11:40:41+09:00
dockerでオートデプロイを導入して令和のWordPress環境に
概要
2017年ぐらいまではほぼWPに食わせてもらっていたというぐらいにWP案件をやりまくっていたものの、そこからPWAなどを触るようになりブラウザシンクやローカル構築に甘やかされまくった結果、WPの仕事が辛くて仕方なくなる
クリアライン
・ブラウザシンクを入れてローカルのthemeを変更したらブラウザシンクでブラウザをオートリロードさせて開発スピードをアップしたい
問題解決に向けて
docker-comopseを導入する
docker-compose.ymlversion: "3" services: db: image: mysql:5.7 volumes: - ./db_data:/var/lib/mysql - ./localhost.sql:/docker-entrypoint-initdb.d/install_wordpress.sql environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: main_db MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: image: wordpress:latest depends_on: - db ports: - "8000:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_NAME: main_db WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_TABLE_PREFIX: wp_ volumes: - ./themes:/var/www/html/wp-content/themes - ./plugins:/var/www/html/wp-content/plugins - ./languages:/var/www/html/wp-content/languages phpmyadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=db:3306 - PMA_USER=wordpress - PMA_PASSWORD=wordpress depends_on: - db ports: - 8080:80 volumes: - /sessions bs-wordpress: image: ustwo/browser-sync command: start --proxy "wordpress:80" --files "themes/**/*.php,themes/**/*.css" volumes: - ./themes:/source/themes depends_on: - wordpress ports: - "3000:3000" - "3001:3001"docker-compose後に
bs-wordpress_1 | [Browsersync] Proxying: http://wordpress:80 bs-wordpress_1 | [Browsersync] Access URLs: bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | Local: http://localhost:3000 bs-wordpress_1 | External: http://172.21.0.5:3000 bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | UI: http://localhost:3001 bs-wordpress_1 | UI External: http://172.21.0.5:3001 bs-wordpress_1 | -----------------------------------というメッセージが出てきてlocalhost:3000でブラウザシンクが立ち上がり
themes配下のphpファイルとcssをを更新するとブラウザシンクが走りリロードされます。何をやっているのか
ついでに
普段のWP環境はこれに
・localhost.sqlを利用してサーバーのDBをローカルにpullする
・WP Offload Mediaを利用して画像ファイルの管理をすべてS3にぶん投げてローカルとサーバーのズレを最小限にする
・AWS code deployを利用して特定のgitブランチにアップすると自動でサーバーにデプロイを行う
ということを組み合わせて行いPRベースでの開発を徹底しています。
そのあたりもまた機会があれば記事にしたいと思います。
- 投稿日:2020-01-12T11:40:41+09:00
dockerでブラウザシンクを導入して令和のWordPress環境に
概要
2017年ぐらいまではほぼWPに食わせてもらっていたというぐらいにWP案件をやりまくっていたものの、そこからPWAなどを触るようになりブラウザシンクやローカル構築に甘やかされまくった結果、WPの仕事が辛くて仕方なくなる
クリアライン
・ブラウザシンクを入れてローカルのthemeを変更したらブラウザシンクでブラウザをオートリロードさせて開発スピードをアップしたい
問題解決に向けて
docker-comopseを導入する
docker-compose.ymlversion: "3" services: db: image: mysql:5.7 volumes: - ./db_data:/var/lib/mysql - ./localhost.sql:/docker-entrypoint-initdb.d/install_wordpress.sql environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: main_db MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: image: wordpress:latest depends_on: - db ports: - "8000:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_NAME: main_db WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_TABLE_PREFIX: wp_ volumes: - ./themes:/var/www/html/wp-content/themes - ./plugins:/var/www/html/wp-content/plugins - ./languages:/var/www/html/wp-content/languages phpmyadmin: image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=db:3306 - PMA_USER=wordpress - PMA_PASSWORD=wordpress depends_on: - db ports: - 8080:80 volumes: - /sessions bs-wordpress: image: ustwo/browser-sync command: start --proxy "wordpress:80" --files "themes/**/*.php,themes/**/*.css" volumes: - ./themes:/source/themes depends_on: - wordpress ports: - "3000:3000" - "3001:3001"docker-compose up後に
bs-wordpress_1 | [Browsersync] Proxying: http://wordpress:80 bs-wordpress_1 | [Browsersync] Access URLs: bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | Local: http://localhost:3000 bs-wordpress_1 | External: http://172.21.0.5:3000 bs-wordpress_1 | ----------------------------------- bs-wordpress_1 | UI: http://localhost:3001 bs-wordpress_1 | UI External: http://172.21.0.5:3001 bs-wordpress_1 | -----------------------------------というメッセージが出てきてlocalhost:3000でブラウザシンクが立ち上がり
themes配下のphpファイルとcssをを更新するとブラウザシンクが走りリロードされます。何をやっているのか
ついでに
普段のWP環境はこれに
・localhost.sqlを利用してサーバーのDBをローカルにpullする
・WP Offload Mediaを利用して画像ファイルの管理をすべてS3にぶん投げてローカルとサーバーのズレを最小限にする
・AWS code deployを利用して特定のgitブランチにアップすると自動でサーバーにデプロイを行う
ということを組み合わせて行いPRベースでの開発を徹底しています。
そのあたりもまた機会があれば記事にしたいと思います。
- 投稿日:2020-01-12T05:02:56+09:00
日本語自然言語処理で必須の前処理まとめ(Dockerによる環境構築込み)
この記事でやること
日本語文章で自然言語処理的なことをやる際に, アルゴリズム選択やパラメータチューニングと同等かそれ以上に重要となる前処理。丁寧に色々やりたいとは言え毎回ゼロから同じようなスクリプトを書くのも面倒なので, 毎回必ずやるであろう
- 全角・半角の統一と重ね表現(!!とかーーとか)の除去
- HTMLタグの除去
- 絵文字の除去
- URLの除去
- 記号の除去
- 数字の表記統一
- 分かち書き
- 見出し語化
あたりの処理を一発で済ませるために用意した自分なりの秘伝のタレを公開します。
ついでにMeCabの導入やJupyter lab環境の構築もDocker化できたので合わせて載せてます。環境構築編
まずは以下のDockerfileを用意します。gensimやspaCyなど今回の前処理には使わないパッケージも入ってますがお気になさらず。
(2020/1/12追記) mecab-ipadic-neologdのインストールで-aオプションを付けないと一部の辞書しかインストールされないのでオプションを追加
(2020/1/13追記) プロセス並列で実行するためのメソッドを追加FROM jupyter/minimal-notebook USER root ## Mecab関連インストール ## mecabrc is installed in /etc/mecabrc ## default dictionary path is /var/lib/mecab/dic/debian ## mecab-ipadic-utf-8 is installed in /var/lib/mecab/dic/ipadic-utf8 ## mecab-ipadic-neologd is installed in /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd RUN apt-get update && \ apt-get install -y curl && \ apt-get install -y file && \ apt-get install -y mecab && \ apt-get install -y libmecab-dev && \ apt-get install -y mecab-ipadic-utf8 && \ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git && \ cd mecab-ipadic-neologd && \ bin/install-mecab-ipadic-neologd -n -y -a && \ rm -rf /home/jovyan/mecab-ipadic-neologd ## Pythonパッケージインストール USER $NB_UID RUN conda install --quiet --yes \ 'conda-forge::blas=*=openblas' \ 'ipywidgets=7.5*' \ 'numpy=1.17*' \ 'pandas=0.25*' \ 'matplotlib=3.1*' \ 'seaborn=0.9*' \ 'sqlalchemy=1.3*' \ 'beautifulsoup4=4.7.*' \ 'scikit-learn=0.22*' \ 'tensorflow=1.13*' \ 'keras=2.2*' && \ conda clean --all -f -y && \ pip install spacy==2.2.3 \ 'https://github.com/megagonlabs/ginza/releases/download/latest/ginza-latest.tar.gz' \ japanize-matplotlib==1.0.5 \ mecab-python3==0.996.3 \ neologdn==0.4 \ emoji==0.5.4 \ gensim==3.8.1 \ pipetools==0.3.5 && \ jupyter nbextension enable --py widgetsnbextension --sys-prefix && \ jupyter labextension install jupyterlab_vim && \ jupyter labextension install @jupyterlab/toc && \ jupyter labextension install @jupyter-widgets/jupyterlab-manager@^1.0.0 && \ rm -rf $CONDA_DIR/share/jupyter/lab/staging && \ rm -rf /home/$NB_USER/.cache/yarn && \ rm -rf /home/$NB_USER/.node-gyp && \ MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \ fix-permissions /home/$NB_USER WORKDIR /home/jovyan/workDockerfileが用意できたら次のコマンドでイメージをビルド・起動してJupyter Labを立ち上げます。
$ docker build -t my-nlp-notebook:1.0 . $ docker run --rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes -e TZ=Asia/Tokyo -v `pwd`:/home/jovyan/work my-nlp-notebook:1.0前処理用テンプレコード
Jupyterに以下のコードを貼っつけます。
(2020/1/12追記) mecabの辞書としてmecab-ipadic-neologdを使う設定が抜けていたので修正。import MeCab import neologdn import emoji import re from bs4 import BeautifulSoup from pipetools import pipe from multiprocessing import Pool class Preprocessor: CATEGORY_INDEX = 0 # node.feature中で品詞が格納されているindex ROOT_FORM_INDEX = 6 # 単語の原型が格納されているindex TAGGER = MeCab.Tagger("-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd") def __init__(self, targets = ["名詞", "動詞", "形容詞", "副詞", "連体詞"]): self.target_categories = set(targets) self.url_pattern = re.compile(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-]+') self.half_width_symbol_pattern = re.compile(r'[!-/:-@[-`{-~]') self.full_width_symbol_pattern = re.compile(u'[■-♯]') self.number_pattern = re.compile(r'\d+') def pipe_all(self, texts): ''' 全前処理工程を行う 1. 全角・半角の統一と重ね表現の除去 2. HTMLタグの除去 3. 絵文字の除去 4. URLの除去 5. 記号の除去 6. 数字の表記統一 7. 分かち書きと見出し語化 ''' result = texts > (pipe | (lambda x: self._loop(x, self._normalize_text)) | (lambda x: self._loop(x, self._remove_html_tag)) | (lambda x: self._loop(x, self._remove_emoji)) | (lambda x: self._loop(x, self._remove_url)) | (lambda x: self._loop(x, self._remove_symbol)) | (lambda x: self._loop(x, self._convert_number_to_zero)) | (lambda x: self._loop(x, self._divide_text)) ) return result def parallel_pipe_all(self, texts, num_process = 2): '''pipe_allをプロセス並列で実行する''' with Pool(processes = num_process) as p: result = p.map(func = self._normalize_text, iterable = texts) result = p.map(func = self._remove_html_tag, iterable = result) result = p.map(func = self._remove_emoji, iterable = result) result = p.map(func = self._remove_url, iterable = result) result = p.map(func = self._remove_symbol, iterable = result) result = p.map(func = self._convert_number_to_zero, iterable = result) result = p.map(func = self._divide_text, iterable = result) return result def _loop(self, texts, func): '''テキストのリストに対する処理を高速化するため内包表記をかます''' return [func(text) for text in texts] def _normalize_text(self, text): '''全角/半角の統一と重ね表現の除去''' return neologdn.normalize(text) def _remove_html_tag(self, text): '''HTMLタグを含むテキストから文字列のみを取り出す''' return BeautifulSoup(text).get_text() def _remove_emoji(self, text): '''絵文字を空文字に置換する''' return ''.join(['' if char in emoji.UNICODE_EMOJI else char for char in text]) def _remove_url(self, text): '''URLを空文字に置換する''' return self.url_pattern.sub('', text) def _remove_symbol(self, text): '''記号をスペースに置換する(意味のある記号も存在するため)''' # 半角記号の除去 text_without_half_width_symbol = self.half_width_symbol_pattern.sub(' ', text) # 全角記号の置換 (ここでは0x25A0 - 0x266Fのブロックのみを除去) text_without_full_width_symbol = self.full_width_symbol_pattern.sub(' ', text_without_half_width_symbol) return text_without_full_width_symbol def _convert_number_to_zero(self, text): '''数字を全て0に置換する''' return self.number_pattern.sub('0', text) def _divide_text(self, text): '''分かち書きとMeCab辞書による見出し語化''' words = [] node = self.TAGGER.parseToNode(text) while node: features = node.feature.split(',') if features[self.CATEGORY_INDEX] in self.target_categories: # 原型がMeCabの辞書に存在しない場合には単語の表層を格納する if features[self.ROOT_FORM_INDEX] == "*": words.append(node.surface) # 辞書に載っている単語については原型に直して格納する else: words.append(features[self.ROOT_FORM_INDEX]) node = node.next return words使い方
pipe_allメソッドに文章のリストを渡せば全処理をシリアル実行してくれます。
マルチコア環境の場合はparallel_pipe_allの方を使うと並列実行されます。
全部の処理が効くように敢えて変な文章を相手に前処理してみたのが以下。text = """ 今週は男2人でカフェ開拓してきたよv(^^)v 僕が頼んだのは濃厚なかぼちゃのタルト。 うめーーーーー!! 超Deliciousで接客もGoodでした? これで1,430.52円は安い!☆ お店のリンク: http://hogehoge.navi/fuga_cafe #週末グルメ <h1>タイトル<p>路地裏のカフェ</p></h1> """ processor = Preprocessor() print(processor.pipe_all([text])) => [['今週', '男', '0', '人', 'カフェ', '開拓', 'する', 'くる', 'v', 'v', '僕', '頼む', 'の', '濃厚', 'かぼちゃ', 'タルト', 'うめー', 'Delicious', '接客', 'Good', 'これ', '0', '0', '0円', '安い', '店', 'リンク', '週末', 'グルメ', 'タイトル', '路地', '裏', 'カフェ']]v(^^)v ⇐こやつの両手が残っちゃってますね
まあこれはいずれ何とかします(え)。実行時間を測ってみる
手元にちょうどいいデータセットがなかったので, ひとまずさっきと同じテキストを1万件前処理した際の実行時間を見てみました。
lenovo ideapad 330S Intel® Core™ i5 8コア
Ubuntu 18.04 LTSの環境で以下を実行。
[1] texts = [text for _ in range(10000)] [2] %%timeit precessor.pipe_all(texts) 4.08 s ± 7.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)正規化, HTMLタグの除去, 分かち書き辺りで時間を食っているようですね。
次に並列実行してみます。と言っても呼び出すメソッド名を変えるだけですが。
どのくらい高速化されたかをわかりやすくするためデータ件数を10万に増やした上でシングルコア計算の場合と比較したものが次のグラフです。
8コア並列までやるとシングルコアの場合の4倍速くらいになっていますね!
- 投稿日:2020-01-12T01:50:41+09:00
Vagrant で Elixir/Phoenix 開発環境を構築する手順
Elixir/Phoenix の開発環境を構築するにはいくつかの方法がありますが、ある程度の規模の Phoenix アプリを開発するなら Docker Compose を利用したくなるでしょう。
しかし、実際に開発を始めると、悩ましい問題に遭遇します。それは、Docker Desktop for Mac あるいは Docker Desktop for Windows の元で動く Phoenix アプリがとても遅い、ということです。いや、Phoenix アプリに限りません。データベースを使用する Web アプリ全般の反応がとても悪いです。「Docker Mac 遅い」または「Docker Windows 遅い」で Google 検索すると、大量の怨嗟の声とさまざまな解決策がヒットします。
ひとつの解決策は、Docker Desktop for Mac/Windows の利用をあきらめて、Vagrant + VirtualBox を採用するというものです。VirtualBox の上に Linux を載せ、そこに Docker をインストールし、Linux 上に Elixir コンテナを構築するという方法です。
筆者が試してみた限りでは、この方法はとてもうまく行きます。しかし、VirtualBox 特有の罠がいくつかあるので、なにもないところから
Vagrantfile
とDockerfile
とdocker-compose.yml
を作るのは意外に難しいものです。そこで、phx-vagrant という GitHub リポジトリに、これらの設定ファイルのセットを作りました。
以下、このリポジトリを clone して Elixir/Phoenix 開発環境を構築する手順を紹介します。
もしこの手順の通りにやってみて環境構築に失敗したら、GitHub で issue を立てて教えていただけると助かります。
動作確認済みのOS
- macOS Mojave (v10.14)
- Windows 10 Pro
※ おそらく Windows 10 Home でも動作しますが、筆者自身は確認していません。もし確認できた方がいらっしゃいましたら、t-kuroda @oiax.jp までご連絡いただけると助かります。
必要なソフトウェア
- Oracle VM VirtualBox 6.0 ※ 最新の 6.1 は非推奨
- Vagrant 2.2 以上
- Git 2.7 以上
VirtualBox のバージョンに関する注記
2020年1月12日時点での VirtualBox の最新版は v6.1.0 ですが、Vagrant の最新版(v2.2.6)は VirtualBox 6.1 に対応していません。可能であれば、VirtualBox 6.0 をインストールしてください。
すでに VirtualBox 6.1 をインストールしている方、あるいは VirtualBox 6.1 を使いたい方は、「mac vagrant virtualbox 6.1」でネット検索して対応方法を探してください。
Git for Windows に関する注記
Git for Windows をインストールする過程で「Configuring the line ending conversions」について尋ねられたとき、デフォルトの「Checkout Windows-style, commit Unix-style line endings」ではなく、2番目の選択肢「Checkout as-is, commit Unix-style line endings」を選んでください。
すでに Git for Windows をインストール済みの場合は、次のコマンドで変更できます。
% git config --global core.autocrlf input環境構築手順
% git clone https://github.com/oiax/phx-vagrant.git % cd phx-vagrant % vagrant plugin install vagrant-disksize % vagrant up % vagrant ssh $ bin/setup.shこれで、Ubuntu 18.04 Server の上に Docker がインストールされ、Elixir 1.9.4 がインストールされた Debian の Docker コンテナができあがります。
ネットワーク接続状況によりますが、初めてこの環境を構築する場合、2時間以上かかることがあります。ほとんどの時間は Ubuntu 18.04 Server の ISO イメージのダウンロードに費やされます。
Phoenix アプリケーション開発手順
Phoenix アプリケーションの新規作成
$ bin/login.sh > mix phx.new . --app my_app --module MyApp途中で「Y」または「n」の入力を求められたら、そのまま Enter キーを押してください。
ソースコードの書き換え
ここから先、生成された Phoenix アプリケーションのソースコードをテキストエディタで書き換えていきます。ホストPC(Mac/Windows)側で編集しても、コンテナ内で Vim を使って編集しても、どちらでも構いません。
データベース接続設定の変更
config/dev.exs
を開き、hostname
の値を"localhost"
から"db"
に変更してください。phoenix_live_reload の設定
以下の記述を
config/dev.exs
のMyApp.Repo
に関する設定(4-10行)の直後に追加してください。if System.get_env("COMPOSE_FILE") == "docker-compose.vagrant.yml" do config :phoenix_live_reload, backend: :fs_poll, backend_opts: [ interval: 500 ], dirs: [ "priv/static", "priv/gettext", "lib/my_app_web/templates", "lib/my_app_web/views" ] endこの記述がないと、HTMLテンプレートやスタイルシートを変更しても、ブラウザが自動更新されません。
webpack の設定
assets/webpack.config.js
の末尾の});
の前に以下の記述を追加してください。watchOptions: { aggregateTimeout: 300, poll: 1000, ignored: /node_modules/ }また、直前の行の末尾に
]
の後にコンマを追加してください。],データベースの作成
> mix ecto.createサーバーの起動
> exit $ bin/start.sh動作確認
ブラウザで http://localhost:4000 を開けば、Phoenix アプリケーションにアクセスできます。
ホストPC(Mac/Windows)側のテキストエディタで以下の2つのファイルを適宜書き換えてください。
lib/my_app_web/templates/page/index.html.eex
assets/css/phoenix.css
ファイルを保存してから数秒以内にブラウザが自動でリロードされ、表示が更新されることを確認してください。
サーバーの停止
ターミナルで
Ctrl-C
を入力すると Phoenix サーバーが停止します。Docker コンテナの停止
$ bin/stop.shVirtualBox ゲストマシンの停止
$ exit % vagrant halt備考
この記事の冒頭で「VirtualBox 特有の罠」と書きました。主な罠は、次の 2 点です。
- VirtualBox の共有フォルダの中にデータベースのデータ領域を置いてはならない。
- VirtualBox の共有フォルダの中に
node_modules
ディレクトリを置いてはならない。これらの罠にはまると、Phoenix サーバーがうまく動きません。
詳しい説明は省きますが、docker-compose.vagrant.ymlの中でいろいろと工夫しています。
- 投稿日:2020-01-12T00:26:09+09:00
Dockerで簡単にRedis試す
1, フォルダ作成
mkdir redis cd redis2, docker-compose.ymlファイル作成
docker-compose.ymlversion: '3' services: redis: image: "redis:latest" container_name: redis_test #下記のコマンド時に使用するコンテナ名 ports: - "6379:6379" #redisのデフォルトのポートは6379 volumes: - "./data/redis:/data"3, 上記で作ったymlファイルがある階層で、下記を実行
$ docker-compose up -d Creating network "redis_default" with the default driver Creating redis_test ... done $ docker exec -it redis_test /bin/bash # Redisクライアントの起動 root@9e25d6b48e8c:/data# redis-cli # 現在のkey全部の確認 127.0.0.1:6379> keys * (empty list or set)4, 文字列型の操作
コマンドリファレンスが分かりやすいです。
# 文字列 valueにkeyをセットする 127.0.0.1:6379> set name hoge OK # 指定したkeyに対応するvalueを表示 127.0.0.1:6379> get name "hoge"# keyに有効期限(秒数)を付けることができる(成功時は1, 失敗時は0を返す) 127.0.0.1:6379> expire name 3 (integer) 1 # 3秒後に、nameキーの値がnilになる 127.0.0.1:6379> get name (nil)# valueを1増やしたり、1減らしたりする 127.0.0.1:6379> set age 20 OK 127.0.0.1:6379> incr age (integer) 21 127.0.0.1:6379> decr age (integer) 20# keyの削除 127.0.0.1:6379> del age (integer) 1 127.0.0.1:6379> keys * (empty list or set)参考にさせて頂いた記事
- 投稿日:2020-01-12T00:17:51+09:00
code-server オンライン環境篇 (7) git 上のcompose を EC2上に展開する
目次
ローカル環境篇 1日目
オンライン環境篇 1日目 作業環境を整備するオンライン環境篇 3日目 Boto3 で EC2 インスタンスを立ち上げる
オンライン環境篇 4日目 Code-Serverをクラウドで動かしてみる
オンライン環境篇 5日目 Docker 上で、code-server を立ち上げる
オンライン環境篇 7日目 git 上のcompose を EC2上に展開する
...
オンライン篇 .. Coomposeファイルで構築オンライン篇 .. K8Sを試してみる
...
魔改造篇
はじめに
前回までで、Docker を利用して、EC Instance 上に Code-Serverを立ち上げることができるようになりました。
今回は、github 上に、compose file から、EC2 Instance に立ち上げるまでをやってみます。
- 作成
- 停止
- 再開
- 削除
- 情報取得
新規の知識はないので、茶々っと作ってみてください。
汚くて良いと思います。成果物例
https://github.com/kyorohiro/advent-2019-code-server/tree/master/app/docker_image_uploader_for_ec2
$ git clone https://github.com/kyorohiro/advent-2019-code-server.git $ cd advent-2019-code-server/remote_cs04/ $ docker-compose build $ docker-compose up -dブラウザで、
http://127.0.0.1:8443/
を開く。Terminal 上で
Terminal$ pip install -r requirements.txt $ aws configure .. ..EC2Instance を 作成
$ python main.py --createEC2 情報を取得
$ python main.py --get >>>> i-0d1e7775a07bbb326 >>>> >>>> 3.112.18.33 >>>> ip-10-1-0-228.ap-northeast-1.compute.internal >>>> 10.1.0.228 >>>> {'Code': 16, 'Name': 'running'}ブラウザー でアクセス
できました!!
一時停止してみよう
$ python main_command.py --stopEC2 Insntace を止めてます。
利用料金を安く抑えることができます。
EBS の Storage の使用量などはかかります。再開してみよう
python main_command.py --start停止したものを再開できます。
IPアドレスが変わるので注意削除しよう
# ec2 instance から logout $ exit # local の code-server 上で $ python main.py --delete次回
EC2ベースにする場合、あとは、解説するようなものはなく、作り込むだけだと思います。
ここまで出来れば、
クラウド上に、VSCode(Code-Server) を配置することは、もう出来ると思います。VSCode に関係なく、 Docker Image 、 Composefile かした物なら何でも
クラウド上に置けますね。次回は K8S編 or Fargate編 に入ります。
今までは自作してきましたが、
ありものを利用して、アレコレしていきます。コード
https://github.com/kyorohiro/advent-2019-code-server/tree/master/remote_cs06