docker node expressの開発環境を作る

windows10でdocker toolboxがインストール済みが前提です。

VirtualBoxのdockerホストを構築してある

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.03.1-ce

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

mkdir sample && cd sample

docker-composeでnodeのコンテナを起動する

docker-compose.ymlを作成する

version: '2'

services:

    sample:
      container_name: sample
      image: node:7.10
image: node:8.10
      ports:
        - "3000:3000"
      tty: true
      working_dir: /app/sample
      volumes:
        - ./:/app/sample
        - /app/sample/node_modules

nodeのコンテナを確認

$ docker ps
CONTAINER ID   IMAGE      COMMAND  CREATED              STATUS         PORTS                   NAMES
b8d8b6eb8494   node:7.10  "node"   About a minute ago   Up 25 seconds  0.0.0.0:3000->3000/tcp  sample

sampleフォルダには、空のnode_modulesフォルダが生成される。
node_modulesをホストとマウントするとモジュールインストールがうまくいかなかったのでコンテナ内に「/app/sample/node_modules」指定する

コンテナにログイン

docker exec -it sample /bin/bash

package.jsonの作成

npm init -y

sampleフォルダにpackage.jsonが追加される

express-generatorをインストールする

npm install -D express-generator

package.jsonを編集する

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "express": "express"
},

scriptのところに「”express”: “express”」を追加する

expressの雛形を作成する

npm run express . -f

「y」を入力して雛形を作成

sample
  bin/
  node_modules/
  public/
  routes/
  views/
  app.js
  docker-compose.yml
  package.json

フォルダはこんな感じになる

express-generatorはもう使わないので削除する

npm rm express-generator

依存モジュールのバージョンも固定もしたいのnpm-shrinkwrap.jsonを作成

npm shrinkwrap --dev

npmインストール

npm install && npm cache clean

起動して確認

npm start

http://192.168.99.100:3000/

次回コンテナを起動したときアプリが起動するようにする

docker-compose.ymlを修正する

version: '2'

services:

    sample:
      container_name: sample
      image: node:7.10
      ports:
        - "3000:3000"
      tty: true
      working_dir: /app/sample
      command: ["npm", "start"]
      volumes:
        - ./:/app/sample
        - /app/sample/node_modules

command: [“npm”, “start”] を追加する

コンテナを停止する

docker stop sample

コンテナを起動する

docker-compose up -d

確認する

http://192.168.99.100:3000/

コンテナを共有するときのためDockerfileを作成する

しかしながら、package.jsonとnpm-shrinkwrap.jsonがある状態で共有

Dockerfile

FROM node:7.10
ENV APP_ROOT /app/sample

WORKDIR $APP_ROOT
COPY package.json $APP_ROOT
COPY npm-shrinkwrap.json $APP_ROOT
RUN npm install && npm cache clean

COPY . $APP_ROOT
EXPOSE 3000
CMD ["npm", "start"]

Dockerfileを使うときのdocker-compose.ymlのimageをbuildにする

version: '2'

services:

    sample:
      container_name: sample
      build: ./
      ports:
        - "3000:3000"
      tty: true
      working_dir: /app/sample
      command: ["npm", "start"]
      volumes:
        - ./:/app/sample
        - /app/sample/node_modules

参考サイト

http://qiita.com/togana/items/40b50426d511327238af

Docker mysql 設定変更

mysqlのdockerコンテナでmysqlの設定変更をするときちょっとはまったのでメモ

mysqlのdockerコンテナ(設定変更前)

docker-compose.yml

# ------------------------------------------
# mysql
# ------------------------------------------
mysql:
build: ./mysql-db
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
volumes_from:
- mysql-data
container_name: mysql-db
restart: always

# ------------------------------------------
# mysql データ
# ------------------------------------------
mysql-data:
image: busybox
volumes:
- ./mysql-data:/var/lib/mysql
container_name: mysql-data

