それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

npm でインストール済み一覧を整理しアンインストール。

インストール済み一覧を表示する。

インストールの結果を表示するには depth

takuya@~$ npm list -g --depth=0
/usr/local/lib
├── hubot@2.19.0
├── jshint@2.9.5
├── jslint@0.11.0
├── less@2.7.2
├── npm@5.6.0
├── uglify@0.1.5
├── uglify-js@3.1.3
├── uglifyjs@2.4.11
├── undefined@0.1.0
├── update@0.7.4
└── upgrade@1.1.0

インストール一覧を見れる。

インストールした結果の一覧を見ることで、インストールしたものを明示的に消せる。楽。

npm list で検索結果が。。。

ふつうに一覧を検索すると大変なことに。

npm -g list

インストールされてるパッケージ結果が、、、すげぇ多すぎ。 インストール一覧を見るとゴチャゴチャ

  │ │ │   └── os-tmpdir@1.0.2 deduped
  │ │ ├─┬ figures@1.7.0
  │ │ │ ├── escape-string-regexp@1.0.5 deduped
  │ │ │ └── object-assign@4.1.1 deduped
  │ │ ├── lodash@4.17.4 deduped
  │ │ ├── mute-stream@0.0.6
  │ │ ├── pinkie-promise@2.0.1 deduped
  │ │ ├── run-async@2.3.0 deduped
  │ │ ├── rx@4.1.0
  │ │ ├─┬ string-width@1.0.2
  │ │ │ ├── code-point-at@1.1.0 deduped
  │ │ │ ├─┬ is-fullwidth-code-point@1.0.0
  │ │ │ │ └── number-is-nan@1.0.1 deduped
  │ │ │ └── strip-ansi@3.0.1 deduped
  │ │ ├── strip-ansi@3.0.1 deduped
  │ │ └── through@2.3.8 deduped
  │ ├── minimist@1.2.0 deduped
  │ ├─┬ mkdirp@0.5.1
  │ │ └── minimist@0.0.8
  │ ├─┬ npmlog@2.0.4
  │ │ ├── ansi@0.3.1
  │ │ ├─┬ are-we-there-yet@1.1.4
  │ │ │ ├── delegates@1.0.0
  │ │ │ └── readable-stream@2.3.3 deduped
  │ │ └─┬ gauge@1.2.7
  │ │   ├── ansi@0.3.1 deduped
  │ │   ├── has-unicode@2.0.1
  │ │   ├── lodash.pad@4.5.1
  │ │   ├── lodash.padend@4.6.1
  │ │   └── lodash.padstart@4.6.1
  │ └── object-assign@4.1.1 deduped
  ├── titleize@1.0.0

えっと、ドレをインストールしたっけ

深さを指定して検索すると何を入れたか解るので助かったのでメモ。

npm list -g --depth=0

不便なので、alias を作っておく

alias npm_installed='npm list --depth=0 '

npm_installed -g 

アンインストールしてみた。

takuya@~$ npm -g uninstall  pug
removed 57 packages in 0.706s

pug だけで 60 近いパッケージに依存してる。さすがパッケージ地獄のnpm だった。

インストールでえらーになったときに困った。

どのパッケージがぶっ壊れたのかを探してて地獄を見た。

npm で gitbook をインストールした

takuya@~$ npm -g install gitbook gitbook-cli
npm WARN deprecated ignore@3.1.2: several bugs fixed in v3.2.1
npm WARN deprecated tough-cookie@2.2.2: ReDoS vulnerability parsing Set-Cookie https://nodesecurity.io/advisories/130
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
/usr/local/bin/gitbook -> /usr/local/lib/node_modules/gitbook-cli/bin/gitbook.js
/usr/local/bin/gitbook -> /usr/local/lib/node_modules/gitbook/bin/gitbook.js

> fsevents@1.1.3 install /usr/local/lib/node_modules/gitbook/node_modules/fsevents
> node install

[fsevents] Success: "/usr/local/lib/node_modules/gitbook/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node" is installed via remote
+ gitbook-cli@2.3.2
+ gitbook@3.2.3
added 1312 packages in 36.976s

2つ入れるのに、ほぼまっさらな状態から、1312 パッケージですか。。多いな。

npm インストールでぶっ壊して復旧に1時間近くかかったのでメモ

git log --graph でマージ状況がよくわかる。

git のコミット履歴を線にして表示してくれる。

 git log --pretty=format:'%h %s' --graph

出力結果はコレ

このような形で、ブランチの履歴がよくわかる。。

* 9504829 say hello world
* daa290b さぎょうちゅうー
* 7a385a4 ハローワールド
* 2bf15e1 サンプルブランチでの更新
* 460e6a0 ローカルブランチでコミット
* d5e9ee2 作ったブランチへコミット
*   4928e4d Merge branch 'test' into 'master'
|\
| * 85a29cc test
|/
* dba3ada add README

オプションの有無で色々

git log --graph
git log --pretty=format:'%h %s' --graph
git log --graph --pretty=oneline 

~/.gitconfig に書いておくと便利

[alias]
  graph= log  --graph

参考資料

Git - リビジョンの選択

http://blog.toshimaru.net/git-log-graph/

gitで作業中の内容をブランチ(リモート)として扱う。

作業内容をぱぱっとブランチにまとめる。

最初から目的別のブランチ切って作業できるほど人は賢くない。

アレコレ触ってるうちに、ライブラリに欠陥を見つけたり、作業目的とは違うファイルもついでに編集したりとか。 そういう、細々としたコミットをコミットに積み重ねるのも面倒くさい。

たとえば、コミット内容をカテゴリ別にステージングするときに git add -p を叩いてファイルを見ながら目的部分だけ拾って comitt / push って意外と効率が悪い。

stash してあとで考えようとしてもstash から戻すときにマージ考えるのも面倒だし。

その状態でいったん保存したい。

ステージングされてないコミットがまだまだあるんだけど、その状態でいったん保存したい。

帰宅時間が来たぞ帰ろう。とりあえず作業内容をブランチにしてみることにした。

あるブランチで作業をしていて、会議時間前になったし、そろそろ一段落させるか。帰宅時間が近づいたけど今日の進捗なしはこまるな−ってときに。

ファイルが更新状態になってる。

takuya@sample$ echo '<?php phpinfo();?>' > info.php
takuya@sample$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.

Changes not staged for commit:

    modified:   info.php

ブランチを作る

takuya@sample$ git checkout -b working
M   info.php
Switched to a new branch 'working'

ブランチをコミットしてリモートpush する

ブランチをコミットする。

takuya@sample$ git commit -m 'さぎょうちゅうー' info.php
[working daa290b] さぎょうちゅうー
 1 file changed, 1 insertion(+)

ブランチをまるっとプッシュする

takuya@sample$ git push origin working
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 533 bytes | 533.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To example:takuya/sample.git
 * [new branch]      working -> working

状態を確認する。

takuya@sample$ git branch -a
  master
* working
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/working

作業中の状態を保存できた

これであとはまた別のことを始めたら良いわけですね。ブランチに進捗あります。

定時に上がって、家のPCで仕事の続きができますね!

git でローカルにブランチを作ってリモート(origin) にブランチをpush するまでの手順

ブランチをちょっとだけ使いこなす。

リモートに存在しないブランチを手元で作ってプッシュするまでの流れ。

レポジトリを持ってくる。

takuya@Desktop$ git clone git@example.com.:takuya/sample.git
takuya@Desktop$ cd sample/

現在のブランチを確認する。

リモートブランチを含め、現在あるブランチを確認する。

takuya@sample$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

ブランチを作成する。

ブランチを作成する(今回はリモートのmaster からブランチを作成)

takuya@sample$ git checkout -b  サンプルブランチ origin/master
Branch 'サンプルブランチ' set up to track remote branch 'master' from 'origin'.
Switched to a new branch 'サンプルブランチ'

ブランチが切られていることを確認する。

ブランチが切られていることを確認する。

takuya@sample$ git branch -a
  master
* サンプルブランチ
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
takuya@sample$ touch index.php
takuya@sample$ git add .

ローカルブランチへコミットする。

ブランチに変更を加えてみる。

takuya@sample$ git commit -m '作ったブランチへコミット'
[サンプルブランチ d5e9ee2] 作ったブランチへコミット
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 index.php
takuya@sample$ git push
Everything up-to-date

リモート(origin) にブランチを転送する。

コミットが出来たら、リモートに「ブランチ」を送信する。このときにリモートブランチが作成される。

takuya@sample$ git push origin サンプルブランチ
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 294 bytes | 294.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for サンプルブランチ, visit:
remote:   https://example.com/takuya/sample/merge_requests/new?merge_request%5Bsource_branch%5D=%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81
remote:
To example.com:takuya/sample.git
 * [new branch]      サンプルブランチ -> サンプルブランチ

ローカルブランチの状態を確認する。

remotes/origin/サンプルブランチ として、リモート(origin) にさっきのブランチが追加されてる。 これで、ローカルにあるブランチからリモートブランチ(新規作成)が出来たことが解る。

takuya@sample$ git branch -a
  master
*  サンプルブランチ
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/サンプルブランチ

ブランチが出来たら、マージ

ブランチが出来たら、次はマージするのですが、マージ作業をブラウザで出来るのがgithub のプルリクの強みだったりするのでいいよね。

ブランチ間のマージ

マージするときは master にマージしていくのが基本方針として、ブランチでの作業が少し進んでいる状態をmaster にマージする感じ。

master をチェックアウトして

takuya@sample$ git checkout master

サンプルブランチを取り込む

takuya@sample$ git  merge サンプルブランチ
Updating 460e6a0..2bf15e1
Fast-forward
 bashrc | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bashrc

取り込んだ、マージをリモートに送信する。

takuya@sample$ git push
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.

ローカルブランチを削除する。

takuya@sample$ git branch -d サンプルブランチ
Deleted branch サンプルブランチ (was 2bf15e1).

必要がなくなったリモートのブランチを消す。

リモートにブランチを削除するpush をする。

takuya@sample$ git push --delete origin サンプルブランチ
To example.com:takuya/sample.git
 - [deleted]         サンプルブランチ

まとめ

ローカルでブランチを作って、ブランチを送信できる

ブランチをマージするのは手元でやるのが基本。サーバー側でまとめて出来るのがgithub の魅力

リモートのブランチへの削除push が出来る

これで、帰宅時間が来たら帰宅時間ブランチを作ってpushすれば良いことが解る。

参考資料

ちょっと進んだGit, Githubの使い方~ブランチ活用編~ - nigoblog

シェルのalias されたコマンドの展開する - alias-expand-line

シェルのコマンドを展開したい。

composite 使おうとしたら、候補多すぎて面倒くさい。補完が補完にならないよね

takuya@~$ com<tab>
comm       command    compare    compgen    complete   compopt    composer   composite  compress   comsat

最初の3文字くらいで、展開されてほしい。 bashの補完で completion を書いても現在位置は置換できないし、alias で短縮しても履歴に元のコマンドを残したい。

alias してみてもうまくいかない。

alias すると、たしかに短くなるのだけど、履歴が汚れる。すげぇ面倒くさいわ。

alias comp=composite
history
997: comp
998: comp
999: comp

sysout<tab>System.out.println() になるような短縮(abbreviation)と補完(completion)をやりたいと思ってました。

alias-expand-line で解決する

ショートカットキー<ctl-alt-e> を押すと、展開される。これだ!

$ ll<ctl-alt-e>

こうなる

$ ls -lt 

これだ。

参考資料

https://superuser.com/questions/247770/how-to-expand-aliases-inline-in-bash

https://unix.stackexchange.com/questions/158038/non-interactive-shell-expand-alias

dockerのexpose のポートをlocalhostに限定する。

docker のポートのIPアドレスを限定したい。

expose したポートを、bind するときに、よく見る例がコレ

docker  run -p 80:80 ...

コレだと、0.0.0.0:80マッピングされる。グローバルアドレスにマッピングしてしまうのですよね。ちょっと先行き不安。

ローカル・ループバックに限定する

docker  run -p 127.0.0.1:80:80 ...

IPv6の ループバックはダメみたい

::1 はダメだった。悲しい。そのうちなんとかなるかも。

