- 投稿日:2020-11-18T23:10:11+09:00
ansibleを使用してnginxやDockerを単純インストール
事前準備
事前にAnsibleをインストールしておく、ssh-keygen -t rsaでキーを作成してキーでログインできるようにする。
共通設定
接続などの共通設定をいかに示す
inventory.ymlweb: hosts: hostname vars: domain: helloworld.com ansible_user: username ansible_ssh_private_key_file: ~/.ssh/id_rsa ansible_sudo_pass: test_passwordnginxをインストールする場合
aptコマンドを使用して単純にインストール
nginx.yml- hosts: web become: yes tasks: - name: "install nginx" apt: name: ['nginx'] state: latest実行結果メモ
$ ansible-playbook -i inventory.yml nginx.yaml PLAY [web] ******************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************** ok: [hostname] TASK [install nginx] ********************************************************************************************************************************************** changed: [hostname] PLAY RECAP ******************************************************************************************************************************************************** hostname : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nginxサーバが動いていることの単純な動作確認
$ curl localhost <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>dockerの単純インストール
aptを使用して単純にインストールするだけの動作
docker.yaml- hosts: web become: yes tasks: - name: "install docker.io" apt: name: ['docker.io'] state: latest実行結果
$ ansible-playbook -i inventory.yml docker.yaml PLAY [web] ******************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************** ok: [hostname] TASK [install docker.io] ****************************************************************************************************************************************** changed: [hostname] PLAY RECAP ******************************************************************************************************************************************************** hostname : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0dockerが動いていることの確認
$ sudo docker ps [sudo] username のパスワード: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 投稿日:2020-11-18T21:18:58+09:00
【docker-compose】volumesの名無し・名ありボリュームの使い方。バインドマウント
個人メモです。
dockerやdocker-composeで指定するボリュームの使い方について。
docker-compose.ymlにある2つのvolumesの違い
docker-compose.ymlの①外側のvolumesと②servicesの中のvolumesには違いがある。
docker-compose.ymlの例version: "3.7" volumes: todo-mysql-data: services: mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql①外側のvolumes
versionと同じ階層にあるvolumesは指定した名前のボリュームを用意している。
これを
名ありボリューム
という。volumes: todo-mysql-data:名ありボリュームの特徴(メリット)
- 複数のコンテナでボリュームを共有できる。
- コンテナを削除しても消えない(コンテナに依存しない)
②servicesの中のvolumes
各サービスの中のvolumesをバインドマウントと呼び、ボリュームとは区別される。
コンテナ内のディレクトリとホスト側のディレクトリをマウント(共有化)する処理を表す。
services: mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql上記例では、ボリューム
todo-mysql-data
をコンテナ内の/var/lib/mysql
にマウントしている。これで、/var/lib/mysqlのデータをボリュームに同期できる。
バインドマウント(bind mount)の書き方
バインドマウントには記述方法がいくつかある。
項目 バインドマウント 内容 名ありボリューム datavolume:/var/lib/mysql 指定したボリュームを、コンテナ内の指定ディレクトリにマウントする 名無しボリューム /var/lib/data コンテナ内のディレクトリのみ指定。ハッシュ値のボリュームが割り当てられる。(コンテナ削除で消える) ルートディレクトリを共有(相対パス) .:app コンテナ内の指定したディレクトリをホスト側の実行中ディレクトリにマウントする。 絶対パスで指定 /opt/data:/var/lib/mysql コンテナ内の指定したディレクトリをホスト側の指定したディレクトリにマウントする。 ・ルートディレクトリを共有
.:app
のような記述は頻繁に目にする。これをすることで、コンテナ内のデータをホスト側で再現できる。(これがないとホスト側でデータが見れない)
・名ありボリュームと名ありボリュームの主な用途
項目 名ありボリューム 名無しボリューム 主な用途 ・(1)複数コンテナでボリュームを共有する(例:db)・(2)ホスト側への同期から除外する(例:node_module) 他のコンテナと共有する必要はないが残しておきたいデータ(例:log) コンテナ削除 残る(コンテナに依存しない) 消える
- 投稿日:2020-11-18T21:16:27+09:00
Dockerでyarnを入れたはずなのに「ERROR: There are no scenarios; must have at least one」と怒られた時の対処法
背景
Dockerでyarnを入れたはずでしたが、いざ以下コマンドを叩いてみると怒られた
Dockerfileの中身
FROM ruby:2.5 RUN apt-get update && apt-get install -y \ build-essential \ libpq-dev \ nodejs \ postgresql-client \ yarn WORKDIR /kosare COPY Gemfile Gemfile.lock /kosare/ RUN bundle installyarnコマンドでエラー発生
root@5847e387581e:/kosare# yarn -v ERROR: There are no scenarios; must have at least one.解決策(一時的な解決策)
基本的には参考に記載のURLと同じことをすれば解決します。
私の場合はすでにrootで入っていたので、sudo
と記載している部分はなくして順番に実行したら解決しました。古いyarnを削除
sudo apt remove cmdtest sudo apt remove yarn最新を取得
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -最新を取得
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.listupdate
apt-get update再インストール
apt-get install yarnバージョン確認
yarn -v解決策(根本的な解決策)
上記のやり方だと、dockerで再度bundle installし直した時に再度同じ事象が発生する。
Dockerfileでbuildした際に解決したいため、以下の2行をdockerfileに追記する。RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.listDockerfile(最終形)
FROM ruby:2.5 RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install -y \ build-essential \ libpq-dev \ nodejs \ postgresql-client \ yarn WORKDIR /kosare COPY Gemfile Gemfile.lock /kosare/ RUN bundle installこれでbuildしなおせば、yarnがちゃんと使えるはず。
参考
https://k-koh.hatenablog.com/entry/2020/04/02/143017
https://github.com/yarnpkg/yarn/issues/7329
https://qiita.com/MasatoraAtarashi/items/3f0317cd648ff63fa92c
- 投稿日:2020-11-18T21:03:55+09:00
Raspberry Pi4(Ubuntu server20.04)でDockerを動かす勘所
初めに
ここに書いたのは、あくまでも2020年11月28日現在の話。Raspberry Pi上のDocker環境は激しく変わる。
Raspberry Pi OSの64bitはまだβ版。しかし64bitしかサポートしないアプリが増えているのでUbuntuを使う。
dockerは公式の最新を使う
ディストリビューションからインストールされるバージョンは大抵古いので、Docker公式のレポジトリを登録して使う。
https://docs.docker.com/engine/install/ubuntu/
$ 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 apt-key fingerprint 0EBFCD88 $ sudo add-apt-repository \ "deb [arch=arm64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.iodocker-compseを入れる
docker-compseは、公式からARM版バイナリが公開されていません。
自力でコンパイルpip3でインストール。$ sudo apt-get install libffi-dev libssl-dev $ sudo apt-get install python3 python3-pip python3-dev $ sudo pip3 install docker-compose
- Python3はデフォルトでインストールされているかも
MySQL
- NG(イメージがダウンロード出来ない)
$ docker pull mysql
- OK
$ docker pull mysql/mysql-serverdocker-compose.ymlで image:mysqlと書いてある部分は、mysql/mysql-serverに置き換える(挙動はあまりかわらない)
- 両者の違いは前者はDocker公式(debian base)で、後者がOracle公式(Oracle Linux base)みたい。
phpmyadmin
- 動かなっかった AMD64版を動かそうとしていたみたい。
$ docker run phpmyadmin/phpmyadminexec user process caused "exec format error" dockerエラーがでてコケた。
- 動いた
$ docker run arm64v8/phpmyadmin
- 公式イメージが動かなければ https://hub.docker.com/u/arm64v8 を調べると良いかも。
jwilder/nginx-proxy
これも動かない。
Dockerfileを見ると同梱するツールがamd64版をハードコードされていた。一緒に入れているツールのarm64版をコンパイルする必要がありそうなので取りあえずパス。
- 投稿日:2020-11-18T20:51:29+09:00
新卒がGoと楽天APIで宿探しBOT作ってみた
概要
4回目の投稿です。
以前、@yagi_engさんがスピーカーを務めたLINEBOTの勉強会に参加してきたので、復習がてら作成記事を書きます。
今回はGoで下記のように自分の位置情報を送信すると、周辺のホテル情報を返すLINEBOTを作成しました。
機能としては大きく2つです。
- 位置情報以外の情報(画像やテキスト)を送信すると、「位置情報を送信してください。」と定型文を返す。
- 位置情報を送信すると、周辺のホテル情報を最大10件返す。
各種ツール
- go 1.14
- VS Code 1.51.1
- Docker 19.03.13
- ngrok 2.3.35
- github.com/line/line-bot-sdk-go v7.6.0+incompatible
- 楽天トラベル施設検索API (version:2017-04-26)
構成
ローカルで立ちあげたサーバをngrokを使って外部公開し、LINF Platformに登録する形をとっています
周辺のホテル情報の検索には楽天トラベル施設検索APIを利用しています。
ツールの準備をする
LINE Developersに登録する
実装に入る前にまずは、LINEが提供するMassaging APIを利用するために下記の三つを行い、APIを利用するための
Channel secret
及びChannel access token
を取得する必要があります。取得にはLINEのアカウントが必要になります。楽天APIに登録する
楽天APIの利用には
アプリID
が必要になります。
Rakuten Developersより、アプリIDの発行を行うことができます。
こちらも利用には楽天会員のアカウントが必要になります。line-bot-sdkを取得する
実装には
line-bod-sdk-go
を利用するため、go get します。go get github.com/line/line-bot-sdk-go/linebot環境構築
DockerでGoの開発環境を構築する
こちらの記事を参考にDockerでコンテナを作り、8080ポートを割り当ててます。CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e56630e11723 linebot_app "bash" 2 days ago Up 2 seconds 0.0.0.0:8080->8080/tcp linebot_app_1定型文の応答
ローカルホストの立ち上げ
まずはmain関数でローカルホストを立ち上げます。
func main() { http.HandleFunc("/callback", callback) log.Fatal(http.ListenAndServe(":8080", nil)) }これで
localhost:8080/callback
にアクセスすると、callback関数が実行されるようになります。次にcallback関数の実装です。
https://github.com/line/line-bot-sdk-goの手順に沿って実装していきます。
実装は下記のようになってます。(
hotelInfoBack()
は記事後半で説明します。)func callback(w http.ResponseWriter, r *http.Request) { //チャネル作成時に取得したChannel secret及びChannel access tokenを引数に渡す bot, err := linebot.New(config.SECRET, config.TOKEN) if err != nil { log.Fatal(err) } //http.Requestを*linebot.Eventにパースする。 events, err := bot.ParseRequest(r) if err != nil { if err == linebot.ErrInvalidSignature { w.WriteHeader(400) //Bad Request } else { w.WriteHeader(500) //Internal Server Error } return } for _, event := range events { //リクエストのイベントがメッセージの受信かどうか if event.Type == linebot.EventTypeMessage { //受信したメッセージの種類による分岐 switch event.Message.(type) { case *linebot.LocationMessage: //位置情報を受信した場合 hotelInfoBack(bot, event) default: //位置情報以外を受信した場合 _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(backMsg)).Do() //bakcMsg = "位置情報を送信してください。" if err != nil { log.Print(err) } } } } }WebhookURLの登録
定型文返答の実装まで終わったら、作成したチャネルのMessageing APIタブからWebhookURLの登録を行います。
ngrokを使って、外部からローカルのサーバにアクセスするためのURLを発行します。(ngrokの使い方はこちら)
発行したhttps://......ngrok.io/callback
入力し、updateをクリックすれば、登録は完了です。
起動
作成したチャネルのMessageing APIタブのQRコードを読み取り、友達追加します。
go run
でローカルのサーバを立ち上げてから、メッセ―ジを送信すると定型文が返って来るようになりました....が余計なメッセージも返って来ています。
自動応答機能をオフにする
上記の問題は、MassaginAPIタブの
Auto-reply messages
の設定を変更することで解決できます。
画面右側のedit
をクリックして、応答メッセージをオフにすれば、余計なメッセージが返ってくることはなくなります。
ホテル情報の応答
応答のための処理
hotelInfoBack()
を実装していきます。func hotelInfoBack(bot *linebot.Client, e *linebot.Event) { msg := e.Message.(*linebot.LocationMessage) //受信した位置情報から、緯度経度を取得する lat := strconv.FormatFloat(msg.Latitude, 'f', 2, 64) lng := strconv.FormatFloat(msg.Longitude, 'f', 2, 64) //ホテル情報を取得する replyMsg, couldGetInfo := getHotelInfo(lat, lng) //取得に失敗した場合は、定型文(エラーが発生しました。)を返す。 if !couldGetInfo { _, err := bot.ReplyMessage(e.ReplyToken, linebot.NewTextMessage(errorMsg)).Do() if err != nil { log.Print(err) } } //応答するカルーセルテンプレートを作成する res := linebot.NewTemplateMessage( "ホテル一覧", linebot.NewCarouselTemplate(replyMsg...).WithImageOptions("rectangle", "cover"), ) //応答を返す _, err := bot.ReplyMessage(e.ReplyToken, res).Do() if err != nil { log.Print(err) } }受信した位置情報に含まれる緯度経度を引数に
getHotelInfo()
を実行し、周辺のホテル情報を取得しています。
応答にはMessaging APIに用意されているカルーセルテンプレートを使います。(詳しくはこちら)ホテル情報を取得する
楽天APIの利用
ホテル情報の検索には楽天トラベル施設検索APIを利用します。
今回は下記のパラメータをリクエストURLにセットして検索を行います。https://app.rakuten.co.jp/services/api/Travel/SimpleHotelSearch/20170426?[parameter]=[value]…
入力パラメータ名 format(レスポンス形式) json latitude(緯度) 送信された位置情報の緯度 longitude(経度) 送信された位置情報の経度 serchRadius(検索範囲 : km max = 3) 1 datumType(緯度経度の表示形式) 1 : 世界測地系 applicationID 発行したアプリID 尚、今回利用する出力パラメータは以下のようになります。
出力パラメータ名 HotelSpecial(施設特色) HotelName (施設名称) HotelThumbnailURL (施設画像サムネイルURL) HotelInformationURL(施設情報ページURL) パースする構造体の作成
今回は取得したjsonを構造体にparseしています。
APIテストフォームより、適当なjsonを取得し、json整形ツールに入れてから、JSON-to-Goを使うことでパースする構造体のコードを取得することができます。
利用する出力パラメータのみを残した下記の構造体を使います。
type response struct { Hotels []struct { Hotel []struct { HotelBasicInfo struct { HotelName string `json:"hotelName"` HotelInformationURL string `json:"hotelInformationUrl"` HotelSpecial string `json:"hotelSpecial"` HotelThumbnailURL string `json:"hotelThumbnailUrl"` } `json:"hotelBasicInfo,omitempty"` } `json:"hotel"` } `json:"hotels"` }ホテル情報取得の実装
getHotelInfo()
の実装です。func getHotelInfo(lat, lng string) ([]*linebot.CarouselColumn, bool) { url := fmt.Sprintf(apiURL, lat, lng, config.API_ID) r, err := http.Get(url) if err != nil { return nil, false } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { return nil, false } var res response //構造体にパースする if err = json.Unmarshal(body, &res); err != nil { return nil, false } var ccs []*linebot.CarouselColumn //カルーセルカラムの作成 for index, hotel := range res.Hotels { if index == 10 { break } cc := linebot.NewCarouselColumn( hotel.Hotel[0].HotelBasicInfo.HotelThumbnailURL, cutOutCharacters(hotel.Hotel[0].HotelBasicInfo.HotelName, 40), cutOutCharacters(hotel.Hotel[0].HotelBasicInfo.HotelSpecial, 60), linebot.NewURIAction("楽天トラベルで開く", hotel.Hotel[0].HotelBasicInfo.HotelInformationURL), ).WithImageOptions("#FFFFFF") ccs = append(ccs, cc) } return ccs, true }引数で受け取った緯度経度を使い、APIをたたいて取得したjsonを構造体にパースしています。
構造体スライスを取得したら、それをもとにfor文を回して、カルーセルカラムを作っていきます。
応答で返すカルーセルテンプレートはカルーセルカラムの配列をフィールドとして持っています。(詳しくはこちら)
今回はカルーセルカラムにAPIから取得した、ホテル名、ホテルサムネイル画像、ホテル特色をセットしています。
また、linebot.NewURIAction()
で楽天トラベルのホテルページへアクセスするactionを作成し、カルーセルカラムにセットしています。尚、応答で返せるカルーセルカラムは最大10件となっています。
また、カルーセルカラムに設定する一部フィールドには文字数の制限があるため、文字を切り出す処理を書いています。//cutOutCharacters 先頭から指定文字数だけを切りだす("abcde",3) → "abc" func cutOutCharacters(s string, count int) string { if utf8.RuneCountInString(s) > count { return string([]rune(s)[:count]) } return s }参考
- 投稿日:2020-11-18T20:39:18+09:00
【Docker】コンテナ内からホストにアクセスする方法。http://host.docker.internal:
コンテナの中からポートにアクセスすることができる。
WEBページの内容を表示する$curl URL
コマンドで確認する。接続方法には、(1)コンテナのポートを指定する方法と、(2)ホストのポートを指定する方法がある。
アクセス手順
1) 起動中のコンテナ内に入る
・
docker exec -it [コンテナ名] bash
これでコンテナ内のbashにアクセスできる。コンテナによってはbashではなくshの場合もある。
2) curlでhttpをリクエストする
▼コンテナのポートに直接アクセスする場合
・curl http://[コンテナ名]:[コンテナ側のポート]
▼ホスト側のポートにアクセスする場合
・curl http://host.docker.internal:[ホスト側のポート]
実例
起動中のコンテナを確認$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d4ae7996f53c django_web "python manage.py ru…" 10 hours ago Up 10 hours 0.0.0.0:8100->8000/tcp django_web_1・
0.0.0.0:8100->8000/tcp
これが重要!「ホスト側のポート番号 -> コンテナ内のポート番号」
「0.0.0.0」はlocalhostではなく、全てのポートからのアクセスを表す。
なので、「0.0.0.0:8100 -> 8000」は全ての8100へのアクセスをコンテナ内の8000番ポートにマッピングするという意味になる。
コンテナ内に入る$ docker exec -it django_web_1 bash root@d4ae7996f53c:/code#コンテナ名「django_web_1」のbashを起動。
コンテナのポートに直接アクセスする場合
root@d4ae7996f53c:/code# curl http://django_web_1:8000
http://コンテナ名:コンテナ側のポート番号
、これでコンテナ指定したポートにアクセスできる。
間違えてホスト側のポートを指定するとエラーになる。エラー例root@d4ae7996f53c:/code# curl http://django_web_1:8100 curl: (7) Failed to connect to django_web_1 port 8100: Connection refused
ホスト側のポートにアクセスする場合
ホスト側のポートにアクセスする場合は
host.docker.internal:ホスト側のポート番号
を使う。root@d4ae7996f53c:/code# curl http://host.docker.internal:8100
host.docker.internal
はdocker側で用意してあるDNS。ホスト側のlocalhostに該当する。これは、コンテナの外側から
curl http://localhost:8100
を実行するのと同じ。
コンテナから出るroot@d4ae7996f53c:/code# exit $以上。
- 投稿日:2020-11-18T20:07:50+09:00
【docker-compose】env_fileとenvironmentの違い。環境変数適用の優先順位について
個人用メモです。
env_fileとenvironmentはどちらもdocker-compose.ymlでrun時に環境変数を指定する。
- run(コンテナ作成)時のみ適用される。
- build(イメージの作成)では使われない
- build時に環境変数を指定したい場合は、build -> argsを使う。
env_fileとenvironmentの違い
・環境変数の読み込み方法と設定方法が違う
env_fileは環境変数が記載されたファイルを読み込む。
environmentはdocker-compose.ymlに直接変数を記述する。
env_fileの例env_file: - .env - .env.prd - .env.local.aws - ./common.env - ./apps/web.envenvironmentの例environment: - NODE_ENV=development - PORT=80 - MIGRATE=true - USER=${USER} - AWS_REGION=ap-northeast-1
・優先度が違う
それぞれで同じ環境変数を指定している場合、env_fileよりもenvironmentの設定の方が優先される。
env_fileで複数のファイル指定や、environmentで複数重複する変数の指定がある場合は、最後の方が優先される。
ホストに環境変数が設定されている場合は、その値が優先される。
・優先順位:
(1)ホスト > (2)environment > (3)env_file > (4)DockerfileのENV
ホストの環境変数が最優先なため、もしホストの環境変数が適用されてしまう場合は、docker側の環境変数名の変更が必要。
env_file
env_fileで指定するファイルパスはdocker-composeを実行したディレクトリが基準となる。
▼ファイルの指定方法
- ファイルが一つの場合
env_file: .env
- ファイルが複数の場合(1つでも可)
複数の場合env_file: - .env - .env.prd - .env.local.aws - ./common.env - ./apps/web.env1つの場合env_file: - .env▼ファイル名は複数の付け方がある
ファイル名 内容 .env デフォルトのファイル名 .env.local.aws 頭に .env がつく common.env 後ろに .envがつく ./apps/web.env 下の階層のファイル
- 投稿日:2020-11-18T19:01:42+09:00
TensorFlowの動作確認環境をDockerで構築する
やりたいこと
TensorFlowのDockerイメージをダウンロード
https://www.tensorflow.org/install/docker?hl=ja
して、コンテナを起動し、tensorflowの動作を確認したい。前提
- 任意のホストにDockerがインストール済であること。
- Dockerコマンドが使えること。
Dockerのインストール手順は
https://qiita.com/kenichiro-yamato/items/7e3cb21613784a27409d事前確認
バージョン
[root@docker ~]# docker -v Docker version 19.03.7, build 7141c199a2稼働中のコンテナ
[root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdocker pull でイメージを取得する
docker pull tensorflow/tensorflow結果
[root@docker ~]# docker pull tensorflow/tensorflow Using default tag: latest latest: Pulling from tensorflow/tensorflow 171857c49d0f: Pull complete 419640447d26: Pull complete 61e52f862619: Pull complete 40085aa86d3c: Pull complete b827fdfa00c7: Pull complete 134f84527676: Pull complete e1f30e7788ed: Pull complete a13925316d82: Pull complete 5decca4d86ff: Pull complete 70c56a3cd1fa: Pull complete Digest: sha256:c57fb9628d80872ece8640a22bd0153b2cc8d62d21d79f4d99c3b237a728b62e Status: Downloaded newer image for tensorflow/tensorflow:latest docker.io/tensorflow/tensorflow:latestイメージが取得できたことを確認
[root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tensorflow/tensorflow latest 623195db36df 7 weeks ago 1.46GBdocker run でコンテナを起動する
メモリ指定、ポート指定、ホスト指定、共有ディレクトリ指定など、オプション指定は任意で変えてください。
docker run -m 4096m -p 80:80 -d --privileged -h yamato.host -i -t -v /root/share:/share:rw --name tensorflow_container1 tensorflow/tensorflowコンテナの起動を確認して接続する
[root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 62f578fc0279 tensorflow/tensorflow "/bin/bash" 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp tensorflow_container1docker exec -it tensorflow_container1 /bin/bash
でtensorflow_container1に接続する。
[root@docker ~]# docker exec -it tensorflow_container1 /bin/bash ________ _______________ ___ __/__________________________________ ____/__ /________ __ __ / _ _ \_ __ \_ ___/ __ \_ ___/_ /_ __ /_ __ \_ | /| / / _ / / __/ / / /(__ )/ /_/ / / _ __/ _ / / /_/ /_ |/ |/ / /_/ \___//_/ /_//____/ \____//_/ /_/ /_/ \____/____/|__/接続成功。
初期状態の確認
既にpython3とpipが使える状態になっている。
root@yamato:~# python -V Python 3.6.9root@yamato:~# pip Usage: pip <command> [options]vimが入っていないのでインストールする。
apt-get updateしてから
apt-get install vimで、vimが使えるようになる。
pyファイルを作成して試す
vim test.py
print ("Hello World! I am Kenichiro Yamato")実行する。
python test.pyで
Hello World! I am Kenichiro Yamatoが表示されたらOK。
tensorflow のサンプルコードを試す
vi sample.py
import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation=tf.nn.relu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(x_train, y_train, epochs=5) model.evaluate(x_test, y_test)実行する。
python sample.pyワーニングやインフォメーションがいくつか出ているが、動作している模様。
2020-11-18 10:00:09.352555: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcudart.so.10.1'; dlerror: libcudart.so.10.1: cannot open shared object file: No such file or directory 2020-11-18 10:00:09.352579: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine. 2020-11-18 10:00:10.743602: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory 2020-11-18 10:00:10.743630: W tensorflow/stream_executor/cuda/cuda_driver.cc:312] failed call to cuInit: UNKNOWN ERROR (303) 2020-11-18 10:00:10.743654: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (yamato.host): /proc/driver/nvidia/version does not exist 2020-11-18 10:00:10.743940: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations: AVX2 To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2020-11-18 10:00:10.752038: I tensorflow/core/platform/profile_utils/cpu_utils.cc:104] CPU Frequency: 3599995000 Hz 2020-11-18 10:00:10.752747: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x4e64770 initialized for platform Host (this does not guarantee that XLA will be used). Devices: 2020-11-18 10:00:10.752763: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version Epoch 1/5 1875/1875 [==============================] - 3s 2ms/step - loss: 0.2193 - accuracy: 0.9347 Epoch 2/5 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0972 - accuracy: 0.9705 Epoch 3/5 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0676 - accuracy: 0.9789 Epoch 4/5 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0525 - accuracy: 0.9831 Epoch 5/5 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0423 - accuracy: 0.9862 313/313 [==============================] - 0s 1ms/step - loss: 0.0640 - accuracy: 0.9801
- 投稿日:2020-11-18T16:24:53+09:00
【Linux】DockerでApacheコンテナ起動
はじめに
DockerでApacheコンテナ起動までの流れをメモ
環境情報
- OS:Redhat 7.7
- Docker:19.03.6-ce
- docker-compose:1.27.4
- apache:2.4.46
docker-compose.yml設定
version: '3' services: apache: build: apache container_name: apache ports: - 80:80 volumes: - ./apache/conf/httpd.conf:/usr/local/apache2/conf/httpd.confDockerfile設定
apache
FROM httpd:latest RUN apt update \ && apt install -y \ git \ gcc \ make \ build-essential \ wget \ curl \ llvm \ xz-utils \ tk-dev \ zlib1g-dev \ libncurses5-dev \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ libssl-dev \ libxml2-dev \ libxmlsec1-dev \ liblzma-dev \ libpq-dev \ libffi-dev WORKDIR /usr/local/apache2apacheコンテナの起動
docker-compose up -d apache
- 投稿日:2020-11-18T16:15:53+09:00
【Linux】Dockerのapacheで自己認証局を作成
はじめに
DockerのApacheで自己認証局を作成する方法をメモ
環境情報
- OS:Redhat 7.7
- Docker:19.03.6-ce
- docker-compose:1.27.4
- apache:2.4.46
apacheコンテナの起動
apacheコンテナ作成までの流れは下記を参照
【Linux】DockerでApacheコンテナ起動CA証明書/秘密鍵を作成
apacheコンテナに入り、自己証明書を作成
- ca_cert.pem:自己署名CA証明書
- ca_key.pem:自己署名CA証明書の秘密鍵
openssl req -new -x509 -sha256 -newkey rsa:2048 -out ca_cert.pem -keyout ca_key.pem -days 365CA証明書の秘密鍵パスワード削除
- ca_key_del_pass.pem:自己署名CA証明書の秘密鍵(パスワード削除)
openssl rsa -in ca_key.pem -out ca_key_del_pass.pemサブジェクト代替名ファイルを作成
- subjectAltName.txt:サブジェクト代替名ファイル
subjectAltName = DNS:【DNS】, IP:【IP】自己証明書の秘密鍵を作成
- server.key:自己証明書の秘密鍵
openssl genrsa 2048 > server.key自己証明書の公開鍵を作成
- server.csr:自己証明書の公開鍵
openssl req -new -sha256 -key server.key > server.csr自己証明書の公開鍵を自己署名CA証明書と自己署名CA証明書の秘密鍵を使用して署名し、デジタル証明書を作成
- server.crt:デジタル証明書
openssl x509 -req -sha256 -days 365 -CAcreateserial -in server.csr -CA ca_cert.pem -CAkey ca_key_del_pass.pem -out server.crt -extfile subjectAltName.txtPEMからDERに変換
ブラウザに取り込む際はDER形式に変換
openssl x509 -inform PEM -outform DER -in cacert.pem -out cacert.cerdocker-compose.yml修正
・作成した自己証明書をvolumesに追加
・portsに「443」を追加version: '3' services: apache: build: apache container_name: apache ports: - 80:80 - 443:443 <==追加 volumes: - ./apache/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf - ./apache/conf/server.crt:/usr/local/apache2/conf/server.crt <==追加 - ./apache/conf/server.key:/usr/local/apache2/conf/server.key <==追加各種ファイルの設定
./apache/conf/httpd.conf
・・・ LoadModule ssl_module modules/mod_ssl.so <==追加 LoadModule socache_shmcb_module modules/mod_socache_shmcb.so <==追加 ・・・ ↓↓↓↓↓↓↓↓↓↓追加↓↓↓↓↓↓↓↓↓↓ Include conf/extra/httpd-ssl.conf <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> ↑↑↑↑↑↑↑↑↑↑追加↑↑↑↑↑↑↑↑↑↑apacheコンテナの最新化
docker-compose up -d apacheHTTPS接続が可能になっていればOK
https://localhost
※ ドメイン名は適宜変更参考
- 投稿日:2020-11-18T16:15:53+09:00
【Linux】DockerのApacheで自己認証局で署名した自己証明書を作成
はじめに
DockerのApacheで自己認証局を作成し、自己証明書を作成する方法をメモ
環境情報
- OS:Redhat 7.7
- Docker:19.03.6-ce
- docker-compose:1.27.4
- apache:2.4.46
apacheコンテナの起動
apacheコンテナ作成までの流れは下記を参照
【Linux】DockerでApacheコンテナ起動docker-compose up -d apacheCA証明書/秘密鍵を作成
apacheコンテナに入り、自己証明書を作成
- ca_cert.pem:自己署名CA証明書
- ca_key.pem:自己署名CA証明書の秘密鍵
openssl req -new -x509 -sha256 -newkey rsa:2048 -out ca_cert.pem -keyout ca_key.pem -days 365CA証明書の秘密鍵パスワード削除
- ca_key.pem:自己署名CA証明書の秘密鍵
- ca_key_del_pass.pem:自己署名CA証明書の秘密鍵(パスワード削除)
openssl rsa -in ca_key.pem -out ca_key_del_pass.pemサブジェクト代替名ファイルを作成
- subjectAltName.txt:サブジェクト代替名ファイル
subjectAltName = DNS:【DNS】, IP:【IP】自己証明書の秘密鍵を作成
- server.key:自己証明書の秘密鍵
openssl genrsa 2048 > server.key自己証明書の公開鍵を作成
- server.key:自己証明書の秘密鍵
- server.csr:自己証明書の公開鍵
openssl req -new -sha256 -key server.key > server.csr自己証明書の公開鍵を自己署名CA証明書と自己署名CA証明書の秘密鍵を使用して署名し、デジタル証明書を作成
- server.csr:自己証明書の公開鍵
- ca_cert.pem:自己署名CA証明書
- ca_key_del_pass.pem:自己署名CA証明書の秘密鍵(パスワード削除)
- server.crt:デジタル証明書
openssl x509 -req -sha256 -days 365 -CAcreateserial -in server.csr -CA ca_cert.pem -CAkey ca_key_del_pass.pem -out server.crt -extfile subjectAltName.txtPEMからDERに変換
ブラウザに取り込む際はDER形式に変換
openssl x509 -inform PEM -outform DER -in cacert.pem -out cacert.cerdocker-compose.yml修正
・作成した自己証明書をvolumesに追加
・portsに「443」を追加version: '3' services: apache: build: apache container_name: apache ports: - 80:80 - 443:443 <==追加 volumes: - ./apache/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf - ./apache/conf/server.crt:/usr/local/apache2/conf/server.crt <==追加 - ./apache/conf/server.key:/usr/local/apache2/conf/server.key <==追加各種ファイルの設定
./apache/conf/httpd.conf
・・・ LoadModule ssl_module modules/mod_ssl.so <==追加 LoadModule socache_shmcb_module modules/mod_socache_shmcb.so <==追加 ・・・ ↓↓↓↓↓↓↓↓↓↓追加↓↓↓↓↓↓↓↓↓↓ Include conf/extra/httpd-ssl.conf <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> ↑↑↑↑↑↑↑↑↑↑追加↑↑↑↑↑↑↑↑↑↑apacheコンテナの最新化
docker-compose up -d apacheブラウザにSSL証明書を取り込む
下記に従って「cacert.cer」を取り込む
SSL証明書をインポート動作確認
HTTPS接続が可能になっていればOK
https://localhost
※ ドメイン名は適宜変更参考
- 投稿日:2020-11-18T16:00:08+09:00
DockerとVisual Studio Codeで.NET 5を体験しよう
はじめに
.NET 5 が公開されましたが、LTSがついていないしインストールするのはどうしようかなぁと思っている方、DockerとVisual Studio Codeがあれば試せますよ。
今回はVisualStudio CodeのRemote Development拡張を利用して、Dockerで起動した.NET5のコンテナに接続してプログラムを実行・デバックできるか確認してみます。テストアプリのビルドと実行
まずは、テストアプリのコンテナを立ち上げ、ASP.NET MVCプロジェクトを作成して動作確認をしていきます。
.NET5 SDKイメージの起動
Docker 内部に作成したファイルをホストOS側に保存しておくために、ボリュームマウント用のディレクトリを作り.NET 5のSDKイメージを起動します。また、ASP.NET MVCプロジェクトは標準でhttpが5000番ポートで、httpsが5001番ポートで提供されるのでそれぞれのポートマッピングをしておきます。
mkdir src docker run -it -p 5000:5000 -p 5001:5001 -v c:¥src:/src mcr.microsoft.com/dotnet/sdk:5.0ASP.NET MVCプロジェクトの作成と実行
コンテナに接続できたら、先ほどマウントした/srcディレクトリに移動して、新しいMVCプロジェクトを作成します。
cd /src mkdir WebSite1 cd WebSite1/ dotnet new mvcThe template "ASP.NET Core Web App (Model-View-Controller)" was created successfully. This template contains technologies from parties other than Microsoft, see https://aka.ms/aspnetcore/5.0-third-party-notices for details. Processing post-creation actions... Running 'dotnet restore' on /src/WebSite1/WebSite1.csproj... Determining projects to restore... Restored /src/WebSite1/WebSite1.csproj (in 67 ms). Restore succeeded.
dotnet run
でプログラムを実行すると、次のようなエラ〜メッセージが表示されlocalhost:5000
がIPV6でバインドできないよ、と言われてしまいます。root@cc0ff91bfc60:/src/WebSite1# dotnet run Building... warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to https://localhost:5001 on the IPv6 loopback interface: 'Cannot assign requested address'. warn: Microsoft.AspNetCore.Server.Kestrel[0] Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'.--urls パラメーターで
http://0.0.0.0:5000
もしくはワイルドカードを使ってhttp://*:5000
を指定して実行すると無事起動できます。root@cc0ff91bfc60:/src/WebSite1# dotnet run --urls http://*:5000 Building... warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. info: Microsoft.Hosting.Lifetime[0] Now listening on: http://0.0.0.0:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /src/WebSite1Webブラウザーでアクセスすると、表示できることが確認できます。
ホストPCのVisualStudio Codeで確認
前項で作成したDocker内のインスタンスにVisualStudio Codeで接続し、作成したプロジェクトの内容を確認してデバック機能が利用できるかを確認していきます。
VisualStudio Codeの拡張機能のインストール
VisualStudio Code の Remote Development拡張をインストールします。
コンテナへのアタッチ
コマンドパレットから
Remote-Containers: Attach to Running Container...
を実行して稼働中のコンテナに接続することができます。
VisualStudio Codeで/src/WebSite1
ディレクトリを開くと、コンテナ内のプロジェクトが表示されます。
デバックの実行
コマンドパレットから
.NET: Generate Assets for Build and Debug
を実行してデバックに必要なファイル(lanunch.jsonとtasks.json)をプロジェクトに追加します。
デバック用のファイルを追加後にF5
もしくはCtrl+Shift+D
でデバックを開始すると、ビルド後にWebサイトが起動しデバック用のWebブラウザーが起動します。その後はローカルで開発している時と同じようにVisualStudio Codeのデバック機能を利用して開発することができます。
Index.cshtmlで環境変数を表示してあげると、コンテナ側の.NETが動作していることがわかります。
まとめ
なんとなく開発環境にはまだ入れたくないなぁと思っている方、結構簡単に試せるのでやってみてください。
参考
- 投稿日:2020-11-18T14:58:20+09:00
Traefikを使ってDockerのローカル開発環境をいい感じに管理する
ローカル開発環境でTraefikに名前解決させることで開発環境毎のポート管理等の手間を省く。
以下のような記述をdocker-compose.ymlに追加して名前解決させたいコンテナをそのネットワークに記述する。networks: docker_default: external: name: docker_defaultTraefikとは
Traefik はDockerにも対応している マイクロサービス向けモダンHTTPリバースプロキシ・ロードバランサ
公式ページTræfɪk is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. It supports several backends (Docker, Swarm, Mesos/Marathon, Consul, Etcd, Zookeeper, BoltDB, Rest API, file...) to manage its configuration automatically and dynamically.
Traefikとportainerの導入
まずdockerなど適当な名前のディレクトを作り以下のようにdocker-compose.ymlを書く。
今回はDockerコンテナをGUIで操作し、管理・監視するためのportainerと言うツールも一緒に構築するversion: '3.8' services: p-portainer: image: portainer/portainer restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock - ./portainer:/data traefik: image: traefik ports: - "80:80" restart: always labels: - "traefik.http.routers.api.rule=Host(`t.localhost`)" - "traefik.http.routers.api.service=api@internal" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik/traefik.toml:/etc/traefik/traefik.toml networks: docker_default: external: name: docker_defaultTraefikの設定ファイルは、toml形式の設定ファイルを作成します。
今回は名前解決のルールをコンテナ名のハイフンより前を正規表現で切り取りネーミングさせます。
(コンテナ名がhoge-fuga
だった場合hoge.localhost
とネーミングされます。※windowsマシンの場合
Docker for windows で /var/run/docker.sock をマウントする必要があるので
上記のdocker-compose.ymlと同じ階層に.env作成し以下を記述するCOMPOSE_CONVERT_WINDOWS_PATHS=1上記のdocker-compose.ymlを書いたディレクトリの直下にtraefik/.traefik.tomlを作成
[api] [ping] entryPoint = "http" [providers.docker] defaultRule = "Host(`{{ trimSuffix \"-\" (regexFind \"(.+?)-\" .Name) }}.localhost`)" network = "docker_default"これを立ち上げれば、
p.localhost
でportainerの画面、t.localhost
でtraefikの管理画面にアクセスできるようになります。まとめ
同時に複数のDocker環境を立ち上げるとポート管理や名前解決が手間になりますが、
traefikのようなプロキシツールを使うと手間が省けて便利です。サンプル
このサンプルでは
test.localhost
で名前解決されます。version: '3.8' services: app: build: context: . dockerfile: ./docker/php/Dockerfile tty: true volumes: - .:/code - ./docker/php/php.ini:/usr/local/etc/php/php.ini test-web: image: nginx:latest depends_on: - app networks: - default - docker_default volumes: - ./public:/code/public - ./docker/nginx/conf.d/local.d/default.conf:/etc/nginx/conf.d/default.conf environment: - TZ=${TZ} networks: docker_default: external: name: docker_default
- 投稿日:2020-11-18T12:00:25+09:00
話題の”全集中”で『Dockerの使い方』を、僕の中に眠るバーチャル禰豆子のためにまとめた。
はじめに
Dockerとは、「開発環境を簡単に作れる便利なツール」です。
本格的に野球しようと思っても、場所作るの大変ですよね…。
ベースを用意して、距離測って置いて、バットもボールも観客席も用意して…。
しかし!Dockerを使えば一瞬でPayPayドームが出来上がります!(出来上がりません。)野球場は無理ですが、システム開発環境であれば可能です。
- LAMPサーバー
- Wordpress
- Rails+DB etc...
瞬時にシステム開発環境を作成し、その環境を複数人に配ることが可能という便利なアプリです。
この記事について
この記事で、コンテナ等の概念は特に触れていません。
以下のような目的で記事を作成しています。
- 実際にDockerを触れてみて、システム環境が整う感覚を味わえる。
- 後日思い出すときにすぐに引き出せる。
ネズコーーー!!!!!!
Dockerがんばって使えるようになるぞーーー!!!実行環境
- Mac Catalina
- Docker for Mac
※インストールまだの方は、上記公式サイトよりお願いします。
参考にさせていただいたサイト
特に一番上のサイトを勉強及び参考にさせていただきました。概念もしっかり記述されているので、この記事の読者の方、是非閲覧されてください。
- 【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その1:コンテナってなに? 〜
- DockerfileのRUN命令とCMD命令の違い【Docker】
- Docker ドキュメント日本語化プロジェクト
- Docker入門(第六回)〜Docker Compose〜
- docker-compose
up
とかbuild
とかstart
とかの違いを理解できていなかったのでまとめてみた- docker-compose.ymlの書き方について解説してみた
では、やってみましょう!
Dockerfileからコンテナを作成
CentOS7にPHPとApachをインストールしたコンテナを作成します。
流れ
① Dockerfileを任意の場所に作成(ファイル名:dockerfile)
② 作成したDockefileからイメージを作成。
③ イメージを元にコンテナを作成する。手順
① まずはdockerfileをPCに作成する。
dockerfile#DockerHubからcentos7のイメージをもとにする。 FROM centos:centos7 #centos7のイメージの中でApachとphpをインストール RUN yum -y install httpd php #Åpachを起動するためのコマンドを実行 CMD ["/usr/sbin/httpd","-DFOREGROUND"]② 作成したDockerfileを元に、イメージを作成。
オプション等の説明はDocker ドキュメント日本語化プロジェクトを参照。
#内容 docker build -t イメージ名:タグ名 Dockerfileのディレクトリ #例|イメージ名はlamptest。タグは1.0。カレントディレクリのdockerfileを使用 docker build -t lamptest:1.0 .
③ 作成したイメージを元にコンテナ起動
#内容 docker run -d -p ポート番号:ポート番号 --name コンテナ名 イメージ名:タグ名 #例|ポート80版を8080版に割り当てる。 # コンテナ名はtestserver。 # イメージとタグは、lamptest:1.0を使用する。 docker run -d -p 8080:80 --name testserver lamptest:1.0
http://localhost:8080にアクセスすると、以下画面が表示されます。
※補足※ コンテナの操作
#起動 docker start コンテナ名 #停止 docker stop コンテナ名 #コンテナの中に入る docker exec -i -t コンテナ名 bash
dockerfileコマンドの詳細説明
使用頻度の多いものを簡潔に記載しています。
より詳しい説明はDocker ドキュメント日本語化プロジェクトを参照してください。From
Dockerイメージをベースに作成する。
#内容 FROM イメージ名:タグ名 #例|centosのイメージをベースにする FROM centos:centos7Run
FROMで指定したイメージ対してコマンドを実行。
#内容 FROM 実行するコマンド #例|yumでhttpdのインストール RUN yum -y install httpdCOPY
Dockerイメージ内(コンテナ内)にコピーしたいファイルを指定。
#内容 FROM イメージ内にコピーしたいファイルのパス コピー先イメージのパス #例|Dockerfileと同じディレクトリにあるhogeファイルを、/tmpディレクトリにコピー。 COPY hoge.txt /tmpADD
URLが指定できる、tarアーカイブ(gzip、bzip2、xz)で圧縮されるファイルを指定すると自動展開される。
それ以外は、COPYコマンドと同じ。#内容 ADD イメージ内にコピーしたいファイルパスやURL コピー先のイメージパス。 #例|tar.gzファイルを展開しつつ、イメージ格納 ADD hoge.tar.gz /tmp #例|URL先のファイルを、指定したディレクトリに保存する。 ADD https://zukan.pokemon.co.jp/detail/025 /tmpRUN
イメージ作成時に、コマンドを実行する。
#内容 RUN コマンド オプション #例|lsコマンドを-aのオプションを添えて。 RUN ls -aCMD
コンテナ起動時に、コマンドを実行する。
#内容 CMD [ コマンド , オプション ] #例|lsコマンドを-aのオプションを添えて。 CMD [ ls , -a ]ENV
環境変数数に値を入れる。(イコールは省略可能。)
#内容 ENV 環境変数名=環境変数の値 ENV 環境変数名 環境変数の値 #例|環境変数MIZUNOKOKYUにichinokataを挿入 ENV MIZUNOKOKYU=ichinokataUSER
ユーザー実行名の切り替え
#内容 USER ユーザー名 #例|ユーザー名をakiunleashに切り替え USER akiunleashdocker-composeで複数のコンテナを作成・連携
アプリとデータベースの複数のコンテナを、一つのシステムとして構築が可能です。
RailsとPostgreSQLのコンテナを別々に作成し、一つのシステムとして連携してみましょう。流れ
① docker-compose.yml等の必要なファイルを作成
② docker-compose runを使用してイメージ及びコンテナの作成
③ Gemfileが更新されるので、docker-compose bulde で再度構築
④ Rails側からPostgreSQLに接続できるようusernameやpasswordを設定変更
⑤ RailsからPostgreSQLのデータベースの作成
⑥ 完成!手順
以下4つのファイルを準備します。
- docker-compose.yml
- dockerfile
- Gemfile
- Gemfile.lock
docker-compose.ymlversion: '3' services: db: image: postgres environment: - POSTGRES_PASSWORD=password web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - dbdockerfile# DockerHubからcentos7のイメージをもとにする。 FROM ruby:2.3.3 # パッケージ管理ソフトのアップデートからの # build-essential libpq-dev nodejs をインストール RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs # コンテナ内にmyappディレクトリ作成 RUN mkdir /myapp # ワークディレクトリに設定 WORKDIR /myapp # dockerfileと同ディレクトリにあるファイルを、コンテナ内に作成 ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock # Gemfileにかかれてるrailsをインストール RUN bundle install # Railsのファイル及びディレクトリをコンテナに作成 ADD . /myappGemfilesource 'https://rubygems.org' gem 'rails', '5.0.0.1'Gemfile.lock#空ファイル
上記ファイルが保存されたディレクトリでコマンド実行
docker-compose run web rails new . --force --database=postgresqlGemfileが更新されるので、再度Gemをインストールするためコマンド実行
docker-compose buildデーターベースと接続するための情報を編集する。
config/database.ymldefault: &default adapter: postgresql encoding: unicode host: db username: postgres password: password pool: 5 development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production username: myapp password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>アプリを起動してみましょう!
docker-compose up -d今の状態はデータベースが無いので作成します。
docker-compose run web rake db:create確認!
http://localhost:3000/にアクセスし以下のページが表示されれば成功です。
不要なコンテナが含まれている場合は一度ダウンして、再起動すると消えます。
# 一度ダウン docker-compose down # 再度アップ docker-compose up -ddocker-compose.ymlの解説
docker-compose.ymlversion: '3' services: db: image: postgres environment: - POSTGRES_PASSWORD=password web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - db
項目 説明 version docker-composeのバージョン services コンテナ名(WEBとDBを作成) image Docker Hubからイメージを使用 environment 環境変数を設定 build 指定したdockerfileを使用する。 command コンテナ作成後に実行するコマンド volumes ファイルをマウント ports ポートの指定 depends_on 起動順序 最後に
Dockerとはどういうものかの感覚を掴むための助けになれば幸いです。
内容に誤りがありましたら、ご指摘いただけると助かります。変更履歴
日付 内容 2020/11/18 初版
- 投稿日:2020-11-18T11:23:41+09:00
【Docker】Volumes(ボリューム)の中身を見る方法。ルート権限付きコンテナを起動する。
Dockerのボリュームの中に入っているフォルダやファイルを確認する方法について。
確認方法
docker volume inspect
でvolumeのmountpoint(絶対パス)を確認する。- イメージからルート権限付きのコンテナを起動する。
- コンテナ内のターミナルでlsコマンドを使う
volumeのmountpointの確認#ボリューム一覧を表示 docker volume ls #mountpointを確認 docker volume inspect [ボリューム名]ルート権限付きのコンテナを起動し、ボリュームの中身を確認#ルート権限つきコンテナ起動 $ docker run -it --privileged --pid=host [イメージ名] nsenter -t 1 -m -u -n -i sh #ボリュームの中身を表示 / # ls [mountpointの絶対パス] #対話モード終了 / # exit以上の操作で、volumeの中身を確認することができる。
実例による確認手順
イメージの確認$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat latest 35064a4fcc93 2 weeks ago 648MB django_web latest 7f0eff7ebc94 2 weeks ago 937MB debian latest 1510e8501783 5 weeks ago 114MB python 3 dfc47c6cee13 6 weeks ago 886MB postgres latest 817f2d3d51ec 7 weeks ago 314MB vuecli 3 4040959eab16 2 months ago 338MBボリューム一覧の表示$ docker volume ls DRIVER VOLUME NAME local 0adf7a2b08b8e09f74ffb7799716e48263f012612dc2047da1d7137a75f12b5d local vuecli3_vue-cli-node-volumemountpointの確認$ docker volume inspect vuecli3_vue-cli-node-volume [ { "CreatedAt": "2020-09-08T05:35:36Z", "Driver": "local", "Labels": { "com.docker.compose.project": "vuecli3", "com.docker.compose.version": "1.26.2", "com.docker.compose.volume": "vue-cli-node-volume" }, "Mountpoint": "/var/lib/docker/volumes/vuecli3_vue-cli-node-volume/_data", "Name": "vuecli3_vue-cli-node-volume", "Options": null, "Scope": "local" } ]docker対話モードに入る$ docker run -it --privileged --pid=host [イメージ名] nsenter -t 1 -m -u -n -i shdocker対話モード/ # ls EFI boot dev home lib mnt proc run srv tmp var bin containers etc init media opt root sbin sys usrvolumeの確認/ # ls /var/lib/docker/volumes/micres_micres-node_modules2/_data @babel mime-db @csstools mime-types @mdi mimic-response @nicolo-ribaudo mini-css-extract-plugin @npmcli minimalistic-assert @rails minimalistic-crypto-utilsルート権限付きコンテナ起動の詳細
最も肝となる、ルート権限付きコンテナの起動コマンドが何をしているか。
>コマンド
$ docker run -it --privileged --pid=host [イメージ名] nsenter -t 1 -m -u -n -i sh`・
-it
-t 擬似ターミナル(--tty)
-i 標準出力常時ON (--interactive)・
--privileged
特権モード。ホストに対するルート権限が与えられた特別なコンテナを起動。・
--pid=host
--pit= コンテナに対するPIDの名前空間を指定。
host コンテナ内でホスト側のPID名前空間を使う。・
nsenter
Dockerで作った名前空間に入るためのコマンドラインツール。
「ENTER into Name Spaces」の頭文字の組み合わせ。
▼nsenterのオプション
・-t
「--target pid」プロセスを指定する。ここでは1を指定。・
-m
「--mount」 マウント名前空間(mount name space)を入力する。名前空間の指定がなければ、PIDで指定したプロセスを使用する。・
-u
「-uts」 UTS名前空間を入力する。名前空間の指定がなければ、PIDで指定したプロセスを使用する。utsはUnix Time Sharing略。
・
-n
「--net」 ネットワーク名前空間を入力する。名前空間の指定がなければ、PIDで指定したプロセスを使用する。・
-i
「--ipc」 IPC名前空間を入力する。名前空間の指定がなければ、PIDで指定したプロセスを使用する。要は、PID=1の処理でいろんな名前空間を立ち上げるらしい。
- 投稿日:2020-11-18T08:52:59+09:00