20200812のdockerに関する記事は19件です。

Debian apt update GPG error

経緯

私はDockerをよく使っていて、公式imageを用いるが、大体はdebianが親になっていることが多い。
そして、メンテナンスされていないimageも多々有り、祖先のdebianイメージのバージョンがどんどん古くなってしまっている。危ない。

そんな古い公式imageを利用することになった。

問題

古いdebianイメージ(私の場合はjessie)でapt updateをするといかのようなエラーが出た

$ apt update
...
W: GPG error: http://security.debian.org jessie/updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY XXXXXXXXXX
  • debian(なのかaptなのか)は、セキュリティのためパッケージが本物であることを検証するためにGPGという仕組みを利用しているらしい。
  • 古いdebianのaptは、その鍵の有効期限が切れていることがあるらしく、今回のようなエラーが出るらしい。
  • GPGというのは公開鍵暗号方式を用いた署名の仕組みらしい。
  • SSLなどと違い第三者機関としての認証局は無く、俺自身が認証局となることだ…という感じらしい。
  • 自分が認証するので、自分の鍵で他人の鍵に署名したりしてもらったりするらしい。
  • 署名していいケースというのは、物理的に対象の人物と出会い、十分に身分を証明してもらったときのみらしい。
  • 対処法をググると腐るほど出てくるが、エラーの鍵をinstallしてしまえばいいという手順がかいてある。しかし私にはそんなことをして良いか(安全か)全然わからん。

だいたい私は今何度「らしい」といったのか。私はただ単にaptでパッケージをインストールしたいだけだというのに。何なんじゃもう。ブラックボックスで使わせてくれよもう

理解度が足りて無く、それをやっていいという納得が得られないので、GPGについて深く理解するしかなさそうだ。

・・・と思っていたところ

$ apt-get update 
$ apt-get install debian-keyring debian-archive-keyring 
$ apt-get update

で治ったではないか。
これが何なのか。正直わからん。

https://packages.debian.org/ja/jessie/debian-keyring

Debian プロジェクトは、偽造を防ぐために開発者が自分のパッケージであることの 表明に GnuPG による電子署名を行うことを要求しています。 本パッケージには、GnuPG のキーリングと Debian 開発者 (アップロード権を持つ者と持たない者) や Debian メンテナの GnuPG 鍵が含まれています。

らしい。

だが、これがセキュリティ的にだめじゃないことだけはわかる。
よくわかっていない私は特に何も認証操作をしていないからだ。

WARNING: The following packages cannot be authenticated!
  debian-archive-keyring debian-keyring

って出てたのでもうダメだ。
もうだめなのだが、もうこれでいいと思うことにした。(後述)


Dockerでの話

Dockerfile
FROM xxxx # メンテナンスを放棄された、祖先に鍵の有効期限が切れた可愛そうなdebianを持つimage

RUN apt-get update \
&& apt-get install -y --force-yes debian-keyring debian-archive-keyring \
&& apt-get update \
&& apt-get install -y \
* \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

という感じになる。
--force-yesWARNING: The following packages cannot be authenticated!を無視する。

なんだか自己改造しているロボットみたいだ。

今回私は仕方なくメンテナンスを放棄されたimageを使ったが、普通は潔く最新のimage使ったいい。公式imageに無いなら自分で作ったほうがいい。

こういうことがないようにDockerhubにimageを公開する開発者の方々に置かれましては、Dockerhubのbuild settingsで「祖先のimageが更新されたら自動で更新する」ようにしておいてほしい。


追記

https://wiki.debian.org/SecureApt#Other_problems

に公式マニュアルっぽいものを発見した。
ここに書いてある対処法はdebian-archive-keyringパッケージの更新だ。

しかし、apt-get install debian-archive-keyringを実行するとThe following packages cannot be authenticated!と出る。

そもそもdebian-archive-keyringパッケージというのはaptの署名鍵を管理するプログラムだ。
とはいえ、こいつもaptパッケージだ。つまりこいつ自身の署名鍵が期限切れしてたらどうしようもないのだ。

普通に使うときは、期限切れの前に余裕を持って更新された鍵が配布されるなり、こいつだけ時期をずらして更新されたりするのだろう。(と推測する)

本末転倒だ。ブートストラップ問題というやつだ。もうダメだ。

このことについてのQ&Aが見つけられて

https://serverfault.com/a/337283

言ってることは、やっぱりこれはブートストラップ問題なので、

  • ちゃんとしたいなら頑張って鍵信用できる方法でinstallしなさい
  • ちゃんとしなくていいならapt-get install debian-archive-keyringを行って警告は無視しなさい

ということだ。
そろそろ私も疲れてきたのでもうちゃんとしたくはない。
このへんで記事は締めくくろうと思う。

ただ、Docker使っているのだから最新のイメージの中の秘密鍵をexportしてくれば、ちゃんとできる気がしますな。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでImageMagickを使える環境を整備する

DockerでImageMagickを使える環境を整備する

DockerでUbuntuの環境整備

imageのpull

$ sudo docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
Digest: sha256:5d1d5407f353843ecf8b16524bc5565aa332e9e6a1297c73a92d3e754b8a636d
Status: Image is up to date for ubuntu:latest
docker.io/library/ubuntu:latest

imageの確認

$ sudo docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
ubuntu                            latest              1e4467b07108        2 weeks ago         73.9MB

コンテナの起動

sudo docker run -it ubuntu

オプションの-itについてはこの方の記事が参考になりました。
docker run -it の「-it」とはなにか
とりあえず-itをつけておけばbashのような端末が使えます。

ubuntuの仮想環境内でImageMagickのインストール

# apt update

とりあえずupdateしないとインストールできないので。終わったら

# apt-get -y install imagemagick

結構時間がかかりますが気長に待ちましょう。途中住んでる地域を聞かれるので適当に答えましょう。

終わったら

# which convert
/usr/bin/convert

Imagemagickがインストールできていることが確認できました。

イメージの保存

ctrl p ctrl q でコンテナを起動したままコンテナから一旦抜ける。
起動中のコンテナを確認

$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
0ab73f0f184a        ubuntu               "/bin/bash"         20 minutes ago      Up 20 minutes                                hungry_joliot

0ab73f0f184aというIDのコンテナから新しいimageをubuntu/imagemagickという名前で作って保存する

$ sudo docker commit 0ab73f0f184a ubuntu/imagemagick

imageができたか確認

$ sudo docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
ubuntu/imagemagick                latest              fdc18d136f6f        8 seconds ago       247MB

できていることが確認できた。
imageのcommitについては以下の記事を参考にさせていただきました。
Dockerでcommitしてみる

再度起動中のコンテナに入ってコンテナを終了する

起動中のコンテナの確認

$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
0ab73f0f184a        ubuntu               "/bin/bash"         27 minutes ago      Up 27 minutes                                hungry_joliot

起動中のコンテナを停止する。psコマンドで出てきたcontainerIDの最初5文字くらいをstopの後に入れる。

$ sudo docker stop 0ab73f

停止しているか確認

$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES

ちゃんと停止していることが確認できた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ec2使用時にdockerの容量がいっぱいになった際の対処法

dockerを起動しようとしたら以下のエラーが発生した。

$ docker-compose build
Failed to write all bytes for _codecs_cn.so
fwrite: No space left on device



容量不足により起動不可となっているようだ。
以下のコマンドを叩くと容量を喰っているファイルを見つけることができる。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         474M     0  474M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M   13M  479M    3% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  8.0G   22M  100% /  //容量不足
tmpfs             99M     0   99M    0% /run/user/1001

/dev/xvda1 というファイルがかなりの容量を占めている。
logなどの不要ファイルを削除しても解決できる場合もあるが、今回はEC2で使用しているEBSのサイズを変更して対応する。
無料利用枠のt2.microでは8GBがデフォルトで、今回は16GBに変更する。(若干料金が発生する:約1$/月)

AWSのEC2に移動し、ボリュームに移動する。
目的のボリュームを選択した状態で アクション→ボリュームの変更→サイズを変更(任意の数字:今回は16)→変更
変更が反映され状態がin-useになったらOK。


あとはターミナルからEC2にログインし、以下のコマンドを順に実行していく。

$ sudo growpart /dev/xvda 1
CHANGED: partition=1 start=4096 old: size=16773087 end=16777183 new: size=33550303 end=33554399

xvdaが16GBに変更されていることが確認できる。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  16G  0 disk 
└─xvda1 202:1    0   8G  0 part /

ファイルシステム上は変更されていないので次のコマンドで変更できる。

$ sudo xfs_growfs /dev/xvda1
meta-data=/dev/xvda1             isize=512    agcount=4, agsize=524159 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1 spinodes=0
data     =                       bsize=4096   blocks=2096635, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2096635 to 4193787

変更が反映されていたら以下のように容量が8GB→16GBに変更されており、
使用率が低減できていることが確認できる。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  16G  0 disk 
└─xvda1 202:1    0  16G  0 part /

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         474M     0  474M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M   13M  479M    3% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1        16G  5.6G   11G   35% /
tmpfs             99M     0   99M    0% /run/user/1001


無事に起動できるようになり、容量にもかなりの余裕ができた。

$ docker-compose build
Building web
:
Successfully built 99f5770ca10a
Successfully tagged app_web:latest

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         474M     0  474M    0% /dev
tmpfs            492M     0  492M    0% /dev/shm
tmpfs            492M   14M  479M    3% /run
tmpfs            492M     0  492M    0% /sys/fs/cgroup
/dev/xvda1        16G  8.1G  8.0G   51% /    //容量に余裕ができた
tmpfs             99M     0   99M    0% /run/user/1001


参考記事
https://www.souichi.club/aws/aws-ebs/
CentOS 7からは、xfs_growfsというコマンドを使うことになったようだ。
https://qiita.com/ponsuke0531/items/04153c6228516e48a55e

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Proxy環境で VS Code Remote Development + Java開発をさせてくれ

こん**は。

突然ですが、VS Code で しかも実行環境はコンテナで Java、開発したいですよね。
でも邪魔してくるやつが居ますよね。そう Proxy です。

社内Proxyの場合企業ごとに状況が異なると思いますが、うまくいった例としてすこしでもあなた様の参考になれば……。

:muscle: モチベーション

  • Proxy 環境下で Docker を利用した VS Code の Remote Development をしたい!
  • いろんなレイヤからプロキシの設定を求められる……:japanese_ogre:
  • プロキシに悩める人に、少しでもヒントとなれば!

:computer: 動作確認環境(ホスト)

  • OS
    • Windows 10
  • Docker
    • Docker for Windows
  • VS Code
    • 1.46.0

:hand_splayed: 前提

  • VS Code と Docker for Windows がインストールされていること
  • Docker for Windows のプロキシ設定は既に完了していること

:file_folder: 用意するファイルたち

Dockerfile

Remote Development 環境の Dockerfile はこちら。

${workspaceFolder}/.devcontainer/Dockerfile
FROM adoptopenjdk/openjdk11:jdk-11.0.7_10-centos

# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser"
# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
# will be updated to match your local UID/GID (when using the dockerFile property).
# See https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=${USER_UID}

ARG MAVEN_VERSION=3.6.1
ARG MAVEN_SHA=b4880fb7a3d81edd190a029440cdf17f308621af68475a4fe976296e71ff4a4b546dd6d8a58aaafba334d309cc11e638c52808a4b0e818fc0fd544226d952544

# プロキシ設定
# devcontainer.json で指定する
# see https://code.visualstudio.com/docs/remote/containers-advanced#_option-2-use-an-env-file
ARG PROXY=${PROXY}
ENV http_proxy=${PROXY}
ENV https_proxy=${PROXY}
ENV HTTP_PROXY=${PROXY}
ENV HTTPS_PROXY=${PROXY}

RUN echo "building..." \
    #
    # Create a non-root user to use if preferred
    # see https://aka.ms/vscode-remote/containers/non-root-user.
    && groupadd --gid ${USER_GID} ${USERNAME} \
    && useradd -s /bin/bash --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} \
    #
    # Install Maven
    && mkdir -p /usr/share/maven /usr/share/maven/ref \
    && curl -fsSL -o /tmp/apache-maven.tar.gz https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
    && echo "${MAVEN_SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - \
    && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
    && rm -f /tmp/apache-maven.tar.gz \
    && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn \
    #
    # Maven User Settings
    # /home/vscode/.m2/ を作成し、vscode ユーザに所有者変更
    && mkdir /home/${USERNAME}/.m2 \
    && chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.m2

# Maven パス設定
ENV MAVEN_HOME /usr/share/maven

開発に Maven を利用しているので、 Maven をインストールしています。
また、本番実行環境が CentOS 7 系のため、Remote Development 環境も CentOS 7 系 + Java をベースイメージとして使っています。

${PROXY} とありますが、こちらは後述する devcontainer.json からイメージビルド時に渡してしまいます。
ビルド時にイメージに埋め込むのはちょっと…とは思いましたが、まあ各人の開発環境でイメージを直接共有する予定もないので、この状態でも問題ないと判断しました。

devcontainer.json

続いて、Remote Development 環境の設定ファイルである devcontainer.json です。

${workspaceFolder}/.devcontainer/devcontainer.json
{
  "name": "Sample Project",
  "dockerFile": "Dockerfile",

  // docker build(イメージ作成)時の設定
  // see - https://github.com/microsoft/vscode-remote-release/issues/46
  "build": {
    "args": {
      // TODO: 環境に合わせて記載
      "PROXY": "http://USER:PASS@HOST:PORT"
    }
  },

  // コンテナ作成時の VS Code のデフォルト設定値(ワークスペースの設定が勝つため注意)
  "settings": { 
    "terminal.integrated.shell.linux": "/bin/bash",
    "java.home": "/opt/java/openjdk",
    // Language Server
    // see - https://github.com/redhat-developer/vscode-java/wiki/Using-a-Proxy
    // TODO: 環境に合わせて記載
    "java.jdt.ls.vmargs": "-Dhttp.proxyHost=HOST -Dhttp.proxyPort=PORT -Dhttp.proxyUser=USER -Dhttp.proxyPassword=PASS -Dhttps.proxyHost=HOST -Dhttps.proxyPort=PORT -Dhttps.proxyUser=USER -Dhttps.proxyPassword=PASS",
    // see - https://github.com/redhat-developer/vscode-java/issues/399#issuecomment-355113311
    "java.import.gradle.enabled": false
  },

  // コンテナ作成時にインストールされる VS Code 拡張(IDで指定)
  "extensions": [
    // Java
    "vscjava.vscode-java-pack",  // Java Extension Pack
  ],

  // コンテナ作成後に実行されるコマンド
  "postCreateCommand": "./.devcontainer/postCreateCommand.sh",

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  "forwardPorts": [
    8090 // app
  ],

  // Dockerコンテナログインユーザ
  "remoteUser": "vscode",
}

ポイントは settingsjava.jdt.ls.vmargs です。
↓ のページにあるとおり、 Java Language Server に対して PROXY を設定してあげる必要があるようです。

Using a Proxy - redhat-developer/vscode-java - GitHub

Maven 設定ファイル

Maven は Maven で Proxy の設定を行います。

自分はこれらのファイルを .devcontainer フォルダ内に置きました。
後述するシェルで vscode ユーザホーム直下の .m2 フォルダ/home/vscode/.m2)にコピーします。

settings.xml
<proxies>
  <proxy>
    <!-- TODO: 環境に合わせて記載 -->
    <id>sample</id>
    <active>true</active>
    <protocol>http</protocol>
    <host>proxy.sample.com</host>
    <port>1234</port>
    <username>user</username>
    <password>{encrypted-password=}</password>
    <nonProxyHosts>localhost</nonProxyHosts>
  </proxy>
</proxies>
settings-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<settingsSecurity>
    <!-- TODO: 環境に合わせて記載 -->
    <master>{encrypted-master-password=}</master>
</settingsSecurity>

参考:Password Encryption - Maven

※ ここはもう少しなんとかしたかった…ができませんでした。環境依存でうまくパスワード類を埋めてやりたかったのですが……。うまい方法をご存じの方はぜひコメントでご指摘いただけると……。

シェル

${workspaceFolder}/.devcontainer/postCreateCommand.sh
#!/usr/bin/bash

# 初期処理
echo ''
echo '--------------------------------------------'
echo ' Init'
echo '--------------------------------------------'
# 設定・基本情報
MAVEN_SETTING_DEST=`realpath ~/.m2/`
echo '基本情報'
echo "作業ディレクトリ: `pwd`"
echo "maven: `mvn --version`"

# Mavenの設定ファイルをコピー
echo ''
echo '--------------------------------------------'
echo ' Copy Maven settings files'
echo '--------------------------------------------'
echo 'コピーを開始します。'
cp ./.devcontainer/settings.xml ./.devcontainer/settings-security.xml ${MAVEN_SETTING_DEST}
echo 'コピーが完了しました。'
ls -la ${MAVEN_SETTING_DEST}

# 終了処理
echo ''
echo '--------------------------------------------'
echo ' Exit'
echo '--------------------------------------------'
echo '処理を終了します。'
exit 0

.devcontainer/devcontainer.jsonpostCreateCommand で指定しているシェルです。コンテナ作成後に叩かれます。

内容としては、Maven 設定ファイルたちを vscode ユーザホーム直下の .m2 フォルダ/home/vscode/.m2)にコピーして差し上げております。
これだけだったらシェルに切り出さずに devcontainer.jsonpostCreateCommand に直接書けばいいと思いますが……:angel:

:rocket: 起動する

あとは普通に起動してあげるだけ!
本筋とはズレるので詳細は割愛しますが、ざっくりと…

  • VS Code の Remote - Containers 拡張をインストールし、
  • Docker を起動して
  • VS Codeが「ここコンテナで開けそうだよ?」って聞いてくるので Reopen in Container

ですね!

このとき .devcontainer フォルダが VS Code ワークスペースのルートフォルダ直下にある必要がありそうです。

:end: 終わりに

ちなみに…自分はマシンのスペックが足らず、最終的にこの方式での開発は諦めました :angel:
が、環境構築が一気にしやすくなりめっちゃ便利だと思うので、スペックに問題なければぜひ前向きに検討すべきと思います!

Proxy 環境下 + VS Code Remote Development + Java な人に、少しでも力なっていれば幸いです。

