- 投稿日:2019-05-12T23:44:29+09:00
だれでもdocker-composeで楽々Django(Python)環境構築(DBなし)
Docker環境作成用のディレクトリ内構成
docker-django -- Dockerfile | -- requirements.txt | -- docker-compose.yml | -- pythonProject(中身空のディレクトリを作成しておく)それでは、requirements.txtを作成します。こちらは、djangoで使用するパッケージを記述していきます。
requirements.txt
requirements.txtDjango==2.2Djangoフレームワーク(バージョン2.1.1)を指定しています。DB関係のパッケージをインストールしたい場合こちらで記述します。
Dockerfile
DockerfileFROM python:3.7 ENV PYTHONUNBUFFERED 1 WORKDIR /code COPY requirements.txt /code/ RUN pip install -r requirements.txt
- FROM ベースイメージの設定(今回はPython)
- ENV 環境変数の設定(コンソールのstdout(標準出力)とstderr(標準エラー出力)のバッファーを無効にする設定)
- WORKDIR コマンドのcd(移動) + ディレクトリ作成をしてくれる
- COPY requirements.txtを/code/にコピー
- RUN コマンド実行 pip install -r requirements.txtはrオプションでファイルの中身のパッケージをまとめてインストールしてくれます。pipはPythonのパッケージ管理ツール
docker-compose.yml
docker-compose.ymlversion: "3" services: python37: build: . volumes: - ./pythonProject/:/code tty: true ports: - 8000:8000
- volumns ファイル同期(マウント)
- tty 起動したコンテナを起動しっぱなしにできる
- portsホストOSからコンテナへポートフォワード(あらかじめ指定したコンテナのポート番号へホストOSのポート番号に届いたパケットを届ける)
◆注意点◆
PHPの経験がある人は、環境構築の際に/var/wwwの場所にコードを配置したと思いますが、PythonコードをWebサーバーのドキュメントルート下に置いてしまうと、他人がWebを通して、コードを読めるようになってしまうため、安全性に欠けてしまいます。そのため、今回はcode下に置いています。コードの置き場所参考記事docker compose up -d
docker-compose.ymlに記述しているすべてのサービスを起動します
コマンドdocker compose up -d完了したら、コマンド打ってコンテナが作成されているか確認してみましょう。できてたら環境構築終わり
コマンド$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 33378ade007f dockerdjango_python37 "python3" 15 minutes ago Up 12 minutes 0.0.0.0:8000->8000/tcp dockerdjango_python37_1Djangoで初期画面を表示する
Djangoでいうアプリケーションとプロジェクトの違い
- アプリケーション 処理を行う
- プロジェクト 設定記述・アプリケーションを配下にもつ$ docker-compose exec python37 bashDjangoプロジェクト作成
コンテナ内に入れましたら、プロジェクトを作成します。
コマンドroot@bc8400473a8a:/code# django-admin startproject djangoProject .最後に.(ドットをつけるのは、階層を深くしたくないからそうしています)(今回プロジェクト名 = djangoProject)
Djangoアプリ作成
プロジェクトと同階層でアプリを作成します。(アプリ名 = sampleApp)
コマンドroot@bc8400473a8a:/code# python manage.py startapp sampleAppDjango初期画面表示
Djangoでは、公開するホストを指定する必要があります。djangoProject下にあるsettings.pyを編集します。
settings.pyALLOWED_HOSTS = ['192.168.99.100']今回は、Dockerを使用していて、192.168.99.100(デフォルトのものを指定)
それではdjangoの開発用のサーバを起動します。
root@bc8400473a8a:/code# python manage.py runserver 0.0.0.0:8000http://192.168.99.100:8000/
にアクセスできて、画面が表示されれば完了です。おめでとうございます!
- 投稿日:2019-05-12T23:44:29+09:00
だれでもdocker-composeで楽々Django(Python)環境構築(DBなし)#1
Docker環境作成用のディレクトリ内構成
pythonProject docker-django -- Dockerfile | -- requirements.txt | -- docker-compose.ymldocker-django(環境用)とpythonProjectは同階層です。
それでは、requirements.txtを作成します。こちらは、djangoで使用するパッケージを記述していきます。requirements.txt
requirements.txtDjango==2.1.1Djangoフレームワーク(バージョン2.1.1)を指定しています。DB関係のパッケージをインストールしたい場合こちらで記述します。
Dockerfile
DockerfileFROM python:3.7 ENV PYTHONUNBUFFERED 1 WORKDIR /code COPY requirements.txt /code/ RUN pip install -r requirements.txt
- FROM ベースイメージの設定(今回はPython)
- ENV 環境変数の設定(コンソールのstdout(標準出力)とstderr(標準エラー出力)のバッファーを無効にする設定)
- WORKDIR コマンドのcd(移動) + ディレクトリ作成をしてくれる
- COPY requirements.txtを/code/にコピー
- RUN コマンド実行 pip install -r requirements.txtはrオプションでファイルの中身のパッケージをまとめてインストールしてくれます。pipはPythonのパッケージ管理ツール
docker-compose.yml
docker-compose.ymlversion: "3" services: python37: build: . volumes: - ../pythonProject/:/code tty: true ports: - 8000:8000
- volumns ファイル同期(マウント)
- tty 起動したコンテナを起動しっぱなしにできる
- portsホストOSからコンテナへポートフォワード(あらかじめ指定したコンテナのポート番号へホストOSのポート番号に届いたパケットを届ける)
docker compose up -d
docker-compose.ymlに記述しているすべてのサービスを起動します
:コマンド
docker compose up -d
完了したら、コマンド打ってコンテナが作成されているか確認してみましょう。できてたら環境構築終わり
コマンドdocker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 33378ade007f dockerdjango_python37 "python3" 15 minutes ago Up 12 minutes 0.0.0.0:8000->8000/tcp dockerdjango_python37_1Djangoで初期画面を表示する
Djangoでいうアプリケーションとプロジェクトの違い
- アプリケーション 処理を行う
- プロジェクト 設定記述・アプリケーションを配下にもつdocker-compose exec python37 bashDjangoプロジェクト作成
コンテナ内に入れましたら、プロジェクトを作成します。
コマンドdjango-admin startproject djangoProject .最後に.(ドットをつけるのは、階層を深くしたくないからそうしています)(今回プロジェクト名 = djangoProject)
Djangoアプリ作成
アプリを作成します。
:コマンド(アプリ名 = sampleApp)
python manage.py startapp sampleApp
Django初期画面表示
Djangoでは、公開するホストを指定する必要があります。djangoProject下にあるsettings.pyを編集します。
settings.pyALLOWED_HOSTS = ['192.168.99.100']今回は、Dockerを使用していて、192.168.99.100(デフォルトのものを指定)
それではdjangoの開発用のサーバを起動します。
python manage.py runserver 0.0.0.0:8000http://192.168.99.100:8000/
にアクセスできて、画面が表示されれば完了です。おめでとうございます!
- 投稿日:2019-05-12T23:35:28+09:00
nuxt docker
DockerfileFROM node:latest # version指定 docker inspect => "NODE_VERSION=11.14.0" EXPOSE 7000 # port 7000 を開ける ENV HOST 0.0.0.0 # container に どのipaddressでも接続できる<=これ無しだと、接続できない。ipaddressが違う?docker-compose.ymlversion: "3" services: web: build: . #<= ./ でも同じ volumes: - ".:/app" #<= ./:/app でも同じ <= host:container ports: - 7000:3000 #<= ホストで7000を開くとコンテナの3000につながる。バインディング。Dockerfileと揃える container_name: "nuxt-sandbox" tty: true #<= 入力を受け付ける上の二つを同じフォルダに置いて、
docker-compose up -d // -d ありだと、バックグラウンド起動、無しだと、ターミナル上で起動しますdocker exec -itnuxt-sandbox bashyarn create nuxt-app <project-name>
- 投稿日:2019-05-12T23:30:10+09:00
docker-compose.ymlとDockerコンテナのPHPで環境変数を使用する
はじめに
これは個人的な備忘録になります。
docker-compose.ymlで環境変数を使用する
docker-compose.ymlがあるディレクトリ直下に、「.env」 を用意する。そのファイル内で定義した値を使用できる。
例えば、以下のように定義をした場合
.env# REDIS関係 REDIS_PORT=6379 REDIS_PASSWORD=passworddocker-compose.ymlでは、以下のように使用できる
docker-compose.ymlredis: image: redis:alpine3.9 command: redis-server --requirepass ${REDIS_PASSWORD} ports: - "${REDIS_PORT}:${REDIS_PORT}"dockerコンテナで環境変数を使用する
dockerコンテナ内で環境変数を使用する場合は、docker-compose.ymlで定義する。
環境変数を1個〜2個指定する場合は、「environment」で定義をする。
以下のファイルでは、DATABASE_HOST/REDIS_HOSTを定義している。docker-compose.ymlapp: build: ./app env_file: .env environment: DATABASE_HOST: db REDIS_HOST: redis depends_on: - db - redis volumes: - ./data/html:/var/www/htmlまた、複数指定したい場合は、「env_file」として、環境変数を記載しているファイルを指定する。
この時に、「.env」ファイルを使い回すことで、環境変数を「.env」ファイルに集約ができる。
PHPのコンテナでPHP.iniで注意点
PHP.iniでは、環境変数を使う、使わない、または有効にする変数の優先順位設定があります。
それが「variables_order」になります。デフォルトでは、「GPCS」となっていますので、環境変数は使えないです。
Dockerの環境変数が読み込めなくてハマりました。
「EGPCS」にすると、環境変数を優先して使ってくれます。php.ini; This directive determines which super global arrays are registered when PHP ; starts up. G,P,C,E & S are abbreviations for the following respective super ; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty ; paid for the registration of these arrays and because ENV is not as commonly ; used as the others, ENV is not recommended on productions servers. You ; can still get access to the environment variables through getenv() should you ; need to. ; Default Value: "EGPCS" ; Development Value: "GPCS" ; Production Value: "GPCS"; ; http://php.net/variables-order variables_order = "GPCS"これでPHPのコード内で環境変数を使えるようになります。
$redis = new Redis(); $redis->connect($_ENV['REDIS_HOST'], $_ENV['REDIS_PORT']);コードだけではなくて、PHP.iniの中でも環境変数は使えるようです。
php.inimemory_limit=${PHP_MEMORY_LIMIT}参考文献
- 投稿日:2019-05-12T23:15:49+09:00
Node.jsで作ったスクレイピングアプリをDockerコンテナで起動してみた
やりたかったこと
- サーバーレス環境でスクレイピングアプリを動かしたかった
- Knative試したかったのでコンテナ化する必要があった
nodejsでスクレイピングするアプリをサクッと作る
まずは好きなところにディレクトリ切って下記コマンドを叩く
npm init
出てくる質問は全てEnter連打した
次にスクレイピングに必要なselenium-webdriverをインストール
https://www.npmjs.com/package/selenium-webdriver
npm install selenium-webdriverscrapingするプログラムを書いていきます。今回はgoogle chromeが既にインストールされている前提で話を進めます。
vim example.jsexample.jsconst { Builder, By, Capabilities } = require('selenium-webdriver'); const capabilities = Capabilities.chrome(); capabilities.set('chromeOptions', { args: [ '--headless', '--no-sandbox', '--disable-gpu', '--window-size=1980,1200', // other chrome options ], }); (async function example() { console.log('start google scraping'); const driver = await new Builder().forBrowser('chrome').withCapabilities(capabilities).build(); try { await driver.get('https://www.google.com/?hl='); const text = await driver.findElement(By.xpath('/html')).getText(); console.log(text); } finally { await driver.quit(); console.log('finish scraping'); } }()); const sleep = time => new Promise((resolve) => { setTimeout(() => { resolve(); }, time); });puppeteerもサクッと立ち上げるのには良さそうだったけどブラウザがchromium縛りになるのが嫌だったので今回はWebdriver使いました
npm scriptsを定義する
package.jsonのscriptsに以下のようにstartタスクを追加しますpackage.json"scripts": { "start": "node ./example.js", "test": "echo \"Error: no test specified\" && exit 1" },試しにスクレイピングを走らせてみます
npm startconsoleログfuga@hoge ~/D/g/scraping-sample> npm start > scraping-sample@1.0.0 start /Users/a12711/Documents/git-localrepository/scraping-sample > node ./example.js start google scraping Gmail 画像 ログイン 日本 プライバシー規約設定 広告ビジネスGoogleについて finish scrapingうまくスクレイピングが動いてそうです
Dockerfileを作る
今回はサクッと作りたかったので、seleniumのstandalone-chromeのイメージを元にして、nodejsをインストールするDockerfileを作成しました
DockerfileFROM selenium/standalone-chrome:3.141.59 WORKDIR /usr/src/app COPY package*.json ./ USER root RUN curl -SL https://deb.nodesource.com/setup_8.x | bash RUN apt-get install -y nodejs RUN npm install COPY . . CMD npm startDocker Build
dockerが入っていない方はdocker desktop等でdocker入れてください
Dockerイメージを作成する
docker build -t sample/robot .コンテナ起動
docker run sample/robotconsoleログfuga@hoge ~/D/g/scraping-sample> docker run sample/robot > scraping-sample@1.0.0 start /usr/src/app > node ./example.js start google scraping Gmail 画像 ログイン 日本 プライバシー規約設定 広告ビジネスGoogleについて finish scraping先程と同様のログが出ています
これでスクレイピングのアプリをDockerコンテナとして動かすことができました
- 投稿日:2019-05-12T21:21:03+09:00
Railsの「annotate」gemが最高すぎる件
環境
- Docker version 18.09.2
- Ruby 2.4.5
- Rails 5.0.0
なぜ書いたのか
「あれ、テーブルってどんな構造してたっけ❓」
っていう時がかなりあった。今まで確認する時は、
- DBに入る
- コマンドぽちぽち入力
- DB抜ける
上記3点のプロセスだったのが、
- Modelのrbファイル確認
annotateをインストールするだけでここまで短縮できることに感動したから
導入、実装
1.Gemfileに追記
Gemfilegroup :development do gem 'annotate' end※基本的に開発環境でのみ使用するので、development内に書く
2.gemをインストール
ターミナル$ docker-compose build3.gemの実行
ターミナル$ docker-compose exec web bundle exec annotateこれでModelを確認すると、下記のような感じでコメントアウトでテーブルの構造が!すごい!
ただこれだとテーブルを作成、更新するたびに実行しなければならないので、
migrationをトリガーに実行するように設定ファイルを生成ターミナルdocker-compose exec web bundle exec rails g annotate:installこれでmigrationの度にannotateが実行されるように?
おまけ
routeにも適用できるらしいのでやってみた
ターミナル$ docker-compose exec web bundle exec annotate --routes参考
https://qiita.com/tsuchinoko_run/items/9bcc15e8992cb237e08a
https://www.udemy.com/share/1014LIB0sacllTQ3s=/
- 投稿日:2019-05-12T19:58:27+09:00
Docker CEからRootless Dockerへ移行してみる on EC2
概要
現在、EC2上でDocker CEを利用している。先日↓の記事を見かけたので、Rootless Dockerへの移行(といっても、Volumeのみ)を試してみる。
RootlessモードでDockerをより安全にする [DockerCon発表レポート] – nttlabs – MediumRootless Docker?
Rootlessモードは,Dockerデーモン及びコンテナを,非rootユーザで実行する技術です.Rootlessモードを用いることにより,万一Dockerに脆弱性や設定ミスがあっても,攻撃者にホストのroot権限を奪取されることを防ぐことが出来ます.
参考: RootlessモードでDockerをより安全にする [DockerCon発表レポート] – nttlabs – Medium
Amazon Linuxでいうところの
ec2-userユーザだけで、Dockerデーモンの起動からdockerコマンドの利用までできるということ。普通にDockerを起動すると、
rootユーザでコンテナを起動する必要があるから、rootを乗っ取られる可能性がある。
よくある一般ユーザをdockerグループに属させて、一般ユーザでdockerコマンドを利用できるようにさせても、Docker自体はrootユーザで起動させているから、rootを乗っ取られる可能性がある。Rootless Dockerは、一般ユーザだけで完結できるから、rootを取られる可能性が限りなく0に近づくってことですかね。
試した環境
少しOSやDocker CEが古いが...
OS[ec2-user@localhost ~]$ cat /etc/os-release NAME="Amazon Linux AMI" VERSION="2018.03" ID="amzn" ID_LIKE="rhel fedora" VERSION_ID="2018.03" PRETTY_NAME="Amazon Linux AMI 2018.03" ANSI_COLOR="0;33" CPE_NAME="cpe:/o:amazon:linux:2018.03:ga" HOME_URL="http://aws.amazon.com/amazon-linux-ami/"DockerCE[ec2-user@localhost ~]$ docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a215d7133c34aa18e3b72b4a21fd0c6136 Built: Mon Mar 4 21:25:23 2019 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a/18.06.1-ce Built: Mon Mar 4 21:26:49 2019 OS/Arch: linux/amd64 Experimental: false移行前のコンテナ環境
まずは、移行を試す環境を作る。
docker volume createでボリュームを作り、centosコンテナにマウントさせて起動する。
起動したコンテナ上で、1GBほどのファイルを作っておく。[root@localhost ~]# docker volume create test test [root@localhost ~]# docker run -itd -v test:/mnt centos Unable to find image 'centos:latest' locally latest: Pulling from library/centos 8ba884070f61: Pull complete Digest: sha256:b5e66c4651870a1ad435cd75922fe2cb943c9e973a9673822d1414824a1d0475 Status: Downloaded newer image for centos:latest d1256d1226bcd445616f13a0e73bbb322056c9151c7adbc7c7d84011e2afe4eb [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d1256d1226bc centos "/bin/bash" 7 seconds ago Up 6 seconds romantic_bell [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 9f38484d220f 8 weeks ago 202MB [root@localhost ~]# docker volume ls DRIVER VOLUME NAME local test [root@localhost ~]# docker exec -it romantic_bell bash [root@d1256d1226bc /]# cd /mnt [root@d1256d1226bc mnt]# dd if=/dev/zero of=zerofile bs=1024 count=1000000 1000000+0 records in 1000000+0 records out 1024000000 bytes (1.0 GB) copied, 2.46405 s, 416 MB/s [root@d1256d1226bc mnt]# ls -lh total 977M -rw-r--r-- 1 root root 977M May 12 08:49 zerofile [root@d1256d1226bc mnt]# exit移行前準備
Rootless Dockerをインストール(Docker CEを削除)する前に、ホスト側から前項で作成したボリュームを退避させる。
退避前にコンテナも止めておく。
退避したボリュームは、Rootless Dockerを実行するユーザ、グループに予め変更しておく。[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d1256d1226bc centos "/bin/bash" 7 seconds ago Up 6 seconds romantic_bell [root@localhost ~]# docker stop romantic_bell romantic_bell [root@localhost ~]# cp -rp /var/lib/docker/volumes /tmp/ [root@localhost ~]# chown -R ec2-user:ec2-user /tmp/volumes/ [root@localhost ~]# docker rm romantic_bell romantic_bellDocker CEのアンインストール
Rootless Dockerを入れる前に、Docker CEをアンインストールする。
アンインストールをしないと、何故かRootless DockerがDocker CEの/var/run/docker.sock等を使って起動しなかった[root@localhost ~]# yum -y remove docker Loaded plugins: priorities, update-motd, upgrade-helper Resolving Dependencies --> Running transaction check ---> Package docker.x86_64 0:18.06.1ce-8.28.amzn1 will be erased --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================== Package Arch Version Repository Size ============================================================================================================================================== Removing: docker x86_64 18.06.1ce-8.28.amzn1 @amzn-updates 150 M Transaction Summary ============================================================================================================================================== Remove 1 Package Installed size: 150 M Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Erasing : docker-18.06.1ce-8.28.amzn1.x86_64 1/1 Verifying : docker-18.06.1ce-8.28.amzn1.x86_64 1/1 Removed: docker.x86_64 0:18.06.1ce-8.28.amzn1 Complete! [root@localhost ~]#Rootless Dockerのインストール&実行
インストールといっても、コマンド1つで終わるらしい。
[ec2-user@localhost ~]$ curl -fsSL https://get.docker.com/rootless | sh # Missing system requirements. Please run following commands to # install the requirements and run this installer again. # Alternatively iptables checks can be disabled with SKIP_IPTABLES=1 cat <<EOF | sudo sh -x curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo yum install -y shadow-utils46-newxidmap EOFパッケージが足りない。
[ec2-user@localhost ~]$ cat <<EOF | sudo sh -x > curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo > yum install -y shadow-utils46-newxidmap > EOF ~省略~ [ec2-user@localhost ~]$ curl -fsSL https://get.docker.com/rootless | sh Could not find records for the current user ec2-user from /etc/subuid . Please make sure valid subuid range is set there. For example: echo "ec2-user:100000:65536" >> /etc/subuid
/etc/subuid,/etc/subgidがない。
そもそも見た記憶がない。作る。[root@localhost ~]$ sudo su - [root@localhost ~]# echo "ec2-user:1000:65536" >> /etc/subuid [root@localhost ~]# echo "ec2-user:1000:65536" >> /etc/subgid [root@localhost ~]# exit [ec2-user@localhost ~]$ curl -fsSL https://get.docker.com/rootless | sh # systemd not detected, dockerd daemon needs to be started manually /home/ec2-user/bin/dockerd-rootless.sh --experimental --storage-driver vfs # Docker binaries are installed in /home/ec2-user/bin # WARN: dockerd is not in your current PATH or pointing to /home/ec2-user/bin/dockerd # Make sure the following environment variables are set (or add them to ~/.bashrc):\n export XDG_RUNTIME_DIR=/tmp/docker-500 export DOCKER_HOST=unix:///tmp/docker-500/docker.sock言われた通りに、
.bashrcに追加する。
また、binディレクトリもできていたので、合わせて追加する。
/tmp/docker-500配下にdocker.sockができるので、嫌な場合はこれらの環境変数を変えておけばよさそう。[ec2-user@localhost ~]$ echo "export XDG_RUNTIME_DIR=/tmp/docker-500" >> ~/.bashrc [ec2-user@localhost ~]$ echo "export DOCKER_HOST=unix:///tmp/docker-500/docker.sock" >> ~/.bashrc [ec2-user@localhost ~]$ echo 'PATH=$PATH:$HOME/bin' >> .bashrc [ec2-user@localhost ~]$ source .bashrcインストールが終わったので、言われたとおりにサーバを起動する。
起動し続けておく必要があるので、screenで起動する。デタッチは、デフォルトはCtrl-a押してd[ec2-user@localhost ~]$ screen [ec2-user@localhost ~]$ /home/ec2-user/bin/dockerd-rootless.sh --experimental --storage-driver vfs INFO[2019-05-12T08:08:51.179358654Z] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address INFO[2019-05-12T08:08:51.330646070Z] Loading containers: done. INFO[2019-05-12T08:08:51.344736419Z] Docker daemon commit=3998dff graphdriver(s)=vfs version=master-dockerproject-2019-05-11 INFO[2019-05-12T08:08:51.344855472Z] Daemon has completed initialization INFO[2019-05-12T08:08:51.362135829Z] API listen on /tmp/docker-500/docker.sock [detached] [ec2-user@localhost ~]$ [ec2-user@localhost ~]$ docker version Client: Version: master-dockerproject-2019-05-11 API version: 1.40 Go version: go1.12.5 Git commit: 53fc2572 Built: Sat May 11 23:39:34 2019 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: master-dockerproject-2019-05-11 API version: 1.40 (minimum version 1.12) Go version: go1.12.5 Git commit: 3998dff Built: Sat May 11 23:46:26 2019 OS/Arch: linux/amd64 Experimental: true containerd: Version: v1.2.6 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc: Version: 1.0.0-rc8 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f docker-init: Version: 0.18.0 GitCommit: fec3683適当なコンテナを起動してみる
dockerコマンドはパスを通したので今までどおり使える。[ec2-user@localhost ~]$ docker run -d -p 8080:80 nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 743f2d6c1f65: Pull complete 6bfc4ec4420a: Pull complete 688a776db95f: Pull complete Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68 Status: Downloaded newer image for nginx:latest a26c026eddf0f0d92db01e6cd6984f83904ffc5b4d69dd245a3a88081cdc6db5 [ec2-user@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a26c026eddf0 nginx "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp xenodochial_khayyam [ec2-user@localhost ~]$ curl http://localhost:8080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [ec2-user@localhost ~]$Rootless Docker動いた
ボリュームの移行
そもそも
volumesディレクトリはどこにあるのか。[ec2-user@ip-172-31-47-41 ~]$ ll /tmp/docker-500/ total 12 drwx-----T 7 ec2-user ec2-user 4096 May 12 08:58 docker -rw-r--r-T 1 ec2-user ec2-user 5 May 12 08:58 docker.pid srw-rw---T 1 ec2-user 1496 0 May 12 08:58 docker.sock drwx-----T 2 ec2-user ec2-user 4096 May 12 08:08 runc [ec2-user@ip-172-31-47-41 ~]$ find . -name 'docker' ./.vim/plugged/ultisnips/docker ./.local/share/docker ~省略~ [ec2-user@ip-172-31-47-41 ~]$ ll .local/share/docker/ total 56 drwx------ 2 ec2-user ec2-user 4096 May 12 08:08 builder drwx------ 4 ec2-user ec2-user 4096 May 12 08:08 buildkit drwx------ 3 ec2-user ec2-user 4096 May 12 08:08 containerd drwx------ 4 ec2-user ec2-user 4096 May 12 09:11 containers -rw------- 1 ec2-user ec2-user 36 May 12 08:08 engine_uuid drwx------ 3 ec2-user ec2-user 4096 May 12 08:08 image drwxr-x--- 3 ec2-user ec2-user 4096 May 12 08:08 network drwx------ 4 ec2-user ec2-user 4096 May 12 08:08 plugins drwx------ 2 ec2-user ec2-user 4096 May 12 08:58 runtimes drwx------ 2 ec2-user ec2-user 4096 May 12 08:08 swarm drwx------ 2 ec2-user ec2-user 4096 May 12 09:11 tmp drwx------ 2 ec2-user ec2-user 4096 May 12 08:08 trust drwx------ 3 ec2-user ec2-user 4096 May 12 08:15 vfs drwx------ 3 ec2-user ec2-user 4096 May 12 09:08 volumes [ec2-user@ip-172-31-47-41 ~]$ホームディレクトリの
.local/share/docker配下にあった[ec2-user@ip-172-31-47-41 ~]$ ll .local/share/docker/volumes total 24 -rw------- 1 ec2-user ec2-user 32768 May 12 09:08 metadata.dbメタデータがあるので、ディレクトリだけ移動
でも移動だけだと認識されないので、同名でdocker volume create[ec2-user@localhost ~]$ mv /tmp/volumes/test ~/.local/share/docker/volume/ [ec2-user@localhost ~]$ docker volume ls DRIVER VOLUME NAME [ec2-user@localhost ~]$ [ec2-user@localhost ~]$ docker volume create test test [ec2-user@localhost ~]$ docker volume ls DRIVER VOLUME NAME local testあとは、
Docker CEのときと同じようにコンテナを作成する。[ec2-user@localhost ~]$ docker run -itd -v test:/mnt centos Unable to find image 'centos:latest' locally latest: Pulling from library/centos 8ba884070f61: Pull complete Digest: sha256:b5e66c4651870a1ad435cd75922fe2cb943c9e973a9673822d1414824a1d0475 Status: Downloaded newer image for centos:latest cfbadb0e2e67047bf25e23a2ce73835dfb9557e8341e4aead1cf658d69eacf9a [ec2-user@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfbadb0e2e67 centos "/bin/bash" About a minute ago Up About a minute jolly_fermi [ec2-user@localhost ~]$ [ec2-user@localhost ~]$ [ec2-user@localhost ~]$ docker inspect jolly_fermi | grep volume "Type": "volume", "Source": "/home/ec2-user/.local/share/docker/volumes/test/_data", [ec2-user@localhost ~]$ docker exec jolly_fermi /bin/ls /mnt -l total 1000004 -rw-r--r-- 1 root root 1024000000 May 12 08:49 zerofile [ec2-user@ip-172-31-47-41 ~]$ docker exec jolly_fermi bash -c "echo 'hello' >> /mnt/hello.txt" [ec2-user@ip-172-31-47-41 ~]$ cat .local/share/docker/volumes/test/_data/hello.txt hello [ec2-user@ip-172-31-47-41 ~]$どうやらボリュームの移行はちゃんとできたようだ
[参考]
moby/rootless.md at master · moby/moby
RootlessモードでDockerをより安全にする [DockerCon発表レポート] – nttlabs – Medium最後に
気が向いたら
docker-composeで作成したものも試しておきたい。
- 投稿日:2019-05-12T19:50:56+09:00
【Docker for Windows】コンテナ上のChromiumのウインドウとサウンドをホストOSへ転送してみた
やったこと
Docker for Windows上のコンテナでChromiumを起動させ、ChromiumのウインドウとサウンドをホストOSであるWindows 10へ転送しました。
コンテナ上のChromiumからウインドウ、サウンドをそれぞれ以下の手法で転送しました。
概念図
動作環境
- Windows 10 Pro version 1803, build 17134.706
- Docker Desktop version 2.0.0.3 (31259), build: 8858db3
- Docker Engine version 18.09.2, build 6247962
やり方
1. ホストOS(Windows 10)側での準備
1.1. X11 Server の導入
1.1.1. X11 Server のインストール
コンテナ上のウインドウを受信するため、Windows 10にX11 Serverをインストールします。
ここでは、X11 ServerとしてVcXsrvを使用します。インストールに当たり、参考にさせて頂きましたサイトを掲載します。(丸投げのような形で申し訳ございません)1.1.2. X11 Server の起動
デスクトップ上の「XLaunch」から、VcXsrvを起動します。(全て[次へ]を選択し、[完了]を押せばOKです)
タスクトレイにVcXsrvのアイコンが表示されていれば、起動しています。
1.2. PulseAudio for Windowsの導入
1.2.1. PulseAudio for Windows のインストール
PulseAudio on Windowsのダウンロードサイトから「zipfile containing preview binaries」を選択して、zipファイルをダウンロードし、任意に場所へ解凍します。
1.2.2. PulseAudio for Windows の設定
- 「etc\pulse\default.pa」の編集
42行目 設定 変更前 load-module module-waveout sink_name=output source_name=input 変更後 load-module module-waveout sink_name=output source_name=input record=0
61行目 設定 変更前 #load-module module-native-protocol-tcp 変更後 load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1
- 「etc\pulse\daemon.conf」の編集
39行目 設定 変更前 ; exit-idle-time = 20 変更後 exit-idle-time = -1 1.2.3. PulseAudio for Windows の起動
解凍した「pulseaudio-1.1」フォルダと同階層に以下のバッチファイルを配置して、実行します。
pulseaudio.bat@echo off cd /d %~dp0 powershell -NoProfile -Command Start-Process -WindowStyle Minimized '.\pulseaudio-1.1\bin\pulseaudio.exe'以下のようなコマンドプロンプトが表示されていれば、起動しています。(「Ctrl+C」で停止できます)
※Windows Firewallから許可を求められた場合は、許可をしてください。
2. Dockerイメージの作成
2.1. X11 の環境設定
Dockerfile内で環境変数 DISPLAYを以下のように設定します。
ENV DISPLAY=host.docker.internal:0.02.2. Pulseaudio の環境設定
Dockerfile内で環境変数 PULSE_SERVERを以下のように設定します。
ENV PULSE_SERVER=tcp:host.docker.internal:4713また、ALSAのdefaultサウンドカードとして、PulseAudio(仮想サウンドカード)を登録します。
{ \ echo "pcm.default pulse"; \ echo "ctl.default pulse"; \ } | tee ~chrome/.asoundrc \ && chown -R chrome:chrome /home/chrome2.3 Dockerfileサンプル
zenika/alpine-chromeをベースに以下のDockerfileを作成しました。
Dockerfile# Credit goes to Zenika (https://github.com/Zenika/alpine-chrome/blob/master/Dockerfile) FROM alpine:latest # Installs latest Chromium package. RUN echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \ && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \ && apk add --no-cache \ chromium@edge \ harfbuzz@edge \ nss@edge \ freetype@edge \ ttf-freefont@edge \ mesa-gl \ pulseaudio \ pulseaudio-libs \ alsa-plugins-pulse@edge \ bash \ && wget https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \ && mkdir -p /usr/share/fonts/NotoSansCJKjp \ && unzip NotoSansCJKjp-hinted.zip -d /usr/share/fonts/NotoSansCJKjp/ \ && chmod 644 /usr/share/fonts/NotoSansCJKjp/*.otf \ && rm NotoSansCJKjp-hinted.zip \ && fc-cache -fv # Add user so we don't need --no-sandbox. RUN addgroup -S chrome \ && adduser -S -G chrome chrome \ && mkdir -p /home/chrome/Downloads \ && { \ echo "pcm.default pulse"; \ echo "ctl.default pulse"; \ } | tee /home/chrome/.asoundrc \ && chown -R chrome:chrome /home/chrome # Run Chrome as non-privileged USER chrome WORKDIR /home/chrome ENV CHROME_BIN=/usr/bin/chromium-browser ENV CHROME_PATH=/usr/lib/chromium/ ENV DISPLAY=host.docker.internal:0.0 ENV PULSE_SERVER=tcp:host.docker.internal:4713 # Autorun chrome ENTRYPOINT ["chromium-browser", "--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage"]2.4 ビルド
docker build -t speaktech/secure-browser:1.0 .3. コンテナの実行
zenika/alpine-chromeの手引きに従い、限られた権限でChromiumのsandobox機能を利用するためにseccompプロファイル(chrome.json)を利用します。
Invoke-WebRequest -Uri https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -OutFile chrome.json docker run -it --rm --security-opt seccomp=$(pwd)/chrome.json speaktech/secure-browser:1.0コンテナを実行すると、Windows 10上でChromiumが起動します。Youtubeなどで音声がWindows 10へ転送されることを確認できれば、完了です。
4. 最後に、なぜやろうと思ったのか?
インターネットへのアクセスをコンテナに実行させることで、セキュアなブラウザ環境ができるのでは?と思い、やってみました。
ブラウザを閉じる度にコンテナごと削除するので、ウイルス感染後の情報漏洩等のリスクが低くなります。
また、Windows Firewallを利用して、コンテナからの通信をウインドウ/サウンドの転送のみに絞ることで、ホストOSのウイルス感染リスクを軽減できると考えます。難点としては、ウインドウとサウンドを非同期に転送している関係上若干音ズレします。(私個人としては、許容範囲内です)
「これで、より安心に、いろいろなサイトを閲覧できる気がします」という意味深な感想で締めさせていただきます。
最後までご拝読いただきまして、ありがとうございました。
- 投稿日:2019-05-12T12:51:50+09:00
GO111MODULE=onなプロジェクトでDockerのビルド時間を短くした工夫
はじめに
Go1.11から採用のGo Modules(vgo)なプロジェクトにて、Dockerのビルドが遅かったのをキャッシュ利用で一応解決できた話。
順を追って
はじめの状態
下記のような構成
. ├── Dockerfile ├── go.mod ├── go.sum └── main.goDockerfile一部抜粋COPY . ./ RUN CGO_ENABLED=0 GOOS=linux go build -o binary # 遅い!Goコードの中では大きなOSSプロジェクトライブラリを利用しているので本コードを改修するたびにDockerビルドにて対象パッケージをダウンロードして遅い!
次にvendorをレポジトリに入れてみた
下記のコマンドでパッケージたちをvendorとしてレポジトリに組み込んでみました。
$ go mod vendor $ tree . ├── Dockerfile ├── go.mod ├── go.sum ├── main.go └── vendor ├── package1 ├── package2Dockerfile一部抜粋COPY . ./ # ここの通信コストが大きくなってしまった RUN CGO_ENABLED=0 GOOS=linux go build -mod=vendor -o binary # ここは速くなったけどこれでパッケージを毎回ダウンロードしないのでビルド時間はたしかに短くなった。
しかしレポジトリが巨大になってしまいました。
そして、このプロジェクトではDocker-Machineのリモート接続でDockerを扱っているのでローカルからリモートへの通信コストがvendorのせいでエグいことになってしまいました。
(そもそも.dockerignoreもまともに記載していなかったのでこれはこれで対応。)解決策 パッケージダウンロードなイメージレイヤを設けてキャッシュ利用
vendorは削除しました。
他言語のプロジェクトと同様な戦略でパッケージに関わる部分を先にダウンロードするイメージレイヤを作ることでキャッシュを活用することにしました。Dockerfile一部抜粋ENV GO111MODULE="on" # Go Modulesを使うと明言する COPY go.mod go.sum ./ # パッケージ用メタファイルだけコピー RUN go mod download # メタファイルに変更がなければキャッシュ利用できる COPY . ./ RUN CGO_ENABLED=0 GOOS=linux go build -o binary
go.modに修正が入らない限りRUN go mod downloadはキャッシュが利用されるので、一番はじめのビルド時間の遅さは解決できました。
また、新しいパッケージを利用しはじめてそれがgo.modに反映されていなくてもgo buildが代わりにダウンロードするので問題なくイメージがビルドされます。最後にDockerfileの全体感
Dockerfileの全体としては以下のような感じにしています。
マルチステージングの機能を利用して最終的にできあがるイメージは最小になるよう努めています。DockerfileFROM golang:1.12.5-stretch as builder WORKDIR /workdir ENV GO111MODULE="on" COPY go.mod go.sum ./ RUN go mod download COPY . ./ RUN CGO_ENABLED=0 GOOS=linux go build -o binary FROM alpine:3.8 WORKDIR /root/ # Multi stage build function of Docker COPY --from=builder /workdir/binary . CMD ["./binary"]
- 投稿日:2019-05-12T01:57:41+09:00








