今まで曖昧だったので調べた。以下がが分かりやすかったです。
シェルスクリプトの定番設定
以下のようなやつ。
#!/bin/bash set -euxo pipefail
これの意味を以下で知りました。なるほど。。というか設定された状態をデフォルトにして欲しいレベルだなぁ。
Ubuntuで容量を沢山食っているフォルダを探すにはncduが便利
ncduを使うとサブフォルダも含めた容量を計算して見せてくれるので非常に便利だった。 Dockerの容量を削減したい時などに重宝しそう。
WindowsではFolderSizesを愛用してます。前はDriveAnalyzerを使っていたけど、重かったので乗り換え。有料だけどサクサクうごくし気に入ってます。
DockerのUbuntuコンテナで起動時にsshdを起動する
Dockerコンテナではsystemctlが使えないらしく、困った。
docker-compose.yamlに以下を記載して対応した。
command: bash -c "/etc/init.d/ssh start && /bin/bash"
今回の使い方ではcommandを上書きし、かつsshでもログインしたい場合が無かったので大丈夫だったけど、そういうケースに対応出来ないのでcommandじゃなくてDockerfileの中で自動起動の設定をしておくとかして対応したいけどやり方が見付からなかった。。init.dの設定とかで出来そうだけどだめなのかな?
SageMaker Processingでconda環境をactivateしてpythonを実行できない
例えば、以下のサンプルコードのようにScriptProcessorを使って.pyファイルを実行する場合。
.pyファイルをconda仮想環境myenvで実行するにはどうすればいいか。
ScriptProcessorのcommandでconda activateしてもだめで、理由はdokcerに渡されたコマンドは/bin/shで実行されるため。
色々悩んだが以下解決策に落ち着いた。
- Dockerfileに以下を書いてcondaコマンドを/bin/sh環境でも実行できるようにする
ENV PATH /opt/conda/bin:$PATH ENV CONDA_DEFAULT_ENV optiver
- ScriptProcessorをProcessorにし、conda runコマンドでconda環境を指定して実行する
processor = Processor( image_uri="...", entrypoint=["conda", "run", "-n", "optiver", "python", "/opt/ml/processing/input/code/preprocess.py"], instance_type=self.processing_instance_type, instance_count=self.processing_instance_count, base_job_name=f"{self.base_job_prefix}/script-optiver-preprocess", sagemaker_session=self.sagemaker_session, role=self.role, )
- preprocess.pyはProcessingStepでinputとして渡す
ProcessingStep( name="...", processor=processor, inputs=[ProcessingInput( input_name="data", source='...', destination='...'), ProcessingInput( input_name="code", source='...', destination='/opt/ml/processing/input/code/preprocess.py') ], outputs=[ ProcessingOutput(output_name="train", source="/opt/ml/processing/train"), ProcessingOutput(output_name="validation", source="/opt/ml/processing/validation"), ProcessingOutput(output_name="test", source="/opt/ml/processing/test"), ] )
こうすることでconda環境をactivateして.pyを実行出来るし、ScriptProcessorでは一つの.pyファイルしかコンテナに入れられないが 複数の.pyファイルをコンテナに渡して実行することができるので良い。
参考:
Dockerfile内で. /opt/conda/etc/profile.d/conda.shを毎回実行しなくて良いようにする
Dockerfileの中でconda環境をactivateした上でコマンドを実行したい場合、
RUN . /opt/conda/etc/profile.d/conda.sh && conda activate myenv RUN python test.py
のようにしてもだめで、RUN実行毎に. /opt/conda/etc/profile.d/conda.sh && conda activate myenv を実行しないといけない。
.bashrcに「. /opt/conda/etc/profile.d/conda.sh && conda activate myenv」を書いてもダメ。理由はRUNで指定したコマンドは/bin/shで実行されるため。/bin/bashではない。
なのでRUN で指定したコマンドを/bin/bashで実行するようにすればいい。それには、Dockerfile内で以下を実行する。
SHELL ["/bin/bash", "-l", "-c"]
これでRUNの前に.bashrcを実行してくれる。
参考:
tty:trueを設定していてもdockerコンテナがすぐ終了してしまう
docker-compose.ymlでcommandのところを以下のようにしていたらだめだった。
command: /etc/init.d/sshd restart && bash
以下のように複数コマンド実行する場合はbashスクリプトとして実行すれば大丈夫。
command: bash -c "/etc/init.d/sshd restart && bash"
なぜこれで大丈夫になるのか全然わからん・・
参考: