20201121のdockerに関する記事は5件です。

DockerでLaravel環境を構築するためのディレクトリ構造を一発で作成できるコマンドライン

DockerでLaravelの環境構築をする度に、ディレクトリやdockerファイル作成のためのコマンドを入力するのが面倒だったので、1回のコマンドラインで下記のような構造を作成できるようにしました。

application
├─ docker
│    ├─ php
│    │   └─ Dockerfile
│    └─ nginx
│        └─ default.conf
└─ docker-compose.yml

$ mkdir -p application/docker/php && mkdir -p application/docker/nginx && cd application/docker/php && touch Dockerfile && cd .. && cd nginx && touch default.conf && cd ../.. && touch docker-compose.yml

上記コマンドを入力すれば最低限Dockerの環境構築に必要なディレクトリやファイルを作成できます。
プロジェクト名「application」などは必要に応じて適宜変更して下さい。

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

docker-composeとGitを利用したWebシステム開発の効率化

はじめに

【コンテナとGitを利用したWebシステム開発の効率化】というタイトルで記事を投稿したが、その後docker-compose も試しに使ってみたので、その時の内容をメモとして残しておく。

実行環境

【Docker導入環境】
  ・Ubuntu 20.04 LTS(GCP上)
  ・docker 19.03.13
  ・docker-compose 1.25.0

【コンテナ環境】
  ・Image Ubuntu:20.04
  ・Apache 2.4.41  ※バージョン指定をしていないのでインストール時の最新

試してみる事

以下の流れで、docker-compose を使ってWebサービスの立ち上げ・停止などを試してみる。

1.環境準備
2.Github上にリポジトリを作成
3.ホスト側で用意するファイル
4.docker-compose を使った操作確認

1.環境の準備

GCP上にVMインスタンスを作成
 ※イメージはUbuntu20.4 LTS

パッケージ管理ツールのアップデート

$ sudo apt update

gitのインストール

$ sudo apt install -y git

dockerのインストール
 ※【Dockerコンテナ内のUbuntuではsystemctlは使えない】の手順1を参考に。

docker-composeのインストール

$ sudo apt install -y docker-compose 

問題なくインストールできているか確認

$ ddocker-compose --version
docker-compose version 1.25.0, build unknown

2.Github上にリポジトリを作成

Github上で以下を実施する。

■Public用のリポジトリを作成 
 ※手順3では、Github上のPublicリポジトリからクローンすることを前提としている。

■作成したリポジトリ内の直下に『App』フォルダを作成

■『App』フォルダ内にindex.htmlを作成
 ※中身は適当に記載

■開発用のブランチを切る
 ※手順3ではブランチ名は main(本番用)dev(開発用) を前提としている。

3.ホスト側で用意するファイル

以下のディレクトリ構成でファイルを用意

./docker-compose.yml
./Dockerfile
./site_config/
  - demo_site.conf

./mount/
  - main/
   - Github上のmainブランチをクローンする

  - dev/
   - Github上のdevブランチをクローンする

ディレクトリ作成
#################################################
# サイトコンフィグの設定ファイルを入れるディレクトリ #
#################################################
$ sudo mkdir ./site_config


################################
# マウント用のディレクトリを作成  #
################################
$ sudo mkdir ./mount

# ソースコード格納場所
$ sudo mkdir ./mount/main
$ sudo mkdir ./mount/dev
Github上のソースをクローン
$ sudo git clone --depth 1 -b main https://github.com/Smiler5617/test_websys.git ./mount/main
$ sudo git clone --depth 1 -b dev https://github.com/Smiler5617/test_websys.git ./mount/dev

以下の様に、各ファイルを作成

demo_site.conf
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/App/
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Dockerfile
# ベースイメージの取得
FROM ubuntu:20.04

# 必要パッケージのインストール
RUN apt update
RUN apt install -y tzdata
RUN apt install -y apache2

# サイト設定の読み込み
COPY ./site_config/demo_site.conf /etc/apache2/sites-available/
RUN a2dissite 000-default
RUN a2ensite demo_site

# マウント用のディレクトリを作成
RUN mkdir /var/www/html/App

# ポート開放
EXPOSE 80

CMD ["apachectl", "-D", "FOREGROUND"]
docker-compose.yml
version: '3.7'

services:
  web_main:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./mount/main/App:/var/www/html/App
    ports:
      - 8080:80

  web_dev:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./mount/dev/App:/var/www/html/App
    ports:
      - 8081:80

4.docker-compose を使った操作確認

全サービスの起動

$ docker-compose up

 ※初回起動時は、ビルドやイメージのダウンロードが自動で開始される。

以下の環境にアクセスできれば、ひとまず起動はできている。
  http://[VMの外部IP(グローバルIPアドレス)]:8080/
  http://[VMの外部IP(グローバルIPアドレス)]:8081/
 

起動停止
Ctrl + C

バックグラウンドで実行

$ docker-compose start
Starting web_main ... done
Starting web_dev  ... done

 ※$ docker-compose up -d でもOKだが、ログの確認したいならstartがよい。

停止

$ docker-compose stop
Stopping 【Googleアカウント名】_web_dev_1  ... 
Stopping 【Googleアカウント名】_web_main_1 ... 

指定してサービスの起動や停止も可能

$ docker-compose start web_main
Starting web_main ... done

$ docker-compose stop web_main
Stopping 【Googleアカウント名】_web_main_1 ... 

サービスの停止&削除

$ docker-compose down

 ※サービスが削除されると、startrestartで起動できなくなる。

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

Dockerfileの中でgnome-terminalの実行を試みるもエラー(GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.gnome.Terminal exited with status 8)

Dockerfileの中でgnome-terminalの実行を試みるもエラー

# gnome-terminal -e "python3 judge/timer.py"
# Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Error calling StartServiceByName for org.gnome.Terminal: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.gnome.Terminal exited with status 8

以下を実行する事で解決

locale-gen ja_JP.UTF-8
export LANG=ja_JP.UTF-8
export LANGUAGE=ja_JP:jp
export LC_ALL=ja_JP.UTF-8
eval `dbus-launch --sh-syntax`

Dockerfileは以下のような感じに記載すれば良い

Dockerfile
# environment setting
#RUN locale-gen en_US.UTF-8  
#ENV LANG en_US.UTF-8  
#ENV LANGUAGE en_US:en  
#ENV LC_ALL en_US.UTF-8
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:jp
ENV LC_ALL ja_JP.UTF-8
RUN echo 'eval `dbus-launch --sh-syntax`' >> /home/jetson/.bashrc

参考

gnome-terminalが機能しなくなった

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

Elasticsearchのindexの引越し。Elasticdumpはlimitオプション再定義で高速処理。

はじめに

Elasticsearch を docker を使って、ローカルマシンで使用している。
Elasticsearchのバージョンをあげてみたくなったので、データをDumpして引越ししてみることにした。

事前調査

2020/11/20現在、Googleを使って、「elasticsearch インデックス 移行」と調べてみると、Elasticdumpというスクリプトを使っているひとが多いようだ。

(以下、Googleの検索結果 表示される順に抜粋)

ElasticSearchのindexデータを移行する - Qiitaqiita.com › Node.js
https://qiita.com/taai/items/9244e7dc4dacf29ab95a

よく使うElasticSearchのクエリ(elasticdump) - Qiitaqiita.com › Elasticsearch
https://qiita.com/nakazii-co-jp/items/3199433d685d0600c6d6

Elasticsearchのデータをdumpしてコピーしたい - DRYな備忘録otiai10.hatenablog.com › entry › 2015/03/04
https://otiai10.hatenablog.com/entry/2015/03/04/152842

Elasticsearch 上のデータを割と簡単にダンプして他の ...inokara.hateblo.jp › entry › 2020/05/02
https://inokara.hateblo.jp/entry/2020/05/02/074402

...
..
.

elasticsearch-dump/elasticsearch-dump: Import and ... - GitHubgithub.com › elasticsearch-dump › el...
https://github.com/elasticsearch-dump/elasticsearch-dump