それでは!

:link: リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GCPでのディープラーニング学習環境構築方法

GCP(Google Cloud Platform)でディープラーニング学習環境構築方法

背景

 ようやくDockerでのディープラーニングGPU学習環境構築に成功した @karaage0703 。疲れを癒す間も無く、ディープラーニングの帝王Google社のデベロッパーアドボケイトから、新たなる天啓がくだる。

 喜び勇んで、GCPの無料アカウントを作成した @karaage0703 そこには、おびただしい数のメニューと、膨大なドキュメント…からあげのGoogleとの戦いは始まったばかりだ!(戦ってません)

GCPでディープラーニング学習環境を構築するメリット

 以下のようなメリットがあります。

  • 様々なフレームワーク(TensorFlow/PyTorch)、バージョンの使い捨ての学習環境を一瞬で構築できる
  • 計算リソースを、文字通り一瞬で確保できる
  • 家にでかいパソコンを置いて熱々になることが無い

 Googleの無料枠で試せる範囲での記事です。無料枠だとGPUは使えないので、GPUは使っていませんが、基本的な流れは同じです(多分)

この記事の前提(必要なもの)

  • 基礎的なLinuxコマンドの知識
  • ネットに繋がるPC(Google ChromeブラウザがあればOK)

GPUでのディープラーニング学習環境構築の流れ

 最初にGCPに登録した後、以下の2通りの方法があります。

  • ComputeEngineで学習環境を構築
  • AI Platformで学習環境を構築

 ComputeEngineでVMを立ち上げると、自分の好きな環境が作れます。自由度が高い反面、Jupyter Notebookへのアクセスなどは、設定が色々大変です。

 AI Platformは、あらかじめセットアップされた環境を使えて、起動すればJupyter Labに一瞬でアクセスしてディープラーニングを始めることができます。

 使用感覚はGoogle Colaboratoryに近いと思います。Google Colaboratoryの詳細は以下ブログ記事参照ください。
Google Colaboratoryを使えば環境構築不要・無料でPythonの機械学習ができて最高

 お手軽に試したいならAI Platformがオススメです。この後、GCP登録から順に説明していきます。とりあえず速く試したい人は「ComputeEngineで学習環境を構築」を飛ばして読んでください。

 

GCPに登録

 GCPの公式サイトにアクセスします。

 無料という文字にフラフラ吸い寄せられてクリックして登録しましょう。クレジットカードの情報は必要ですが、無料枠を使い切ってもそのまま課金されることはないようです。

ComputeEngineで学習環境を構築

Compute Engineにアクセスします。

 VMインスタンスと表示されるはずなので「作成」をクリックしましょう。

gcp_vm_01.png

 VMインスタンスは、ブートディスクの設定だけ、以下のようにUbuntu 18.04LTSを指定しましょう。

gcp_image.png

 他はそのままでOKです。GPUの指定の設定もあるのですが、無料枠だと設定できません。課金したらGPUを指定できるようになります。

 しばらくまつとVMが立ち上がります。もうこの時点で、Ubuntuがインストールされたマシンが自由に使えるようになったことになります。

 以下のように表示されるので「SSH」の横の下矢印をクリックしましょう。以下のように表示されるので「ブラウザウィンドウで開く」を選びましょう(そのままSSHをクリックしてもOKです)。

gcp_01.jpg

 以下のようにブラウザでクラウド上のサーバにアクセスできます。

gcp_02.png

 このまま学習環境をaptコマンドやpipコマンドで構築すれば、立派なディープラーニング学習環境です。

Dockerを使って環境構築

 VMインスタンス上でDockerを使えば、環境が簡単に構築できます。詳細は以下記事参照ください。

DockerでのディープラーニングGPU学習環境構築方法

 Docker自体は、以下コマンド実行してインスタンスを再起動すれば使えるようになります。

$ curl -s https://raw.githubusercontent.com/karaage0703/ubuntu-setup/master/install-docker.sh | /bin/bash

 例えば、TensorFlowのDockerイメージを使えば以下コマンドでDocker環境が立ち上がります。

$ docker run -it --rm --name tensorflow-cpu tensorflow/tensorflow:latest

 以下のようにTensorFlow環境が起動します。

docker.png

 冒頭で教えてもらったDeep Learning ContainersのDockerイメージも同様に使えます。

deeplearning-platform-releaseで使用したいイメージを探せます。

 例えば、以下のようにDockerイメージを使えます。

$ docker run -it --rm --name tensorflow-gcp gcr.io/deeplearning-platform-release/tf2-cpu.2-0

 Jupyter Labを使用したい場合は設定が必要です。

AI Platformで学習環境を構築

 AI Platformにアクセスします。

 真ん中上の「新しいインスタンス」をクリックした後、好きなフレームワークを選択します(無料枠だとGPUは使えません)。

gcp_ai_01_01.png

 カスタマイズもできますが、今回はそのまま作成をクリックします。

gcp_ai_02.png

 インスタンスができたら「JUPYTER LABを開く」をクリックします。

gcp_ai_03.png

 以下のようなブラウザ画面が表示されます。これでJupyter Notebookやコンソールにログインできます。

gcp_ai_04.png

 Jupyter Notebookにアクセスすると、ちゃんとTensorFlowがセットアップされています。 

gcp_ai_05.png

GCP Tips

 Tipsなどをメモしていきます。

メニューのピン留め

 メニューはピン留できます。

gcp_menu_01.png

 ピン留すると、以下のようにアクセスしやすくなります。

gcp_menu_02.png

 Googleの中の人から教えてもらいました。

まとめ

 GCPでのディープラーニング学習環境構築方法に関して、簡単に説明しました。

 あまりにメニューが多く絶望しかけましたが、機械学習やディープラーニングなら、Compute EngineとAI Platformを押さえておけば良いのかなと感じました。特にAI Platformはお手軽で良いですね。今後さらにメニューが拡充していきそうです。

 しかし、こんなに簡単に使えるならDockerとか頑張って覚えなくて良かったのでは?という気が今更してきましたが、気づかなかったことにしましょう… 

 今後、GCPに課金もして使っていこうかなと思っています。GCP初心者なので、オススメの使い方などあれば教えてください。

参考リンク

「 GCP入門編」記事一覧(トップゲート)

無料!Tensorflow-gpuをCUDA, cuDNNと共にインストールして使う方法(GCP)

GCPを使ったKaggleのデータ分析 導入編

変更履歴

  • 2020/08/12 GCP Tips追記
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerでpostgresとpgweb(GUI)を構築したっす

DockerによるPHP、Apache、PostgreSQLの開発環境を構築した時の流れをまとめようと思います。

また、データベース管理インタフェースを使うと直感的に操作できて便利なので、PostgreSQLについてはモダンなUIであるpgwebも導入してみます。

環境

  • Mac for Docker
  • Apache2.4
  • PHP7.1
  • PostgreSQL9.6

構成

スクリーンショット 2020-08-11 12.15.42.png

ファイル群

docker/web/Dcokerfileに以下を記述します。

FROM php:7.1-apache

COPY ./php.ini /usr/local/etc/php/

RUN set -ex apk --no-cache add postgresql-dev libpq-dev && \
    apt-get update && apt-get install -y libpq-dev \
    vim \
    less \
    && docker-php-ext-install pdo pdo_pgsql pgsql mbstring

docker/web/Dcokerfileと同じ階層にphp.iniを作成します。

docker/web/php.ini
[Core]
display_errors = On
error_reporting = E_ALL
error_log = /var/log/apache2/error.log
log_errors = On

[Date]
date.timezone = 'Asia/Tokyo'

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = auto
mbstring.http_input = auto
mbstring.http_output = auto
mbsting.encoding_translation = Off
mbstring.detect_order = auto

dockerディレクトリにdocker-compose.ymlを作成します。

docker/docker-compose.yml
version: '3'

services:
  web:
    build: ./docker/web/
    ports:
      - 8110:80
    volumes:
      - .:/var/www/html
    depends_on:
      - db
  db:
    image: postgres:9.3
    container_name: postgres
    ports:
      - 5433:5432
    volumes:
      - ./docker/db:/docker-entrypoint-initdb.d
    environment:
      POSTGRES_DB: test
      POSTGRES_USER: test
  db-gui:
    image: sosedoff/pgweb
    container_name: "pgweb"
    ports:
      - "8081:8081"
    depends_on:
      - db

表示確認用ファイル作成

dockerディレクトリにindex.phpを作成します。
とりま、phpinfo()のみでOKです。

docker/index.php
<?php

phpinfo();

コンテナ立ち上げる

以下コマンドで実行します。

docker-compose up -d

コンテナ確認してみます。

$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
a25edb35c693        sosedoff/pgweb      "/usr/bin/pgweb --bi…"   10 seconds ago      Up 9 seconds        0.0.0.0:8081->8081/tcp   pgweb
e5f1ce8c159f        php_job_web         "docker-php-entrypoi…"   10 seconds ago      Up 9 seconds        0.0.0.0:8110->80/tcp     web
c2ae9b7b2ab6        postgres:9.3        "docker-entrypoint.s…"   11 seconds ago      Up 10 seconds       0.0.0.0:5433->5432/tcp   postgres

ブラウザ確認

