Docker 不要リソースお掃除 compose

Docker 不要リソースお掃除 compose

概要

ECS EC2 で一部コンテナが 起動開始 → 失敗 → 起動開始 → 失敗 を繰り返し
サーバが容量不足 no space left に陥る事象がありました。

その時の対応をまとめました。

続きを読む
docker build 時に Text file busy で shell が実行できない対策

docker build 時に Text file busy で shell が実行できない対策

概要

Dockerfile 内に以下のように shell の実行を記述していました。

1
2
RUN chmod +x hoge.sh \
&& hoge.sh

上記記述のある状態で docker build 実行した所、以下のようなエラーに遭遇しました。

1
/bin/sh: hoge.sh: Text file busy

What is Text file busy ?

書き込みのために現在開いている手続きのみの (共用テキスト) ファイルを実行しようとした場合や、実行中の手続きのみのファイルを書き込みのために開こうとしたり、削除しようとしたりする場合に発生します。

上記鑑みると
chmod +x hoge.sh 実行中に hoge.sh を実行しようとしたが為に発生しているということ??
と推測。

環境情報

  • Ubuntu 14.04.5 LTS \n \l
  • Docker version 17.05.0-ce, build 89658be
  • Base Image: ruby:2.5-alpine

対策

以下 sync 処理を追加し無事問題解決できました。

1
2
3
RUN chmod +x hoge.sh \
&& sync \
&& hoge.sh

What is sync command ?

参考

docker-comopse で Rails 5 (Puma) + Nginx + Mysql 構築 on Vagrant(Ubuntu)

docker-comopse で Rails 5 (Puma) + Nginx + Mysql 構築 on Vagrant(Ubuntu)

自身の Rails 開発環境の雛形として利用している docker-compose です。

以下設定手順です。

Vagrant 起動

1
2
3
4
macOS%$ git clone https://github.com/kenzo0107/vagrant-docker
macOS%$ cd ./vagrant-docker/
macOS%$ vagrant up
macOS%$ vagrant ssh

Rails プロジェクト作成

1
2
3
// on vagrant
vagrant%$ cd /vagrant/rails-puma-nginx-mysql
vagrant%$ docker-compose run --rm web rails new . --force --database=mysql --skip-bundle

puma 設定ファイルセット

1
vagrant%$ cp puma.rb ./rails/config/
  • ./rails/config/puma.rb
1
2
3
4
5
6
7
8
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

データベース設定ファイルセット

1
vagrant%$ cp database.yml ./rails/config/
  • ./rails/config/database.yml
1
2
3
4
5
6
7
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: <%= ENV['MYSQL_ROOT_PASSWORD'] %> # <--- MYSQL_ROOT_PASSWORD
host: db # <--- service name

データベース作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vagrant%$ docker-compose run --rm web rails db:create
Created database 'app_development'
Created database 'app_test'

vagrant%$ docker-compose exec db mysql -u root -p -e'show databases;'
Enter password: (password)
+--------------------+
| Database |
+--------------------+
| information_schema |
| app_development | <--- add !
| app_test | <--- add !
| mysql |
| performance_schema |
| sys |
+--------------------+

以上で必要最低限の Rails プロジェクトの準備ができました!

Rails, Nginx, MySQL 全コンテナ起動

1
vagrant%$ docker-compose up -d

ブラウザより http://192.168.35.101 へアクセスし
Rails トップページが表示されることが確認できます。

総評

docker でコンテナ化しているので Nginx, MySQL 等、
バージョンアップしたい時でもコンテナを置き換えるだけで簡単に使用感を確認できたり
機能を確認できたりと便利です。

これに Elasticsearch + Kibana でログを可視化したり
Mailcatcher でメール送信を確認できるようにしたりと
開発するには十分な状況が用意できます。

是非開発の一助になれば幸いです。

Vagrant + docker-compose で Rails 5.1.0 (Puma) + Nginx + MySQL 環境構築

Vagrant + docker-compose で Rails 5.1.0 (Puma) + Nginx + MySQL 環境構築

概要

簡易的に Rails 環境を構築・開発できる様にすべく構築しました。

こんな時に利用してます。

  • 新規プロジェクト開発
  • 新規 gem, その他ミドルウェアの試験
  • 簡単なモックを作ってディレクターに見せたい時とか