やりたいこと

  • デフォルトタイムゾーンを東京にする
  • 大きなデータを送る上限が4MBになっているので32MBにする

設定の変更について

コンテナの「/etc/mysql/conf.d/」にcnfファイルを追加すれば、mysql起動時に設定を読み込んでくれて設定が変更できる

コンテナ内を確認

docker exec -it mysql-db /bin/bash

cnfファイル追加前は、docker.cnf、mysql.cnfがあった。

$ ls -l /etc/mysql/conf.d/
-rw-r--r-- 1 root root 43 Feb 28 06:56 docker.cnf
-rw-r--r-- 1 root root 875 Nov 28 19:25 mysql.cnf

まずてきとうにmysqld.cnfというファイルを作成

docker-compose.ymlのある場所にconf.dというディレクトを作成して、mysqld.cnfを作成する
mysqld.cnf

[mysqld]
max_allowed_packet = 32M
default-time-zone = 'Asia/Tokyo'

docker-compose.ymlを修正してみる

# ------------------------------------------
# mysql
# ------------------------------------------
mysql:
build: ./mysql-db
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
volumes:
- ./conf.d:/etc/mysql/conf.d  ★dockerホストをマウントして、ファイルを置いておけばいける?
volumes_from:
- mysql-data
container_name: mysql-db
restart: always

コンテナ内を確認

docker exec -it mysql-db /bin/bash

もともとあったdocker.cnf、mysql.cnfがなくなり、新しく作成したmysqld.cnfはあった。

コンテナ内でmysqlの設定確認

mysql -p -e "show variables like '%max_allowed_packet%';"
mysql: [Warning] World-writable config file '/etc/mysql/conf.d/mysqld.cnf' is ignored.

設定が反映されていない。しかも権限のエラーが出てる。権限が777になっていて、権限を弱めてあげる必要があるみたいだ。

volumesで権限ってどうやって変更する???

volumesを使ってdockerホストをマウントして権限も変更する方法がよくわからない。DockerfileでADDしてcnfファイルを追加してやることにする

Dockerfile

# base images
FROM mysql:5.7

# author
MAINTAINER hoge

# カスタムのcnfファイルを追加
ADD mysqld.cnf /etc/mysql/conf.d/
# 権限の変更
RUN chmod 644 /etc/mysql/conf.d/mysqld.cnf

docker-compose.yml

# ------------------------------------------
# mysql
# ------------------------------------------
mysql:
build: ./mysql-db ★Dockerfileの場所
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
volumes_from:
- mysql-data
container_name: mysql-db
restart: always

確認

$ docker exec -it mysql-db /bin/bash
root@a8a0e6e35a32:/# mysql -p -e "show variables like '%max_allowed_packet%';"
Enter password:
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| max_allowed_packet | 33554432 |
| slave_max_allowed_packet | 1073741824 |
+--------------------------+------------+
root@a8a0e6e35a32:/# mysql -p -e "show variables like '%time_zone%';"
Enter password:
+------------------+------------+
| Variable_name | Value |
+------------------+------------+
| system_time_zone | UTC |
| time_zone | Asia/Tokyo |
+------------------+------------+

まとめ

mysqlの設定変更はできたが、Dockerfileの作成をあまりしたことないので、これでいいのか不明。
docker-compose.ymlとDockerfileについてまだまだ不勉強すぎる

DockerToolbox でローカル開発環境構築 1 docker-composeの環境変数

windows10 home 上でdockerを使いローカル開発環境を作ろうとしていろいろはまった。homeなのでDocker for Windows(Hyper-Vを使うやつ)は使えないので、Docker Toolbox のwindows版を使うことにした。cenosをdockerホストにして少しだけdockerの勉強はしていたが、windowsだとなにかと問題があったりする。

Docker Toolbox

  • https://docs.docker.com/toolbox/overview/

 

webサーバー立てる

まずは、nginxでwebサーバーを構築しようとdocker-composeを使いdocker-compose.ymlを作成

 