localhost:8110にアクセスします。
以下のように表示されればOKです。
スクリーンショット 2020-08-12 14.17.32.png

pgwebの設定

localhost:8081にアクセスします。
以下のように入力すれば接続できるはずです。

スクリーンショット 2020-08-12 14.05.56.png

項目
Host データベースのコンテナ名
Username environmentのPOSTGRES_USER
Password 空欄でOK(セキュリティ的にアウトなので注意)
Database environmentのPOSTGRES_DB
SSL Mode disable

データベース管理ツールのpgwebからデータベースのアクセスするには、DBコンテナのIPが必要なのですが、docker-compose.yml に記載したデータベースコンテナ名でアクセス出来ます。

よって、Host名はデータベースのコンテナ名を指定しています。

pgwebでテーブルを作ってみる

スクリーンショット 2020-08-12 14.47.41.png

create table users (
  id integer, 
  name varchar(10)
);

をRunQueryしたらUsersテーブルの出来上がり。

まとめ

ご紹介したものは、あくまでローカルでの開発時を想定しており、本番利用には適さないです。

また、ローカルとはいえ、データベース認証をしっかり行うこと(ユーザー名・パスワードを分かりにくい文字列にするなど)を推奨します。

間違いがありましたらご指摘いただけますと幸いっす。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ktor + Docker + SSL の環境構築

Docker環境で、kotlinのWebフレームワークであるKtorを動かす方法をまとめます。

動作環境

GCP の Container-Optimized OS で確認しました。また、docker-composeを使って構築しました。

Docker

version 19.03.6

docker-compose

version 1.24.0
Compose file version 3

Ktor

version 1.3.2

システム構成

server-architecture-simple.png

internet以外は、docker-composeのDockerコンテナ名(container_name)と紐付いています。

ディレクトリ構成は以下になっています。

docker-compose.yml
app/
  Dockerfile
  wait-for-mysql.sh
  src/
  ... Ktorのgradleプロジェクトのファイル群 ...
db/
  Dockerfile
  my.cnf
  • app: Ktorのソースなどを格納
    • Dockerfile: ktorコンテナのビルド用Dockerfile
  • db: MySQLコンテナ関連のファイルを格納
    • Dockerfile: mysql_hostコンテナのビルド用Dockerfile
    • my.cnf: MySQL設定ファイル

Ktor

それでは各コンテナのDockerfileとdocker-composeのサービス定義をみていきます。
まずktorのコンテナです。基本的には公式のクイックスタートに沿って構築します。KtorのコンテナをビルドするDockerfileは次のようになっています。

app/Dockerfile
FROM openjdk:8-jre-alpine

# ktor
ENV APPLICATION_USER ktor
ENV KTOR_ENV production
RUN adduser -D -g '' $APPLICATION_USER

RUN mkdir /app
RUN chown -R $APPLICATION_USER /app

USER $APPLICATION_USER

# あらかじめビルドしておいたjarファイルをコンテナにコピー
# ここではktorapp-0.0.1.jarというjarファイルをパッケージング済みである前提です
COPY ./build/libs/ktorapp-0.0.1.jar /app/ktorapp.jar
COPY ./wait-for-mysql.sh /app/wait-for-mysql.sh
WORKDIR /app

# mysqlクライアントをインストール
USER root
RUN apk add mysql-client
RUN chmod 755 /usr/bin/mysql

# ktorユーザーに戻す
USER $APPLICATION_USER

# DBパスワードは設定ファイルのものを使用する
ARG DB_ROOT_PASS
ENV DB_PASS=${DB_ROOT_PASS}

CMD ["sh", "-c", "./wait-for-mysql.sh mysql_host root ${DB_PASS} java -server -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=2 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=2 -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UseStringDeduplication -jar ktorapp.jar"]

クイックスタートと異なるのは、MySQLコンテナが起動完了するのを待つスクリプトを追加している点です。
DBユーザーはrootユーザ固定にしてしまっていますが、パスワードは.envファイルから読み込んだものを使用しています。
また、CMD実行時にDBパスワードの変数を展開するために、こちらの回答を参考にして変更しています。変更しないと、変数名DB_PASSがそのまま文字列として実行されてしまっていました。

CMD ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-XX:InitialRAMFraction=2", ...]

CMD ["sh", "-c", "./wait-for-mysql.sh mysql_host root ${DB_PASS} java -server -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=2 ..."]

MySQLコンテナの起動完了を待つスクリプトは以下です。
Dockerの公式にあったサンプルはPostgresになっていますが、こちらの記事はMySQLになっていましたので、参考にさせていただきました。

wait-for-mysql.sh
#!/bin/sh
# wait-for-mysql.sh

set -e

host="$1"
shift
user="$1"
shift
password="$1"
shift
cmd="$@"

until /usr/bin/mysql -h"$host" -u"$user" -p"$password" &> /dev/null
do
  >&2 echo "MySQL is unavailable - sleeping"
  sleep 1
done

>&2 echo "MySQL is up - executing command"
exec $cmd

ここまでがktorコンテナをビルド・起動するためのスクリプトです。次にktorコンテナを使用しているdocker-composeのサービスの箇所をみていきましょう。

docker-compose.yml
version: "3"

services:
  # Ktorアプリケーション
  app:
    container_name: ktor
    expose:
      - 8080
    environment:
      - VIRTUAL_HOST=virtual.host.example
      - VIRTUAL_PORT=8080
      - LETSENCRYPT_HOST=virtual.host.example
      - LETSENCRYPT_EMAIL=mailaddress@mail.example
    build: 
      context: ./app
      args:
        DB_ROOT_PASS: $DB_ROOT_PASS
    depends_on:
      - db
    networks:
      - reverse-proxy

# ... 省略 ...

networks:
  reverse-proxy:
    external: true

buildで構築するDockerfileがあるappディレクトリを指定し、引数としてDBのパスワードを渡しています。それをDockerfileのなかで解釈し、MySQL起動完了待ちスクリプトに渡していました。

後述するDBコンテナやnginxのリバースプロキシ、Let's Encrypt companionなどもすべて同一のネットワークを使用するので、ここではrevese-proxyという既存のネットワークを使うようにしています。(ひとつのdocker-compose.ymlに全てのコンテナ定義を書く場合はデフォルトの同一ネットワークが適用されるので不要かもしれませんが...)

DB

mysql_hostのコンテナです。
docker-composeのサービス定義はこちらを参考にしました。ただ、Container Optimized OSだとMySQLコンテナがログ(/var/log/mysql)への書き出し権限がないため起動に失敗しましたが、その問題はこちらを参考に解決しました。ありがとうございます。

まず、コンテナをビルドするDockerfileです。

db/Dockerfile
FROM mysql:8.0
RUN mkdir /var/log/mysql
RUN chown mysql:mysql /var/log/mysql

イメージをダウンロードして、ログ出力先ディレクトリを作成し権限を設定しています。
次に、docker-composeのサービス定義の箇所です。

docker-compose.yml
services:
  # MySQL
  db:
    build: 
      context: ./db
    container_name: mysql_host
    volumes:
      - db-store:/var/lib/mysql
      - db-logs:/var/log/mysql
      - ./db/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS}
      - TZ=${TZ}
    ports:
      - ${DB_PORT}:3306
    networks:
      - reverse-proxy

# ... 省略 ...

volumes:
  db-store:
  db-logs:

今回はDBユーザーはrootユーザーのみ使用していますので、DB情報の環境変数は以下のみセットしています。

  • MYSQL_DATABASE: DB名
  • MYSQL_ROOT_PASSWORD: rootユーザーのパスワード

実は最初はDBユーザーの環境変数MYSQL_USERrootで指定してたんですが、そうすると、MySQLコンテナが起動したときにrootというユーザーを作成しようとして起動に失敗してしまうんですね...。
参考: https://stackoverflow.com/a/45086773
Ktorからrootユーザーではなく別のユーザーでアクセスしたい方は適宜セットしてください。

設定値の読み込みは.envファイルを使用しています。

.env
DB_NAME=<db name>
DB_ROOT_PASS=<password>
DB_PORT=3306
TZ=Asia/Tokyo

リバースプロキシ

nginx_proxyコンテナです。Ktorへリクエストを転送するリバースプロキシになります。このコンテナとLet's Encryptを使ってSSL証明書を発行するコンテナ(letsencrypt_companion)については、KtorクイックスタートのSSL通信にするためのガイドを参考に構築しました。

jwilder/nginx-proxyという素晴らしいイメージをそのまま使うので、docker-composeのサービス定義のみです。

docker-compose.yml
  nginx:
    image: jwilder/nginx-proxy
    container_name: nginx_proxy
    environment: 
      - NGINX_PROXY_CONTAINER=nginx_proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - certs:/etc/nginx/certs:ro
      - vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
    networks:
      - reverse-proxy

  # ...

volumes:
  certs:
  vhost:
  nginx-html:
  • certs:/etc/nginx/certs:roroは read only モードとのことですが、このコンテナからは証明書を読み込むだけで書き込みは必要ないのでつけています。
  • NGINX_PROXY_CONTAINER=nginx_proxylabelは、Let's Encrypt companionコンテナがnginxプロキシコンテナを識別するために使用するもののようです

上記で3つのvolumesを定義しています。それらはSSL証明書発行のために使用されるので、後述のLet's Encrypt companionコンテナと共有しています。それぞれのボリュームについて解説します。