構築手順をまとめました。

環境

  • macOS Sierra 10.12.5
  • VirtualBox 5.1.18r114002
  • Vagrant 1.9.3
  • VagrantBox Ubuntu 14.04.5
  • Docker version 17.06.0-ce, build 02c1d87

Git Clone

1
2
3
4
5
macOS%$ git clone https://github.com/kenzo0107/vagrant-docker
macOS%$ cd vagrant-docker
macOS%$ vagrant up
macOS%$ vagrant ssh
vagrant%$ cd /vagrant/rails-puma-nginx-mysql/

Rails プロジェクト作成

1
2
// database = mysql
vagrant%$ docker-compose run --rm web rails new . --force --database=mysql --skip-bundle

puma.rb 設定

1
2
3
// backup
vagrant%$ cp ./rails/config/puma.rb ./rails/config/puma.rb.bk
vagrant%$ cp puma.rb ./rails/config/
  • ./rails/config/puma.rb
1
2
3
4
5
6
7
8
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

データベース接続情報設定

1
2
3
// backup
vagrant%$ cp ./rails/config/database.yml ./rails/config/database.yml.bk
vagrant%$ cp database.yml ./rails/config/
  • ./rails/config/database.yml
1
2
3
4
5
6
7
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: <%= ENV['MYSQL_ROOT_PASSWORD'] %> # <--- MYSQL_ROOT_PASSWORD
host: db # <--- service name

DB 作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vagrant%$ docker-compose run --rm web rails db:create
Created database 'app_development'
Created database 'app_test'

vagrant%$ docker-compose exec db mysql -u root -p -e'show databases;'
Enter password: (password)
+--------------------+
| Database |
+--------------------+
| information_schema |
| app_development | <--- add !
| app_test | <--- add !
| mysql |
| performance_schema |
| sys |
+--------------------+

Rails 実行

1
vagrant%$ docker-compose up -d

http://192.168.35.101 にアクセスすると Rails のウェルカムページが表示されます。

rails g

rails g 実行時は基本 one-off container で実行するのが良いです。

例えば以下は articles テーブルを作成、また、関連する controller, view, model を作成します。

1
vagrant%$ docker-compose run --rm web rails g scaffold article title:string body:text

Gemfile 更新

Gemfile 更新した際はビルドし再起動します。

1
2
3
vagrant%$ docker-compose stop web
vagrant%$ docker-compose build web
vagrant%$ docker-compose up -d web

あとがき

Rack server との接続は一癖ありましたが、そこさえ乗り越えたら
すっと行きました ♪

DB は 3306 でオープンしてるので
Mac のローカルから Sequel Pro で接続して確認できます。

これをベースに EFK でログ確認できる様にしたり、
mailcatcher でメール機能を試験できる様にしたりと
何かと便利です。

Docker 有難や ♪

Mackerel で Docker の起動状態確認

Mackerel で Docker の起動状態確認

概要

Docker コンテナがいつの間にか Exit していた!
なんてことを防ぐ為の Mackerel Agent の設定です。

mackerel-plugin-docker-state インストール

1
2
3
4
5
6
7
$ sudo mkdir -p /etc/mackerel-agent/conf.d
$ sudo curl https://raw.githubusercontent.com/ABCanG/mackerel-plugin-docker-state/master/mackerel-plugin-docker-state -o /etc/mackerel-agent/conf.d/mackerel-plugin-docker-state
$ sudo chmod +x /etc/mackerel-agent/conf.d/mackerel-plugin-docker-state
$ sudo cat <<'EOF'>/etc/mackerel-agent/conf.d/docker-state.conf
[plugin.metrics.docker-state]
command = "/etc/mackerel-agent/conf.d/mackerel-plugin-docker-state"
EOF

mackerel-agent.conf に include 設定追加

  • /etc/mackerel-agent/mackerel-agent.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
pidfile = "/var/run/mackerel-agent.pid"
root = "/var/lib/mackerel-agent"
verbose = false
apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
diagnostic = true

roles = ["xxxxxxxx:xxx"]

# include conf.d/*.conf
include = "/etc/mackerel-agent/conf.d/*.conf"

