dockerコンテナで複数同時にjupyterを稼働させれば、機械学習用やbot用、webスクレイピング用などと、用途を分けて使用できるので、大変便利です。
また、DB(データベース)専用のコンテナだけ別に用意して、用途に応じて使い分ければ、他プロジェクト等の邪魔にもなりません。
そんなjupyterlabの便利な作業環境の作り方をご紹介です。
なお普通に稼働させるだけなら、anacondaをdockerhubでpullして、次のコマンドを入力すれば1発です。
docker run -i -t -p 8888:8888 continuumio/anaconda3 /bin/bash -c "\
conda install jupyter -y --quiet && \
mkdir -p /opt/notebooks && \
jupyter notebook \
--notebook-dir=/opt/notebooks --ip='*' --port=8888 \ --no-browser --allow-root"
あっという間に、いま話題の機械学習で人気のpythonを動かすことができます。
ただ、これでは、後から必要なモジュールをインストールしたり、複数同時に管理するのに不向きです。
折角dockerを導入しているなら、最初の環境設定(jupyterのインストール)をしっかり行った方が、後から楽です。
またセキュリティ対策も考慮したうえで、jupyterを導入する事も大事なポイントです。
毎回パスワード入力でログインする、httpsの暗号化された環境で使用すると安全性が高まります。
尚、自分のマシンにdockerをインストールしてlocalhostのpathで使っているなら、それほど気にする必要がないかもしれませんが、レンタルVPS(かごやのレンタルサーバーやconohaなど)を使用しているなら、httpsは、ほぼ絶対条件と考えるべきです。
jupyterはなぜhttps(SSL化)で使うべきなの?
初心者の方でもわかるように簡単に説明しますと、通信される中身がそのままの状態になっているか、暗号化されて解読されにくくなっているかの違いです。
郵便物に例えるなら、http通信がハガキ、https通信が封筒(書留)です。
大袈裟かもしれませんが、httpでのアクセスの場合、通信状態が丸見えの状態になっていると思ってください。jupyterでパスワード情報などを送信しているなら、仮にデータが第3者に覗かれてしまっても、暗号化されてわかりにくい状態になっていた方が安心です。
dockerを使用すれば、コンテナの組み合わせで簡単にhttps(SSL)化が可能です。
もちろん無料で使う事もできます。
ただ、数年前に使用されていた、「nginx-proxy」と「letsencrypt-nginx-proxy-companion」の方法は2022年の時点では利用(imageが存在しないので)できません。
詳しくは、便利になったはずなのに、応用パターンで使用するにはちょっとめんどくさい「docker swag」についてを参考にしてください。
そこで、新パターンとして、https-potalを利用する方法をご紹介です。
さらにjupyterを利用する時、総合開発環境としてのanacondaを利用するかどうかでも、やり方が違ってきます。
anacondaは色々便利なモジュールが最初からフル装備されているので、機械学習などでpythonを動かすなら大変便利です。
ただ、その分データ容量も増えるのが難点です。
また今回jupyterのhttps化(SSL化)で、ちょっと躓いた部分もあり、試行錯誤した結果、anacondaの有・無バージョンでjupyterを導入したので、2パターンのやり方を記載します。
docker-composeでSSL対応のjupyter lab環境を構築(anaconda有)
簡単に違いを説明すると、ディープラーニング等で重宝する機械学習用のモジュールなどがたくさん最初からインストールされているのがanacondaです。
初心者の方では、使用しない機能もたくさんありますが、とにかく何でも揃っているので、後から環境の事をあまり考えないで、作業に専念する事が魅力です。
jupyterlab環境にhttps-potalを使う理由
jupyterlabをhttps(SSL化)で利用するには、認証局によるサーバー証明書が必要になります。
VPSレンタルサーバー会社に有料で発行してもらう事もできますが、 Let’s Encrypt を使用すれば、無料で使えます。
ただし、Let’s Encryptを使って自分で発行する証明書は、有効期限が3ヵ月と短いので、その都度更新する必要があります。
この Let’s Encryptによる証明書の発行と更新の2つの作業を自動化してくれるdockerコンテナになるのが、「https-potal」や「swag」です。
以前は、このサーバー認証と更新作業は別々のdockerコンテナで管理するのが主流でした。
先に説明した「jwilder/nginx-proxy」と「jrcs/letsencrypt-nginx-proxy-companion」の組み合わせですが、2022年時点では廃れてしまった古い方法なので、ご注意ください。
サーバー証明書を発行だけするなら「certbot」も便利ですが、1度SSL化のjupyter環境さえ構築してしまえば、ほぼメンテナンスが不要になるhttps-potalが初心者には優しいでしょう。
dockerでjupyterlabとhttps-potalの組み合わせ
dockerによるanacondaとjupyterlabの基本ディレクトリは次のようになります。
jupyter
├── docker-compose.yml
├──── web
└──Dockerfile
├── workspace
└── nginx
以上の構成にしておけば、基本のimageをDockerfileに記載しておき、稼働のON、OFFをdocker-compose.ymlに任せる事ができます。
docker-compose.ymlに記載する内容は、2つのコンテナだけで十分です。
version: '3'
services:
jupyter_web:
build:
context: ./web
dockerfile: "Dockerfile"
image: jupyterlab_anaconda
container_name: jupyter_web_conda
user: root
volumes:
- ./workspace:/workspace
restart: always
expose:
- '8888'
environment:
- PUID=1000
- PGID=1000
networks:
- jupyter_net_https_conda
jupyter_https:
image: steveltn/https-portal:1
container_name: jupyter_https_conda
ports:
- '80:80'
- '443:443'
restart: always
volumes:
- ./nginx/ssl_certs:/var/lib/https-portal
- ./nginx/conf.d:/etc/nginx/conf.d
environment:
PUID: 1000
PGID: 1000
DOMAINS: 'mamarutest.com -> http://jupyter_web:8888'
WEBSOCKET: "true"
STAGE: production
depends_on:
- jupyter_web
networks:
- jupyter_net_https_conda
networks:
jupyter_net_https_conda:
driver: bridge
- jupyter_web:anacondaにjupyterインストール
- jupyter_https:https-potal(リバースプロキシ)
jupyter_webコンテナの大事なポイント
build:
context: ./web
dockerfile: "Dockerfile"
image: jupyterlab_anaconda
docker-compose buildに対応するため、buildの記載を入れています。
buildによって作成するimage名を指定します
dockerfile: Dockerfileの記載は省略する事も可能ですが、後から見た時に仕組みを思い出しやすいように書いておいた方が無難です。
portsを使わない事で、jupyter_webのコンテナへの直接のアクセスを禁止しています。
jupyter_httpsコンテナの大事なポイント
docker hubにあるsteveltn/https-portal:1のイメージをそのまま使用しています。
サーバー証明書の揮発化を防ぐために必要な記述が以下の通りです。
volumes:
- ./nginx/ssl_certs:/var/lib/https-portal
- ./nginx/conf.d:/etc/nginx/conf.d
ホスト側のデータと新規に作成されるjupyter_httpsのコンテナをマウントしておきます。
これで、コンテナが削除されても、サーバー証明書が消える事がなくなります。
jupyterのhttps化で最も大事な記述が次です。
environment:
DOMAINS: 'mamarutest.com -> http://jupyter_web:8888'
WEBSOCKET: "true"
STAGE: production
2行目は、コンテナのjupyter_webの8888ポートがmarutest.comに代替えされるという意味です。
矢印のように左から右ではなく、右から左に作用します。
また、WEBSOCKETの記述を忘れると、jupyterが稼働しません。
(wordpress等の通常のWEBサイトなら、WEBSOCKETの記述がなくても動くので、忘れがちです。WEB+httpsと設定が異なります)
さらに、STAGEは3段階に分かれており、local、staging、productionがあります。
- local:localhostなどの自己証明書で使用、他テスト環境でもOK
- staging:mamarutest.comなどのドメインで使用
- production:mamarutest.comなど正規のドメインで使用(警告がでなくなる)
最終的にはproducitonでの使用が良いですが、なんども証明書を発行していると使えなくなってしまうので、localやstagingできちんと稼働するのを確認してから切り替えるのが良いでしょう。
またdocker+sorescopeの時にはうまく稼働したワイルドカードDNSのドメインも使えません。
https://crypto-nft-fire.com/docker-serposcope/
サーバー証明書がうまく認識しないようで、jupyterが動きません。
onamae.comなどのキャンペーンを利用すれば、1年間無料でドメインを利用する事が出来るので、ここは必ずドメインを取得しておきましょう。
jupyterのhttps(SSL)化で必要なドメイン登録作業
ドメインを取得後、使用するVPS(レンタルサーバー)でドメインの登録作業があります。
1例として、onamae.comでドメイン取得、conohaで登録する場合のやり方をご紹介です。
onamae.comでのドメイン登録作業
ドメイン取得後、VPSで利用できるようにネームサーバーの変更をおこないます。
今回は、coonhaのVPSで利用するので、conoha用のns-a1.conoha.io、ns-a2.conoha.io、ns-a3.conoha.ioの登録を行います。
conohaのVPSを使う場合のドメイン登録作業
VPSを利用するconoha側でもドメインを登録する必要があります。
onamae.comで入手したドメインのDNS登録すると、3つのタイプが表示されます。
これにVPSで利用しているIPアドレスを追加、全部の4つのタイプが出来ていれば登録終了です。
dockerでanaconda(jupyter lab)を使う為に必要なDockerfile
docker hubでpullすることが出来るcontinuumio/anaconda3のimageから始めると簡単です。
尚、Dockerfileは、dockerfileでもなく、DockerFileでもなく、必ず最初だけ大文字のDockerfileにしないと認識してくれないので注意です。
FROM continuumio/anaconda3
WORKDIR /workspace
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& apt-get install -y sudo wget vim curl gawk make gcc \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/* \
&& ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN conda install -c conda-forge jupyterlab -y --quiet && \
conda install nodejs -y && \
conda install scikit-learn
RUN pip install mplfinance && \
pip install yahooquery && \
pip install motor && \
pip install pybotters
RUN jupyter serverextension enable --py jupyterlab
ENV DEBIAN_FRONTEND dialog
RUN mkdir /workspace && \
jupyter notebook --generate-config
ENTRYPOINT ["jupyter", "lab", "--ip='*'", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.allow_origin='*'"]
CMD ["--notebook-dir=/workspace"]
jupyter稼働に必要なnode.jsなどは、anacondaに最初からインストールされていますが、認識しないケースがあったのであえてインストールしています。
その他は、ファイナンス系で必要なモジュールをインストールしています。
Dockerfileで大事な箇所は、ENTRYPOINTです。この記述を間違えただけで、jupyterが稼働しなくなります。
ENTRYPOINT ["jupyter", "lab", "--ip='*'", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.allow_origin='*'"]
特に、”–NotebookApp.allow_origin=’*'”の記述がないとカーネル認識がないままjupyterが起動するので、コマンド入力の受け付けができません。
不具合解消の正攻法では、jupyterのconfigファイルにc.NotebookApp.allow_origin = ‘*’と記述するのが正解ですが、dockerを使うなら、以上のような使い方もできます。
また、”–LabApp.token=””と記述すれば、パスワードなしでjupyter labを起動する事もできます。
ただ、ドメイン名を知っていれば誰でもアクセスできるので、おすすめできません。(IPテーブルでアクセスできるパソコンを指定するなど、セキュリティを高める方法は、他にもありますが・・・)
VPS(レンタルサーバー)でjupyterを稼働させるならこれで環境構築作業は終了です。
#imageファイルの新規作成 or 更新
$ docker-compose build
#jupyterの起動
$ docker-compose up
自己PCで、localhostを利用する場合、この環境構築だけではjupyterlabが動かないケースもあります。その時は、/etc/hostsにtest.localなどのドメイン名を追記すると良いでしょう。
docker-composeのjupyterにDBを連携させる方法
jupyter labを使用していると、DBの管理を別にしたくなるケースもあるでしょう。
そのような時は、もう1つ別にDB付きのjupyter labを立ち上げる方法もあります。
ポイントは、jupyterlab_anacondaで用意したimageの使いまわしです。
jupyter-mongo
├── docker-compose.yml
├── mongo
└── Dockerfile
├── workspace
└── nginx
完全に別のjupyterlabにするなら、jupyter_webのimageも別にした方が良いですが、DBを追加するだけなので、あえて同じにしています。
尚、docker-compose.ymlとDockerfileの組み合わせで何度もbuildとupを行う場合、imageも別にするのが、正しい運用方法です。
version: '3'
services:
jupyter_web:
image: jupyterlab_anaconda
container_name: jupyter_web_mongo
user: root
volumes:
- ./workspace:/workspace
- ./mongo_jupyter/data:/home/work
restart: always
expose:
- '8888'
environment:
- PUID=1000
- PGID=1000
depends_on:
- mongodb
networks:
- jupyter_net_mongo
mongodb:
build:
context: ./mongo
dockerfile: "Dockerfile"
image: mongodb_compass
container_name: mongodb
volumes:
- ./mongo/mongo-data:/data/db
- ./mongo/mongodb-configdb:/data/configdb
ports:
- '27017:27017'
jupyter_https:
image: steveltn/https-portal:1
container_name: jupyter_https_mongo
ports:
- '2980:80'
- '29443:443'
restart: always
volumes:
- ./nginx/ssl_certs:/var/lib/https-portal
- ./nginx/conf.d:/etc/nginx/conf.d
environment:
PUID: 1000
PGID: 1000
DOMAINS: 'marumaru-test.com -> http://jupyter_web:8888'
WEBSOCKET: "true"
STAGE: local
depends_on:
- jupyter_web
networks:
- jupyter_net_mongo
networks:
jupyter_net_mongo:
driver: bridge
mongoDBという、DB専用のコンテナを追加しています。
また、jupyter labを複数稼働させるために、ホストに繋がるポートは別に変更しています。
尚、使用するポートが異なるので、同じDNS(DOMAINSに記載するドメイン)を使っても大丈夫です。
mongoDB用のDockerfile、そのままmongoのimageを使ってもOKですが、タイムを日本時間に変更するなど、buildで多少の変更は加えておいた方が良いでしょう。
FROM mongo
RUN apt-get update \
&& apt-get install -y sudo wget vim curl gawk make gcc \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/* \
&& ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
jupyterで作ったDBは、MongoDB Compassで確認すると視覚的にもわかりやすいので、おすすめです。
ややこしいですが、MongoDB Compassのソフトは、自宅のPCにインストールして、CompassからVPSサーバにアクセスする流れになります。
docker-composeでSSL対応のjupyter lab環境を構築(シンプル構成)
python初心者の方がお勉強で使用する程度なら、anacondaなしでも十分問題なく使用できます。
シンプル構成なので、何か問題があった時、問題の切り分け等が簡単です。
基本はanaconda付きのjupyter labとほぼ同じです。docker-compose.ymlファイルなど、jupyter_webのimage以外全部一緒でもOKです。
ただ、複数同時に稼働させるために、コンテナ名だけ別にしておいた方が良いでしょう。
違いは、Dockerfileです。
シンプルな反面、必要なpythonモジュールを全部自分でインストールしなければなりません。
FROM python:3
USER root
WORKDIR /workspace
ENV DEBIAN_FRONTEND noninteractive
# 必要なパッケージを記載
RUN apt-get update && apt-get install --no-install-recommends -y \
curl && \
apt-get clean
# 必要なPythonモジュールを記載
RUN python -m pip install --upgrade pip && pip install \
numpy \
scipy \
matplotlib \
ipython \
scikit-learn \
pandas \
pillow \
mglearn \
requests \
pyperclip \
beautifulsoup4 \
motor \
pybotters \
jupyterlab
RUN jupyter serverextension enable --py jupyterlab
ENV DEBIAN_FRONTEND dialog
RUN mkdir /workspace && \
jupyter notebook --generate-config
ENTRYPOINT ["jupyter", "lab", "--ip='*'", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.allow_origin='*'"]
CMD ["--notebook-dir=/workspace"]
必要なモジュールを追加して、docker-compose build、その後docker-compose upの繰り返しなので、慣れてくるとかなり楽です。
anacondaバージョンに比べて、挙動がおかしくなる確率も格段に低いです。
尚、docker image psで確認すると、anacondaのイメージは約3.8GB、jupyter単独は約1.8GBと2GBの差があります。
docker+https-potal+jupyterをレンタルサーバー(VPS)で構築する時の注意
最後にjupyterのhttps化ではまった箇所のご紹介です。
https化さえしなければ、初心者でもdockerを使えば10分ほどで環境構築が可能ですが、はまると何時間も環境構築に時間がかかるので、dockerの仕組みをしっかり理解してから、docker-composeを使いましょう。
dockerの意味があまりないかも知れませんが、dockerコンテナを1つ作ったらその中で全てのソフト等をインストールするというのも1つの方法です。
jupyter_webのカーネルが認識しない
jupyterlabがブラウザで立ち上がっても、pythonコマンド等が認識しない場合があります。
そのような時は、おそらく次のいずれかに原因があります。
ドメインを登録したばかりでドメインが認識しない!
DNS登録して1時間ぐらいでドメインは使えるようになりますが、SSLで認識するのにはさらに時間がかかります。
Let’s Encryptでサーバー証明書を発行してから24時間ぐらいは、気長に待ちましょう。
A.comで使用できるけど、B.comでは使えないという場合は、ドメインの可能性が高いです。
ファイヤーウォールでポート許可がOKになっていない!
ファイヤーウォールのポートが開いていなかったというポンミスもあるので、ご注意ください。
デフォルト443のポートは開いているケースが多いですが、複数のjupyter labを起動する時はポートを変更する必要があります。その時、対象のポートが開いているのか、確認も大事です。
$ ufw status
ポートの解放、10443を開放する場合
$ ufw allow 10443
ファイヤーウォールの再起動
$ ufw reload
jupyterの起動設定のセキュリティが高すぎる!
dockerのログを確認すると、Blocking Cross Origin API request などといった、Cross Origin系の問題が表示される場合、chromブラウザ等のセキュリティチェックに引っかかっている可能性があります。
これは、dockerの問題と言うより、jupyter側の設定の問題です。
環境ファイルconfigに次の記述を加えるだけで解決するケースが多いです。
c.NotebookApp.allow_origin='*'
尚、私の場合、Dockerfileに記述して、対策しています。
node.jsファイルがインストールされていない
jupyterの起動には、node.jsが必須です。
次のようなログがあった場合は、node.jsを疑ってみてください。
Could not determine jupyterlab build status without nodejs
インストールタイミングで壊れてしまった場合などは、再インストールで解消するとの報告などもよく見かけますが、これで解決したことはありません。
ドメインが機能していない場合も同じようなエラーログが表示されます。
色々インストールしすぎると、jupyter再起動後に認識しなくなるケースもあるので、imageコンテナのバージョン管理はしっかりおこないましょう。
以上 環境構築さえしっかりできれば、非常に便利なjupyter labですが、問題の切り分けに失敗すると深みにはまるので、ご注意です。
docker+jupyterをパスワード付きで運用できるようにする方法
Dockerfileに記述ずみです。そのままコピペすれば、最初だけ、トークンを入力し、その後はパスワード運用ができるようになります。