system temporary path is world-writable: /tmp/tmp is world-writable: /tmp
bundleを実行したらエラーが出るようになってしまった。
root@406b7f0636e3:/app# bundle exec rails db:migrate
system temporary path is world-writable: /tmp
/tmp is world-writable: /tmp
/usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `initialize': Operation not supported - connect(2) for /app/spring-0/dd8a5fc4ec68a287140deded829e3a66 (Errno::ENOTSUP)
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `open'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `connect'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:31:in `call'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/command.rb:7:in `call'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/rails.rb:24:in `call'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/command.rb:7:in `call'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client.rb:30:in `run'
from /usr/local/bundle/gems/spring-4.1.1/bin/spring:49:in `<top (required)>'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/binstub.rb:11:in `load'
from /usr/local/bundle/gems/spring-4.1.1/lib/spring/binstub.rb:11:in `<top (required)>'
from <internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:86:in `require'
from <internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:86:in `require'
from /app/bin/spring:10:in `block in <top (required)>'
from <internal:kernel>:90:in `tap'
from /app/bin/spring:7:in `<top (required)>'
from bin/rails:2:in `load'
from bin/rails:2:in `<main>'
使っているdocker imageは ruby:3.0.3-buster
よくよく調べてみると、/tmp
の権限がなぜか0777
。本来なら、user sticky bitが立っていないといけないので、 1777
にならないといけない。
root@406b7f0636e3:/app# ls -ald /tmp/
drwxrwxrwx 2 root root 40 Oct 16 04:00 /tmp/
以下を実行したら問題が解決しました。
# chmod 1777 /tmp
問題の原因を探るために、元のimageを起動してみたらimageの初期状態で 1777
でした。
# docker run --rm -it ruby:3.0.3-buster bash
root@d4676cb2cb7e:/# ls -ald /tmp
drwxrwxrwt 2 root root 4096 Mar 28 2022 /tmp
元のimageでチェックしてみても、 1777
なので元々この設定のようです。
% docker run --rm -it debian:10 ls -ald /tmp
drwxrwxrwt 2 root root 4096 Oct 9 00:00 /tmp
Ubuntuの最新でも同じです。
% docker run --rm -it ubuntu:latest ls -ald /tmp
drwxrwxrwt 2 root root 4096 Jan 26 2023 /tmp
chmod 1777 /tmp で回避はできることはできますが、毎回やるのが面倒です。
テンポラリディレクトリ周りで何かしら不具合が置きていて、 spring-0
というディレクトリがカレントディレクトリに作られてしまいます。本来ならば、 /tmp/ に作成されるべきもの。
再度調べたら、rubygem起因の様子。
要経過観察。
違うシチュエーションですが、同様の問題に遭遇したためこちらの Scrap が参考になりました。
ありがとうございます。
ちなみに
spring-0 というディレクトリがカレントディレクトリに作られてしまいます。本来ならば、 /tmp/ に作成されるべきもの。
こちら、推測ですが Ruby の tmpdir ライブラリの挙動として、/tmp
など ( TMPDIR
環境変数で示された PATH なども含む ) が利用できなかった場合、最終的にカレントディレクトリを利用するようなロジックになっているのが原因と思われます。
スマートな回避方法があったら教えていただきたいです!
ちなみに、手元の環境で ruby:3.0.3-buster
の /tmp
ディレクトリを見た感じ sticky bit がセットされてて問題なさそうに見えました。
$ docker run --rm -it ruby:3.0.3-buster ls -ald /tmp/
drwxrwxrwt 2 root root 4096 Mar 28 2022 /tmp/
同じイメージでも利用しているコンテナランタイムによって挙動が違う可能性? があるかも... (このあたりよくわかっていないです 🙇 )
手元の環境は
- macOS: 13.6.7(22G720)Ventura
- CPU: Apple M2
- コンテナ実行環境
- Docker Desktop 4.21.1 (114176)
docker version
$ docker version
Client:
Cloud integration: v1.0.35
Version: 24.0.2
API version: 1.43
Go version: go1.20.4
Git commit: cb74dfc
Built: Thu May 25 21:51:16 2023
OS/Arch: darwin/arm64
Context: desktop-linux
Server: Docker Desktop 4.21.1 (114176)
Engine:
Version: 24.0.2
API version: 1.43 (minimum version 1.12)
Go version: go1.20.4
Git commit: 659604f
Built: Thu May 25 21:50:59 2023
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.6.21
GitCommit: 3dce8eb055cbb6872793272b4f20ed16117344f8
runc:
Version: 1.1.7
GitCommit: v1.1.7-0-g860f061
docker-init:
Version: 0.19.0
GitCommit: de40ad0
関係あるか不明ですが runc において tempfs の sticky bit が立っていないという Issue を見かけましたが... runc は使ったことが無く、これが関係しているかどうかは全くわかっていません 🙏
ありがとうございます。
手元の環境でも再現を試みましたが、再現しなくなってしまってました。
(そして、以前のコメントで誤認識があったので一部修正しました)
元のimageの方はsticky-bitが立っているので、その後の処理またはDocker側でなにかしているのかもしれませんね。
なるほどです。
ちなみに私が遭遇したは、 AWS Lambda の Ruby ランタイムで Dir.tmpdir
を呼び出すとエラーになる現象でした。
で、調べてみたら /tmp
に sticky bit が立っていないということが判明したのでした...