...
...

Mackrel Agent 再起動

1
$ sudo service mackerel-agent restart

グラフ確認

しばらくするとグラフが表示されます。
※0 or 1 のみのグラフなので積み重ねグラフの方が見やすかったです

※上記グラフではコンテナ 2 つが起動しています。

新規監視ルールを作成

running で検索すると出てきます。

3 分間の平均が 1 より低くなったら
コンテナが停止(Exit)と見なし通知する様にしました。

総評

今回たまたま Mackerel の入ったサービスを触る機会を頂きました。

Mackerel の様なマネージドサービスを利用するメリットは
監視サーバを監視しないで良い、
という省運用コストだなぁと改めて実感。

docker-compose で開発環境構築 〜Nginx アクセスログ(ltsv) を fluentd + elasticsearch + kibana で可視化〜

docker-compose で開発環境構築 〜Nginx アクセスログ(ltsv) を fluentd + elasticsearch + kibana で可視化〜

概要

前回構築した Vagrant 環境上で docker-compose による開発環境構築をします。

今回は前回の続きで Nginx のアクセスログを Elasticsearch + Fluentd + Kibana で可視化してみます。
アプリ

簡単構築手順

1
2
3
4
5
6
7
8
9
10
macOS% $ git clone https://github.com/kenzo0107/vagrant-docker
macOS% $ cd vagrant-docker
macOS% $ vagrant up
macOS% $ vagrant ssh
vagrant% $ cd /vagrant/nginx-efk

// -d デタッチモードでないのは各コンテナの起動状況がログで見える為です。
vagrant% $ docker-compose up
...
...

docker-compose 構成

Git にまとめています。

1
2
3
4
5
6
7
8
9
10
├── docker-compose.yml
├── fluentd
│   ├── conf
│   │   ├── conf.d
│   │   │   └── nginx.log.conf
│   │   └── fluent.conf
│   └── Dockerfile
└── nginx
└── conf
└── nginx.conf

ポイント

  • nginx のログ格納場所を volume 指定しホスト側とシンク。 それを fluentd 側でも volume 指定し tail するようにしました。

以下のようなイメージです。

ブラウザから Nginx 起動確認

ブラウザから http://192.168.35.101/ にアクセスすると
Nginx の Welcome ページが確認できます。

先程の docker-compose up 後に以下のようなログが見え
fluentd が Nginx アクセスログを捕まえているのがわかります。

Kibana にアクセス

ブラウザから http://192.168.35.101:5601 にアクセスすると
Kibana ページが表示されます。

  1. Index name or pattern

    • fluentd-* 指定
  2. Time-field name

    • @timestamp 指定
  3. Create ボタン押下

  4. レフトメニューから Discover クリック

macOS からログ確認

当然ながら macOS と vagrant とシンクしているので
macOS 上からもログが tail できます。

1
macOS%$ tail -f <path/to/vagrant-docker>/docker/nginx-efk/_log/nginx/access.log

以上です。
参考になれば幸いです。

Docker コマンド早見表

Docker コマンド早見表

バージョン

1
2
3
docker --version

Docker version 17.04.0-ce, build 4845c56

コンテナ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker ps                     # running コンテナ一覧
docker ps -a # 全コンテナ一覧表示
docker start <CONTAINER ID> # コンテナ起動
docker restart <CONTAINER ID> # コンテナ再起動
docker stop <CONTAINER ID> # コンテナ終了
docker kill <CONTAINER ID> # コンテナ強制終了
docker attach <CONTAINER ID> # コンテナへアタッチ
docker top <CONTAINER ID> # コンテナプロセスを表示
docker logs -f <CONTAINER ID> # コンテナログ表示
docker inspect <CONTAINER ID> # コンテナ情報表示
docker rm <CONTAINER ID> # コンテナID指定でコンテナ削除
dockre rm <CONTAINER NAME...> # コンテナ名(複数)指定でコンテナ削除
docker container prune # 停止コンテナを削除

dockr run -it -h <host name> <IMAGE>[:TAG] <command> # イメージよりコンテナ起動 command 実施

イメージ