takuya@ubuntu01:~/docker-test$ docker-compose up -d
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.db.ports is invalid: Invalid port "::1:5432:5432", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]

docker-compose の場合

docker-compose の yml の場合はこう書くといいみたい。

    ports:
      - 127.0.0.1:5432:5432

なるほど、コレだとループバックだからiptables も考えなくていいから安心ですね。

参考資料

https://docs.docker.com/compose/compose-file/#ports

https://stackoverflow.com/questions/45109398/how-can-i-make-docker-compose-bind-the-containers-only-on-defined-network-instea

docker の mysql に sql を流し込んでデータベースを作ったり初期データをいれる

docker のmysql にデータを流し込みたい。

docker のmysql にデータ流し込む

docker exec -i 49723f3d7ed1  mysql -uroot -pPASWORD database_name < data.sql

exec のオプションに -it ではなく tty なしで -i だけでいい。

データベースにデータを投入するためだけに Dockerfile から COPY とか EXPOSE 3306 とか VOLUMEするのも面倒な話なので。

データベースにデータを投入したことを確認したい。

bash などを経由しなくても直接 tty を繋いで mysql のコンソールに繋いであげれば良いことが解る。

docker exec -it 49723f3d7ed1  mysql -uroot -pPASWORD database_name 

これでOK

docker-composeの管理が面倒なのでerb と makefileにした

docker-compose.yml が面倒くさい。

docker-compose は良く出来てるんだけど、環境変数だとか環境設定がめんどくさくないですか?

dockerfile から docker-compose.yml に進化して相当使いやすくなってるのはわかるんですね。

でも不便なものは不便。

コメントとか変数とか書きたい。

yml syntax チェックとかかしたい。

erb で変換することにしたら楽だった。

$ erb docker-compose.erb.yml | ruby -ryaml -e 'puts YAML.dump(YAML.load(ARGF.read()))' > docker-compose.yml

erb 変換して、その結果をrubyYAML に流し込んで整形することにした。 結構複雑なコメントとか書けるようになって嬉しかった。

makefile も併せて作った。

  • erb → yml に変換する
  • yml → docker 起動

この辺のワークフローをmakefile で作った。

name=php-apache-mysql
registry=takuya.registory.example.com/takuya/docker/$(name)

conf=docker-compose.yml
project-name=my$(name)
compose=docker-compose
cmd=$(compose) -f $(conf) --project-name $(project-name)

docker-compose.yml: docker-compose.erb.yml
    erb docker-compose.erb.yml | ruby -ryaml -e 'puts YAML.dump(YAML.load(ARGF.read()))' > $(conf)


.PHONY: all build run up down registory push clean

all: build

build:  docker-compose.yml
    $(cmd) build
run: build
    $(cmd) up
up: build
    $(cmd) up -d
down:
    $(cmd) down
kill-all:
    $(cmd) down

registry:
    @docker build -t $(registry) .
push: registry
    @docker push $(registry)
clean:
    -rm $(conf)

makefile 楽だわ。

gulp とかこういうビルドシステムは数あるけど、シンプルにやりたいことがぱぱっと出来るので 古き良きツールもまだまだ見捨てたらかわいそうだなって思った的な。

Dockerfileを作って試すときのコマンドが長いのでmakefileにした

dockerfile 書いたら負けってのは解る。

でも、dockerfile を書かないと、dockerのボリュームの切り分けタイミングや、entrypoint が理解できないし。

dockerfile を書いたことがないと docker hub から pull してきても使い方がわからない。

dockerfile を書いて実行するのが面倒くさい。

練習がてらに、dockerfileをたくさん書いたけど、コマンドが長くなってしまうので不便だよね。 dockerfile のサンプルをgithub で見ても殆どの人が、Rakefilemakefile を置いているので、やっぱりそうなんだと思った。

Makefile書いた

### dockerfile 単体時の設定

name = takuya-debian
.PHONY: all build run

all: build

build.log: ./Dockerfile
    @docker build -t $(name) .
    date +"%Y-%m-%d %H:%i:%s "> ./build.log

build: build.log

run:
    @docker run -it -d $(name)