docker-volumes.png
※ 一部の矢印が点線なのはread onlyにしているのを表現したかったからです...

certsボリューム

発行されたSSL証明書が格納されます。nginx_proxyコンテナからは読み込むだけなのでro(read only)にします。

vhostボリューム

nginxのlocationなど設定ファイルが格納されるボリュームです。Let's EncryptでSSL証明書を発行する際に、Let's Encryptから検証のためのリクエストが送信されるので、そのリクエストを受け付けるlocation設定がこちらのボリュームに格納されるようです。
ためしに、コンテナを作成したあとにボリュームのなかを見てみると...

$ docker volume inspect ktorapp_vhost
[
    {
        "CreatedAt": "2020-08-10T06:43:59Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "ktorapp",
            "com.docker.compose.version": "1.24.0",
            "com.docker.compose.volume": "vhost"
        },
        "Mountpoint": "/var/lib/docker/volumes/ktorapp_vhost/_data",
        "Name": "ktorapp_vhost",
        "Options": null,
        "Scope": "local"
    }
]

/var/lib/docker/volumes/ktorapp_vhost/_dataというところにデータが格納されているようです。

$ sudo ls -la /var/lib/docker/volumes/ktorapp_vhost/_data
total 12
drwxr-xr-x 2 root root 4096 Aug 10 06:43 .
drwxr-xr-x 3 root root 4096 Aug  8 13:37 ..
-rw-r--r-- 1 root root  278 Aug 10 06:43 default

defaultというファイルがありました。みてみると、

$ sudo cat /var/lib/docker/volumes/ktorapp_vhost/_data/default
## Start of configuration add by letsencrypt container
location ^~ /.well-known/acme-challenge/ {
    auth_basic off;
    auth_request off;
    allow all;
    root /usr/share/nginx/html;
    try_files $uri =404;
    break;
}
## End of configuration add by letsencrypt container

URLパスのドメイン/.well-known/acme-challenge/へのアクセスは/usr/share/nginx/html配下を見にいくようなlocation設定を追加しているようです。これはコンテナのnginx-htmlボリュームのマウントポイント=/usr/share/nginx/htmlと一致しています。

nginx-htmlボリューム

Let's Encryptによる検証のためのファイルが格納されます。こちらも見てみましょう。

$ sudo ls -la /var/lib/docker/volumes/ktorapp_nginx-html/_data/
total 20
drwxr-xr-x 3 root root 4096 Aug 10 06:43 .
drwxr-xr-x 3 root root 4096 Aug  8 13:37 ..
drwxr-xr-x 3 root root 4096 Aug  8 14:01 .well-known
-rw-r--r-- 1 root root  494 Nov 19  2019 50x.html
-rw-r--r-- 1 root root  612 Nov 19  2019 index.html

.well-known がありました。さらにこの下に acme-challengeディレクトリがあり、そこに検証用ファイルが生成されるみたいです。

Let’s Encrypt companion

letsencrypt_companionコンテナです。こちらもjrcs/letsencrypt-nginx-proxy-companionという素晴らしいDockerイメージをそのまま使うだけです。Let's Encryptを使ってSSL証明書を自動で発行してくれます。さきほど紹介したcerts vhost nginx-html ボリュームを使用して検証のためのlocation設定やファイル作成を行い、SSL証明書を発行します。

docker-compose.yml
  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt_companion
    depends_on:
      - nginx
    volumes:
      - certs:/etc/nginx/certs:rw
      - vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: always
    networks:
      - reverse-proxy

さきほどのリバースプロキシのコンテナとは異なり、certsへのアクセス権限が書き込み可(rw)になっていることに注意してください。

コンテナ起動

実際にコンテナの生成/起動を行ってみます。

前提

Container Optimized OS では、docker-composeコマンドはエイリアス設定を行わないとできないみたいですので、チュートリアルを参考に設定しました。
Running Docker Compose with Docker

手順

まず、とても微妙なのですが...ローカル環境でKtorアプリケーションをビルド・パッケージングします...。ここもサーバー側でやりたいのでいずれ更新します・・・。

> ./gradlew build

パッケージングしたjarファイルをGCPサーバーにアップロードします。ここではプロジェクトパス/app/build/libs配下におきます。そしてdocker-composeでコンテナ群を起動します。

$ docker-compose up
Network reverse-proxy declared as external, but could not be found. Please create the network manually using `docker network create reverse-proxy` and try again.

reverse-proxyネットワークがないと怒られました。

$ docker network create reverse-proxy
fdf7cedf66ea285984eabbc77b49a1b27720b06e774d3d39975fd46066fa59c7

もう一回チャレンジしてみます。

$ docker-compose up
... 省略 ...
ktorapp        | MySQL is unavailable - sleeping
ktorapp        | MySQL is up - executing command
ktorapp        | 2020-08-11 07:32:29.390 [main] TRACE Application

今度はできました!以上です。

そのほかの参考記事

Docker、ボリューム(Volume)について真面目に調べた

Docker network 概論

docker コマンドの --build-arg で設定した値を Dockerfile の CMD で利用する方法

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VMサーバーをコンテナに移行する計画

これはそろそろDockerを使えるようになりたい筆者の試行錯誤の軌跡です。

VMからコンテナへ

現在、完全に自分だけのためではありますが、複数サービス運用のためローカルマシンのVMで作ったサーバー3台を運用しています。

Untitled(1) (6).png

  • Deploy:コンテンツ配信用
  • Resource:プライベートクラウドストレージ
  • Develop:ソースコード管理

Deployで配信するコンテンツには、通常通り/var/www/html配下にファイルを配置し配信するもの(以下、web root)、音楽や動画を配信するメディアストリーミング、Djangoアプリケーション、Node.jsアプリケーションがあります。
web rootにはWeb Socket(Python実装)を利用するものもあります。
それらのうち、DjangoアプリケーションとNode.jsアプリケーションはバーチャルホストとしてサブドメインを割り当てています。
Resourceのowncloud、Developのgitlabも、バーチャルホストとしてサブドメインでDeployから配信しています。

これらをDockerに移植していこうという計画を立てます。
理由は単純で、そろそろDockerを使えるようになりたいからです。
探り探りではありますが、少しずつ進めていきたいので、その軌跡を残そうという記事です。

以下のような完成形をイメージしています。
(コンテナ初心者です。構成の甘さとかベストプラクティスとかあればご教示ください。)

Untitled(2) (2).png

よくある「プロセス単位でコンテナを作成」っていう説明がなかなか理解できなかったのですが、
具体的にどう切り分ければコンテナとして扱いやすいかを考えると、すんなり理解できました。

とりあえずDockerを準備

一気にやってしまう時間を確保するのが難しいので、少しずつ進められるようにとりあえずDockerを使えるようにし、VMと共存させます。
Docker起動に必要なHyper-VとVirtualBoxが共存できない問題がありましたが、VirtualBoxを6.1系にアップデートすると共存できました。
以下のような構成が当面の目標です。

Untitled(3) (1).png

画像のようにnginxのコンテナを起動し、VMにリバースプロキシするよう設定し、http系のアクセスがVMからコンテナに向くよう変更しました。
が、つながりませんでした。
ブラウザにはERR_SSL_PROTOCOL_ERRORと表示されており、コンテナのnginxは文字化けしていて解読できませんでした。

移行計画、不穏な幕開けです。

次回:DockerでVMへのリバースプロキシ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel で Docker 使いたいなら Vessel にしておこう

Vessel そこそこ使ってる人はいるんだろうけど、 Laradock 使ってツラいことになってる人がそこそこいそうなので Vessel 使うと楽だよということをに書いておきます。

Vessel とは

Vessel は簡単に下記環境を Docker で作成することができます。

  • PHP7.4
  • MySQL 5.7
  • Redis
  • NodeJS, NPM, Yarn, Gulp

ちょっと自分の環境にあわない(例えばデータベースに PostgreSQL を使っている等)場合は書き換えることができます(各種ファイルがコピーされるだけなので)。おおむね、PHP, データベース, キャッシュストレージ, NodeJS があれば 8〜9 割くらいの現場ではフィットするんじゃないでしょうか。

使用にあたっての注意点(追記)

Vessel は https://github.com/shipping-docker/vessel/blob/master/docker-files/docker/node/Dockerfile#L1node:latest を使っててこのままだとイメージサイズが大きいので変更したほうがよいです。

インストール

Composerを使ってインストールできます。

composer require shipping-docker/vessel

これはかなり嬉しいですね。 git submodule add とかできれば書きたくない。

次に設定ファイルを publish します。

php artisan vendor:publish --provider="Vessel\VesselServiceProvider"

すると docker ディレクトリに Docker の各種ファイル、プロジェクトルートに docker-compose.ymlvessel というシェルスクリプトがコピーされます。

で最後に

bash vessel init

とすれば準備完了。簡単ですね。

使い方

コンテナを起動するには

./vessel start

とすればコンテナが起動します。停止するには

./vessel stop

で停止します。

この vessel というシェルスクリプトが上手くできていて、Docker のコマンド(自分はすぐ忘れる)を補ってくれます。例えばコンテナ内で php artisan xxx したい時は

./vessel artisan xxx (tinker とか make:controller とか)

