unicorn コンテナを ECS fargate で起動すると
Errno::EACCES: Permission denied - connect(2) for /var/run/unicorn/unicorn.sock
で起動しなかった。
先に結論を書いておくと、 「VOLUME の指定は絶対パスにする必要があり、例え絶対パスで指定していてもそれがエイリアスでは所有者の設定がなされない」
nginx コンテナ、unicorn コンテナ間の通信を unix domain socket で行うために、/var/run/unicorn
をバインドマウントでボリューム共有している。
さらに、コンテナ内のアプリケーションを root で動かすのはセキュリティ上良くないので、app
ユーザーで unicorn を起動している。
app
ユーザーがソケットファイルに書き込めるようにするため、chown
でパーミッションを変更している。
# unicorn.Dockerfile
# 関係ある箇所のみ抜粋
RUN mkdir -p /var/run/unicorn \
&& chown app:app /var/run/unicorn
VOLUME /var/run/unicorn
# ecs.yml
# TaskDefinition の CloudFormation で バインドマウントの設定をしている箇所
VolumesFrom:
- ReadOnly: false
SourceContainer: app
ローカルで起動しても問題なし。
ECS Exec して確認してみると、/var/run/unicorn
が root:root
になっている。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/bind-mounts.html
デフォルトでは、ボリュームのアクセス許可は 0755 に設定され、所有者は root に設定されます。これらのアクセス許可は Dockerfile でカスタマイズできます。
「設定方法はあっているが、所有者の設定が効いていなさそう」
ついでにここで、/var/run
が /run
のエイリアスであることに気づく。
結局ドキュメントだけでは解決せず、ググりまくって同じ状況で解決しているイシューコメントを見つけたことで解決できた。 aws/containers-roadmap#863 (comment)
I suspect that's because the VOLUME is referring not to a 'real' absolute path on disk but symlinked path (the real path on disk would be /run/squid if you resolve all the links)....
the solution here is simply to change the volume to be:
VOLUME ["/run/squid"]
おそらく fargate はエイリアスの指定では認識してくれず、絶対パスにする必要があるとのこと。