## makefile 中での $() は $$() にする
login:
     @docker exec -it $$( docker ps -q  --filter 'ancestor=$(name)' -f 'status=running' )  bash


kill:
     @docker kill $$( docker ps -q  --filter 'ancestor=$(name)' -f 'status=running' ) 

makefile やコマンドを実行するときのポイント

  • 作成中の docker image にはかならず名前をつける
  • 名前を指定して実行する
  • 名前を使って終了する

docker ps の filter オプションを使う。

ubuntu のイメージを全て表示する

docker ps -a  --filter 'ancestor=ubuntu'

ubuntu のイメージで実行中のもの

docker ps -a  --filter 'ancestor=ubuntu' --filter 'status=running'

これらの他にもフィルタが在るのだけど。 docker ps をフィルタで使うことでとても楽に管理ができるようになった。

参考資料

https://docs.docker.com/engine/reference/commandline/ps/#filtering

debian ミラーをやめてさくらインターネットのミラーを頼る

debian ミラーって時々遅いので

自前のミラーを使って作ってるけど、それでも遅いので。

docker file が apt update 始まると apt ですごく時間が取られる

自分のミラーが見に行くところを変えていく

deb http://debian-mirror.sakura.ne.jp/debian/ stretch main
deb http://debian-mirror.sakura.ne.jp/debian/ stretch-updates main
deb http://debian-mirror.sakura.ne.jp/debian/ stretch/updates main

deb http://debian-mirror.sakura.ne.jp//debian/ stretch main stretch main
deb http://debian-mirror.sakura.ne.jp/debian/ stretch-updates main
deb http://debian-mirror.sakura.ne.jp/debian/ stretch/updates main

deb http://deb.debian.org/debian stretch main
deb http://deb.debian.org/debian stretch-updates main
deb http://security.debian.org stretch/updates main

コマンドで。

sed -i.bak  -s 's%http://deb.debian.org/debian%http://debian-mirror.sakura.ne.jp/debian//%g'  /etc/apt/sources.list \
#sed -i.bak  -s 's%http://security.debian.org/debian%http://debian-mirror.sakura.ne.jp/debian//%g'  /etc/apt/sources.list \

dockerはプロセスをaufs というかマウントで分離してくれるけど、docker pull 出来ないものを使おうとするととても不便だね。

ssh の秘密鍵をサーバー毎に指定して違う鍵に変えてログインする方法

SSH秘密鍵を使い分けたい。

git サーバーや自宅サーバーや、さくらVPSAmazonクラウド・・・そしてお仕事のサーバーなど SSHサーバーが多くなってくると鍵の管理が面倒になったりします。

サーバーごとに秘密鍵を変えることが出来る

ssh コマンドを使う際に、コマンドのオプションで鍵を指定することが出来る。

ssh -i  path/to/my/private_key.file myserver

でも面倒くさい・・・鍵を毎回指定するのが面倒だ。

そして ssh 設定をつかう github や SourceTreeなどのアプリケーションだと起動オプションで鍵を指定することが出来ない。

ssh 設定を使う

ssh には ~/ssh/config という設定ファイルがある。

このファイルを使えば、サーバー毎、鍵毎に設定と変えることが出来る。

Host 192.168.2.1
   Hostname 192.168.2.1
   IdentityFile ~/.ssh/router.key

SourceTreeなどのユーザーのSSH設定を読み込んでくれるアプリケーションを使う場合でも大丈夫

ssh 設定の例

複数の鍵とユーザー名を設定で切り分ける。

Host my-rooter
   Hostname 192.168.2.1
   IdentityFile ~/.ssh/router.key

Host my-rooter-root
   Hostname 192.168.2.1
   IdentityFile ~/.ssh/my-root.key
   user root

こう書いておけば、

takuya:~ @ ssh 192.168.2.1   # ~/.ssh/id_rsa かつ user takuya
takuya:~ @ ssh my-router     # ~/.ssh/router.key  かつ user takuya
takuya:~ @ ssh myrouter-root   # ~/.ssh/my-root.key かつ  user root

このように、サーバーの用途毎に名前をつけておき、ユーザー名や使う秘密鍵を指定することが出来る。

設定例