でOKです。上記コマンドは

docker-compose exec -u ユーザー名 コンテナ名 php artisan コマンド

と同じですが、かなり短くなって覚えやすくなってるのがわかると思います。他にも

./vessel test

で PHPUnit でテストができたり

./vessel node or npm or yarn

で各種コマンドが実行できたり

./vessel dump

mysqldump が実行できたり

./vessel mysql

で MySQL コマンドが実行できたり

./vessel ssh コンテナ名

でコンテナに入ったりできます。

あとは…そうですね。私はホストOSがUbuntuなので dockerでvolumeをマウントしたときのファイルのowner問題 が発生して困ることが多いのですがこの辺にも対処してくれています。

まとめ

Docker を開発環境と割り切って使うのであれば Vessel は非常におすすめです。そうでなくても vessel ファイルをちょっとカスタマイズして活用するのもいいのではと思います。私は理由があって Vessel が使えない現場でも vessel ファイルっぽいものを作って導入しています。

プロジェクトメンバー全員が Docker に習熟していれば必要ないかもしれませんが、私も Docker が得意なわけじゃないのでこういったパッケージがあるのは嬉しいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel で Docker 使って開発したいなら Vessel にしておこう

Vessel そこそこ使ってる人はいるんだろうけど、 Laradock 使ってツラいことになってる人がそこそこいそうなので Vessel 使うと楽だよということをに書いておきます。

Vessel とは

Vessel は簡単に下記環境を Docker で作成することができます。

  • PHP7.4
  • MySQL 5.7
  • Redis
  • NodeJS, NPM, Yarn, Gulp

ちょっと自分の環境にあわない(例えばデータベースに PostgreSQL を使っている等)場合は書き換えることができます(各種ファイルがコピーされるだけなので)。おおむね、PHP, データベース, キャッシュストレージ, NodeJS があれば 8〜9 割くらいの現場ではフィットするんじゃないでしょうか。

使用にあたっての注意点(追記)

Vessel は https://github.com/shipping-docker/vessel/blob/master/docker-files/docker/node/Dockerfile#L1node:latest を使っててこのままだとイメージサイズが大きいので変更したほうがよいです。

インストール

Composerを使ってインストールできます。

composer require shipping-docker/vessel

これはかなり嬉しいですね。 git submodule add とかできれば書きたくない。

次に設定ファイルを publish します。

php artisan vendor:publish --provider="Vessel\VesselServiceProvider"

すると docker ディレクトリに Docker の各種ファイル、プロジェクトルートに docker-compose.ymlvessel というシェルスクリプトがコピーされます。

で最後に

bash vessel init

とすれば準備完了。簡単ですね。

使い方

コンテナを起動するには

./vessel start

とすればコンテナが起動します。停止するには

./vessel stop

で停止します。

この vessel というシェルスクリプトが上手くできていて、Docker のコマンド(自分はすぐ忘れる)を補ってくれます。例えばコンテナ内で php artisan xxx したい時は

./vessel artisan xxx (tinker とか make:controller とか)

でOKです。上記コマンドは

docker-compose exec -u ユーザー名 コンテナ名 php artisan コマンド

と同じですが、かなり短くなって覚えやすくなってるのがわかると思います。他にも

./vessel test

で PHPUnit でテストができたり

./vessel node or npm or yarn

で各種コマンドが実行できたり

./vessel dump

mysqldump が実行できたり

./vessel mysql

で MySQL コマンドが実行できたり

./vessel ssh コンテナ名

でコンテナに入ったりできます。

あとは…そうですね。私はホストOSがUbuntuなので dockerでvolumeをマウントしたときのファイルのowner問題 が発生して困ることが多いのですがこの辺にも対処してくれています。

まとめ

Docker を開発環境と割り切って使うのであれば Vessel は非常におすすめです。そうでなくても vessel ファイルをちょっとカスタマイズして活用するのもいいのではと思います。私は理由があって Vessel が使えない現場でも vessel ファイルっぽいものを作って導入しています。

プロジェクトメンバー全員が Docker に習熟していれば必要ないかもしれませんが、私も Docker が得意なわけじゃないのでこういったパッケージがあるのは嬉しいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerのCentos7イメージを使ってApache+PHP環境を構築した

はじめに

Docker公式Hubのイメージを使えばサクッと構築できますが、今回はCentOS7上で動作させたかったので試しに構築してみました。

開発環境

  • Windows10
  • Windows for Docker

LAMPのバージョン

  • Apache 2.4
  • PHP 7.0

Dockerfile

https://github.com/guranytou/docker-test-phpapache
書いたDockerfile。
将来的にはこのイメージを基にLAMP環境を構築したいので、PDOなどをインストールしています。

実際に動かしてみる

Apache+PHPのコンテナのビルドを行います。

$ cd /apache-php/build
$ docker build -t php-apache:1 .

イメージが作成できたので、次はこのイメージを基にコンテナ作成を行います。

$ docker run -d -it --privileged -p 80:80 --name php-apache-test php-apache:1 /sbin/init

あとがき

Dockerfileを使えるようになると格段に構築が楽になるなと感じました。
次はDocker-composeも利用して、LAMP環境を構築したいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WindowsでDockerを使ったStorybookでHMRが効かない

状況

Windowsのファイルシステム上に存在するdocker-compose.ymlでLinuxコンテナを起動してStorybookを動かしたのですが、HMRが効きませんでした。

原因

WindowsとLinuxのファイルシステムの違いにより、ファイルの変更(inotify)をコンテナが検知できないことが原因のようです。

回避策

今回は以下の設定をStorybookのwebpack設定に追加して強制的にファイルを監視することにしました。