docker-compose.yml

nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
privileged: true
ports:
- 80:80
- 443:443
volumes:
- ./docker-compose.d/certs:/etc/nginx/certs:ro
- ./docker-compose.d/htpasswd:/etc/nginx/htpasswd
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: always

docker-compose up -d を実行すると下記のエラー

ERROR: for nginx-proxy Cannot create container for service nginx-proxy: invalid bind mount spec "C:\\Users\\hoge\\docker\\docker-compose.d\\htpasswd:/etc/nginx/htpasswd:rw": invalid volume specification: 'C:\Users\hoge\docker\docker-compose.d\htpasswd:/etc/nginx/htpasswd:rw'
ERROR: Encountered errors while bringing up the project.

google翻訳すると
* 無効なバインドマウント仕様
* 無効なボリューム指定
いやいやDocker Toolboxのdocker-machineでは、winのローカルのC:\Userと
docker-machine(VirtualBox)の/c/Userがファイル共有されマウント済みであるはず

絶対パスで指定してみる

volumes:
- /c/Users/hoge/docker/docker-compose.d/certs:/etc/nginx/certs:ro
- /c/Users/hoge/docker/docker-compose.d/htpasswd:/etc/nginx/htpasswd
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro

ERROR: for nginx-proxy Cannot create container for service nginx-proxy: create \c\Users\hoge\docker\docker-compose.d\htpasswd: "\\c\\Users\\hoge\\docker\\docker-compose.d\\htpasswd" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intented to pass a host directory, use absolute path
ERROR: Encountered errors while bringing up the project.

google翻訳すると
* ローカルボリューム名に無効な文字が含まれています

 

いろいろ検索して調査

https://github.com/docker/compose/blob/master/CHANGELOG.md#190-2016-11-16

1.9.0 (2016-11-16)

  • Breaking changes
WindowsでDocker Toolbox / Machineを使用して作成する場合、デフォルトでボリュームパスはC:\ Usersから/ c / Users-styleに変換されなくなりました。 この変換を再度有効にしてボリュームが機能し続けるようにするには、環境変数COMPOSE_CONVERT_WINDOWS_PATHS = 1を設定します。 Docker for Windowsのユーザーは影響を受けず、変数を設定する必要はありません。

とのことです。

環境変数を設定


変数名(N): COMPOSE_CONVERT_WINDOWS_PATHS 変数値(V): 1

これで、絶対パスでなくても起動できた。docker-machineに問題あると調査していてはまった。
まさかdocker-composeの問題とは

はじめてのAWS EC2にDocker Registryコンテナを立てて保存先はS3にする ローカルからEC2のDocker-registryへpushできるようにする

これからEC2を利用し、インスタンス1つでDockerコンテナをたくさん稼働してマイクロサービスをいろいろ作っていきたい。
サービスを開発していく環境でイメージをいろいろ管理していきたいので、Docker Hubの利用を検討したが、プライベートは有料なので自前でDocker Registryを作ることに。
Docker Registryはそこそこ容量がいるので、S3に保存することとする。

前提として

前回構築したSSL、リバースプロキシの環境も使っていきます。

はじめてのAWS EC2インスタンスにDockerインストール、docker-compseでnginx-proxyとletsencrypt-nginx-proxy-companionを使う

Docker Registryのイメージを取得する

$ docker pull registry:2.6.0

※ 最新バージョンはこちらで確認
https://github.com/docker/distribution/releases

Docker Registryのイメージを確認

$ docker images
REPOSITORY    TAG         IMAGE ID            CREATED             SIZE
registry      2.6.0       d1e32b95d8e8        2 weeks ago         33.17 MB

作業用ディレクトリを作成してdocker-compose.ymlを作成

$ mkdir /home/ec2-user/work
$ cd /home/ec2-user/work
$ vim docker-compose.yml

docker-compose.yml