gitlab / github.com の場合

 Host github-work
   hostname github.com
   identityfile /users/takuya/.ssh/github-work

github /gitlab の場合は git@hostname/username/reponame となっていて、すべてのユーザーは git ユーザーでアクセスししている。 github 側で登録済みの公開鍵からユーザーを識別している感じ。

gitlab で使う鍵を指定する

 Host gitlab.example.com
   hostname gitlab.example.com
   identityfile ~/.ssh/gitlab-ssh-priv.key
 Host git.1.example.com
   hostname git.1.example.com
   identityfile ~/.ssh/git-priv.key

gitlab 毎に使う鍵を変えるなども出来る。

設定をまとめたい

hostalias を使う

Host mine
     HostAlias my01.example.com
     HostAlias my02.example.com
     HostAlias my03.example.com

こうしておけば、順番に試してくれたり。

他にできる設定

.ssh/config はかなりいろいろな設定ができる。

SSH接続時に同時にVPNを作成したり、 SSH接続時にポートを指定したり

詳しくは man

man ssh_config

参考書籍

OpenSSH

OpenSSH[実践]入門 Software Design plus

OpenSSH[実践]入門 Software Design plus

xargsでリダイレクト> を使う方法

xargs やfind exec でリダイレクトを使うには

sh を挟むのが覚えやすくて楽

sh -c ' cmd "{}"> out.txt '

find と xargs の例

find . | xargs -I@ sh -c ' echo "@" >> names.txt '
find . -exec  sh -c ' echo "{}" >> names.txt '

参考資料

https://stackoverflow.com/questions/845863/how-to-use-in-an-xargs-command

nginxで unix ドメイン socket をlisten してバックエンド専用に設定する。

nginx 使いまくり問題

docker やCDNとか使ってると、いくつのプロキシが挟まるんだよ。管理面倒くさいんだよ。って問題にぶち当たる。特にphp 関連。

browser → 企業・学校内プロキシ → CDN → docker ホスト nginx → dockerコンテナnginx → php-fpm

コレ全部が、SSLのデクリプトとエンクリプションや、TCPコネクションでsyn/ack してると思うとゾッとしない話ではない。そりゃhttp2でTCP節約が必要になるよねって感じる。

リバースプロキシから裏側はTCPを減らせるのでは。

docker ホスト nginx → dockerコンテナnginx → php-fpm

この部分がlocalhost:9000とかで待ち受けてるけど、全部unix ドメインソケットにしてしまえば、接続も管理も楽になるんじゃないかと。

nginx が unix sock で待ち受ける

ポートの管理とかTCPのコネクションが面倒くさいので、unix ソケットでnginx を動かしてみたらどうだろうか。 と思ったので試してみた。

nginx で設定してみる。

/etc/nginx/sites-enabled/default

server {
  #listen 80 default_server;
  #listen [::]:80 default_server;
  listen unix:/var/lib/nginx/backend.sock;
  access_log off;

  # SSL configuration
  #
  ##略
}

接続してみる

echo  'GET /' | nc -U /var/lib/nginx/backend.sock

nginx のunix:sock に応答する プロキシを 構成する。

リバースプロキシからバックエンドのnginxにunixソケットで接続できるようにする。

nginx:80 → nginx:sock に対応するものを作る。

upstream nginx-internal-sock {
    server unix:/usr/local/var/run/nginx-internal.sock;
}
server{

    listen 80;
    server_name 'www';
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Accept-Encoding "";
        proxy_pass http://nginx-internal-sock;
    }

}

または次のように書く

server{

  listen 80;
  server_name 'www';
  
  location / {
    proxy_pass http://unix:/usr/local/var/run/nginx-internal.sock; 
    ## ↑ http://unix:/ は記述ミスじゃなくて本当にこう書きます
  }

}

パスが違うのは、docker の起動時にボリュームでマッピングしてるから

-v /usr/local/var/run/:/var/lib/nginx/

socket ファイルを直接ボリュームマッピングすると socket がすでに存在しますと言われて起動できないので注意

何に使うの?

ポートの管理が面倒くさい。

docker で localhost:8001 / localhost:8002 / localhost:8003 と次々とnginxが占拠していくので何がなんだかわからなくなる。