Qiita先輩方の記事の作成日が5年前であっったりしたが、githubは2020年に入っても頻繁にメンテナンスされているようだ。elasticsearchのバージョンは気にせず使えるのではないだろうか。
Google検索結果で表示される情報は、やや作成日が古いものもあることが気になったが、2020年もメンテされているなら使っても問題は少ないのではないか、と期待して、私もこの node.js スクリプトを使ってみることとした。

準備

elasticdump は、nodeスクリプトなので、マシンにnode実行環境が必要であった。私の環境ではすでにnode実行環境があるので npm install elasticdump した(あとで気づいたのだがdockerもあるようだ。)。

実行1 ( dump output=json, input=elasticsearch/index )

事前調査のいずれの先輩たちも、「elasricdump --output ^^^ --input ~~~」と、インプットとアウトプットの指定だけでdumpをし、dumpをelasticsearchに読み込ませているので、そのまま真似してやってみたのだが・・・

ドキュメント数が1200万を超え、ストレージサイズが6GBを超えていた私のindexではjsonのdumpデータの出力完了までに先輩たちと同じやり方では、24時間かかった

出力されたファイルのサイズ: 5302184689 byte

<参考:マシン環境> intel i7-3770k, 16GB Memory, SSD 960GB
<参考:docker Engine> v19.03.13
<参考:docker resources> CPUs:4, Memory:5.50GB, Swap:2GB, Disk image size:59.6GB

振り返り1

そんなに時間かかるものなのか?
動作ログを見てみる・・・なるほど、objectを100ずつ扱っていたのか。
これ、もっと増やせないのか?

elasticsearch-dump のGitHubを読むと、設定オプションがあった。

--limit
                How many objects to move in batch per operation
                limit is approximate for file streams
                (default: 100)

よし、では、dumpしたJsonを新環境に書き込むにあたっては、「--limit」オプションを追加しよう。

実行2 ( dump output=elasticsearch/index, input=json )

実行1の output と input のオプションの対象を入れ替え、 さらに limitオプションを付け足して実行する。いちどにあつかうオブジェクトの量を増やした効果を見てみた。limitの値をどの程度にするのが適切なのかわからなかったが、今回は なんとなく8000 とした。

この設定では、処理時間は 1時間半弱 であった。 概算でも16倍ほど高速だ。

振り返り2

limitの値を80倍に設定して、処理時間は24時間から1時間半へと16分の1になった。この程度の時間であれば、まだ個人利用のPCであっても我慢できる範囲だろう。まだどこかほかにボトルネックがあるのだろうが、このスクリプトで処理時間を変動させる要因のひとつはlimit値であることはまちがいない。次の機会があれば、さらにlimit値をあげてみたい。ただし、適切な値の決定方法がわからない。技術者の勘と経験で決めていいのだろうか。

まとめ

Elasticsearchのデータ移行にあたり、elasticdumpスクリプトを使った。inputとoutputのデータダンプの方向の違いはあるが、limitオプションの設定値をデフォルトの数十倍にして処理速度を比較した。その結果、limitオプションの設定値を大きくすることで、処理時間を大幅に短縮できることがわかった

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

(コンテナのネットワーク)プログラマのためのDocker教科書読む.3

少しずつDockerの本を読んでいます。

Dockerコンテナのネットワーク

Dockerコンテナ同士が通信するとき、Dockerネットワークを介して行う。

ネットワークを一覧表示する

docker network ls [オプション]
オプション 説明
-f,--filter 出力をフィルタする
-no-trunc 詳細を出力する
-q,--quiet ネットワークIDのみ出力

フィルタリングする時はkey=valueで行う。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f7b4cc9fbd9b        bridge              bridge              local
1d8a4387b9ef        host                host                local
6f720bd92331        none                null                local
df1cd37e9ffd        wordpress_default   bridge              local

bridgeネットワークIDのみを表示する

$ docker network ls -q --filter driver=bridge
f7b4cc9fbd9b
df1cd37e9ffd

この時点でもうNETWORK IDがなんなのか分からなくなったので、
こちらのガイドを読んだ。

Docker コンテナ・ネットワークの理解

ウェブアプリの構築は、安全についての考慮が必要。そのためにあるDockerネットワーク機能。

デフォルトネットワークとは