1
2
3
4
docker pull <IMAGE NAME>[:tag]     # イメージダウンロード
docker images ls # イメージ一覧
docker inspect <IMAGE ID> # イメージ情報表示
docker rmi <IMAGE ID> # イメージ削除

イメージ作成

1
2
docker build -t NAME[:TAG]
docker commit -m "<comment here>" <CONTAINER ID> <IMAGE NAME>[:TAG]

Docker Compose

1
2
3
4
5
docker-compose up -d    # デタッチモードでイメージよりコンテナ起動
docker-compose ps # コンテナ一覧表示
docker-compose stop # docker compose 管理下全てのコンテナ停止
docker-compose start # docker compose 管理下全てのコンテナ起動
docker-compose rm # docker compose 管理下全ての停止コンテナ削除
Vagrant (Ubuntu) に Docker, Docker Compose インストール

Vagrant (Ubuntu) に Docker, Docker Compose インストール

概要

開発環境構築用に作成した、
Vagrant (Ubuntu) に Docker と Docker Compose をインストールする手順をまとめました。

Vagrantfile 作成

かなりシンプルにしてます。

  • Vagrantfile
1
2
3
4
5
6
7
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "private_network", ip: "192.168.35.101"
end

vagrant provision で docker compose をインストールすることも可能ですが
vagrant ならではの provision だと他環境で利用できない為、OS 上でインストールする方針です。

VM 起動

1
2
3
4
5
6
7
8
9
MacOS%$ vagrant up
...
しばし待つ
...

MacOS%$ vagrant ssh

// ssh ログイン成功
vagrant%$

Vagrant Ubuntu 環境情報確認

1
2
3
4
5
6
7
vagrant%$ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty

カーネルバージョン確認

1
2
vagrant%$ uname -r
3.13.0-116-generic

カーネルバージョンが 3.10 より低いとバグを引き起こす危険性があるので NG。
別のカーネルバージョンの高い box を使用しましょう。

古いバージョンをアンインストール

1
vagrant%$ sudo apt-get remove docker docker-engine

extra パッケージインストール

Docker に aufs ストレージを使用許可する為です。

1
2
3
4
5
vagrant%$ sudo apt-get update
vagrant%$ sudo apt-get -y install \
wget \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual

Docker インストール

1
2
3
4
5
6
7
8
9
// Docker インストール
vagrant%$ wget -qO- https://get.docker.com/ | sh

// Docker バージョン確認
vagrant%$ docker --version
Docker version 17.04.0-ce, build 4845c56

// vagrant ユーザを docker グループに追加 (一旦ログアウトしログインし直すと有効になることを確認できます)
vagrant%$ sudo usermod -aG docker vagrant

Docker Compose インストール

1
2
3
4
5
6
7
8
9
10
11
vagrant%$ curl -L "https://github.com/docker/compose/releases/download/1.12.0/docker-compose-$(uname -s)-$(uname -m)" >  ~/docker-compose

// 実行権限付与
vagrant%$ chmod +x ~/docker-compose

// 実行パス移動
vagrant%$ sudo mv docker-compose /usr/bin/

// Docker Compose バージョン確認
vagrant%$ docker-compose --version
docker-compose version 1.12.0, build b31ff33

一度ログアウトし再度ログイン

1
2
3
vagrant%$ exit
MacOS%$ vagrant ssh
vagrant%$

メモリとスワップ利用量の調整

Docker を使用していない時にメモリのオーバーヘッドとパフォーマンス劣化を低減させる様、
GRUB (GRand Unified Bootloader: グラブ or ジーラブ) に設定する必要があります。

  • grub 設定
1
2
3
4
vagrant%$ sudo vi /etc/default/grub

# GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
  • GRUB (GRand Unified Bootloader: グラブ or ジーラブ) 更新
1
2
3
4
vagrant%$ sudo update-grub

// 念の為、再起動
vagrant%$ sudo reboot

以上で準備完了です ♪

早速試してみる

簡単なチュートリアルとして nginx コンテナを立ててみます。

1
2
3
4
5
6
7
8
9
10
vagrant%$ docker run --rm -p 80:80 nginx:mainline-alpine