docker-registry:
  image: registry:2.6.0
  container_name: docker-registry
  privileged: true
  ports:
    - 5000
  environment:
    VIRTUAL_HOST: registry.example.com
    LETSENCRYPT_HOST: registry.example.com
    LETSENCRYPT_EMAIL: example@gmail.com
    REGISTRY_STORAGE: s3
    REGISTRY_STORAGE_S3_ACCESSKEY: [S3フルアクセスのIAMユーザーのアクセスキー]
    REGISTRY_STORAGE_S3_SECRETKEY: [S3フルアクセスのIAMユーザーのシークレットキー]
    REGISTRY_STORAGE_S3_BUCKET: [バケット名]
    REGISTRY_STORAGE_S3_REGION: ap-northeast-1 ←東京リージョン
    REGISTRY_STORAGE_S3_ROOTDIRECTORY: /       ←バケットのディレクトを指定(ルートディレクトリ)
  restart: always

※事前にregistry.example.com のドメイン設定は、EC2のIPかドメインに設定しておくこと

Docker Registryのコンテナを起動する

$ docker-compose up -d

Docker Registryを使ってみる

今回、ローカルからリモートのレジストリへpushしてみる

イメージ名を変更するためタグを貼る

プライベートレジストリにpushするためにはイメージの名前を変える必要があります。

docker tag [イメージ名]:[tag] [レジストリのIP、URL]:[ポート]/[任意のリポジトリ名]/[イメージ名]:[tag]
docker tag centos:latest registry.example.com/registry-test/centos

※今回、jwilder/nginx-proxyのコンテナがEC2のフロントにあり、ポートは443なるため、ポートの指定はしない。

イメージを確認

$ docker images
REPOSITORY                                 TAG    IMAGE ID     CREATED      SIZE
registry.example.com/registry-test/centos  latest 67591570dd29 7 weeks ago  191.8 MB
centos                                     latest 67591570dd29 7 weeks ago  191.8 MB

イメージをプッシュする

docker push イメージ名
docker push registry.example.com/registry-test/centos
The push refers to a repository [registry.example.com/registry-test/centos]
3981cd79f308: Pushing [==================================================>] 122.1 MB/122.1 MB
34e7b85d83e4: Preparing
error parsing HTTP 413 response body: invalid character ・・・・・・・・・・・・・

HTTP 413 は、アップロードしようとしたデータサイズが大きいと怒られているのでnginxの上限値を上げたら解消される?あとで調査

S3に保存されているか確認する

バケット名の直下に「docker」ディレクトができいる。なんか保存されていそう。

/[バケット名]/docker/registry/v2/・・・

client_max_body_sizeの設定を追加

/etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    server_names_hash_bucket_size 128;
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    client_max_body_size 1G; ←★1Gにしてみた

}
daemon off;

まだしてないこと

  • basic認証をnginxで設定すること

はじめてのAWS EC2インスタンスにDockerインストール、docker-compseでnginx-proxyとletsencrypt-nginx-proxy-companionを使う

巷ではSSLが当たり前になってきました。
さくらVPSからAWSへの移行作業といっしょにdockerでマイクロサービスが作れる環境、そしてSSL化もしたい。
といったところでいろいろ調査したり試したりしています。

SSL化ではAWS Certificate Managerがあります。しかしELB(ロードバランサー)でしか使えないよう。詳しく調べていないけど。。。

まあここは、無料で有名なLet’s Encryptを使うことにしました。
公式HP:https://letsencrypt.org/
Github:https://github.com/letsencrypt/letsencrypt

mozaic.fmでLet’s Encryptについて詳しく説明されていました。
https://mozaic.fm/episodes/23/lets-encrypt.html

Lets Encryptは無料の認証局で、誰でも簡単に使えて、かつ自動化ができます!
下記の手順では、letsencrypt-nginx-proxy-companionが自動でやってくれます。

Linuxコマンド 1つ前のディレクトリに戻る windowsの戻るボタン的な