Dockerのインストールは、自動的に3つのネットワークを作成する。
bridge,host,none

さっき一覧で表示されたのを見直すと、ちゃんと3つあっt・・4つあった。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f7b4cc9fbd9b        bridge              bridge              local
1d8a4387b9ef        host                host                local
6f720bd92331        none                null                local
df1cd37e9ffd        wordpress_default   bridge              local

これは数ヶ月前にチャレンジしたDockerのものだと思われる。
コンテナとイメージしか削除してなかったから残ってしまっていたみたい。ここで知れてよかった?

前回出てきたdocker0はブリッジ(bridge)ネットワークのことを言うらしい。

LinuxにDockerをインストールすると、サーバの物理NICがdocker0という仮想ブリッジネットワークに接続される。172.17.0.0/16のサブネットマスクをもつプライベートIPアドレスが与えられる。

自分で書いてたのに理解できていなかったという。

docker run --net=<ネットワーク名> オプションでネットワーク名を指定しない限りDockerデーモンはデフォルトでこのネットワークにコンテナを接続する。なるほど!

ifconfig でネットワークの詳細を確認する。

$ ifconfig
lo0: flags=8...

docker0がない。lo0って何...

docker0がなくてlo0がある問題

このことを調べてみたら、Docker for Mac上のコンテナから、Mac上のアプリケーションに簡単に接続する方法という記事がでてきた。

Dockerホスト上(mac)にdocker0ブリッジデバイスが生成されず、Dockerコンテナから通信するためのホストのIPアドレスが明示されません。Macのループバックインターフェイスに任意のIPアドレスのエイリアスを設定することで、そのIPアドレスに対しコンテナ上からアクセスすることができるようになります。

Docker for Mac 18.03以降では、host.docker.internalを指定することで、Docker for Mac上のコンテナから、Mac上のアプリケーションに簡単に接続できるそう。

こちらのわかりやすい記事から拝借。

docker-compose.override.yaml
version: "3.5" # docker-compose.yamlのバージョンと合わせる

services:
  app: # host.docker.internalを使用したいサービス名
    extra_hosts:
      - "host.docker.internal:172.101.0.1" # 下のsubnetの指定に合わせる

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: 172.101.0.0/16 # 他のnetworkと被らないように指定
...

host.docker.internalの使い方はextra_hostsに記述するそう。
サブネット部分172.101.0同じだ。

このdocker-compose.override.yamlというファイルは、docker-composeコマンド実行時に自動で読まれるファイル。自分専用設定を書く際に重宝する。おいおい出てくると思うからとりあえず今は忘れる。

Windowsなら考えなくてよい問題みたい。

どうやって接続がされているのかを見る

Dockerホスト上全てのデフォルトネットワークブリッジを見るには以下を使う

docker network inspect bridge

見てみる