Unable to find image 'nginx:mainline-alpine' locally
mainline-alpine: Pulling from library/nginx
709515475419: Already exists
4b21d71b440a: Pull complete
c92260fe6357: Pull complete
ed383a1b82df: Pull complete
Digest: sha256:5aadb68304a38a8e2719605e4e180413f390cd6647602bee9bdedd59753c3590
Status: Downloaded newer image for nginx:mainline-alpine

ブラウザアクセス

ローカルの Mac からブラウザでアクセス

http://192.168.35.101

※192.168.35.101 … Vagrant で指定した private ip

問題なく Welcome ページが表示されました。

先程のログに以下のようにアクセスログが出力されるのがわかります。

1
192.168.35.1 - - [13/Apr/2017:10:45:46 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"

MacOS → Vagrant → Docker
とアクセスできるようになりました ♪

追記

今回作成した Box を Vagrant Cloud に置きました。

https://atlas.hashicorp.com/kenzo0107/boxes/ubuntu14.04.5LTS-docker-dockercompose/

こちら設定を元にこれから様々な環境構築を記載していきたいと思います ♪

参照

Docker Compose チュートリアル

Docker Compose チュートリアル

前回 Vagrant (Ubuntu)で Docker, Docker Compose 環境構築しました。

上記環境を元に Docker Compose チュートリアルを実行しました。

完全な備忘録です。

プロジェクトディレクトリ作成

1
vagrant%$ mkdir composetest && cd composetest

app.py 作成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
count = redis.incr('hits')
#return 'Hello World! I have been seen {} times.\n'.format(count)
return 'Hello from Docker! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)

requirements.txt 作成

pip でインストールするモジュールを列挙します。

1
2
flask
redis

Dockerfile 作成

1
2
3
4
5
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

docker-compose.yml 作成

1
2
3
4
5
6
7
8
9
10
11
version: '2'
services:
web:
build: .
ports:
- '5000:5000'
volumes:
- .:/code

redis:
image: 'redis:alpine'

Docker Compose でイメージビルド、コンテナ起動

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
vagrant%$ docker-compose up

Creating composetest_web_1
Creating composetest_redis_1
Attaching to composetest_redis_1, composetest_web_1
redis_1 | 1:C 13 Apr 14:25:38.483 # Warning: no config file specified, using the default config. Inorder to specify a config file use redis-server /path/to/redis.conf
redis_1 | _._
redis_1 | _.-``__ ''-._
redis_1 | _.-`` `. `_. ''-._ Redis 3.2.8 (00000000/0) 64 bit
redis_1 | .-`` .-```. ```\/ _.,_ ''-._
redis_1 | ( ' , .-` | `, ) Running in standalone mode
redis_1 | |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
redis_1 | | `-._ `._ / _.-' | PID: 1
redis_1 | `-._ `-._ `-./ _.-' _.-'
redis_1 | |`-._`-._ `-.__.-' _.-'_.-'|
redis_1 | | `-._`-._ _.-'_.-' | http://redis.io
redis_1 | `-._ `-._`-.__.-'_.-' _.-'
redis_1 | |`-._`-._ `-.__.-' _.-'_.-'|
redis_1 | | `-._`-._ _.-'_.-' |
redis_1 | `-._ `-._`-.__.-'_.-' _.-'
redis_1 | `-._ `-.__.-' _.-'
redis_1 | `-._ _.-'
redis_1 | `-.__.-'
redis_1 |
redis_1 | 1:M 13 Apr 14:25:38.486 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 13 Apr 14:25:38.486 # Server started, Redis version 3.2.8
redis_1 | 1:M 13 Apr 14:25:38.486 # WARNING overcommit_memory is set to 0! Background save may failunder low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf andthen reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1 | 1:M 13 Apr 14:25:38.486 * The server is now ready to accept connections on port 6379
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | * Debugger is active!
web_1 | * Debugger PIN: 135-466-976
web_1 | 192.168.35.1 - - [13/Apr/2017 14:25:53] "GET / HTTP/1.1" 200 -
web_1 | 192.168.35.1 - - [13/Apr/2017 14:25:53] "GET /favicon.ico HTTP/1.1" 404 -

ブラウザにアクセスしてみる。

表示されました!

リロードする度に以下数字部分がインクリメントされるのが確認できます。

1
Hello from Docker! I have been seen 1 times.

便利 ♪