とくに、nginx→(nginx+phpfpm) 間のリバースプロキシをすると管理が面倒くさいし、docker-composeのYAMLもだんだん増えてしまうので、ファイル名で扱うほうが楽かなかって思ったりしてる。ポート被らないし、ファイル名で識別できるし。ドメインソケットのほうがちょっとだけ速いし。

nginx-fpm をワンペアで扱う

apache+mod_php を使うのであれば、Apacheインスタンスを見ておけばいいが、 fastcgi+apachefastcgi+nginx にすると管理が面倒くさいのでソケットを volumeで外に出そうかなと。

アプリ側の設定 sites-enabled/myapp-php.nginx

upstream my-app-php-fpm {
   server unix:/usr/local/var/run/php-fpm/php-fpm.sock;
}
server{

    listen unix:/usr/local/var/run/my-app-nginx-internal.sock;
    root /var/www/html;

    location ~* \.php$ {
    fastcgi_pass  my-app-php-fpm;
    }

}

フロント側の設定。 sites-enabled/www.myapp.example.com.nginx

upstream nginx-internal-sock {
    server unix:/usr/local/var/run/my-app-nginx-internal.sock;
}
server{

    listen 80;
    server_name www.myapp.example.com;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Accept-Encoding "";
        proxy_pass http://nginx-internal-sock;

    }

}

こうしておけば、unix socket でバックエンドにつながるので、マシン上に大量にのっけてもポート管理が煩雑にならない。

pull して実行したらcomposer.yaml でポート被った!あああぅっ。ってならなくて済むんじゃないかなと。

apt-cacherで docker buildを速くする

docker build おそい。。。

Dockerfileを書くのが苦痛。ちょっと変えたらすぐに再構築が行われて、上手くキャッシュが効かないことが在る。

apt-update で待たされる。

apt-get update && apt upgrade && apt install がもう無理。1度や2度なら我慢するけど、10回実行する可能性があるならもう我慢できない。

キャッシュしようキャッシュ。

apt-cacher-ngでキャッシュしよう。

---
version: '2'
services:
  apt-cacher:
    container_name: proxies-apt-cacher
    image: sameersbn/apt-cacher-ng
    ports:
    - 3142:3142

docker-composer

docker-composer up -d

クライアント側にキャッシュ設定書こう。

dockerfile作ってるときだけつかう、APT設定ファイル書きましょう

Dockerfile

APT の設定をdocker ファイル作ってるときだけ cacher に向けて、build を考える速度で実行できるようにしておきたい。

apt-cacher-ng は debian でも ubuntu でもどちらでも受け付けてくれる万能選手なので優秀だ。

ubuntu の例。

FROM ubuntu:artful

MAINTAINER takuya_1st

## docker file 作成時の用途
RUN echo 'Acquire::HTTP::Proxy "http://172.17.0.1:3142";' >> /etc/apt/apt.conf.d/01proxy \
 && echo 'Acquire::HTTPS::Proxy "false";' >> /etc/apt/apt.conf.d/01proxy
RUN echo 'APT::Install-Recommends 0;' >> /etc/apt/apt.conf.d/01norecommends \
 && echo 'APT::Install-Suggests 0;' >> /etc/apt/apt.conf.d/01norecommends

## jaist にお願いする。
RUN sed -i.bak  -s 's%http://archive.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g'  /etc/apt/sources.list
# RUN sed -i.bak  -s 's%http://security.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g'  /etc/apt/sources.list

docker registry mirror と組み合わせる

ボトルネックを解消する。 docker 作ってて困るボトルネックは大きく4つ

  • apt install
  • docker pull
  • git clone
  • composer.phar install

これらをまとめて対策したいが、git clone と composer はちょっとめんどくさいので後回しにした。

docker pull を速くする、docker レジストリのミラー機能と組み合わせてまとめて起動しちゃう。

併せた。

---
version: '2'
services:
  apt-cacher:
    container_name: proxies-apt-cacher
    image: sameersbn/apt-cacher-ng
    ports:
    - 3142:3142
  docker-registry-proxy:
    container_name: proxies-docker-registry
    image: my.reg.example.com/docker-registry-proxy
    ports:
    - 5000:5000

