- 投稿日:2020-09-22T23:55:15+09:00
日本語対応版SDAPSのDockerイメージを作ってみた
はじめに
SDAPSで日本語を含む質問票を作成し、レポートを出力することができるように、sdapsコマンドを実行するDockerイメージを作成してみました。
Dockerfileや変更部分は全て下記のGitHubに公開しています。
成果物
GitHubとDockerHubにそれぞれDockerfileとすぐに使えるようイメージを登録し、公開しています。
- https://github.com/YasuhiroABE/docker-sdaps-ja
- https://hub.docker.com/repository/docker/yasuhiroabe/sdaps-ja
参考資料
この記事を書く際に参考にしたURLをリストにしています。
- https://sdaps.org/
- http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
- https://qiita.com/YasuhiroABE/items/75639f4b95731171b894
開発環境
開発には次のような環境を利用しています。
作成したDockerコンテナも、この開発環境に合わせてUbuntu 20.04をベースにしています。
- ホストOS
- Ubuntu 20.04.1 on VMware Workstation 16 Pro
- Docker
- 19.03.12 (docker-ce 5:19.03.12~3-0~ubuntu-bionic DEB package)
- SDAPS
- 1.9.7 (sdaps 1.9.7-0.2ubuntu2 DEB package)
テスト環境
以下のOS上でDockerイメージが正常に稼動することをテストしています。
- Linux Distribution
- Ubuntu 20.04.1 amd64版
- Windows10 (2004)
- WSL2 + Docker Desktop for Windows (19.03.12)
- macOS (10.15.6)
- Docker Desktop for Mac (19.03.12)
質問票の印刷、読み取りには以下のような機材を使用しています。
- レーザープリンター (OKI B841)
- 一般的なPPC用紙 (白色普通紙)
- 印刷品位 - 高精細 (1200x1200)
- ドキュメントスキャナ (Brother ADS-3600W)
- 設定 - TIFFマルチページ・300dpi・モノクロ・長辺とじ
コピー(複写)機の利用について
いまのところ質問票を準備するために、コピー機は使用していません。
過去には問題が発生した経験はありますが、近年はコピー機で臨時に枚数を増やした際にも問題なく処理できています。コピー機を利用する際には、事前に十分テストを重ねてパラメータを保存するなど再現性を確保するようにするのがお勧めです。使い方
いくつかsdaps由来のバグがあってエラーメッセージが出る場合がありますが、それらを含めてコマンドの利用方法を紹介することにします。
コマンド実行時には、Dockerのvolume機能を利用して、回答票のTeXファイルとプロジェクト・ディレクトリを配置する作業用ディレクトリを作成し、必ずコンテナ内の/projにマウントするようにしてください。
- Dockerコンテン内の作業用ディレクトリ: /proj
作業の流れ
おおまかには次のような順序で利用しています。
- 作業用ディレクトリを作成し、移動 (e.g. dev.proj1/ ; cd dev.proj1)
- 質問票のTeXファイルを作成 (e.g. example-ja.tex)
- setupコマンドを実行し、プロジェクト・ディレクトリを作成
- 記入済みの質問票をスキャンし、TIFFファイルを作業用ディレクトリに配置 (e.g. 01.tif, 02.tif,...)
- addコマンドを繰り返し実行し、TIFFファイルを登録
- recognizeコマンドを実行し、データを抽出
- report_texコマンドでreportファイルを作成 (e.g. report_1.pdf)
- csvコマンドで生データを抽出 (e.g. data_1.csv)
準備作業
使用するDockerイメージはコマンド実行前にpullしておきます。
pullの実行例$ sudo docker pull yasuhiroabe/sdaps-ja:ub2004-2 ub2004-2: Pulling from yasuhiroabe/sdaps-ja e6ca3592b144: Pull complete ... Digest: sha256:26458bd39267149a3ccebc36f60a3082e0f519545596166accede1eac4eed8f7 Status: Downloaded newer image for yasuhiroabe/sdaps-ja:ub2004-2 docker.io/yasuhiroabe/sdaps-ja:ub2004-2作業用ディレクトリについて
GitHubに登録していませんが、作業用にdev.proj1/, dev.proj2/ 作業用ディレクトリを作成し、サンプルの回答票TeXファイル、プロジェクトディレクトリを配置しています。
参考までに最終的なdev.proj2ディレクトリの様子を掲載しておきます。
treeコマンドの出力結果$ tree dev.proj2 dev.proj2 ├── 01.tif ├── 02.tif ├── 20200310_survey │ ├── 1.tif │ ├── 2.tif │ ├── data_1.csv │ ├── data_2.csv ... │ ├── questionnaire.pdf ... │ ├── report_1.pdf │ ├── report_2.pdf ... │ ├── translator-sdaps-dictionary-English.dict ... └── 20200310_survey.tex 1 directory, 43 files
日本語質問票のサンプル
テストのために使用したファイルを掲載しています。
コメントやコンテンツの一部を削除していますので、オリジナルを参照してください。example.texを元に日本語を埋め込んだ例\documentclass[ english, a4paper, checkmode=check, pagemark, stamp]{sdapsclassic} \usepackage[utf8]{inputenc} % For demonstration purposes \usepackage{multicol} \usepackage{xltxtra} \setmainfont{IPAPMincho} \setsansfont{IPAPGothic} \setmonofont{IPAGothic} \XeTeXlinebreaklocale "ja" \author{作者} \title{タイトル} \begin{document} \begin{questionnaire} \begin{info} \texttt{info}環境を利用することで、任意のテキストを追加することができます。 \end{info} \addinfo{Date}{10.03.2013} \section{5段階評価} \singlemark{どのくらいの頻度でSDAPSを利用していますか?}{ほとんどない}{毎日} \end{questionnaire} \end{document}あらかじめ定義されている定型文の一部についても置換が可能です。
translator-sdaps-dictionary-English.dictの例\ProvidesDictionary{translator-sdaps-dictionary}{English} \providetranslation{infotext}{記入方法/Instructions to fill out the form.} \providetranslation{standard-deviation}{Standard-Deviation} \providetranslation{info-cross}{マーク例/Check} \providetranslation{info-correct}{修正例/Uncheck to correct} \providetranslation{answers}{Answers} \providetranslation{questionnaireid}{Questionnaire-ID:} \providetranslation{surveyid}{Survey-ID:} \providetranslation{draft}{draft} \providetranslation{info-mark}{For questions with a range (1-5) choose the answer the mark that fits best.} \providetranslation{info-select}{満足度などについては、5段階で 1つにマークしてください。} \providetranslation{mean}{Mean}example-ja.texとtranslator-sdaps-dictionary-English.dictを、作業用ディレクトリ(dev.proj1)に配置した様子は次のようになります。
$ tree dev.proj1/ dev.proj1/ ├── example-ja.tex └── translator-sdaps-dictionary-English.dict 0 directories, 2 files
次のような手順で質問票を生成します。
$ sudo docker run --rm -v `pwd`/dev.proj1:/proj \ --name sdaps-ja \ yasuhiroabe/sdaps-ja:ub2004-2 \ setup --add translator-sdaps-dictionary-English.dict \ work/ example-ja.tex質問票は、この例の場合、dev.proj1/work/questionnaire.pdf に配置されます。
【補足】オリジナルの translator-sdaps-dictionary-English.dict の入手方法
Ubuntuなどでパッケージからインストールできる場合は、/usr/share/sdaps/tex/ からコピーすれば良いのですが、それができない場合にDockerイメージから抽出する方法をメモしておきます。
"docker cp"はイメージからのファイル抽出には使えないので、少々面倒ですが、次のような方法でオリジナルのファイルを抽出することができます。
コンテナ内部のファイルをローカルファイルシステムにコピーする## sdapsコマンドを実行する("-rm"オプションは付けない) $ docker run yasuhiroabe/sdaps-ja:latest ## コンテナIDを確認する $ docker ps -a |grep sdaps-ja a9e5dcb2a026 yasuhiroabe/sdaps-ja:latest "/run.sh --help" 17 seconds ago Exited (0) 16 s econds ago eloquent_haibt ## コンテナIDを利用して必要なファイルをコピーする $ docker cp a9e5dcb2a026:/usr/share/sdaps/tex/translator-sdaps-dictionary-English.dict my-translator.dictsetupコマンド
回答票のTeXファイルを作成したら、sdapsコマンドにプロジェクト・ディレクトリを作成させます。事前にプロジェクト名でディレクトリを作成するとエラーになります。
setup実行例$ make proj1-setup sudo docker run --rm \ -v `pwd`/dev.proj1:/proj \ --name sdaps-ja \ yasuhiroabe/sdaps-ja:ub2004-2 \ setup \ --add translator-sdaps-dictionary-English.dict \ work/ example-ja.texコマンド実行時のメッセージThis is XeTeX, Version 3.14159265-2.6-0.999991 (TeX Live 2019/Debian) (preloaded format=xelatex) restricted \write18 enabled. entering extended mode This is XeTeX, Version 3.14159265-2.6-0.999991 (TeX Live 2019/Debian) (preloaded format=xelatex) restricted \write18 enabled. entering extended mode ... Running xelatex now multiple times to generate the questionnaire. Running xelatex now multiple imes to generate the questionnaire. タイトル Author: 作者 Date: 10.03.2013指定したプロジェクト・ディレクトリ(dev.proj1/work/)の中に、questionnaire.pdf が配置されます。
この例では、translator-sdaps-dictionary-English.dictを指定しています。 (省略可能)
このファイルはプロジェクト・ディレクトリを作成すればコピーされますが、事前に入手したい場合には次のような方法で可能です。addコマンド
質問票をスキャンし、TIFFマルチページ形式のファイル(この例では01.tif)をプロジェクト・ディレクトリに配置してから、addを実行します。
add実行例$ make proj1-add sudo docker run --rm \ -v `pwd`/sdaps.proj:/proj \ yasuhiroabe/sdaps-ja:ub2004-2 add work 01.tiffコマンド実行時のメッセージProcessing 01.tiff Done使用している機材では1ファイルに25ページ分の回答しか格納できないので、これを越える場合は複数回、addコマンドを実行します。
recognizeコマンド
回答シートの登録が終った時点で、その登録したシートを解析するフェーズです。
recognize$ make proj1-recognize sudo docker run --rm \ -v `pwd`/dev.proj1:/proj \ yasuhiroabe/sdaps-ja:ub2004-2 \ recognize workコマンド実行時のメッセージConnection Error (Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory) Connection Null ... Warning: 1.tif, 1: Matrix not recognized. Warning: No page number for page 1.tif, 1 exists. Warning: Got a wrong survey ID (1.tif, 1)! It is None, but should be 2449560734. Warning: 1.tif, 3: Matrix not recognized. Warning: No page number for page 1.tif, 3 exists. Warning: Got a wrong survey ID (1.tif, 3)! It is None, but should be 2449560734. 4 sheets Processed 4 of 4 sheets, took 1.852894 seconds ‘‘‘ ## report_texコマンド 解析した結果を元にレポートPDFファイルを抽出するために使用します。 ```bash:report_tex実行例 $ make proj1-reporttex sudo docker run --rm \ -v `pwd`/dev.proj1:/proj \ yasuhiroabe/sdaps-ja:ub2004-2 \ report_tex work/コマンド実行時のメッセージUnable to init server: Could not connect: Connection refused Unable to init server: Could not connect: Connection refused This is XeTeX, Version 3.14159265-2.6-0.999991 (TeX Live 2019/Debian) (preloaded format=xelatex) restricted \write18 enabled. entering extended mode ... Running xelatex now multiple times to generate the report.処理が終るとプロジェクト・ディレクトリ(dev.proj1/work/)の中に、report_.pdfファイルが生成されています。
report_texコマンドのオプションに、--create-tex*オプションがあり、TeXファイルを抽出する機能がありますが、これは/tmpに途中経過を出力するため、もし利用する場合には、適当なディレクトリを/tmpにマウントしてください。この例はGNUmakefile内の、proj2-reporttexタスクに記載しています。report_1.pdfには次のように結果が出力されます。"Answers:", "Mean:", "Standard-Deviation:"などを日本語化したい場合には、translator-sdaps-dictionary-English.dict を変更してください。
csvコマンド
生データをCSV形式で抽出したい場合に利用します。レポートの内容が正しいか検証するために使用します。
Excelで偏差などを計算すると誤差の処理方法の違いから、微妙に違う値が表示されるなどするかもしれません。csv実行例$ make proj1-csv sudo docker run --rm \ -v `pwd`/dev.proj1:/proj \ yasuhiroabe/sdaps-ja:ub2004-2 \ csv export work/生成されたCSVファイルは、プロジェクト・ディレクトリの data_*.csv に出力されています。
dev.proj1/work/data_2.csvの内容questionnaire_id,global_id,empty,valid,recognized,review,verified,1_review,1_1_review,1_1 None,None,0,1,1,,0,,,3 None,None,1,0,1,,0,,,-1 None,None,0,1,1,,0,,,4 None,None,1,0,1,,0,,,-1主な利用例は以上です。
作業中に発生した問題
最後に作業中に遭遇した問題についてメモを残しておきます。興味のある方はどうぞ。
sdaps reportを実行するとエラーが発生する
コンテナの中から実行した時だけ、"Unable to init server: Could not connect: Connection refused"というメッセージが表示されます。
エラー発生時のコマンドライン## あらかじめ dev.proj2/ には、質問票のTeXファイルと回答をsdaps addした20200310_survey/ディレクトリを配置しています $ sudo docker run --rm -v `pwd`/dev.proj2:/proj \ --name sdaps-ja \ yasuhiroabe/sdaps-ja:ub2004-2 report 20200310_survey/エラーのタイミングが不明だったので、起動スクリプトを作成し、straceで処理の様子を観察しました。
デバッグ用run.sh#!/bin/bash cd "${WORKING_DIR}" strace sdaps "$@"そこでメッセージが出力される
connect(6, {sa_family=AF_UNIX, sun_path=@"/home/sdaps/.cache/broadway1.socket"}, 38) = -1 ECONNREFUSED (Connection refused)どうやら裏で画像イメージを処理するかなにかでロードしているライブラリが初期化処理で、Xサーバーに接続しようとして失敗しているように見えます。
sdapsがちゃんと実行できるローカル環境でもDISPLAY環境変数を稼動していない方に向けると失敗します。エラーの再現$ env DISPLAY="" sdaps report 20200310_survey ------------------------------------------------------------------------------ - SDAPS -- report ------------------------------------------------------------------------------ Unable to init server: Could not connect: Connection refused Unable to init server: Could not connect: Connection refusedこのため、DISPLAY環境変数をdocker runの際に--envオプションで追加することにしました。
Ubuntu 20.04のX serverはunix domain socketのみを開いているので(6000番ポートは閉じている)、/tmp/.X11-unixをmountしています。この辺りは、lsofの出力と参考情報にあるリンク先を参考にしています。それでもDBus周りのエラーは残っていますが、とりあえずスルーすることにします。
次に発生したDBus周りのエラー$ make proj2-report sudo docker run --rm \ -e DISPLAY=:0.0 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v `pwd`/dev.proj2:/proj \ --name sdaps-ja \ sdaps-ja \ report 20200310_survey/ (sdaps:1): dbind-WARNING **: 13:41:40.375: Couldn't connect to accessibility bus: Failed to connect to socket /tmp/dbus-5MKrJQOOU3: Connection refusedなおX serverに接続しなくても、エラーのまま処理は正常に終了しているので、実際の利用時にはこれらの変数は設定していません。
- 投稿日:2020-09-22T23:48:30+09:00
GCPでMinecraftサーバー
はじめに
Minecraftのサーバーを、GCP(Google Cloud Platform)上にDockerで簡単に立てられないかってことで調べました。
最後に書くけど、Minecraftのライセンスがどうなっているのかよくわからないので、わかる方がいたらそっと教えてください。m(_ _)m前提として、下記の知識がちょっと必要。
- GCPの設定画面とかがちょっとわかる
- linux(ubuntu)がちょっとわかる
- dockerがちょっとわかる
GCE使うので、無料期間が終わっている人はGCEのお金がかかりますので、ご注意ください。無料期間中でも選択によってはかかるかも。
あとゲームが終わったらVM停止。ぜったい。
1.GCEの準備
GCE(Google Compute Engine)とは、GCPで提供するクラウド上の仮想マシン。GCP上ではVM インスタンスと書かれている。VMはバーチャルマシン。
1.1. インスタンスの作成
ほぼデフォルトのままで大丈夫だけど、3点変更。
1つ目が、マシンタイプを
e2-medium (vCPU x2、メモリ 4GB)
以上にすること。
最初ケチって、e2-micro(vCPU x2、メモリ 1GB)
にしたら、JavaのThreadがどうこう、ヒープメモリがどうこうというエラーが出ていた。(詳しくは割愛)
単純に大きくすることで解消。ただし4GBでも多少カクつく!余裕があればそれ以上もお試してください。私は余裕が・・・2つ目は、気を付けるというかブートディスクのオペレーティング システムを
Ubuntu
にしました。ほかでもいいと思うけど試してません。3つ目は、ネットワーキングのネットワーク タグ。
minecraft-server
とかにしておく。
これは、この次の手順でファイアウォールの穴を開けるときに指示します。起動すると、VM インスタンスのページに作ったのが一覧表示(1件だけかもしれないけど)され、音楽の再生ボタンみたいな右向き三角が出てればOK。
そこの外部IPのところに表示されているIPアドレスが、外から接続する際のIPアドレス。少し発展的な内容ですが、このIPアドレスは、デフォルトでは エフェメラル という起動のたびに変わる設定です。固定にしたい場合は、ネットワーキングのネットワークインタフェースの外部 IPをエフェメラル
からIPアドレスを生成
へ変更します。(たぶんちょっと追加料金かかる)1.2. ファイアウォールに穴開け
GCE上のMinecraftのサーバーと、クライアントのデータやり取りは、ポート番号25565を使ってやる。なので、GCPのファイアウォールの25565番を開けてやる必要がある。
GCPのメニューのVPC ネットワーク
>ファイアウォール
>ファイアウォール ルールを作成
。
名前は適当でよくて、変更点は2点。1つ目は、ターゲットを
minecraft-server
へ。1.1.の3つ目で指定したやつです。2つ目は、ソースIPの範囲を
0.0.0.0/0
へ。誰でも接続できますよっていうこと。接続できるIPアドレスを制限したい人はここで厳密に設定してください。2. Dockerをインストール
作ったVM インスタンスに、Dockerをインストールします。
説明はざっくりとさせていただきます。まずGCEのVM インスタンスの一覧から、
SSH
って書いてあるプルダウンの中のブラウザ ウィンドウで開く
で黒い画面=SSH接続のコンソール画面を出します。そこから先はUbuntuで下記。# Dockerインストール用のシェルをダウンロード $ curl -fsSL get.docker.com -o get-docker.sh # 実行 $ sudo sh get-docker.sh # ユーザーをdockerグループに追加 $ sudo usermod -aG docker (ユーザー名)最後のは、dockerコマンドを打つたびに
sudo docker ~
と入力するのが面倒なので、ユーザーをdockerグループに入れるという呪文です。SSH接続の再起動が必要なので、黒い画面を開きなおします。
docker version
でバージョンが出たら、ここまで成功。3.Minecraftをインストールと起動
インストールというか、Dockerコンテナを作るっていう話です。上記の続きから。
# データ用のフォルダを作って、権限を設定しておく $ sudo mkdir /var/mc_data/ $ sudo chmod 777 /var/mc_data/ # MinecraftサーバーのDockerイメージを取得 $ docker pull itzg/minecraft-server # Minecraftサーバー起動! $ docker run -d -e EULA=TRUE -p 25565:25565 -v /var/mc_data:/data --name minecraft --restart always itzg/minecraft-serverこれでサーバーの起動まで終了。
黒い画面は、右上のバツボタンで閉じていいです。4. クライアントから接続
Minecraftのマルチプレイのダイレクト接続で、VMインスタンスの外部IPアドレスを指定することで入れます。
5. 終了(必須)
GCEは起動している時間に応じて課金されるので、週末遊んでその次の週末までやらない場合とか、やってない間は止めたいです。というか必須!その止め方。
GCEのVMインスタンスの一覧で、チェックボックスで選択して、音楽の停止ボタンみたいなので停止。
VMインスタンスの停止 という画面が出ます。パソコンでいうと、電源落とすという意味。6. 再起動
また次の週末に起動する方法。
GCEのVMインスタンスの一覧で、チェックボックスで選択して、音楽の再生ボタンみたいなので起動。
パソコンでいうと電源オン。VMの起動の後、Minecraftサーバーの時間にちょっと時間がかかります。30秒とか1分とかそれくらい。
待たずに起動すると、Minecraftの画面に下記のエラーが出ました。サーバーへの接続に失敗しました。 io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information:ちょっとわかる人だと、VM起動とともにDockerコンテナも動き出すのか心配になりますが、起動します。大丈夫。
7.補足と疑問
7.1. Minecraft内の時間
サーバーが起動しててログインしてない間、Minecraft内の時間は進むのか、止まるのか。
かまどに木を1スタック突っ込んで燃やし、Minecraftは終了してみました。1個10秒かかるので64個は640秒で約10分です。無駄に誰もログインしていない状態で10分放置しました。結果は、止まってた。誰も入ってないと時間が止まるのか。
うーん、無駄な時間を過ごしてしまった。けど知っておくべきことを知れてよかった。よく考えてみると、マルチプレイでログインしてる別の人が離れたところにいる場合でも止まりそう。つまり、プレイヤーがいる周りだけ更新されていくということか。当たり前だったか。
(スポーンチャンクはどうなのか。非常に気になるけど未検証。)7.2. RCON
実はまだよくわかっていないのですが、Minecraftサーバー用のコンソール機能がRCONと言われるもののようです。
ログインしている人のリストとか、キックとか、アイテムを与えるとか、ブロックを作るとか、神様みたいな感じです。チートな状態だと、入力できるコマンドかも。Minecraft console commands and cheatsサーバーを起動した状態(=Dockerが起動している状態)で実行可能です。
まずVM インスタンスのSSHの黒い画面を起動。
次に下記を入力で、指示できる状態に入ります。
(抜け方はわからないので、いつもCtrl+Cで抜けてます。)$ docker exec -it minecraft rcon-cli起動しているDockerコンテナの中に入って、rcon-cliというモジュールを実行するというもの。
下記のように、後ろにコマンド(例ではlistコマンド)を入れると、そのコマンドだけ実行して終わる。$ docker exec -it minecraft rcon-cli list上記を連続的に呼び出すようにshellを組めば、複数のコマンドをまとめたものとか、大きな建築物とかプログラムでできそうな感じですね。
7.3. Minecraftの料金
サーバーのexeを実行すると、サーバーの人だけは料金はかかり、そこへ接続する人はかからないという話をどこかで聞いた。(やってない)
今回の手順の場合はどうなんだろうか。ID/パスワードをどこかで聞かれるかなと思ってたけど、最終的に聞かれなかった。私はクライアントのMinecraftのライセンスを持っていて、普通に接続できていることがそれゆえなのか、なくてもできるのか、結局わからずじまいのままです。すみません。
- 投稿日:2020-09-22T22:31:17+09:00
Docker開発環境でCapybaraを使ったブラウザテスト環境を構築する
概要
docker開発環境でRSpecテスト環境を構築するやり方をまとめました。
初心者で独学なので間違っている部分やもっといいやり方があると思いますが、その時はご指摘頂けると嬉しいです。以下の記事を参考にしました。
Rails on DockerでRSpecのSystem testをSelenium Dockerを使ってやってみた。はじめに
以前、Dockerを使ったRails開発でブラウザテストが実行できないでブラウザテストのエラー解消の記事を投稿しましたが、
コメントを頂き、docker-composeを使ってchrome自体をサービスの一つとして動かせば、
Rails環境を汚さずに簡単にテストができるとアドバイスを頂きましたので試してみました。
ご指摘ありがとうございました!1.docker-compose.ymlにchromeのサービスを追加
使用するイメージはChromeが最初からインストールされたものである、standalone-chromeを使います。
docker-compose.ymlversion: '3' services: web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/[app名] ports: - 3000:3000 depends_on: - db - chrome # ←追加 tty: true stdin_open: true db: image: mysql:5.7 volumes: - db-volume:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: password # ↓追加 chrome: image: selenium/standalone-chrome:latest ports: - 4444:4444 # ↑追加 volumes: db-volume:2.RSpecの導入
rspec-railsのgemを追記します
Gemfilegroup :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails', '~> 4.0.1' # 追加 gem 'factory_bot_rails', '~>4.11' endgemをインストールします。
$ docker-compose build※ビルドした後はコンテナの再起動を忘れずに
RSpecのインストール
$ docker-compose run web rails g rspec:install次に、インストールすると作成されるファイルの中に、"rails_helper.rb"に設定を記述していきます。
RSpec実行時にdocker-seleniumのコンテナのブラウザを使用するように設定します。/spec/rails_helper.rb#~ Capybara.register_driver :remote_chrome do |app| url = "http://chrome:4444/wd/hub" caps = ::Selenium::WebDriver::Remote::Capabilities.chrome( "goog:chromeOptions" => { "args" => [ "no-sandbox", "headless", "disable-gpu", "window-size=1680,1050" ] } ) Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps) end #~ RSpec.configure do |config| config.before(:each, type: :system) do driven_by :rack_test end config.before(:each, type: :system, js: true) do driven_by :remote_chrome Capybara.server_host = IPSocket.getaddress(Socket.gethostname) Capybara.server_port = 4444 Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}" end #~ end最後に
.rspec
を編集して、rails_helper.rbの設定を読み取るようにします。.rspec- --require spec_helper + --require rails_helper以上です。
あとはテストを記述してテストを実行できるか確認してみます。
#コンテナ起動時 $ docker-compose exec web rspec [rspecテストファイルのpath]テスト失敗時にブラウザのハードコピーを確認することができました。
- 投稿日:2020-09-22T22:19:18+09:00
pleasanter+PostgreSQL+SSL+dockerで自動バックアップを作ってみた
概要
- 前回記事の続きです。
- 本格的にシステムを使う事を考えた場合、バックアップはちゃんと考えておく必要が有ります。
- 今回は自動でバックアップできるようにシステム化しました。
- 対応できるバックアップ種別は「Fullバックアップ」と「PITR(ポイント・イン・タイム・リカバリ)」です。
- AWS S3の設定を入れておくことで、バックアップデータをS3に同期する事も出来ます。
コンテナ構成
バックアップ作業用にコンテナが追加になっています。
追加されたコンテナを下表に示します。
postgres-dbとcron-backupはDBの領域を共有しており、
PITRが使える状態になっています。
コンテナ名 概要 cron-backup バックアップ用クーロンコンテナ postgres-db PostgreSQL DB pleasanter-web PleasanterのWebシステム バックアップスクリプト
自動バックアップ機構に使用されるスクリプトは以下となります。
これらのスクリプトはpcron-backupコンテナに配備されます。
スクリプト名 概要 /var/backup_sh/pg_rman.sh PITRを実行 /var/backup_sh/pg_dumpall.sh Full Backupを実行 /var/backup_sh/pg_dumpall.sh S3同期を実行 バックアップ設定
ディレクトリ構成
pcron-backupコンテナから見たディレクトリ構成し下表となります。
共有が〇となっているパスに関してはpostgres-dbコンテナと共有しています。バックアップ結果のデータは「/var/db_backup」に集まってくるように出来ています。
このため、このディレクトリをコンテナ外の接続してバックアップを取得しておけば必要なコンテナの外側からバックアップは取れる状態になります。
パス名 概要 コンテナ間共有 /var/db_backup/PITR/ ポイント・イン・タイム・リカバリ用のバックアップディレクトリ /var/db_backup/dumpall 全データバックアップ用のディレクトリ /var/backup_sh バックアップ用Shell格納ディレクトリ /var/ バックアップ用Shell格納ディレクトリ /var/lib/postgresql/data/ postgresqlデータ領域 〇 /var/lib/postgresql/arclog postgresqlWAL領域 〇 取得頻度
バックの動作管理はcronにより制御されています。
該当cromの設定は「cron-backup\config\crontab」にあります。
初期状態では以下の指定になっています。
必要に応じて、対象時間を切り替えてください。
種別 頻度 全バックアップ 毎日午前3時に1回 PITR(ポイント・イン・タイム・リカバリ) 30分毎 バックアップの開始
これらバックアップスクリプトはDocker Composeを起動すると自動的に起動を開始します。
開始にあたり、何か特別な操作は不要です。逆にバックアップを取りたくない場合、該当のコンテナを起動しないように
バックアップ設定 オプション機能 S3同期
概要
ここまでのバックアップ機能だけですと、何かあってコンテナが飛んだ時にデータを損失する危険性があります。
バックアップはどこか別の場所に確保しておく必要があります。
現代は、S3という便利なものかあるのでそこに自動同期するようにつくってあります。有効化
AWS CLIの設定が存在する時に有効化されます。
有効化判定の対象となるパスし以下です。「/root/.aws/config」
この設定ファイルはconfigとしてコンテナ内部にコピーさせるよりは、コンテナの外に置いておいてマウントさせるほうが楽です。
(以下の★の部分です。)docker-compose.ymlcron-backup: build: context: cron-backup/. volumes: - *APP_DB_data - *APP_DB_arclog # 自動バックアップされた結果は「/var/db_backup」に格納される。 # コンテナの外からアクセスする場合は、このパスを外から見える所に配置しておく - db-backup:/var/db_backup # S3で自動バックアップする場合 # aws cliの設定を以下パスに行う。 # 存在しない場合はバックアップは行われない - ./cron-backup/config/aws-cli:/root/.aws/ ← ★設定
ホストがWindows環境の場合、GITの設定によっては、設定ファイルがCRLFで取得される事があります。
設定ファイルをその状態でコンテナ内に持っていくと改行コードが合わなくて正しく動かないので、設定ファイルの改行コードの取り扱いには注意してください。まず、AWS CLIの設定が必要です。
このあたりは一般的な設定なので、ご自分のアカウントから必要な情報を取得してください。cron-backup\config\aws-cli\credentials[default] aws_access_key_id = アクセスキー aws_secret_access_key = シークレットキー次に、バックアップ対象の設定を行います。
これはshell形式の設定となります。cron-backup\config\aws-cli\S3Config.sh#!/bin/bash # --- S3 同期設定 # 同期対象となる S3 バケット名 export S3_TARGET_BUCKET_NAME={バケット名} # 同期対象となる S3 ディレクトリ名 export S3_TARGET_DIRECTORY_NAME={ディレクトリ名}実行タイミング
S3への同期はバックアップ処理が実行されたタイミングとなります。
設定が正しくできていれば、開始のために特別な設定は不要です。セーフモード
S3への同期はaws cliの「rsync」コマンドのdeleteオプション付きで行われます。
このコマンドを用いた場合、同期先のディレクトリは同期元のディレクトリと同一になるように動作します。
ここで、同一とはつまり「同期元になくて同先先にあるファイルは消去される」という意味です。
新規に環境を作った直後に設定を間違えてこのバックアップが動いてしまうと、必要なデータが消えてしまい大変な事になります。そこで、S3のバックアップ処理にはセーフモードが付いています。
セーフモードでは、S3の対象バケットの対象ディレクトリに既存のコンテナがもっているバックアップ系統とは異なるデータが確認された場合、上書きはせずに「ディレクトリ名-safe」というディレクトリを作ってそちら側にバックアップを行うという処理となります。
バックアップ系統の同一性確認には、バックアップ時に生成される「BackupFiles.sha256.7z」というファイルを参照して実施します。基本的には、ユーザーはあまり気にする必要はありませんが、環境移行の時などは既存のバックアップを壊してしまわないように十分注意して実行してください。
また、初回バックアップ実施後は「ディレクトリ名-safe」のようなディレクトリが出来ていないか確認してください。
リストア
リストアに関しては、
バックアップデータの取得方法により戻し方が変わってきます。全バックアップで取得した場合
以下、cron-backupコンテナで作業した事とします。
バックアップファイルは7z形式、かつ、暗号化されています。
適宜復元してください。
(暗号キーに関してはshellファイル「cron-backup\shell\pg_dumpall.sh」を参照してください)
以下コマンドは、復元されたファイルが「backup」という名称となっている事を前提としています。
全バックアップからの復元は以下コマンド一発で完了です。psql -h postgres-db -p 5432 -U postgres -f backupPITR
PITRの場合、少しややこしいです。
PITRの場合、postgresが動いているとうまく復元できないため、
cron-backupコンテナだけ起動させます。docker-compose up pleasanter-cron-backup手順0 . データコピー
pleasanter-cron-backupコンテナで実施します。
復元に使用するデータを用意します。
復元に用いるデータは「/var/db_backup/PITR/」にコピーしてください。手順1 . クーロン停止
pleasanter-cron-backupコンテナで実施します。
クーロンを普通に起動しておくとバックアップクーロンがデータのバックアップを開始してしまいます。
そこで、バックアップクーロン停止しておきます。crontab -l > my_cron_backup.txt crontab -r手順2 . バックアップ済みデータ確認
pleasanter-cron-backupコンテナで実施します。
以下コマンドで取得済みのバックアップ一覧を表示します。/usr/lib/postgresql/12/bin/pg_rman show -B /var/db_backup/PITR/コマンドを実行すると以下のようにバックアップとして戻すことが出来るタイミングの一覧が表示されます。
root@885777f50d56:~/out/cron-backup/shell# /usr/lib/postgresql/12/bin/pg_rman show -B /var/db_backup/PITR/ ===================================================================== StartTime EndTime Mode Size TLI Status ===================================================================== 2020-09-22 21:44:35 2020-09-22 21:44:38 INCR 33kB 3 OK 2020-09-22 21:43:32 2020-09-22 21:43:35 INCR 33kB 3 OK 2020-09-22 21:40:54 2020-09-22 21:40:58 INCR 33kB 3 OK 2020-09-22 21:39:32 2020-09-22 21:39:35 INCR 33kB 3 OK 2020-09-22 21:38:47 2020-09-22 21:38:51 INCR 33kB 3 OK 2020-09-22 21:32:47 2020-09-22 21:36:18 FULL 61MB 3 OK手順3 . リストア
pleasanter-cron-backupコンテナで実施します。
PITRの場合、戻し方には二つのパターンがあります。最終バックのタイミングに戻す
以下コマンドを用います。
/usr/lib/postgresql/12/bin/pg_rman restore -B /var/db_backup/PITR/ -D /var/lib/postgresql/data/任意タイミングに戻す
任意タイミングに戻す場合、戻す対象の時間を指定する事が可能です。
コマンドは以下となり、「recovery-target-time」として対象時間を指定します。/usr/lib/postgresql/12/bin/pg_rman restore --recovery-target-time '2020-09-06 14:29:00' -B /var/db_backup/PITR/ -D /var/lib/postgresql/data/手順6 . クーロン戻し
pleasanter-cron-backupコンテナで実施します。
クーロンの設定を元に戻します。crontab my_cron_backup.txt crontab -lDBの整合性チェック
ここの処理は「全バックアップ」、「PITR」のいずれから戻した場合においても共通で必要となります。
バックアップ処理ではシステム動作中にデータを抜いてきています。
このため、DB上に存在するセッション情報などが中途半端な状態で残っています。以下コマンドを使って、DB上の不要なデータを一度クリーンします。
(docker ホストで実行します。)docker ps | grep leasanter-web | cut -d' ' -f 1 | xargs -I {} docker exec {} cmdnetcore/codedefiner.sh後処理
DBを戻したら後処理が必要です。
速やかなFUllバックアップ
動くことを確認したら速やかにFullバックアップを取りましょう。
以下コマンドを直接叩く事でFullバックアップの取得が可能です。
ただし、S3設定がされている場合、S3への同期も走るので、十分注意して実施してください。「/var/backup_sh/pg_dumpall.sh」
PITRにおけるベースバックアップの再取得
バックアップから戻した後の場合、PITRではベースバックアップがそれまでに取得されているものと変わっている可能性があ要ります。
(PITRでは、ベースバックアップに差分を重ねるという取り方をするが、リストアによりベースバックアップと最新のDB状態がすれた場合、後続のバックアップ処理が正しく実施できなくなる。)
そこで、ベースバックアップの再取得が必要となります。
- 「/var/db_backup/PITR/」パスにPITRのバックアップデータがあります。これを移動させます。
- 「/var/backup_sh/pg_rman.sh」コマンドを使って、バックアップデータが空の状態で再度バックアップを実施します。(S3同期するので注意が必要)
参考
OSC北海道2014_JPUG資料
MastodonのPostgreSQLをpg_rmanを使ってバックアップする
pg_rman
pg_rmanを使ってみる
pg_rmanによるPostgreSQLの簡単バックアップ&リカバリ
- 投稿日:2020-09-22T21:33:48+09:00
docker help 日本語訳
docker help
実行時に表示されるドキュメントの日本語訳。使用法:
docker [OPTIONS] COMMAND
自己完結型コンテナーランタイム
オプション:
- --config string クライアント構成ファイルの場所(デフォルトは
~/.docker
)- -c, --context string デーモンへの接続に使用するコンテキストの名前(
DOCKER_HOST
env
var
およびdocker context use
で設定されたデフォルトのコンテキストをオーバーライドします)- -D, -debug デバッグモードを有効にする
- -H, --host list 接続するデーモンソケット
- -l, -log-level string ログレベルを設定します(デフォルトは
info
)
- "debug"
- "info"
- "warn"
- "error"
- "fatal"
- --tls
--tlsverify
によって指定された TLS を使用します。- --tlscacert string この CA のみが署名した信頼証明書(デフォルトは
~/.docker/ca.pem
)- --tlscert string TLS 証明書ファイルへのパス(デフォルトは
~/.docker/cert.pem
)- --tlskey string TLS キーファイルへのパス(デフォルトは
~/.docker/key.pem
)- --tlsverify TLS を使用してリモートを確認する
- -v, --version バージョン情報を出力して終了
管理コマンド:
- app* Docker アプリケーション(Docker Inc., v0.8.0)
- builder ビルドを管理する
- buildx* BuildKit を使用してビルド(Docker Inc., v0.3.1-tp-docker)
- checkpoint チェックポイントを管理する
- config Docker 構成を管理する
- container コンテナを管理する
- context コンテキストを管理する
- image イメージを管理する
- manifest Docker イメージマニフェストとマニフェストリストを管理する
- network ネットワークを管理する
- node Swarm ノードを管理する
- plugin プラグインを管理する
- scan* Docker Scan(Docker Inc., v0.3.3)
- secret Docker シークレットを管理する
- service サービスを管理する
- stack Docker スタックを管理する
- swarm スウォームを管理する
- system Docker を管理する
- trust 信頼する Docker イメージを管理する
- volume ボリュームを管理する
コマンド:
- attach ローカルの標準入力、出力、およびエラーストリームを実行中のコンテナーにアタッチする
- build Dockerfile からイメージをビルドする
- commit 変更を加えたコンテナーから新しいイメージを作成する
- cp コンテナーとローカルファイルシステム間でファイル / フォルダーをコピーする
- create 新しいコンテナを作成する
- deploy 新しいスタックをデプロイするか、既存のスタックを更新します
- diff コンテナーのファイルシステム上のファイルまたはディレクトリへの変更を検出する
- events サーバーからリアルタイムのイベントを取得する
- exec 実行中のコンテナでコマンドを実行する
- export コンテナーのファイルシステムを tar アーカイブとしてエクスポートする
- history イメージの履歴を表示する
- images イメージを一覧表示する
- import tarball からコンテンツをインポートしてファイルシステムイメージを作成します
- info システム全体の情報を表示する
- inspect Docker オブジェクトに関する低レベルの情報を返す
- kill 実行中の 1 つ以上のコンテナーを強制終了する
- load tar アーカイブまたは STDIN からイメージを読み込む
- login Docker レジストリにログインする
- logout Docker レジストリからログアウトする
- logs コンテナのログを取得する
- pause 1 つ以上のコンテナ内のすべてのプロセスを一時停止します
- port コンテナのポートマッピングを一覧表示、またはポートマッピングを指定する。
- ps コンテナーの一覧表示
- pull レジストリからイメージまたはリポジトリを取得する
- push イメージまたはリポジトリをレジストリに登録する
- rename コンテナーの名前を変更する
- restart 1 つ以上のコンテナを再起動します
- rm 1 つ以上のコンテナーを削除する
- rmi 1 つまたは複数のイメージを削除する
- run 新しいコンテナでコマンドを実行する
- save 1 つ以上のイメージを tar アーカイブに保存します(デフォルトで STDOUT にストリーミングされます)
- search Docker Hub でイメージを検索する
- start 停止している 1 つ以上のコンテナーを起動する
- stats コンテナのリソース使用状況統計のライブストリームを表示する
- stop 実行中の 1 つ以上のコンテナーを停止する
- tag SOURCE_IMAGE を参照するタグ TARGET_IMAGE を作成します
- top コンテナの実行中のプロセスを表示する
- unpause 1 つ以上のコンテナー内のすべてのプロセスの一時停止を解除します
- update 1 つ以上のコンテナーの構成を更新する
- version Dockerの バージョン情報を表示する
- wait 1 つ以上のコンテナーが停止するまでブロックし、その終了コードを出力します
コマンドの詳細については
docker COMMAND --help
を実行してください。
- 投稿日:2020-09-22T19:40:32+09:00
Docker x Laravel phpMyAdmin を導入する
以前の記事(最強のLaravel開発環境をDockerを使って構築する【新編集版】)のコメントにてphpMyAdminを使用したいという要望がありましたので補足の記事を作成させていただきます。
手順
https://github.com/ucan-lab/docker-laravel
docker-compose.yml に phpMyAdmin のサービスを追加
docker-compose.ymlvolumes: # 追記 pma-session-store: services: # 追記 pma: image: phpmyadmin/phpmyadmin:5.0.2 environment: - PMA_HOST=db - PMA_USER=root - PMA_PASSWORD=secret ports: - 8080:80 volumes: - pma-session-store:/sessionsDockerコンテナの構築
$ docker-compose up -dphpMyAdmin へアクセス
上記のURLへアクセスし、phpMyAdminの画面が表示されればokです。
補足
MySQL新認証プラグイン caching_sha2_password
私のdbコンテナの設定でMySQL8.0系で認証方式を新しいcaching_sha2_passwordに設定しています。phpMyAdminは5.0.1以降でないとcaching_sha2_passwordに対応していないのでタグで新しいバージョンを明示的に指定してます。latestが5系を指すようになったら外してもいいかもです。
蛇足
(MySQLのCLIやSequel Ace等のクライアントツールで特に不便がないのでがあるので個人的にはphpMyAdminは入れなくてもいいかなと思ってます)
- 投稿日:2020-09-22T19:40:32+09:00
Docker x Laravel phpMyAdmin のコンテナを構築する
以前の記事(最強のLaravel開発環境をDockerを使って構築する【新編集版】)のコメントにてphpMyAdminを使用したいという要望がありましたので補足の記事を作成させていただきます。
手順
https://github.com/ucan-lab/docker-laravel
docker-compose.yml に phpMyAdmin のサービスを追加
docker-compose.ymlvolumes: # 追記 pma-session-store: services: # 追記 pma: image: phpmyadmin/phpmyadmin:5.0.2 environment: - PMA_HOST=db - PMA_USER=root - PMA_PASSWORD=secret ports: - 8080:80 volumes: - pma-session-store:/sessionsDockerコンテナの構築
$ docker-compose up -dphpMyAdmin へアクセス
上記のURLへアクセスし、phpMyAdminの画面が表示されればokです。
補足
MySQL新認証プラグイン caching_sha2_password
私のdbコンテナの設定でMySQL8.0系で認証方式を新しいcaching_sha2_passwordに設定しています。phpMyAdminは5.0.1以降でないとcaching_sha2_passwordに対応していないのでタグで新しいバージョンを明示的に指定してます。latestが5系を指すようになったら外してもいいかもです。
蛇足
(MySQLのCLIやSequel Ace等のクライアントツールで特に不便がないのでがあるので個人的にはphpMyAdminは入れなくてもいいかなと思ってます)
- 投稿日:2020-09-22T19:05:01+09:00
非ネット接続環境でのDockerのセットアップ
社内の開発環境等、非インターネット接続環境でのDocker Engineのセットアップ方法の作業メモ
前提環境
- 検証用のため、AWS上に環境を準備。
利用AMI:RHEL-7.1_HVM-20150803-x86_64-1-Hourly2-GP2
インスタンスタイプ:t2.medium(2vCPU/4GiB)RHEL7.1環境Red Hat Enterprise Linux Server release 7.1 (Maipo)Docker導入準備
インターネット接続環境であれば、以下手順に従い、yum installで一発だが、今回は非インターネット接続環境という前提の為、依存性を解決しつつ、必要なrpmを準備
http://docs.docker.jp/engine/installation/linux/rhel.html
- Red Hat Customer PortalよりDocker Engineのパッケージ一式をダウンロード
必要RPM一覧[root@ip-172-31-47-162 docker]# ls -ltr total 13100 -rw-r--r--. 1 ec2-user ec2-user 56232 Sep 22 06:16 docker-selinux-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 7969356 Sep 22 06:19 docker-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 918432 Sep 22 06:20 lvm2-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 783492 Sep 22 06:22 lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 214388 Sep 22 06:28 device-mapper-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 162532 Sep 22 06:28 device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 155168 Sep 22 06:28 device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 265880 Sep 22 06:28 device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 2869284 Sep 22 06:28 device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm [root@ip-172-31-47-162 docker]#
- まずは、Docker Engineのメインのパッケージである、「docker-1.6.2-14」をダウンロードの上、yum localinstallにて、依存性のあるパッケージを抽出。
- Red Hat Customer Portalより必要なパッケージをダウンロードし、SCPにてAWS上のRHEL環境に転送。
- 非インターネット接続環境とする為、EC2のセキュリティグループのアウトバウンドは、全て拒否設定。
- デフォルトのrepo設定だと、以下エラーが出力され、localinstallすらできない(アウトバウンド拒否している為、デフォルトのrepoに問い合わせできない)為、設定変更。
エラー出力[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./container-selinux-2.10-2.el7.noarch.rpm: 2:container-selinux-2.10-2.el7.noarch Marking ./container-selinux-2.10-2.el7.noarch.rpm to be installed Examining ./docker-1.12.6-16.el7.x86_64.rpm: 2:docker-1.12.6-16.el7.x86_64 Marking ./docker-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-client-1.12.6-16.el7.x86_64.rpm: 2:docker-client-1.12.6-16.el7.x86_64 Marking ./docker-client-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-common-1.12.6-16.el7.x86_64.rpm: 2:docker-common-1.12.6-16.el7.x86_64 Marking ./docker-common-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm: 2:docker-rhel-push-plugin-1.12.6-16.el7.x86_64 Marking ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm to be installed Examining ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm: 1:oci-register-machine-0-3.11.gitdd0daef.el7.x86_64 Marking ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm to be installed Examining ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm: 1:oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64 Marking ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm to be installed Examining ./skopeo-containers-0.1.20-2.el7.x86_64.rpm: 1:skopeo-containers-0.1.20-2.el7.x86_64 Marking ./skopeo-containers-0.1.20-2.el7.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package container-selinux.noarch 2:2.10-2.el7 will be installed --> Processing Dependency: policycoreutils >= 2.5-11 for package: 2:container-selinux-2.10-2.el7.noarch Could not contact CDS load balancer rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, trying others. Could not contact any CDS load balancers: rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, rhui2-cds02.ap-northeast-1.aws.ce.redhat.com. [root@ip-172-31-47-162 docker]#repoの設定変更[root@ip-172-31-47-162 yum.repos.d]# yum-config-manager --save --setopt=local-myrepository.skip_if_unavailable=trueDocker Engineのインストール
- yum localinstallコマンドにてDocker Engineのインストール
インストールの実行[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm: device-mapper-persistent-data-0.3.2-1.el7.x86_64 Marking ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm to be installed Examining ./docker-1.6.2-14.el7.x86_64.rpm: docker-1.6.2-14.el7.x86_64 Marking ./docker-1.6.2-14.el7.x86_64.rpm to be installed Examining ./docker-selinux-1.6.2-14.el7.x86_64.rpm: docker-selinux-1.6.2-14.el7.x86_64 Marking ./docker-selinux-1.6.2-14.el7.x86_64.rpm to be installed Examining ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm to be installed Examining ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm to be installed Skipping: ./old, filename does not end in .rpm. Resolving Dependencies --> Running transaction check ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 will be installed ---> Package docker.x86_64 0:1.6.2-14.el7 will be installed ---> Package docker-selinux.x86_64 0:1.6.2-14.el7 will be installed ---> Package lvm2.x86_64 7:2.02.115-3.el7_1.2 will be installed ---> Package lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ======================================================================================================================== Package Arch Version Repository Size ======================================================================================================================== Installing: device-mapper-event x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-1.02.93-3.el7_1.2.x86_64 37 k device-mapper-event-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 27 k device-mapper-persistent-data x86_64 0.3.2-1.el7 /device-mapper-persistent-data-0.3.2-1.el7.x86_64 17 M docker x86_64 1.6.2-14.el7 /docker-1.6.2-14.el7.x86_64 32 M docker-selinux x86_64 1.6.2-14.el7 /docker-selinux-1.6.2-14.el7.x86_64 25 k lvm2 x86_64 7:2.02.115-3.el7_1.2 /lvm2-2.02.115-3.el7_1.2.x86_64 1.8 M lvm2-libs x86_64 7:2.02.115-3.el7_1.2 /lvm2-libs-2.02.115-3.el7_1.2.x86_64 2.2 M Updating: device-mapper x86_64 7:1.02.93-3.el7_1.2 /device-mapper-1.02.93-3.el7_1.2.x86_64 189 k device-mapper-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-libs-1.02.93-3.el7_1.2.x86_64 293 k Transaction Summary ======================================================================================================================== Install 7 Packages Upgrade 2 Packages Total size: 54 M Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 1/11 Updating : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 2/11 Installing : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 3/11 Installing : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 4/11 Installing : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 5/11 Installing : docker-selinux-1.6.2-14.el7.x86_64 6/11 Installing : device-mapper-persistent-data-0.3.2-1.el7.x86_64 7/11 Installing : 7:lvm2-2.02.115-3.el7_1.2.x86_64 8/11 Installing : docker-1.6.2-14.el7.x86_64 9/11 Cleanup : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Cleanup : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Verifying : device-mapper-persistent-data-0.3.2-1.el7.x86_64 1/11 Verifying : 7:lvm2-2.02.115-3.el7_1.2.x86_64 2/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 3/11 Verifying : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 4/11 Verifying : docker-1.6.2-14.el7.x86_64 5/11 Verifying : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 6/11 Verifying : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 7/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 8/11 Verifying : docker-selinux-1.6.2-14.el7.x86_64 9/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Installed: device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 docker.x86_64 0:1.6.2-14.el7 docker-selinux.x86_64 0:1.6.2-14.el7 lvm2.x86_64 7:2.02.115-3.el7_1.2 lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 Updated: device-mapper.x86_64 7:1.02.93-3.el7_1.2 device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 Complete! [root@ip-172-31-47-162 docker]#インストール後の稼働確認
- docker engineの起動&ステータス確認
DockerEngineの起動&起動確認[root@ip-172-31-47-162 docker]# systemctl start docker [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# systemctl status docker docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled) Active: active (running) since Tue 2020-09-22 06:29:23 EDT; 10s ago Docs: http://docs.docker.com Main PID: 18149 (docker) CGroup: /system.slice/docker.service └─18149 /usr/bin/docker -d --selinux-enabled --add-registry registry.access.redhat.com Sep 22 06:29:16 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:16-04:00" lev..." Sep 22 06:29:22 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:22-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal systemd[1]: Started Docker Application Container E...e. Hint: Some lines were ellipsized, use -l to show in full. [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@ip-172-31-47-162 docker]#
- 外部接続できない為、docker searchコマンドは失敗(想定通り)
エラー出力[root@ip-172-31-47-162 docker]# docker search hello-world FATA[0127] Error response from daemon: Get https://index.docker.io/v1/search?q=hello-world: dial tcp 52.55.43.248:443: connection timed out [root@ip-172-31-47-162 docker]#
- 投稿日:2020-09-22T19:05:01+09:00
非ネット接続環境でのDocker Engineのセットアップ
社内の開発環境等、非インターネット接続環境でのDocker Engineのセットアップ方法の作業メモ
前提環境
- 検証用のため、AWS上に環境を準備。
利用AMI:RHEL-7.1_HVM-20150803-x86_64-1-Hourly2-GP2
インスタンスタイプ:t2.medium(2vCPU/4GiB)RHEL7.1環境Red Hat Enterprise Linux Server release 7.1 (Maipo)Docker導入準備
インターネット接続環境であれば、以下手順に従い、yum installで一発だが、今回は非インターネット接続環境という前提の為、依存性を解決しつつ、必要なrpmを準備
http://docs.docker.jp/engine/installation/linux/rhel.html
- Red Hat Customer PortalよりDocker Engineのパッケージ一式をダウンロード
必要RPM一覧[root@ip-172-31-47-162 docker]# ls -ltr total 13100 -rw-r--r--. 1 ec2-user ec2-user 56232 Sep 22 06:16 docker-selinux-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 7969356 Sep 22 06:19 docker-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 918432 Sep 22 06:20 lvm2-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 783492 Sep 22 06:22 lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 214388 Sep 22 06:28 device-mapper-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 162532 Sep 22 06:28 device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 155168 Sep 22 06:28 device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 265880 Sep 22 06:28 device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 2869284 Sep 22 06:28 device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm [root@ip-172-31-47-162 docker]#
- まずは、Docker Engineのメインのパッケージである、「docker-1.6.2-14」をダウンロードの上、yum localinstallにて、依存性のあるパッケージを抽出。
- 新しいDocker Engineバージョンだと、依存性地獄で面倒なので、あえて古いバージョン(RHEL7.1と親和性高そうなもの)を選択。。。
- Red Hat Customer Portalより必要なパッケージをダウンロードし、SCPにてAWS上のRHEL環境に転送。
- 非インターネット接続環境とする為、EC2のセキュリティグループのアウトバウンドは、全て拒否設定。(これにより、EC2からインターネット接続は不可。)
- デフォルトのrepo設定だと、以下エラーが出力され、localinstallすらできない(アウトバウンド拒否している為、デフォルトのrepoに問い合わせできない)為、設定変更。
エラー出力[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./container-selinux-2.10-2.el7.noarch.rpm: 2:container-selinux-2.10-2.el7.noarch Marking ./container-selinux-2.10-2.el7.noarch.rpm to be installed Examining ./docker-1.12.6-16.el7.x86_64.rpm: 2:docker-1.12.6-16.el7.x86_64 Marking ./docker-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-client-1.12.6-16.el7.x86_64.rpm: 2:docker-client-1.12.6-16.el7.x86_64 Marking ./docker-client-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-common-1.12.6-16.el7.x86_64.rpm: 2:docker-common-1.12.6-16.el7.x86_64 Marking ./docker-common-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm: 2:docker-rhel-push-plugin-1.12.6-16.el7.x86_64 Marking ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm to be installed Examining ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm: 1:oci-register-machine-0-3.11.gitdd0daef.el7.x86_64 Marking ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm to be installed Examining ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm: 1:oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64 Marking ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm to be installed Examining ./skopeo-containers-0.1.20-2.el7.x86_64.rpm: 1:skopeo-containers-0.1.20-2.el7.x86_64 Marking ./skopeo-containers-0.1.20-2.el7.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package container-selinux.noarch 2:2.10-2.el7 will be installed --> Processing Dependency: policycoreutils >= 2.5-11 for package: 2:container-selinux-2.10-2.el7.noarch Could not contact CDS load balancer rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, trying others. Could not contact any CDS load balancers: rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, rhui2-cds02.ap-northeast-1.aws.ce.redhat.com. [root@ip-172-31-47-162 docker]#repoの設定変更[root@ip-172-31-47-162 yum.repos.d]# yum-config-manager --save --setopt=local-myrepository.skip_if_unavailable=trueDocker Engineのインストール
- yum localinstallコマンドにてDocker Engineのインストール
インストールの実行[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm: device-mapper-persistent-data-0.3.2-1.el7.x86_64 Marking ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm to be installed Examining ./docker-1.6.2-14.el7.x86_64.rpm: docker-1.6.2-14.el7.x86_64 Marking ./docker-1.6.2-14.el7.x86_64.rpm to be installed Examining ./docker-selinux-1.6.2-14.el7.x86_64.rpm: docker-selinux-1.6.2-14.el7.x86_64 Marking ./docker-selinux-1.6.2-14.el7.x86_64.rpm to be installed Examining ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm to be installed Examining ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm to be installed Skipping: ./old, filename does not end in .rpm. Resolving Dependencies --> Running transaction check ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 will be installed ---> Package docker.x86_64 0:1.6.2-14.el7 will be installed ---> Package docker-selinux.x86_64 0:1.6.2-14.el7 will be installed ---> Package lvm2.x86_64 7:2.02.115-3.el7_1.2 will be installed ---> Package lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ======================================================================================================================== Package Arch Version Repository Size ======================================================================================================================== Installing: device-mapper-event x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-1.02.93-3.el7_1.2.x86_64 37 k device-mapper-event-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 27 k device-mapper-persistent-data x86_64 0.3.2-1.el7 /device-mapper-persistent-data-0.3.2-1.el7.x86_64 17 M docker x86_64 1.6.2-14.el7 /docker-1.6.2-14.el7.x86_64 32 M docker-selinux x86_64 1.6.2-14.el7 /docker-selinux-1.6.2-14.el7.x86_64 25 k lvm2 x86_64 7:2.02.115-3.el7_1.2 /lvm2-2.02.115-3.el7_1.2.x86_64 1.8 M lvm2-libs x86_64 7:2.02.115-3.el7_1.2 /lvm2-libs-2.02.115-3.el7_1.2.x86_64 2.2 M Updating: device-mapper x86_64 7:1.02.93-3.el7_1.2 /device-mapper-1.02.93-3.el7_1.2.x86_64 189 k device-mapper-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-libs-1.02.93-3.el7_1.2.x86_64 293 k Transaction Summary ======================================================================================================================== Install 7 Packages Upgrade 2 Packages Total size: 54 M Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 1/11 Updating : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 2/11 Installing : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 3/11 Installing : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 4/11 Installing : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 5/11 Installing : docker-selinux-1.6.2-14.el7.x86_64 6/11 Installing : device-mapper-persistent-data-0.3.2-1.el7.x86_64 7/11 Installing : 7:lvm2-2.02.115-3.el7_1.2.x86_64 8/11 Installing : docker-1.6.2-14.el7.x86_64 9/11 Cleanup : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Cleanup : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Verifying : device-mapper-persistent-data-0.3.2-1.el7.x86_64 1/11 Verifying : 7:lvm2-2.02.115-3.el7_1.2.x86_64 2/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 3/11 Verifying : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 4/11 Verifying : docker-1.6.2-14.el7.x86_64 5/11 Verifying : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 6/11 Verifying : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 7/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 8/11 Verifying : docker-selinux-1.6.2-14.el7.x86_64 9/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Installed: device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 docker.x86_64 0:1.6.2-14.el7 docker-selinux.x86_64 0:1.6.2-14.el7 lvm2.x86_64 7:2.02.115-3.el7_1.2 lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 Updated: device-mapper.x86_64 7:1.02.93-3.el7_1.2 device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 Complete! [root@ip-172-31-47-162 docker]#インストール後の稼働確認
- docker engineの起動&ステータス確認
DockerEngineの起動&起動確認[root@ip-172-31-47-162 docker]# systemctl start docker [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# systemctl status docker docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled) Active: active (running) since Tue 2020-09-22 06:29:23 EDT; 10s ago Docs: http://docs.docker.com Main PID: 18149 (docker) CGroup: /system.slice/docker.service └─18149 /usr/bin/docker -d --selinux-enabled --add-registry registry.access.redhat.com Sep 22 06:29:16 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:16-04:00" lev..." Sep 22 06:29:22 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:22-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal systemd[1]: Started Docker Application Container E...e. Hint: Some lines were ellipsized, use -l to show in full. [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@ip-172-31-47-162 docker]#
- 外部接続できない為、docker searchコマンドは失敗(想定通り)
エラー出力[root@ip-172-31-47-162 docker]# docker search hello-world FATA[0127] Error response from daemon: Get https://index.docker.io/v1/search?q=hello-world: dial tcp 52.55.43.248:443: connection timed out [root@ip-172-31-47-162 docker]#
- 投稿日:2020-09-22T19:05:01+09:00
非インターネット接続環境でのDocker Engineのセットアップ
社内の開発環境等、非インターネット接続環境でのDocker Engineのセットアップ方法の作業メモ
前提環境
- 検証用のため、AWS上に環境を準備。
利用AMI:RHEL-7.1_HVM-20150803-x86_64-1-Hourly2-GP2
インスタンスタイプ:t2.medium(2vCPU/4GiB)RHEL7.1環境Red Hat Enterprise Linux Server release 7.1 (Maipo)Docker導入準備
インターネット接続環境であれば、以下手順に従い、yum installで一発だが、今回は非インターネット接続環境という前提の為、依存性を解決しつつ、必要なrpmを準備
http://docs.docker.jp/engine/installation/linux/rhel.html
- Red Hat Customer PortalよりDocker Engineのパッケージ一式をダウンロード
必要RPM一覧[root@ip-172-31-47-162 docker]# ls -ltr total 13100 -rw-r--r--. 1 ec2-user ec2-user 56232 Sep 22 06:16 docker-selinux-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 7969356 Sep 22 06:19 docker-1.6.2-14.el7.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 918432 Sep 22 06:20 lvm2-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 783492 Sep 22 06:22 lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 214388 Sep 22 06:28 device-mapper-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 162532 Sep 22 06:28 device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 155168 Sep 22 06:28 device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 265880 Sep 22 06:28 device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm -rw-r--r--. 1 ec2-user ec2-user 2869284 Sep 22 06:28 device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm [root@ip-172-31-47-162 docker]#
- まずは、Docker Engineのメインのパッケージである、「docker-1.6.2-14」をダウンロードの上、yum localinstallにて、依存性のあるパッケージを抽出。
- 新しいDocker Engineバージョンだと、依存性地獄で面倒なので、あえて古いバージョン(RHEL7.1と親和性高そうなもの)を選択。。。
- Red Hat Customer Portalより必要なパッケージをダウンロードし、SCPにてAWS上のRHEL環境に転送。
- 非インターネット接続環境とする為、EC2のセキュリティグループのアウトバウンドは、全て拒否設定。(これにより、EC2からインターネット接続は不可。)
- デフォルトのrepo設定だと、以下エラーが出力され、localinstallすらできない(アウトバウンド拒否している為、デフォルトのrepoに問い合わせできない)為、設定変更。
エラー出力[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./container-selinux-2.10-2.el7.noarch.rpm: 2:container-selinux-2.10-2.el7.noarch Marking ./container-selinux-2.10-2.el7.noarch.rpm to be installed Examining ./docker-1.12.6-16.el7.x86_64.rpm: 2:docker-1.12.6-16.el7.x86_64 Marking ./docker-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-client-1.12.6-16.el7.x86_64.rpm: 2:docker-client-1.12.6-16.el7.x86_64 Marking ./docker-client-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-common-1.12.6-16.el7.x86_64.rpm: 2:docker-common-1.12.6-16.el7.x86_64 Marking ./docker-common-1.12.6-16.el7.x86_64.rpm to be installed Examining ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm: 2:docker-rhel-push-plugin-1.12.6-16.el7.x86_64 Marking ./docker-rhel-push-plugin-1.12.6-16.el7.x86_64.rpm to be installed Examining ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm: 1:oci-register-machine-0-3.11.gitdd0daef.el7.x86_64 Marking ./oci-register-machine-0-3.11.gitdd0daef.el7.x86_64.rpm to be installed Examining ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm: 1:oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64 Marking ./oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64.rpm to be installed Examining ./skopeo-containers-0.1.20-2.el7.x86_64.rpm: 1:skopeo-containers-0.1.20-2.el7.x86_64 Marking ./skopeo-containers-0.1.20-2.el7.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package container-selinux.noarch 2:2.10-2.el7 will be installed --> Processing Dependency: policycoreutils >= 2.5-11 for package: 2:container-selinux-2.10-2.el7.noarch Could not contact CDS load balancer rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, trying others. Could not contact any CDS load balancers: rhui2-cds01.ap-northeast-1.aws.ce.redhat.com, rhui2-cds02.ap-northeast-1.aws.ce.redhat.com. [root@ip-172-31-47-162 docker]#repoの設定変更[root@ip-172-31-47-162 yum.repos.d]# yum-config-manager --save --setopt=local-myrepository.skip_if_unavailable=trueDocker Engineのインストール
- yum localinstallコマンドにてDocker Engineのインストール
インストールの実行[root@ip-172-31-47-162 docker]# yum localinstall ./* Loaded plugins: amazon-id, rhui-lb Examining ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64.rpm to be installed Examining ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm: 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 Marking ./device-mapper-libs-1.02.93-3.el7_1.2.x86_64.rpm as an update to 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 Examining ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm: device-mapper-persistent-data-0.3.2-1.el7.x86_64 Marking ./device-mapper-persistent-data-0.3.2-1.el7.x86_64.rpm to be installed Examining ./docker-1.6.2-14.el7.x86_64.rpm: docker-1.6.2-14.el7.x86_64 Marking ./docker-1.6.2-14.el7.x86_64.rpm to be installed Examining ./docker-selinux-1.6.2-14.el7.x86_64.rpm: docker-selinux-1.6.2-14.el7.x86_64 Marking ./docker-selinux-1.6.2-14.el7.x86_64.rpm to be installed Examining ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-2.02.115-3.el7_1.2.x86_64.rpm to be installed Examining ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm: 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 Marking ./lvm2-libs-2.02.115-3.el7_1.2.x86_64.rpm to be installed Skipping: ./old, filename does not end in .rpm. Resolving Dependencies --> Running transaction check ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 will be installed ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.1 will be updated ---> Package device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 will be an update ---> Package device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 will be installed ---> Package docker.x86_64 0:1.6.2-14.el7 will be installed ---> Package docker-selinux.x86_64 0:1.6.2-14.el7 will be installed ---> Package lvm2.x86_64 7:2.02.115-3.el7_1.2 will be installed ---> Package lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ======================================================================================================================== Package Arch Version Repository Size ======================================================================================================================== Installing: device-mapper-event x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-1.02.93-3.el7_1.2.x86_64 37 k device-mapper-event-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 27 k device-mapper-persistent-data x86_64 0.3.2-1.el7 /device-mapper-persistent-data-0.3.2-1.el7.x86_64 17 M docker x86_64 1.6.2-14.el7 /docker-1.6.2-14.el7.x86_64 32 M docker-selinux x86_64 1.6.2-14.el7 /docker-selinux-1.6.2-14.el7.x86_64 25 k lvm2 x86_64 7:2.02.115-3.el7_1.2 /lvm2-2.02.115-3.el7_1.2.x86_64 1.8 M lvm2-libs x86_64 7:2.02.115-3.el7_1.2 /lvm2-libs-2.02.115-3.el7_1.2.x86_64 2.2 M Updating: device-mapper x86_64 7:1.02.93-3.el7_1.2 /device-mapper-1.02.93-3.el7_1.2.x86_64 189 k device-mapper-libs x86_64 7:1.02.93-3.el7_1.2 /device-mapper-libs-1.02.93-3.el7_1.2.x86_64 293 k Transaction Summary ======================================================================================================================== Install 7 Packages Upgrade 2 Packages Total size: 54 M Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 1/11 Updating : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 2/11 Installing : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 3/11 Installing : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 4/11 Installing : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 5/11 Installing : docker-selinux-1.6.2-14.el7.x86_64 6/11 Installing : device-mapper-persistent-data-0.3.2-1.el7.x86_64 7/11 Installing : 7:lvm2-2.02.115-3.el7_1.2.x86_64 8/11 Installing : docker-1.6.2-14.el7.x86_64 9/11 Cleanup : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Cleanup : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Verifying : device-mapper-persistent-data-0.3.2-1.el7.x86_64 1/11 Verifying : 7:lvm2-2.02.115-3.el7_1.2.x86_64 2/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.2.x86_64 3/11 Verifying : 7:device-mapper-event-libs-1.02.93-3.el7_1.2.x86_64 4/11 Verifying : docker-1.6.2-14.el7.x86_64 5/11 Verifying : 7:device-mapper-event-1.02.93-3.el7_1.2.x86_64 6/11 Verifying : 7:lvm2-libs-2.02.115-3.el7_1.2.x86_64 7/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.2.x86_64 8/11 Verifying : docker-selinux-1.6.2-14.el7.x86_64 9/11 Verifying : 7:device-mapper-1.02.93-3.el7_1.1.x86_64 10/11 Verifying : 7:device-mapper-libs-1.02.93-3.el7_1.1.x86_64 11/11 Installed: device-mapper-event.x86_64 7:1.02.93-3.el7_1.2 device-mapper-event-libs.x86_64 7:1.02.93-3.el7_1.2 device-mapper-persistent-data.x86_64 0:0.3.2-1.el7 docker.x86_64 0:1.6.2-14.el7 docker-selinux.x86_64 0:1.6.2-14.el7 lvm2.x86_64 7:2.02.115-3.el7_1.2 lvm2-libs.x86_64 7:2.02.115-3.el7_1.2 Updated: device-mapper.x86_64 7:1.02.93-3.el7_1.2 device-mapper-libs.x86_64 7:1.02.93-3.el7_1.2 Complete! [root@ip-172-31-47-162 docker]#インストール後の稼働確認
- docker engineの起動&ステータス確認
DockerEngineの起動&起動確認[root@ip-172-31-47-162 docker]# systemctl start docker [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# systemctl status docker docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled) Active: active (running) since Tue 2020-09-22 06:29:23 EDT; 10s ago Docs: http://docs.docker.com Main PID: 18149 (docker) CGroup: /system.slice/docker.service └─18149 /usr/bin/docker -d --selinux-enabled --add-registry registry.access.redhat.com Sep 22 06:29:16 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:16-04:00" lev..." Sep 22 06:29:22 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:22-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal docker[18149]: time="2020-09-22T06:29:23-04:00" lev..." Sep 22 06:29:23 ip-172-31-47-162.ap-northeast-1.compute.internal systemd[1]: Started Docker Application Container E...e. Hint: Some lines were ellipsized, use -l to show in full. [root@ip-172-31-47-162 docker]# [root@ip-172-31-47-162 docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@ip-172-31-47-162 docker]#
- 外部接続できない為、docker searchコマンドは失敗(想定通り)
エラー出力[root@ip-172-31-47-162 docker]# docker search hello-world FATA[0127] Error response from daemon: Get https://index.docker.io/v1/search?q=hello-world: dial tcp 52.55.43.248:443: connection timed out [root@ip-172-31-47-162 docker]#
- 投稿日:2020-09-22T18:06:49+09:00
Express+PostgreSQL+SequelizeをDockerで構築してみる【後編】
前回
https://qiita.com/rockguitar67/items/b644a63b3e39cc1fcaea
はい続きです。
③DB周りの設定
コンテナ内のExpress環境においてDB設定がなされているファイルがあります。
ここでdocker-compose.ymlで設定したDBへのアクセス情報が明記されています。db_client.jsmodule.exports = { pg_client: function () { const { Client } = require('pg') const client = new Client({ user: process.env.DB_USER, host: process.env.DB_HOST, port: process.env.DB_PORT, database: process.env.DB_NAME }) return client }, };一応現状でもDBにアクセス自体はできると思います。
routes内のindex.jsを見てみましょう!'URL/'にGETでアクセスした時にどういった挙動をするかを書きます。
先ほどのsb_client.jsを読み取って、DBとの接続を可能にしています。routes/index.jsrouter.get('/', function (req, res, next) { const client = require("../db_client").pg_client() client.connect() .then(() => console.log("success!!")) .then(() => client.query("select * from chat order by timestamp desc")) .then(function (results) { console.table(results.rows) res.render('index', { result: results.rows }) })しかし6行目を見ていただくと、DB処理をSQL文で呼び出しています。
これでもSQLの勉強としては良いのですが、複数のテーブルを用意して、それらを繋ぎ合わせるリレーションなどの処理を行う際はもっと楽なORMを活用します。④ORMの活用
オブジェクト関係マッピング(英: Object-relational mapping、O/RM、ORM)とは、データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。 wikipedia参照
Node.jsを使用する際にORMとしてSequelizeを活用します。
Terminal# npm install -g sequelize sequelize-cli # sequelize-cli initこの時点で作業ディレクトリにconfig.jsonやmodelディレクトリが生成されます。
config
./config/config.json{ "development": { "username": "postgres", "password": null, "database": "mydatabase", "host": "database", "dialect": "postgres", "operatorsAliases": false },config.jsonでhostに127.0.0.1を指定するのが一般的だそうですが、Dockerの場合だとmigrationの時点で、DBにアクセスできないよ、とエラーを吐くことがあります。その為docker-compose.ymlで設定したDB_HOST(=database)をそのまま活用します。
とりあえず作成するテーブルとカラム情報を決めて、DBを作成します!
Terminal# sequelize-cli model:generate --name user --attributes firstName:string,lastName:string,email:string # sequelize-cli db:migratemigration
migrationが完了すると、DBのカラム情報がmigrationフォルダ内に表示されます。
./migration/日付-create-user.jsmodule.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.createTable('users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, firstName: { type: Sequelize.STRING }, lastName: { type: Sequelize.STRING }, email: { type: Sequelize.STRING }, createdAt: { allowNull: false, type: Sequelize.DATE }, updatedAt: { allowNull: false, type: Sequelize.DATE } }); }, down: async (queryInterface, Sequelize) => { await queryInterface.dropTable('users'); } };model
migrationが完了すると、Modelに入力したDBのカラム情報が表示されます。
これを確認できたら一応完了です。./model/user.jsuser.init({ firstName: DataTypes.STRING, lastName: DataTypes.STRING, email: DataTypes.STRING }, { sequelize, modelName: 'user', });model/index.jsや今回作成したmodel/user.jsはリレーション設定やアソシエーションなどで編集しますが、この時点ではノータッチです。
ユーザー登録→ユーザー表示の一連の流れ
簡単にユーザー登録アプリでも作ります。
https://github.com/LostGeneration1999/Express_PostgreSQL_ORM
フォームからユーザー:藤川球児を入力して表示させました。
#参考記事
https://qiita.com/markusveeyola/items/64875c9507d5fa32884e
PostgreSQLへのアクセス
https://qiita.com/yusuke-ka/items/448843020c0406363ba5ORM関連
https://qiita.com/izszzz/items/31d448c501d24d31c846ORM関連
https://qiita.com/KoKeCross/items/144949ba03e5138fc6d5
- 投稿日:2020-09-22T18:06:20+09:00
Express+PostgreSQL+SequelizeをDockerで構築してみる【前編】
前説
将来的にはフロントエンドはVue、バックエンドはExpressのような構成を目指します。
まずはバックエンドでExpress+PostgreSQL+Sequelizeでの環境構築です!①Dockerでコンテナ動作まで
初期ファイル構成
-Dockerfile -docker-compose.yml -app |-- package.jsonDockerfile
Dockefile# イメージ指定 FROM node:latest # 環境変数設定 ENV NODE_ENV="development" # 作業ディレクトリ作成&設定 WORKDIR /src COPY ./app /src RUN npm installdocker-compose.yml
ここでNode.jsのExpress(サーバーサイド)コンテナの構造とDBコンテナの構造を設計します。
- ポート番号は5432が一般的です。
- Volumesではコンテナを破棄しても、データを永続化できます。その為データをコンテナ外に保存します。
docker-compose.ymlversion: '3' services: app: # Dockerfile保存場所 build: context: ./ depends_on: - database image: n-app #volumes設定 volumes: - "./app:/src" # コンテナ名 container_name: n-app # ポート接続 ports: - 3000:5000 environment: PORT: 5000 DB_USER: postgres DB_HOST: database DB_PORT: 5432 DB_NAME: mydatabase tty: true database: image: postgres:12.3 volumes: - ./init-sql:/docker-entrypoint-initdb.d:ro environment: POSTGRES_DB: mydatabase TZ: "Asia/Tokyo" POSTGRES_HOST_AUTH_METHOD: trustpackage.json
自分用です。
Volumesを設定することにより、コンテナ上でInstallしたパッケージもホスト上・コンテナ上にも保存されます。コンテナを破棄した場合もVolumesを設定することにより、package.jsonをもとに'npm install'で破棄したコンテナの環境を復元できます。
- scripts内では"node 〇〇"のコマンドの'〇〇'の部分を設定します。 現状./bin/wwwはExpressの雛形ファイルを生成しないと作成されませんので、注意が必要です。
app/package.json{ "name": "myapp", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www", }, "dependencies": { "cookie-parser": "~1.4.3", "debug": "~2.6.9", "ejs": "~2.5.7", "express": "~4.16.0", "http-errors": "^1.6.3", "morgan": "~1.9.0", "nodemon": "^2.0.4", "pg": "*", "sequelize": "^6.3.5", "sequelize-cli": "^6.2.0" } }自分は以下のサイトを参考にしました。
以下のサイトの方のgithubからcloneして、必要な情報を追加しました。
あらかじめExpressのテンプレートが整っていたので、大変便利でした。https://qiita.com/tamoco/items/caffca436546a1a5fcc8
ではDockerを使ってコンテナを動かしましょう。
Terminal$ docker-compose build Building app Step 1/5 : FROM node:10.12 ---> a2b9536415c2 Step 2/5 : ENV NODE_ENV="development" ---> Using cache ---> 40f981aef1ce Step 3/5 : WORKDIR /src ---> Using cache ---> ec233d742a63 Step 4/5 : COPY ./app /src ---> Using cache ---> 88f269307e53 Step 5/5 : RUN npm install ---> Using cache ---> b22a8c36f08e $ docker-compose up -d $ docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------- n-app node Up 0.0.0.0:3000->5000/tcp ta-app_database_1 docker-entrypoint.sh postgres Up 5432/tcp $ docker exec -it n-app bash root@f195575a066f:/src#上記のところで構築したコンテナに入ることができました。
②Express環境構築
ExpressとはNode.js上で動作するWebアプリのMVC型フレームワークです。
自分の場合は偉大なる先人様のリポジトリからCloneしたため、あらかじめExpressの雛形が揃っていました。Expressの雛形を生成したい場合はこんな感じでしょうか。
# npm install express-generator -g 1. viewをpugファイルで作成したい場合(Default) # express --view=pug myapp viewをejsファイルで作成したい場合 2. express -e myapp次回
https://qiita.com/rockguitar67/items/0020d734201632077cb5
参考文献
Docker-Expressの構築
https://qiita.com/tamoco/items/caffca436546a1a5fcc8https://gitlab.com/tamoco-mocomoco/study-docker-compose/-/tree/master/app/routes
https://qiita.com/yoshiplum/items/129e7ad1ffc3a02b9eb2
Docker-Volumesについて
https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
- 投稿日:2020-09-22T15:52:11+09:00
IKS + Db2 on IBM Cloud で DBアクセスアプリを動かしてみた(7.WebSphere Liberty コンテナの準備)
はじめに
「IKS + Db2 on IBM Cloud で DBアクセスアプリを動かしてみた」の 第7回です。
ここでは、 コンテナの準備ついて記載します。実施内容は以下の通りです。
- WebSphere Liberty コンテナの取得
- 関連ファイルの配置
- Docker ファイルの作成・ビルド
- イメージの IBM Cloud Container Registry への登録
ベースのコンテナイメージとして、 WebSphere Liberty アプリケーションサーバーを利用します。
正確には Open Liberty で、サポートはありませんが無償で検証等で利用することができます。WebSphere Liberty コンテナの取得
ベースとなる Liberty イメージは Docker Hub から取得します。
IBM Cloud CLI を導入した Linux を使って実施します。(Docker も導入されているはずです)Docker Hub から 「WebSphere-liberty」で検索すると
Liberty のイメージがヒットします。内容を見ると、kernel というタグがあることがわかります。
また、イメージの使い方についても簡単な説明がありますので、一通り目を通しておきます。
(後述する、ユーザーID なども記載されています)Docker 導入・起動済みの Linux 上から以下のコマンドで WebSphere-Liberty のイメージを取得します。
# docker pull websphere-liberty:kernel kernel: Pulling from library/websphere-liberty 5d9821c94847: Pull complete a610eae58dfc: Pull complete a40e0eb9f140: Pull complete ce03bf3de33a: Pull complete d26a401e3cfc: Pull complete 7c8d5d75e559: Pull complete deaa1a0c4db8: Pull complete bd803d95ded0: Pull complete 6a3c56e2964a: Pull complete ae3986011977: Pull complete a55f77d5aa37: Pull complete 299a2589f823: Pull complete Digest: sha256:9312eecbfe9d85677857eb40a55cc90c2ccd32005dad2f6a6cbfc4bef5dfbdb3 Status: Downloaded newer image for websphere-liberty:kernel docker.io/library/websphere-liberty:kernel # docker images REPOSITORY TAG IMAGE ID CREATED SIZE websphere-liberty kernel 878137168ed8 5 days ago 311MBこれで、 WebSphere-Liberty のイメージが取得できました。簡単ですね。
関連ファイルの配置
さて、 取得済みの WebSphere-Liberty のイメージをベースに、
第6回で作成したアプリケーションや各種設定なども含めたイメージを作成します。
その準備として、必要なファイルを用意します。作業用ディレクトリ(図中 "." )以下に ツリー上にファイルを配置します。
(作業用ディレクトリ内のディレクトリ構成は違っていても構いません。後述の DockerFile 作成時にコンテナ内の必要な場所にコピーすることになります。以下に、ファイルとその内容について補足していきます。
DockerFile
これは、次の章で記載しますのでここでは割愛します。
LibertyCounter.war
これは、第6回で作成した war ファイルを sftp 等で配置します。(手順略)
db2jcc4.jar
Db2 にアクセスするための JDBC ドライバーです。
DB2 JDBC Driver Versions and Downloads から取得します。 バージョンは、 IBM Cloud でオーダーした Db2 に合わせて v11.1 の物を用います。
(特殊なことはしませんので、多少バージョンが違うものでも稼働すると思います。)ダウンロードの詳細な手順は割愛しますが、 IBM ID が必要になりますのでご留意ください。
2020/09 時点では、ダウンロードできるファイル名は 「v11.1.4fp5_jdbc_sqlj.tar.gz」になりますが、
そのファイルを何度か展開し、 中にある db2jcc4.jar ファイルを取得します。 他のものは不要です。server.xml
これは、WebSphere-Liberty のメインの設定ファイルです。
この中で各種設定を行っています。 まず全文を記載したのち、個別部分に補足を入れます。
下記のもののオリジナルのファイルを入手したい場合、
WebSphere-Liberty イメージからコンテナを1つ生成し、その中の/config
以下から取得してください。<?xml version="1.0" encoding="UTF-8"?> <server description="Default server"> <!-- Enable features --> <featureManager> <feature>jndi-1.0</feature> <feature>webProfile-8.0</feature> </featureManager> <!--For a user registry configuration, configure your user registry. For example, configure a basic user registry using the basicRegistry element. Specify your own user name below in the name attribute of the user element. For the password, generate an encoded password using bin/securityUtility encode and add it in the password attribute of the user element. Then uncomment the user element. --> <basicRegistry id="basic" realm="BasicRealm"> <!-- <user name="yourUserName" password="" /> --> </basicRegistry> <!-- To allow access to this server from a remote client host="*" has been added to the following element --> <httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" httpsPort="9443" /> <!-- Automatically expand WAR files and EAR files --> <applicationManager autoExpand="true"/> <dataSource id="dataSource01" jndiName="jdbc/sample" type="javax.sql.ConnectionPoolDataSource" containerAuthDataRef="dbuser" recoveryAuthDataRef="dbuser"> <properties.db2.jcc serverName="${env.DB_SERVERNAME}" portNumber="${env.DB_PORT}" databaseName="${env.DB_DBNAME}" /> <jdbcDriver> <library> <fileset dir="${DB2_JCC_DRIVER_PATH}" includes="db2jcc4.jar"/> </library> </jdbcDriver> <connectionManager minPoolSize="1" maxPoolSize="2" purgePolicy="EntirePool"> </connectionManager> </dataSource> <authData id="dbuser" user="${env.DB_USERNAME}" password="${env.DB_PASSWORD}"> </authData> </server>
<feature>
部分では、利用する機能を指定します。 Web系の簡単なアプリケーションであれば webProfile-8.0 があれば大丈夫です。(また、他に必要なものがあれば、依存関係に基づき自動的にロードされます)<featureManager> <feature>jndi-1.0</feature> <feature>webProfile-8.0</feature> </featureManager>httpEndpoint では使用するポートを指定しています。
今回は HTTP で 9080 ポートにアクセスします。<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" httpsPort="9443" />以下の設定は データソースの設定です。
JNDI 名として、jdbc/sample
を記載(アプリケーション側でハードコードしたものです。ここでもハードコード…(外に出し忘れました。。。))
env. から始まる変数は環境変数から取得します。
${env.DB_SERVERNAME}
: DB_SERVERNAME 環境変数から DBサーバーの名前を取得します
${env.DB_PORT}
: DB_PORT 環境変数から DB のポート番号を取得します。
${env.DB_DBNAME}
: DB_DBNAME 環境変数から DB名を取得します。<dataSource id="dataSource01" jndiName="|" type="javax.sql.ConnectionPoolDataSource" containerAuthDataRef="dbuser" recoveryAuthDataRef="dbuser"> <properties.db2.jcc serverName="${env.DB_SERVERNAME}" portNumber="${env.DB_PORT}" databaseName="${env.DB_DBNAME}" />次に JDBC Driver の設定です。
変数のうち、 env. ではないものは、 次に説明する server.env ファイルから取得します。
${DB2_JCC_DRIVER_PATH}
: JDBC Driver ファイル (db2jcc4.jar) のコンテナ内でのパスを server.env から取得します。
minPoolSize="1" maxPoolSize="2"
: DB接続プールを最小 1, 最大 2 に設定します。
IBM Cloud の無料 Db2 は最大接続数が 30 のため、最大を 10 などに設定していると、コンテナが増えたときにすぐ最大接続数に到達してエラーになります。そのため、低めの 2 に設定しています。<jdbcDriver> <library> <fileset dir="${DB2_JCC_DRIVER_PATH}" includes="db2jcc4.jar"/> </library> </jdbcDriver> <connectionManager minPoolSize="1" maxPoolSize="2" purgePolicy="EntirePool"> </connectionManager>2つ上のボックスで、 dbuser という形で(ファイル内で)参照している DB関連のユーザー情報です。
これも、 env. を使い、環境変数から DBユーザー名とパスワードを取得しています。<authData id="dbuser" user="${env.DB_USERNAME}" password="${env.DB_PASSWORD}">変数についてまとめると、以下のような感じです。
変数 指定方法 取得先 DBサーバー名 env.DB_SERVERNAME 環境変数 DB_SERVERNAME DBポート番号 env.DB_PORT 環境変数 DB_PORT DB名 env.DB_DBNAME 環境変数 DB_DBNAME DBユーザー名 env.DB_USERNAME 環境変数 DB_USERNAME DBユーザーのパスワード env.DB_PASSWORD 環境変数 DB_PASSWORD JDBC ドライバーパス DB2_JCC_DRIVER_PATH server.env ファイルの DB2_JCC_DRIVER_PATH JNDI名 jdbc/sample (ハードコード) - (変数化し忘れ) server.env
今回、server.env ファイルは JDBC ドライバのパスを指定しているだけです。
他にも同じようなやり方で情報を渡すことが可能です。
変更が多そうなものは環境変数として kubernetes から渡し、イメージとして変更する必要が無いものは server.env で指定すればよいでしょう。server.envDB2_JCC_DRIVER_PATH=/config/jdbc/
これで DockerFile 以外の物の配置は完了したことになります。
Dockerfile
次に、 Dockerfile と
docker build
コマンドでイメージを作成します。
まず、 Dockerfile の内容を確認しましょう。 この Dockerfile の基本は、 Docker Hub 上の
WebSphere-Liberty イメージの説明ページに記載されています。FROM : 先に pull したイメージを指定します。
LABEL maintainer : 作った人のメールアドレスを指定します。(なければ無いで構いません)ADD : ディレクトリや圧縮ファイル等を指定の場所に追加します。 ここでは
./files
以下を/config
以下に追加しています。また、あわせてオーナーを 1001 に変更しています(1001 は WebSphere-Liberty ベースイメージで指定されています)
COPY : LibertyCounter.war ファイルを /config/dropins にコピーし、オーナーを変更しています。※WebSphere-Liberty では、 (設定次第ではありますが) dropins にアプリケーションを入れれば展開・デプロイされます。
configure.sh : これは WebSphere-Liberty イメージに付属のもので、最終的に必要となる WebSphere-Liberty のモジュール等をダウンロードし、起動させるスクリプトです。
DockerfileFROM docker.io/websphere-liberty:kernel LABEL maintainer "shimauma@example.com" ADD --chown=1001:0 ./files /config COPY --chown=1001:0 ./war/LibertyCounter.war /config/dropins RUN configure.sh
Dockerfile の詳細は割愛します。(Web に多くの情報があると思います)
Dockerfile 作成後、それをビルドしてイメージを作成します。
-t
で イメージ名とタグを指定しています。 "." はカレントディレクトリの Dockerfile をビルドする指定です。ビルド# ls Dockerfile files war # docker build -t liberty-counter:v3.0 . Sending build context to Docker daemon 3.879MB Step 1/5 : FROM docker.io/websphere-liberty:kernel ---> 878137168ed8 Step 2/5 : LABEL maintainer "shimauma@example.com" ---> Running in 1b88bab5c511 Removing intermediate container 1b88bab5c511 ---> c4d48a0967a9 Step 3/5 : ADD --chown=1001:0 ./files /config ---> 524464dc8c9f Step 4/5 : COPY --chown=1001:0 ./war/LibertyCounter.war /config/dropins ---> be9224862fcf Step 5/5 : RUN configure.sh ---> Running in 8072633d8513 Removing intermediate container 8072633d8513 ---> 11424458a589 Successfully built 11424458a589 Successfully tagged liberty-counter:v3.0これでビルド完了です。
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE liberty-counter v3.0 11424458a589 48 seconds ago 459MB websphere-liberty kernel 878137168ed8 5 days ago 311MBIBM Cloud container registry への登録
作成したイメージを IBM Cloud container registry へ登録します。
具体的には、 イメージ名に IBM Cloud container registry を付与し、push する、という流れになります。まず、第2回で説明した手順で、IBM Cloud にログインします。(手順省略)
次に、第4回で説明した手順 で、イメージを登録します。イメージ登録は以下のように行います。
まず、tag を付けます。# docker tag liberty-counter:v3.0 jp.icr.io/shimauma_zzzzz/default/liberty-counter:v3.0 # docker images REPOSITORY TAG IMAGE ID CREATED SIZE jp.icr.io/shimauma_zzzzz/default/liberty-counter v3.0 11424458a589 17 minutes ago 459MB liberty-counter v3.0 11424458a589 17 minutes ago 459MB websphere-liberty kernel 878137168ed8 5 days ago 311MB次に push します。
# docker push jp.icr.io/shimauma_zzzzz/default/liberty-counter:v3.0 The push refers to repository [jp.icr.io/shimauma_zzzzz/default/liberty-counter] 438065068251: Pushed 3bf39480c5d8: Pushed 055ed22e3425: Pushed bfd7e29956e1: Pushed dda1b0da9873: Pushed 73bca3f685ab: Pushed 045898917c82: Pushed ea2e902881eb: Pushed 96471ed8874f: Pushed 39f28991b87f: Pushed e243b6bd9c42: Pushed 8553a689df1b: Pushed a2d674c9d7ed: Pushed 4ad5df11bd98: Pushed 6effd95c47f2: Pushed v3.0: digest: sha256:9ea8239c910e2eb7b490822b1463fd9f624442d65a5ea06f4e3cbc89e10c286e size: 3462IBM Cloud Container Registry 上にイメージがあることを確認します。
# ibmcloud cr images イメージをリストしています... リポジトリー タグ ダイジェスト 名前空間 作成日 サイズ セキュリティー状況 jp.icr.io/shimauma_zzzzz/default/liberty-counter v3.0 a5d5a57c1570 shimauma_zzzzz 20 minutes ago 276 MB 1 件の問題 OKセキュリティ状況に1件の問題が出ていますね。
ここでは対応は割愛しますが、内容についてはコンソールで確認することが可能です。2020/09/23) 追記
上記の脆弱性がやっぱり気になりましたので、対応しました。
こちらをご覧ください → 番外編.コンテナイメージのUpdate
お疲れ様でした。
今回はここまでとし、次回は [8.IKS へのコンテナのデプロイ] を実施します。←:IKS + Db2 on IBM Cloud で DBアクセスアプリを動かしてみた(6.DBアクセスアプリケーションの準備 (java))
↑:IKS + Db2 on IBM Cloud で DBアクセスアプリを動かしてみた(1.概要)
→:IKS + Db2 on IBM Cloud で DBアクセスアプリを動かしてみた(8.IKS へのコンテナのデプロイ)
- 投稿日:2020-09-22T14:25:02+09:00
Go+MySQL+Dockerで簡単なCRUDを実装する
はじめに
先日、「業務で使う予定ないとはいえGoぐらいある程度知っておいたほうがいいよな...」と思い、Goを使って簡単なCRUDを実装してみたのでそのやり方を備忘録としてまとめておきます。
基本的には以下のサイトの内容を組み合わせて少しアレンジしたものになっています。Goの勉強をする上でこれらのサイトには非常にお世話になったのでこちらもご参考ください。
DockerでGoの開発環境を構築する
Go / Gin で超簡単なWebアプリを作る
Go言語(Golang)入門~MySQL接続編~
docker-compose MySQL8.0 のDBコンテナを作成する
docker-compose upでMySQLが起動するまで待つ方法(2種類紹介)GoをDockerで立ち上げる
まずはGoをDockerで立ち上げていきます。
作業ディレクトリ直下に
- DockerFile
- docker-compose.yml
- main.go
を作成しますDockerFileFROM golang:latest RUN mkdir /app WORKDIR /appdocker-compose.ymlversion: '3' services: go: build: context: . dockerfile: DockerFile command: /bin/sh -c "go run main.go" stdin_open: true tty: true volumes: - .:/appmain.gopackage main import "fmt" func main() { fmt.Println("Hello, World!") }これで
docker-compose up
を行うとコンソール上にHello, World!と出てくると思います。
これが出ればまずGoの起動は成功です。簡単に各ファイルの解説をします。
・DockerFile
Goのコンテナ(仮想環境)を作成します。
ここでWORKDIR /app
を指定していることで以降の動作をすべて/app
以下で行ってくれます。・docker-compose.yml
DockerFileで作ったコンテナを立ち上げるときの設定などを書きます。
これにより、DockerFileにあるコンテナを立ち上げてその中でgo run main.go
のコマンドを叩いてmain.goを起動します・main.go
Goに関する処理はここに書いていきます。今回はHello, World!を出力するだけで終了しています。GoでWebページを作成する
とりあえずGoの起動ができたので次はGoを使ってWebページを作っていきましょう。
今回はGinというフレームワークを使ってみます。
- DockerFileにインストールを追加
- docker-compose.ymlにportsの記述を追加
- main.goの内容を書き換え
- templates/index.htmlを作成
を行ってください。DockerFileFROM golang:latest RUN mkdir /app WORKDIR /app RUN go get github.com/gin-gonic/gindocker-compose.ymlversion: '3' services: go: build: context: . dockerfile: DockerFile command: /bin/sh -c "go run main.go" stdin_open: true tty: true volumes: - .:/app ports: - 8080:8080main.gopackage main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() router.LoadHTMLGlob("templates/*.html") router.GET("/", func(ctx *gin.Context){ ctx.HTML(200, "index.html", gin.H{}) }) router.Run() }templates/index.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Sample App</title> </head> <body> <h1>Hello World!!!</h1> </body> </html>これで
docker-compose build docker-compose up -dを行ってしばらく待ってから
http://localhost:8080にアクセスするとHello World!と表示されると思います。今回やったことを解説します。
今回はGinというフレームワークを追加しました。
GinはDockerFileでコンテナ作成後にgo get github.com/gin-gonic/gin
というコマンドでインストールされ、main.goで呼び出されます。
そしてmain.goの中でtemplatesの中身が読み取られ、router.GET("/", func(ctx *gin.Context){ ctx.HTML(200, "index.html", gin.H{}) })によってroot("/")に対してtemplates/index.htmlが紐づけられることになります。
ちなみにrouter.GETの第一引数("/")を"/test"などに変えると、http://localhost:8080ではなく、http://localhost:8080/testでindex.htmlが表示されるようになります。最後にdocker-compose.ymlにportを追加することでlocalhost:8080へのアクセスを可能にしています。
DockerでMySQLを起動する
ここまででGoでのWebページ作成はできるようになりました。しかし、実際にはWebサービスを作るときにDBとの接続は避けて通れない内容になってきます。
そこで次はDockerを使ってMySQLを立ち上げていきます。まずはdocker-compose.ymlに
・dbコンテナについての記述
・volumeの記述
を追加してください。docker-compose.ymldb: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: go_database MYSQL_USER: go_test MYSQL_PASSWORD: password TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - db-data:/var/lib/mysql - ./db/my.cnf:/etc/mysql/conf.d/my.cnf ports: - 3306:3306 volumes: db-data: driver: localまた、dbディレクトリを作り、その中にmy.cnfファイルを作成してください。
my.cnf[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_bin default-time-zone = SYSTEM log_timestamps = SYSTEM default-authentication-plugin = mysql_native_password [mysql] default-character-set = utf8mb4 [client] default-character-set = utf8mb4(この辺は参考ページそのままです。ログに関する部分だけなぜか上手くいかなかったので外しています)
ここまでやって
docker-compose up -d
をやるとMySQLのコンテナも立ち上がるはずです。
設定の記述しかないのでここの説明は省略します。GoとMySQLを接続する
MySQLが立ち上がったので早速Goにつないでみます。
今回は接続にsqlドライバーとGORMというフレームワークを使います。
- DockerFileにインストールの追加
- docker-compose.ymlに依存関係の記述を追加
- main.goにDB接続の処理を追加
を行ってください。DockerFileFROM golang:latest RUN mkdir /app WORKDIR /app RUN go get github.com/gin-gonic/gin RUN go get github.com/go-sql-driver/mysql RUN go get github.com/jinzhu/gormdocker-compose.ymlversion: '3' services: go: build: context: . dockerfile: DockerFile command: /bin/sh -c "go run main.go" stdin_open: true tty: true volumes: - .:/app ports: - 8080:8080 depends_on: - "db" db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: go_database MYSQL_USER: go_test MYSQL_PASSWORD: password TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - db-data:/var/lib/mysql - ./db/my.cnf:/etc/mysql/conf.d/my.cnf ports: - 3306:3306 volumes: db-data: driver: localmain.gopackage main import ( "fmt" "time" "github.com/gin-gonic/gin" "github.com/jinzhu/gorm" _ "github.com/go-sql-driver/mysql" ) func main() { db := sqlConnect() defer db.Close() router := gin.Default() router.LoadHTMLGlob("templates/*.html") router.GET("/", func(ctx *gin.Context){ ctx.HTML(200, "index.html", gin.H{}) }) router.Run() } func sqlConnect() (database *gorm.DB) { DBMS := "mysql" USER := "go_test" PASS := "password" PROTOCOL := "tcp(db:3306)" DBNAME := "go_database" CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo" count := 0 db, err := gorm.Open(DBMS, CONNECT) if err != nil { for { if err == nil { fmt.Println("") break } fmt.Print(".") time.Sleep(time.Second) count++ if count > 180 { fmt.Println("") fmt.Println("DB接続失敗") panic(err) } db, err = gorm.Open(DBMS, CONNECT) } } fmt.Println("DB接続成功") return db }これで
docker compose up
を行い、コンソールに「DB接続成功」と出たら成功です。追加された内容はsqlConnectがメインなのでそこを解説します。
func sqlConnect() (database *gorm.DB) { DBMS := "mysql" USER := "go_test" PASS := "password" PROTOCOL := "tcp(db:3306)" DBNAME := "go_database" CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo" count := 0 db, err := gorm.Open(DBMS, CONNECT) if err != nil { for { if err == nil { fmt.Println("") break } fmt.Print(".") time.Sleep(time.Second) count++ if count > 180 { fmt.Println("") fmt.Println("DB接続失敗") panic(err) } db, err = gorm.Open(DBMS, CONNECT) } } fmt.Println("DB接続成功") return db }前半部はDBに接続するための情報を定義しています。docker-compose.ymlで設定した内容を入力してください。
その後、db, err := gorm.Open(DBMS, CONNECT)
でDBに接続します。しかし、MySQLの起動時間によってはこのコマンドが実行される時点でMySQLの準備が完了していない場合があります。
そこでこのコードでは2つの対策をしています。1つめはdocker-compose.ymlでの依存関係の設定です。
ここでdepends_onを設定したことにより、dbコンテナが立ち上がってからgoコンテナが立ち上がるようになります。2つめはリトライ処理です。
dbコンテナが起動してからもMySQLが立ち上がるまでに時間がかかるのでもしDBにつながらなかった場合に1秒待ってからリトライするようにしています。
これだと本当にエラーのときにリトライし続けてしまうので適当な回数でエラーを返すようにします。このコードでは3分つながらなかったらエラーになるようになっています。CRUDを実装する
ついにMySQLにもつながるようになったので最後にCRUDの処理を実装して実際の流れをみていきましょう。
あと変更するのはmain.goとindex.htmlのみです。
- Userの定義を作成
- マイグレーション
- post処理の実装
- ユーザー追加フォーム、ユーザー削除ボタンの実装
をやっていきます。main.gopackage main import ( "fmt" "strconv" "time" "github.com/gin-gonic/gin" "github.com/jinzhu/gorm" _ "github.com/go-sql-driver/mysql" ) type User struct { gorm.Model Name string Email string } func main() { db := sqlConnect() db.AutoMigrate(&User{}) defer db.Close() router := gin.Default() router.LoadHTMLGlob("templates/*.html") router.GET("/", func(ctx *gin.Context){ db := sqlConnect() var users []User db.Order("created_at asc").Find(&users) defer db.Close() ctx.HTML(200, "index.html", gin.H{ "users": users, }) }) router.POST("/new", func(ctx *gin.Context) { db := sqlConnect() name := ctx.PostForm("name") email := ctx.PostForm("email") fmt.Println("create user " + name + " with email " + email) db.Create(&User{Name: name, Email: email}) defer db.Close() ctx.Redirect(302, "/") }) router.POST("/delete/:id", func(ctx *gin.Context) { db := sqlConnect() n := ctx.Param("id") id, err := strconv.Atoi(n) if err != nil { panic("id is not a number") } var user User db.First(&user, id) db.Delete(&user) defer db.Close() ctx.Redirect(302, "/") }) router.Run() } func sqlConnect() (database *gorm.DB) { DBMS := "mysql" USER := "go_test" PASS := "password" PROTOCOL := "tcp(db:3306)" DBNAME := "go_database" CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo" count := 0 db, err := gorm.Open(DBMS, CONNECT) if err != nil { for { if err == nil { fmt.Println("") break } fmt.Print(".") time.Sleep(time.Second) count++ if count > 180 { fmt.Println("") panic(err) } db, err = gorm.Open(DBMS, CONNECT) } } return db }templates/index.html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Sample App</title> </head> <body> <h2>ユーザー追加</h2> <form method="post" action="/new"> <p>名前<input type="text" name="name" size="30" placeholder="入力してください" ></p> <p>メールアドレス<input type="text" name="email" size="30" placeholder="入力してください" ></p> <p><input type="submit" value="Send"></p> </form> <h2>ユーザー一覧</h2> <table> <tr> <td>名前</td> <td>メールアドレス</td> </tr> {{ range .users }} <tr> <td>{{ .Name }}</td> <td>{{ .Email }}</td> <td> <form method="post" action="/delete/{{.ID}}"> <button type="submit">削除</button> </form> </td> </tr> {{ end }} </ul> </body> </html>これで
docker-compose up -d
を行い、http://localhost:8080にアクセスするとユーザー登録フォームが現れ、ユーザーを登録すると下に登録したユーザーの情報が表示されるようになります。
また、コンテナを削除して上げ直しても登録されたユーザーは削除されず、ユーザー一覧に表示が残るようになります。それでは追加部分の解説をしていきます。
まず、main.goでUserという構造体を作成しています。gorm.Model
でidなどモデルに必要な内容をUserに入れ、更にUser特有のname, emailを追加しています。
この構造はdb.AutoMigrate
によってDBに反映されます。続いて各パスでのCRUD処理を実装していきます。
rootパスではユーザー一覧を取得します。
db.Find(&users)でDB内にあるユーザー一覧をUser構造として取得します。
間にOrderを挟むことで取得時に古いユーザーが上に来るようにしています。
最後に取得したユーザーをindex.htmlに渡しています。/newパスではフォームの内容をもとにユーザーを作成しています。
ctx.PostFormでフォームによってsubmitされた内容を取得し、その内容をdb.Createで永続化しています。
処理が終わったらrootにリダイレクトします。/deleteパスではidを指定してユーザーを削除しています。
こちらではURLにユーザーのidを指定しているのですが、同様にctxから取得します。
そしてその内容からdb.Firstでユーザーを取得し、db.Deleteで該当のユーザーを削除します。
ここで、idはstringで渡されているのでstrconv.Atoiでint型に変換していることに注意してください。index.htmlでは一般的なhtmlの書き方でformとtableを作成しています。
ここで、{{ range .users }}
という形でmain.goから渡されたusersを受け取っています。おわりに
今回はGoでのWebサービス開発の導入としてGo+MySQL+Dockerで簡単なCRUDを実装してみました。あくまで練習なのでバリデーションとか細かい制御などは考えていません。
今回行った内容は初歩ではありますが、この内容を広げて複雑化していくことで実際にWebサービスを作ることができると思います。
もしGoで何か作ってみたいと考えている方がいらっしゃったらぜひ参考にしてみてください!
- 投稿日:2020-09-22T09:10:31+09:00
【SRE/Docker】Dockerizeでの起動制御
docker-compose
を使用する際にDBの接続を待ちたいなどがあった時に便利なDockerize
について書いていきます。起動制御の選択肢
下記をみる限り、
wait-for-it
、dockerize
の2つが有効なようです。
Compose における起動順の制御 — Docker-docs-ja 17.06 ドキュメントDocker Compose でMySQLが起動するまで待つ - Qiita
docker-compose upでMySQLが起動するまで待つ方法(2種類紹介) - QiitaDockerize
Dockerizeとは
GitHub - jwilder/dockerize: Utility to simplify running applications in docker containers
使う
dockerfile
とdocker-compose.yaml
を修正します。ENV DOCKERIZE_VERSION v0.6.0 RUN apk add --no-cache openssl \ && wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
dockerize
のコマンドをdocker-compose
で定義します。
dockerize -wait tcp://db:5432
というコマンドで、依存関係のあるアプリケーションの起動を待つことができるようになります。entrypoint: - dockerize - -timeout - 60s - -wait - tcp://mysql:3306 command: ./main # goでの実行
- 投稿日:2020-09-22T05:40:35+09:00
Windows10 HomeでもDockerの環境構築できる !! WSL1 からWSL2に変更する際に出るエラー error : 0x800701bc の解決方
Docker 初学者必見!!
はじめに
・Windows10 ユーザー
・Dockerの環境構築をしたい
・WSL2の設定に困っている
人に向けた、記事になります。
公式サイト
これにそって進めます。
(※ページの下の方にはいくつかのトラブルシューティングが記載されています。)Windows10 Home のバージョンを確認してください!
error : 0x800701bc の解決方!
同じようなエラーが出た人は、Linux kernelのupdateをしなければ、Linuxが起動しません。
そこで、GitHubで解決方を探していたところ、海外の方が解決していたのでその記事を掲載します。
参考にしたGitHubのページ
( https://github.com/microsoft/WSL/issues/5393 )
要は、kernelのupdateが必要
こちらのサイトから、updateができます!!
https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-packageインストーラ起動させれば、解決!
これで、Linuxを起動させることができます??????
あとは、Dockerのインストーラを起動して、順に進めれば完了です
Dockerの学習に役立てばうれしいです
引用
- 投稿日:2020-09-22T05:40:35+09:00
Windows10 HomeでもDockerの環境構築ができる !! WSL1 からWSL2に変更する際に出るエラー error : 0x800701bc の解決方! (2020年9月)
Docker 初学者必見!!
はじめに
・Windows10 ユーザー
・Dockerの環境構築をしたい
・WSL2の設定に困っている
人に向けた、記事になります。
公式サイト
これにそって進めます。
(※ページの下の方にはいくつかのトラブルシューティングが記載されています。)Windows10 Home のバージョンを確認してください!
error : 0x800701bc の解決方!
同じようなエラーが出た人は、Linux kernelのupdateをしなければ、Linuxが起動しません。
そこで、GitHubで解決方を探していたところ、海外の方が解決していたのでその記事を掲載します。
参考にしたGitHubのページ
( https://github.com/microsoft/WSL/issues/5393 )
要は、kernelのupdateが必要
こちらのサイトから、updateができます!!
https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-packageインストーラを起動させれば、解決!
これで、Linuxを起動させることができます??????
あとは、Dockerのインストーラを起動して、順に進めれば完了です
Dockerの学習に役立てばうれしいです
引用