今さら知って損した気分になりました。cdだけを打ち込んでホームディレクトに移動したとき、ため息出てたけど、1つ前に戻るコマンドあったんですね。windowsにあるんならあると思ってすぐに検索するのものだと思いますが、恥ずかしながら今日しりました。

$ cd –

1つ前のさっきいたディレクトに戻ります。

はじめてのAWS EC2インスタンス(Amazon Linux)にS3のバケットをgoofysでマウントする

EC2でS3をマウントするにはs3fsがメジューみたいですが、s3fsが遅いという情報があり、今回goofysを使ってマウントすることにしました。

EC2インスタンスにS3のバケットをgoofysでマウントする

goとfuseのパッケージが必要となるためインストール

sudo yum install golang fuse

 

AWS CLIの設定

$ aws configure
AWS Access Key ID [None]: [S3 フルアクセスユーザのAccess key ID]
AWS Secret Access Key [None]: [S3 フルアクセスユーザのSecret access key]
Default region name [None]: ap-northeast-1
Default output format [None]: json

※アジアパシフィック (東京)のリージョン: ap-northeast-1

http://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html#s3_region

 

バケットの確認

aws s3 ls s3://[バケット名]

GOPATHを設定

export GOPATH=$HOME/go
echo $GOPATH /home/ec2-user/go

goofysのインストール

go get github.com/kahing/goofys go install github.com/kahing/goofys

マウントポイントの作成

sudo mkdir /mnt/bucket

/mnt/bucketへアクセス権限を付与(とりあえず全アクセス)

sudo chmod -R 777 /mnt/bucket/

 

マウント

./go/bin/goofys [バケット名] /mnt/bucket

注意:コマンドが帰ってきたら完了です。マウントに成功してもしなくても、何も戻ってこないので実際に確認してみます。

 

プロセス確認

$ ps auxf | grep goofys

ec2-user 31604 0.0 0.2 110472 2188 pts/0 S+ 22:11 0:00 \_ grep --color=auto goofys
ec2-user 30988 0.0 1.3 225460 14168 ? Ssl 17:21 0:00 /home/ec2-user/go/bin/goofys バケット名 /mnt/bucket

ボリューム確認

$ df -h

ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 488M 56K 488M 1% /dev
tmpfs 498M 0 498M 0% /dev/shm
/dev/xvda1 30G 1.6G 28G 6% /
バケット名  1.0P 0 1.0P 0% /mnt/bucket

自動マウント

手動でマウントするのは面倒なので、/etc/fstabにサーバー起動時にマウントされるように設定します。

 

rootユーザーでAWS CLIの設定

$ sudo aws configure
AWS Access Key ID [None]: [S3 フルアクセスユーザのAccess key ID]
AWS Secret Access Key [None]: [S3 フルアクセスユーザのSecret access key]
Default region name [None]: ap-northeast-1
Default output format [None]: json

 

fstabを修正

$ vim /etc/fstab

LABEL=/ / ext4 defaults,noatime 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/home/ec2-user/go/bin/goofys#[バケット名] /mnt/bucket fuse _netdev,allow_other,--dir-mode=0775,--file-mode=0666,--uid=500,--gid=500 0 0
※--dir-mode、--file-modeと--uid、--gidはファイルやディレクトリが作成された際のデフォルト権限/所有者の設定

インスタンスを再起動して確認してみる

$ reboot

マウント確認する

$ df -h
オプション | 説明
-----------+--------------------------------------------------------------------
_netdev    | ネットワークが有効になるまでマウントを待つためのオプション。
           | ネットワーク経由のデバイスを起動時にマウントさせたい場合などに指定する。
allow_other| 他のユーザーでも利用できるようにする。
--file-mode| マウントする際のファイル権限を設定する。
--uid      | マウントするユーザーIDを指定する。
--gid      | マウントするグループIDを指定する。

参考サイト

http://qiita.com/kooohei/items/a14f22cb0381342d1861