これでだいぶ楽になった。

Dockerfile 書いたら負けって解ってるんだけど、docker pull で持ってきたイメージの中でapt update されてたりするのでだいぶ楽になった。思考を止めず、思考の速度でdockerfile 記述に一歩近づいた

関連資料

dockerのプロキシ(docker mirror registry)を設置してdocker hubからのpullを早くする - それマグで!

dockerのプロキシ(docker mirror registry)を設置してdocker hubからのpullを早くする

docker pull が遅い。

docker hub からのpull が遅い。docker-machine を作ったりvirtualbox で遊んでたりすると遅いんですよ。docker pullが

軽量化?いいやキャッシュが先だ

「お前のDockerイメージはまだ重い」とかDockerイメージの軽量化かダイエットに関する記事も多いんだけど、その時間も惜しい。dockerのコンテナの目的の一つが時間の節約だ。alpineで、秘伝のスープみたいなDockerfile を書くためのノウハウを蓄積する時間をダイエットしたいんだ。

まずは、ダイエットに時間掛けるより先にキャッシュでなんとかしてみよう。

apt-cacher みたいなのほしい。

docker の build 時や起動時の apt も遅かったり、docker build 時にすぐキャッシュが消えて apt が再実行されるので apt-cacher も速くするのに有効だった。

幾つものmachine で次々やってると docker hub の遅さも辛い。

docker hub mirror registry を起動して使う

Registry as a pull through cache | Docker Documentation に詳しいことが書いてあった。

設定は次の通り

  1. docker registry に mirroring の設定をする
  2. 手元のdocker に mirroring を使うように設定する。

docker registry に mirroring の設定をする

docker hub はログインしないと使えないので、ミラー用につかうレジストリが docker hub にログインできるように設定する。

proxy:
  remoteurl: https://registry-1.docker.io
  username: [username]
  password: [password]

これは面倒くさいので、docker イメージにした。

Dockerfile

FROM registry:2


RUN echo -ne "\
proxy:\n\
  remoteurl: https://registry-1.docker.io\n\
  username: takuyaXXXXX\n\
  password: PASSWORDn\
" >> /etc/docker/registry/config.yml

起動すら面倒くさい

起動すら面倒くさいので makefile 書いておいた。

make run

docker-compose は apt-cacheや HTTPプロキシと併せて起動するように別に書いた。

githubにおいておいた。

github.com

docker に設定する。

Docker for Mac に設定した。docker for Macが、ミラーを使ってくれるように設定した。

f:id:takuya_1st:20180109005345p:plain:w200

効果測定

じゃあ、これでどれくらい時短が出来るのか。

最後にどれくらい速くなる?測定だ

mirror のキャッシュが効く前(初回ロード)

takuya@docker-compose$ time docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
50aff78429b1: Pull complete
f6d82e297bce: Pull complete
275abb2c8a6f: Pull complete
9f15a39356d6: Pull complete
fc0342a94c89: Pull complete
Digest: sha256:fbaf303d18563e57a3c1a0005356ad102509b60884f3aa89ef9a90c0ea5d1212
Status: Downloaded newer image for ubuntu:latest

real    0m19.145s
user    0m0.047s
sys 0m0.043s

mirror でのキャッシュしたあと

docker rmi ubuntu でキャッシュを消して 再度取得してみる。

$ time docker rmi ubuntu
$ time docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu
50aff78429b1: Pull complete
f6d82e297bce: Pull complete
275abb2c8a6f: Pull complete
9f15a39356d6: Pull complete
fc0342a94c89: Pull complete
Digest: sha256:fbaf303d18563e57a3c1a0005356ad102509b60884f3aa89ef9a90c0ea5d1212
Status: Downloaded newer image for ubuntu:latest

real    0m4.883s
user    0m0.043s
sys 0m0.035s

比較

効果はバツグンだ。

導入前 導入後 時間差
19.145s 4.883s 14s

何処で使うのか。

イントラですよイントラ。

docker-machine が全部ミラー用を見るようにしておけば、virualbox などの docker-machineもバンバン使えるね。

参考資料