Jupyter notebookをdockerコンテナで起動してホストのブラウザから使えるようにする
今回はdockerコンテナでjupyter notebookを起動してブラウザで見れるようにしました。
実行環境はubuntuでdocker, docker-composeがインストールされていることを前提としています。
また、開発環境での利用を想定しており セキュリティ設定は考慮しておりません。
1. docker-compose用のファイルを作成
始めにDockerfileとDocker-compose.ymlをいかの通り作成します。
1.1 Dockerfile
pythonが使えるimageを指定して、notebookライブラリをインストールしています。
FROM python:3.9
WORKDIR /app
SHELL ["/bin/bash", "-c"]
RUN apt-get update &
RUN pip install --upgrade pip
RUN pip install notebook
1.2 docker-compose.yml
コンテナからホストへportを渡しすためにports:
の指定が必要になります。
今回はjupyter notebookがデフォルトで使用するポート8888をコンテナおよびホストで使う設定にしています。
version: '3'
services:
app:
build: .
volumes:
- ./:/app
ports:
- 8888:8888
tty: true
2. コンテナに入ってjupyter notebook起動
2.1 コンテナ起動
まずはコンテナ起動。
(以下ホストでコマンド実行する場合はコマンドラインの先頭に$をつけてます)
$ docker-compose up -d
次に起動確認。
$ docker-compose ps
StateがUp
ならOK。portの設定もここで確認できます。
Name Command State Ports
----------------------------------------------------------
jnotebook- python3 Up 0.0.0.0:8888->8888
docker_app_1 /tcp,:::8888->8888
/tcp
2.2 コンテナに入ってjupyter notebookを起動
以下コマンド実行でコンテナに入る。
$ docker-comose exec app bash
次に以下のコマンドでjupyter notebookを起動。
jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token=''
オプションの意味は
--port=8888
8888ポートを利用。
--ip=0.0.0.0
外部からのアクセスを許可。ホストからアクセスするために設定。
--allow-root
rootでの起動を許可。dockerコンテナのユーザー権限がデフォルトではroot
ユーザーになっているため。
--NotebookApp.token=''
ブラウザでアクセスするときのトークン入力を無効にする。
実行後ターミナルには以下のように表示される。
root@875788d8dc37:/app# jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token=''
[I 05:42:04.018 NotebookApp] Authentication of /metrics is OFF, since other authentication is disabled.
[W 05:42:04.158 NotebookApp] All authentication is disabled. Anyone who can connect to this server will be able to run code.
[I 05:42:04.163 NotebookApp] Serving notebooks from local directory: /app
[I 05:42:04.163 NotebookApp] Jupyter Notebook 6.4.8 is running at:
[I 05:42:04.163 NotebookApp] http://875788d8dc37:8888/
[I 05:42:04.163 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 05:42:04.165 NotebookApp] No web browser found: could not locate runnable browser.
またコンテナ内から接続できるか確認する場合はcurl
コマンドを使って確認できる。
curl -L localhost:8888
起動していれば以下のようにhtmlが表示される。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
失敗してる場合は以下の様になったりする。
curl: (7) Failed to connect to localhost port 8888: 接続を拒否されました
2.3 ホストから(コンテナに入らず)jupyter notebookを起動する方法
(*2024年8月24日追記)
コンテナにわざわざ入るのが面倒に思う場合は、ホストからも実行可能です。
方法は以下のようにdocker-compose exec [コンテナ名]
を2.2のコマンドの先頭に追加して実行するだけです。
$ docker-compose exec app jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token=''
3. ホストからブラウザ接続
ブラウザを開いてhttp://localhost:8888
に接続してnotebookのページが表示されればOK!!
4. 実行時のルートディレクトリを指定
今のままだだとブラウザ接続時にdockerのファイルが見えてしまってるので、接続時のルートディレクトリを指定します。
まず任意のディレクトリをコンテナ外で作成し(今回はwork
)、そこをルートディレクトリとして扱います。(コンテナに入って作成するとディレクトリの所有者がrootになってしまいます。)
$ mkdir work
次にnotebook起動のオプションに--notebook-dir 'work'
を追加して起動します。
これで表示のルートディレクトリが変更できます。
jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token='' --notebook-dir 'work'
5. notebook実行をshファイルで行う
起動時に毎回オプション指定するのが煩わしいのでshファイルから実行するようにします。
jn.shを作成以下を記載します。
jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --NotebookApp.token='' --notebook-dir 'work'
実行するとき。以下をコマンド実行します
(権限なくて実行できないときはコンテナ外でchmod 755 jn.sh
する。)
./jn.sh
jupyter notebook --generate-config
でデフォルトでオプションを指定することもできるのですがファイルの場所がユーザディレクトリ下になってしまうので今回はshファイルを採用しました。
6. コンテナ内の実行ユーザーをrootから一般ユーザーに変更する
(*2023年8月10日追記)
Linuxですと今のままだとコンテナ内の実行ユーザーがrootのため、notebookで作成したファイルの所有者がrootとなってしまいホストの一般ユーザーでは編集ができません。
macだとホスト側のユーザーをコンテナ内でもデフォルトで使うのでここは不要だと思います。
(数年前に確認したので今はわかりませんが。)
そのためコンテナ内の実行ユーザーを一般ユーザーに変更することにします。
作成する一般ユーザーの名前は任意ですが、ここではpyuser
としています。
ただし以下の方法はホストとコンテナに作成した一般ユーザーのgidが一致していることが前提となってます。(デフォルトでは双方1000になってます。)
6.1 dockerfile
イメージのビルド時に一般ユーザーを作成するようにします。変更後はイメージをビルドし直す必要があります。
FROM python:3.9
WORKDIR /app
SHELL ["/bin/bash", "-c"]
RUN apt-get update &
RUN pip install --upgrade pip
RUN pip install notebook
####### 追加箇所 #######
RUN useradd -m pyuser
USER pyuser
#######################
6.2 notebook起動コマンド jn.sh
実行オプションから --allow-root
を削除します。
削除後のnotebook起動コマンドはこちら。
jupyter notebook --port=8888 --ip=0.0.0.0 --NotebookApp.token='' --notebook-dir 'work'
これで修正は完了です。一度イメージを削除して修正前と同じ手順で実行するとユーザーがrootから変わっています。
Discussion