$ docker network inspect bridge
[
    {
      "Name": "bridge",

~略~

        "Config": [
            {
              "Subnet": "172.17.0.0/16",
              "Gateway": "172.17.0.1"
            }
          ]
...

ここのSubnetGatewayを見ておく。
docker runコマンドは新しいコンテナに対し、自動的にネットワークを割り当てる。

コンテナを2つ起動する

$ docker run -itd --name=container1 nginx
31e0144049b63d69e97047ba4974e525aa0e
$ docker run -itd --name=container2 nginx
08c474ab40291f148744ef6da39a4e9729ee

もう一度確認する

$ docker network inspect bridge

~略~

    "Config": [
        {
            "Subnet": "172.17.0.0/16",
            "Gateway": "172.17.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
        "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
      "91f14744ef6da39a4e9729ee311fb100000": {
          "Name": "container2",
          "EndpointID": "6eac2e57c7d08acdcafec3bd2700000000",
          "MacAddress": "MacAddress",
          "IPv4Address": "172.17.0.3/16",
          "IPv6Address": ""
      },
      "63d69e9047ba4974e5edffe745": {
          "Name": "container1",
          "EndpointID": "db8da63ecb9fbd6c4b29c5f65c3f10000000",
          "MacAddress": "MacAddress",
          "IPv4Address": "172.17.0.2/16",
          "IPv6Address": ""
        }
    },

~略~

2つのコンテナのContainersそれぞれのIPv4Addressが割り当てられている。
Gatewayはルーターのようにネットワークをつなぐためのもの。

ここまでまとめ

ネットワークの指定をせずにコンテナを立ち上げると、デフォルトのbrigeネットワークが使われて、その際のIPは自動で設定される。

新しいネットワークの作成

ネットワークを作成する

docker network create [オプション] ネットワーク名

-d,--driverオプションでbridgeoverlayを選択できる。デフォルトはbridgeになっている。
(このoverlayネットワークは複数のホストをまたぐネットワークになる。)

作成する

$ docker network create --driver=bridge web-network

確認する(bridgeのみの一覧を表示させる)

$ docker network ls --filter driver=bridge
f7b4cc9fbd9b        bridge              bridge              local
635e9f46ac57        web-network         bridge              local
df1cd37e9ffd        wordpress_default   bridge              local

web-networkが出来ていることが確認できた。

詳細を見る

$ docker network inspect web-network
[
    {
        "Name": "web-network",
        "Id": "337bfb03",
        "Created": "created",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },

先ほどとは違い172.18.0.0/16とサブネットの値が違っている!!
(だから他ネットワークと被っていない!!)

ネットワークへの接続/切断

接続する

$ docker network connect [オプション] ネットワーク コンテナ

接続して、コンテナを起動し、接続の詳細をみる

$ docker network connect web-network container1
$ docker start container1
$ docker network inspect web-network

{
    "Name": "web-network",

~略~

    "Config": [
        {
            "Subnet": "172.18.0.0/16",
            "Gateway": "172.18.0.1"
        }
    ]


~略~

  "Containers": {
      "31e0144049b63d69e97047ba4974e5edffe71d": {
          "Name": "container1",
          "EndpointID": "6422af21664b935bedb7f2",
          "MacAddress": "MacAddress",
          "IPv4Address": "172.18.0.2/16",
          "IPv6Address": ""
      }
    },

~略~

IPv4Addressをみると、コンテナcontainer1web-networkに接続されていることが確認できた。

切断する

$ docker network disconnect ネットワーク コンテナ
$ docker stop container1
$ docker network disconnect web-network container1

ネットワークがデフォルトのbridgeに接続されているかを確認する

$ docker start container1
$ docker container inspect container1
$ docker network inspect bridge


  {
      "Name": "bridge",

~略~

      "Config": [
        {
          "Subnet": "172.17.0.0/16",
          "Gateway": "172.17.0.1"
        }
      ]
    },

~略~

      "Containers": {
        "31e0144049b63d69e970974e5edf71725aa": {
          "Name": "container1",
          "EndpointID": "70e9a2ecfc03ec1632e1e8b2513624f3657",
          "MacAddress": "MacAddress",
          "IPv4Address": "172.17.0.2/16",
          "IPv6Address": ""
        }
      },


デフォルトのbridgeに接続されているので、web-networkはきちんと切断されている。

ネットワークの削除

ネットワークを削除するときは、接続中の全てのコンテナとの接続をdocker network disconnectコマンドで切断する必要がある。

docker network rm [オプション] ネットワーク

削除する。(前に作成してずっと残っていたネットワークも一緒に。)

$ docker network rm web-network
web-network

$ docker network rm wordpress_default
wordpress_default

綺麗になった!

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f7b4cc9fbd9b        bridge              bridge              local
1d8a4387b9ef        host                host                local
6f720bd92331        none                null                local

まとめ

  • Dockerインストール時に自動で3つネットワークが設定されている。bridge,host,none
  • コンテナのネットワークは、指定がなければデフォルトのbridgeに接続される。
  • 作成したネットワークを削除するときは、接続解除してから行うこと。

向き合うのを逃げてきたネットワークでしたが、調べてるとDockerのネットワークのしくみをぼんやりと頭でイメージ出来るようになりました。理解するのに時間かかったけど、調べてよかったです。
ネットワークの詳細一覧は初見殺しだけど、必要なとこだけを見てみるとよかったんですね。

参考文献

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