webpack.config.js
module.exports = async ({ config }) => {
  // --中略--
  config.watchOptions = {
    aggregateTimeout: 200,
    poll: 1000
  }
  // --中略--

この方法はあまりスマートではないですが、簡単に対策が取れます。
他の対策としてこちらの記事の回避策も参考になるかもです。状況や環境によってどの策が良いかは変わるかと思います。

終わりに

都合につきWindowsを使わなければならないので、WindowsとDockerのさらなる発展を祈っております。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rアプリケーションを実行してFunction Computeを開発する方法

このチュートリアルでは、Rアプリケーションを実行してFunction Computeを開発する方法を学びます。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

背景

まず、Alibaba CloudのFunction Computeがありますが、これはイベント駆動型のサービスで、ユーザーはサーバーの健全性を管理したり、その他の要因を考慮することなくコードを書いたりアップロードしたりすることができます。Function Computeは、ユーザーのコードを実行するために必要なコンピューティングリソースの量を準備し、自動的にスケーリングします。ユーザーは、コードを実行するために必要なリソースのみを支払うことになります。

次に、サーバーレスアプリケーションのためのデプロイメントツールであるFunがあります。これは、Function Compute、API GatewayLog Serviceなどのリソースを管理するのに役立ちます。Funを使用して、template.ymlファイルに指定したリソースを記述することで、リソースの開発、ビルド、デプロイを行うことができます。

注意: この記事で説明したテクニックは、Fun 2.10.1 以降に適用されます。

ツール

このチュートリアルでは、Rアプリケーションを実行して関数計算を開発する方法について説明します。このチュートリアルで概説されているプロジェクトはmacOS上で開発されていますが、LinuxやWindowsと互換性のあるプラットフォームに依存しないツールも含まれています。この例に進む前に、DockerFunFcliが正しくインストールされ、最新バージョンにアップデートされ、適切に設定されていることを確認してください。これらのツールのダウンロード、アップデート、設定は、ここにリンクされているページの指示とリソースで行うことができます。

FunとFcliはローカル環境をシミュレートするためにDockerに依存しています。MacOSユーザーは、これらのツールをインストールするためにhomebrewを使用することができます。

brew cask install docker
brew tap vangie/formula
brew install fun
brew install fcli

Windows と Linux ユーザーは、これらのツールのインストール方法については、Installation を参照してください。インストール後、最初に fun config を実行して設定を初期化することを忘れないでください。

注意: 既にFunをインストールしている場合は、バージョン2.10.1以上であることを確認してください。

$ fun --version
2.10.1

R アプリケーションの実行

まずはプロジェクトを初期化します。fun initコマンドを使って、このテンプレートプロジェクトをローカル環境に簡単に初期化することができます。

fun init vangie/rlang-example

そして、以下のような内容のindex.pyのテストコードを使ってローカルテストを行います。

import rpy2.robjects as robjects
from rpy2.robjects import pandas2ri

def handler(event, context):  
    pandas2ri.activate()
    return str(robjects.r('paste0("1 + 1 = ", 1 + 1)'))

前述のコードは、rpy2をインポートし、R言語で単純な加算操作を行うことで動作します。fun localコマンドを使用して、ローカルで機能をテストすることができます。このステップを実行するには、ローカル環境にDockerが正しくインストールされている必要があります。

$ fun local invoke onePlusOne
skip pulling image aliyunfc/runtime-python3.6:1.4.0...
['1 + 1 = 2']

RequestId: 6e1f2402-9443-4392-9f6a-d87b4f79887a      Billed Duration: 7543 ms      Memory Size: 1998 MB      Max Memory Used: 123 MB

そして、fun deployコマンドを使ってアプリケーションをデプロイします。

$ fun deploy
using region: cn-shanghai
using accountId: ***********4733
using accessKeyId: ***********KbBS
using timeout: 60

Waiting for service rlang to be deployed...
    Waiting for function onePlusOne to be deployed...
        Waiting for packaging function onePlusOne code...
        package function onePlusOne code done
    function onePlusOne deploy success
service rlang deploy success

そして、以下のコマンドでアプリケーションを実行します。

$ fcli function invoke -s rlang -f onePlusOne
['1 + 1 = 2']

R言語のコンパイル

コンパイル済みのR言語環境、rpy2ライブラリ、関連するapt依存ファイルは、.funディレクトリの下に置かれています。通常、自分でコンパイルする必要はありません。私自身の経験では、コンパイルには毎回30分程度かかります。既存のR言語のコンパイルオプションがビジネスの要件を満たすことができない場合は、コンパイルとインストール方法の完全なリストを提供するfun.ymlファイルを見ることができます。それに応じていくつかの調整を行い、fun install コマンドを使ってインストールを完了させることができます。

参考文献

1、ソースからRを構築する
2、Rソース
3、rpy2に関するドキュメント

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

port forwardingをunix socketにbindするとはかどる

port forwardingをunix socketにbindすると、dockerコンテナ内にvolume mountを通じて持っていけるので便利。
以下、mysqlを例にする。

コマンド

ssh -o StreamLocalBindUnlink=yes -fNL /tmp/sock/db.sock:$DB_HOST:3306 bastion

bastionはもちろん、踏み台サーバー
fNオプションは不要であれば外して良い。
-o StreamLocalBindUnlink=yes をつけると、指定したpathにunix socketが既に存在する場合でも上書きしてforwardingしてくれる。

dockerコンテナ内での使用

--volume /tmp/sock:/tmp/sock 付きでコンテナを起動する。

mysql --socket /tmp/sock/db.sock -u ...

curlでも使える

https://qiita.com/toritori0318/items/193df8f749a9c4bda883
ブラウザからアクセスできないのが残念(コンテナ内でブラウザを使うわけではないが、portにbindするのとunix socketにbindするのを切り替えるのが面倒くさい)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Alibaba Cloud ECSへのNode.jsのインストールと設定

このチュートリアルでは、Alibaba Cloud ECSインスタンスにNode.jsをインストールして設定します。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

前提条件

  • Alibaba Cloud Elastic Compute Service (ECS)を有効にし、有効な支払い方法を確認する必要があります。新規ユーザーの場合は、新規アカウントで300ドル~1200ドル相当のAlibaba Cloudクレジットを獲得できます。ECSインスタンスのセットアップ方法がわからない場合は、このチュートリアルまたはクイックスタートガイドを参照してください。ECSインスタンスには、少なくとも1GBのRAMと1つのCoreプロセッサが必要です。
  • Alibaba Cloudから登録されたドメイン名。すでにAlibaba Cloudまたは他のホストからドメインを登録している場合は、そのドメインネームサーバーレコードを更新することができます。
  • ドメイン名は、あなたのAlibaba Cloud ECSのIPアドレスを指している必要があります。
  • Alibaba CloudのVNCコンソールまたはPCにインストールされているSSHクライアントにアクセスします。
  • サーバーのホスト名を設定し、root権限のユーザーを作成します。

環境の設定

サーバーの設定

パッケージのインストールを進める前に、以下のコマンドを実行してUbuntuシステムをアップデートしてください。このコマンドを実行するには、root ではないユーザーから sudo 権限でログインすることを忘れないでください。

# sudo apt update && sudo apt upgrade

ソフトウェアプロパティ共通のインストール

Docker CEのインストールに対応したファイルを取得するためには、software-properties-commonパッケージが必要です。software-properties-commonパッケージをインストールするには、以下の手順に従います。

software-properties-commonをインストールするには、以下のコマンドを実行します。

# sudo apt-get install software-properties-common -y 

apt-transport-httpsのインストール

Docker CEのインストールにはapt-transport-httpsが必要です。apt-transport-httpsをインストールするには、以下の手順を実行します。

apt-transport-httpsをインストールするには、以下のコマンドを実行します。

# sudo apt-get install apt-transport-https -y 

ca-certificatesのインストール

Docker CEのインストールにはca-certificatesが必要です。ca-certificatesをインストールするには、以下の手順で行います。

ca-certificatesをインストールするには、コマンドを実行します。

# sudo apt-get install ca-certificates -y 

curlのインストール

Docker CEのインストールにはcurlが必要です。curlをインストールするには、以下の手順で行います。

curlをインストールするには、コマンドを実行します。

# sudo apt-get install curl -y 

Docker CEのインストール

Docker community editionをインストールするには、以下の手順で完了します。

以下のコマンドを実行して、Docker用のGPGキーを追加します。

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

以下のコマンドを実行して、GPGキーのフィンガープリントを確認します。

# sudo apt-key fingerprint 0EBFCD88

ここで、以下のコマンドを実行してDockerリポジトリを追加します。

# sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”

以下のコマンドを実行してシステムをアップデートし、追加されたリポジトリをロードします。

# sudo apt update

以下のコマンドを実行してDockerをインストールします。

# sudo apt install docker-ce

以下のコマンドを実行して、ユーザ名をdockerグループに追加します。

# sudo adduser aareez docker 

現在のシェルセッションを閉じて新しいセッションを開始すると、dockerが実行できなくなり、パーミッションエラーが発生する可能性があります。

次に、以下のコマンドを実行して、dockerが正しく実行されているかどうかを確認します。

# docker run hello-world

Docker Composeのインストール

Docker composeをダウンロードしてインストールするには、以下の手順で行います。

以下のコマンドを実行して、最新版のdocker composeをダウンロードしてインストールします。

# sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

以下のコマンドを実行して、ファイルのパーミッションを設定します。

# sudo chmod +x /usr/local/bin/docker-compose

以下のコマンドを実行して起動したコンテナの一覧を取得します。

# docker container ls —all

image.png

ポート808080を使用しているコンテナを停止します。そのためには、コンテナのIDを取得し、以下の8baab990c424に置き換えて、以下のコマンドを実行します。

# docker stop 8baab990c424

Node.jsのインストールと設定

このチュートリアルでは、具体的にNode.jsの公式イメージを使ってDocker上にインストールしていきます。Node.jsをダウンロードしてインストールするには、以下のコマンドを実行して、公式のdockerリポジトリから最新のNodejsを引っ張ってくる必要があります。

# docker pull linode/server-node-js

ここで以下のコマンドを実行してdockerイメージを実行します。

# docker run -d -p 80:3000 linode/server-node-js

これで、アリババクラウドECSのIPアドレスまたはそのIPアドレスを指すドメイン名にアクセスして確認することができるようになりました。http://your_domain.tld/test.htm

以下のページが表示されます。

image.png

ファイアウォールとポートの設定

ファイアウォールを有効にしている場合は、クラウドサーバーの Alibaba Cloud セキュリティグループで、ポート 80/tcp と 443/tcp の例外を追加するルールを定義する必要があります。ECSインスタンスの作成時にこれらのポートを有効にすることができますが、これらのポートのブロックを解除し忘れた場合は、このガイドの手順に従ってください:セキュリティグループルールの追加

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VultrでKUSANAGI Runs on Dockerが動くまで(その4)

はじめに

前回の記事『VultrでKUSANAGI Runs on Dockerが動くまで(その3)』ではVPC環境であるVultrにKUSANAGI RoD環境を構築しWordpressが動くところまで確認しました。
今回はリバプロサーバとしてhttps-portal環境を作っていきます。

https-portal
https://github.com/SteveLTN/https-portal

動作環境など

  • Ubuntu 20.04
  • docker 19.03.12
  • docker-compose 1.26.2
$ docker-compose ps
       Name                     Command                 State                          Ports                     
-----------------------------------------------------------------------------------------------------------------
kusanagi01_config    docker-entrypoint.sh wp -- ...   Restarting                                                 
kusanagi01_db        docker-entrypoint.sh mysqld      Up                                                         
kusanagi01_ftp       /bin/sh -c /docker-entrypo ...   Up                                                         
kusanagi01_httpd     /docker-entrypoint.sh /usr ...   Up           0.0.0.0:8080->8080/tcp, 0.0.0.0:8443->8443/tcp
kusanagi01_php       /usr/local/bin/docker-entr ...   Up  

https-portalとは

https-portalLet's Encrypt対応のリバプロサーバDockerコンテナです。複数FQDNへの分散、Let's Encryptの自動更新などさくっとやってくれます。

Let's Encrypt
https://letsencrypt.org/ja/

フォルダ構成

フォルダ構成は以下のようにしました。新たにhttps-portalフォルダを作成し、その中にdocker-compose.ymlを作成しています。

/home
  └$USER
        ├https-portal                ← リバプロサーバー(マルチサイト& Let’s Encrypt対応)
        │ └docker-compose.yml
        │ 
        ├kusanagi01                 ← KUSANAGI Runs on Docker(WordPressサイト1つ目)
        │ ├nginx
        │ │ └nginx.conf
        │ ├php
        │ │ └ uploads.ini
        │ └docker-compose.yml
        │
        └kusanagi02                 ← KUSANAGI Runs on Docker(WordPressサイト2つ目)
          └docker-compose.yml

Kusanagi Rodのdocker-compose.ymlを修正する

https-portalとKusanagi Rod間で通信をできるように同一のネットワークに属するようにします。
docker-compose.ymlでnetworkにshared-networkを設定します。

$HOME/kusanagi01/docker-compose.yml
version: '3'

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 9000
  shared-network:                          ※追加
    external: true                          ※追加

services:
  httpd:
    container_name: kusanagi01_httpd
    image: primestrategy/kusanagi-nginx:1.17.9-r0
    restart: always
    env_file:
      - .kusanagi
      - .kusanagi.httpd
    volumes:
      - kusanagi:/home/kusanagi
      #- kusanagi:/etc/letsencrypt
      - kusanagi:/var/www/html/.well-known
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "8080:8080"
      - "8443:8443"
    extra_hosts:
      - "example.com:127.0.0.1"
    networks:                             ※追加
      - shared-network                        ※追加

        #certbot:
        #container_name: kusanagi01_certbot
        #image: certbot/certbot:v1.6.0
        #restart: always
        #network_mode: "service:httpd"
        #env_file:
        #- .kusanagi.httpd
        #volumes:
        #- kusanagi:/var/www/html/.well-known
        #- kusanagi:/etc/letsencrypt
        #command:
        #- --version

## CONFIG
  config:
    container_name: kusanagi01_config
    restart: always
    build:
        context: ./wpcli
    user: "1000:1001"
    env_file:
      - .kusanagi
      - .kusanagi.wp
      - .kusanagi.db
    volumes:
      - database:/var/run/mysqld
      - kusanagi:/home/kusanagi
    command: wp --version

  php:
    container_name: kusanagi01_php
    image: primestrategy/kusanagi-php:7.4.8-r0
    restart: always
    env_file:
      - .kusanagi
      - .kusanagi.php
      - .kusanagi.mail
    network_mode: "service:httpd"
    volumes:
      - database:/var/run/mysqld
      - kusanagi:/home/kusanagi
      - ./php/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini

## MYSQL 
  db:
    container_name: kusanagi01_db
    image: mariadb:10.5.4-focal
    restart: always
    user: "999:999"
    env_file:
      - .kusanagi.mysql
    network_mode: "service:httpd"
    volumes:
      - database:/var/run/mysqld
      - database:/var/lib/mysql

## FTPD
  ftp:
    container_name: kusanagi01_ftp
    image: primestrategy/kusanagi-ftpd:1.0.2-r1
    restart: always
    network_mode: "service:httpd"
    env_file:
      - .kusanagi
      - .kusanagi.wp
    volumes:
      - kusanagi:/home/kusanagi


volumes:
  kusanagi:
  database:

docker環境を再構築します。

$ docker-compose down
$ docker-compose up -d

https-portalのdocker-compose.yml

networkをshared-networkにしてkusanagi01とkusanagi02と同一ネットワークにしています。
DOMAINS行で振り分け先のWebサーバを指定します。複数指定する場合はカンマで区切ればOKです。振り分け先をhttpではなくhttpsにしているのはうまくサイトが表示されないからです。(Wordpress側の設定を変えてあげればここをhttpにできるかもです。)
テスト中はSTAGE行をlocalにしておくことでオレオレ証明書で通信ができます。productionに変更すればLet's Encrypt証明書になります。

$HOME/https-portal/docker-compose.yml
version: '3'

services:
  https-portal:
    container_name: https-portal
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    restart: always
    environment:
      DOMAINS: 'fqdn1 -> https://kusanagi01_httpd:8443, fqdn2 -> https://kusanagi02_httpd:8443'
      #STAGE: 'production'
      STAGE: 'local'
      #FORCE_RENEW: "true"
      ERROR_LOG: stderr
      ACCESS_LOG: stdout
      CLIENT_MAX_BODY_SIZE: 64M
    networks:
      - shared-network

networks:
  shared-network:
    external: true

docker環境を再構築します。

$ docker-compose down
$ docker-compose up -d

動作確認

ブラウザでアクセスできることを確認します。今度は8080/TCPとか8443/TCPにする必要はないです。
http://FQDN/
https://FQDN/

ちゃんとログが出力されていることも確認しておきましょう。
https-portalのアクセスログ

$ docker logs https-portal
xxx.xxx.xxx.xxx - - [31/Jul/2020:15:18:45 +0000] "GET /wp-login.php HTTP/2.0" 200 2237 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.49" "-"

kusanagi01-httpdのアクセスログ

$ docker logs kusanagi01_httpd
0.126 - - 172.19.0.3 - - [01/Aug/2020:00:18:45 +0900] "GET /wp-login.php HTTP/1.0" 200 2237 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.49" "xxx.xxx.xxx.xxx"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerの使い方 2日でDocker習得編 (udemy 米国AI開発者がゼロから教えるDocker講座)

夏のDocker合宿2日目

機械学習の環境構築をDockerで行う(Jupiter Lab)
メリット 
★環境構築のエラー回避
チーム開発の手間を下げる
リソースの有効活用(企業レベル?)

前提
Q「パス」を通すとは?
環境変数 $PATHにパスを追加すること。
コンピューターがプログラムをそのパスから持ってこれるようにすること。
パスを通すためのLinuxコマンド

sudo
どのコマンドもルート権限で実行できるようになる。

1 $echo$PATH (今どこにパスが通っているのか確認)
2  $export PATH=/path/to/something:$PATH パスを追加する

実践 Anacondaをコンテナに持っていき、インストールする

手順
1 docker run
2 sh Anaconda~(パッケージ名).sh
3 export PATH ~
4 sh /パス -b -p /パス   (インストール時、面倒なインタラクティブなやりとりを回避するため)

ブラウザでlocal:host8888にアクセスする(Jupyterlabにアクセスする)
ブラウザ上でコンテナのなかでJupyterlabを立ち上げ、ホストにコードが保存される形で、コンテナからコードを書く。
(マウントする)

docker run -p 8888:8888 -v ~/Desktop/フォルダ名(Host側):/(コンテナ側) --name my-lab \ <docker image>

Dockerfileの中身

FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
sudo \
wget \
vim
WORKDIR /opt 
RUN wget https://repo.continuum.io/archive/Anaconda3-2020.02-Linux-x86_64.sh&& \
    sh Anaconda3-2020.02-Linux-x86_64.sh -b -p /opt/anaconda3 && \
    rm -f Anaconda3-2020.02-Linux-x86_64.sh

ENV PATH /opt/anaconda3/bin:$PATH

RUN pip install --upgrade pip
WORKDIR /
CMD ["jupyter","lab","--ip=0.0.0.0","--allow-root","--LabApp.token=''"]

大事なことは、上のコマンドの流れを覚えることではなくて、(いきなりスラスラ作るのは無理!)
Dockerfileをどういう風に作るかのプロセスを試行錯誤しながら慣れていくこと

AWSにDockerを立ち上げる

jmeter-in-aws-ec2.png

EC2ににアクセスするときの、権限を書く (sshで接続)

chmod400<file>
ssh -i  <keyname> ubuntu@<インスタンスDNS>

※キーがあるディレクトリからアクセスを行う。 (場所が違うとキーを見つけられずアクセスできない)

SFTP(Secure File Transfer Protocol) ファイルを送信するためのプロトコル(コマンド)
SSH (Secure Shell) シェルを動かすためのコマンド

AWSでDockerコンテナを起動する方法
1 tarファイルに圧縮して送る (EC2のサーバーのセキュリティが厳しい時など)

#docker image → tar ファイル  ... dockerimageを tar.fileに変換する
$docker save {image} > {tar.file}

#tarファイル→docker image  ...EC2コンテナに送り、コンテナ内でtar.file(image)を開く
docker load < {tar.file}

2 Dockerfileを送って、開く 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Docker】ローカル環境でNginxが動く最小構成を作る

PHP開発環境を作る上で、まずNginxが動く環境をローカルに構築してみます。

前提

  • Docker for Macがインストール済み

ファイル構成

以下の構成で2ファイル作成します。

├── docker-compose.yml
└── public
    └── index.html

各ファイルのソースはこのように設定します。

docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
       - ./public:/usr/share/nginx/html
index.html
<h1>Hello world!</h1>

Docker起動

$ docker-compose up

http://localhost:8080 にブラウザでアクセスすると無事にHello world!が表示されました。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Docker-composeのよく使うコマンド まとめ(初学者)

はじめに

Dockerにてよく使うコマンドを備忘録としてまとめておきます。

コマンド

Dockerのversionを確認

$ docker --version

現在起動しているコンテナを表示

$ docker ps 

-aオプション
全てのコンテナを表示

コンテナを停止

$ docker container stop コンテナIDまたはコンテナ名

コンテナを指定して停止

$ docker stop コンテナ名またはコンテナID

取得したイメージを一覧

$ docker images

docker-compose.ymlの内容に基づいてイメージを作成する

$ docker-compose build

docker-compose.ymlに書かれた依存関係をもとに、よしなにイメージを元にしてコンテナの作成と起動する。イメージはdocker-compose buildで作成する必要がある。

$ docker-compose up

おわりに

個人アプリにDockerを導入する際に上記のコマンドをよく使うと感じました。
参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む