简体   繁体   English

Django shell_plus:如何访问Docker Container中的Jupyter notebook

[英]Django shell_plus: How to access Jupyter notebook in Docker Container

I am trying to access a Jupyter Notebook created with the shell_plus command from django-extensions in a Docker container.我正在尝试从 Docker 容器中的 django-extensions 访问使用shell_plus命令创建的 Jupyter Notebook。

docker-compose -f local.yml run --rm django python manage.py shell_plus --notebook

My configuration is based on the answers of @RobM and @Mark Chackerian to this Stack Overflow question .我的配置基于@RobM 和@Mark Chackerian 对这个Stack Overflow 问题的回答。 Ie I installed and configured a custom kernel and my Django apps config file has the constant NOTEBOOK_ARGUMENTS set to:即我安装并配置了自定义 kernel 和我的 Django 应用程序配置文件将常量NOTEBOOK_ARGUMENTS设置为:

NOTEBOOK_ARGUMENTS = [
    '--ip', '0.0.0.0',
    '--port', '8888',
    '--allow-root',
    '--no-browser',
]

I can see the container starting successfully in the logs:我可以在日志中看到容器成功启动:

[I 12:58:54.877 NotebookApp] The Jupyter Notebook is running at:
[I 12:58:54.877 NotebookApp] http://10d56bab37fc:8888/?token=b2678617ff4dcac7245d236b6302e57ba83a71cb6ea558c6
[I 12:58:54.877 NotebookApp]  or http://127.0.0.1:8888/?token=b2678617ff4dcac7245d236b6302e57ba83a71cb6ea558c6

But I can't open the url. I have forwarded the port 8888 in my docker-compose , tried to use localhost instead of 127.0.0.1 and also tried to use the containers IP w/o success.但是我无法打开 url。我已经在我的docker-compose中转发了端口 8888,尝试使用localhost而不是127.0.0.1并且还尝试使用容器 IP 没有成功。

It feels like I am missing the obvious here … Any help is appreciated.感觉我错过了这里显而易见的东西……感谢任何帮助。

For the sake of records as of 2020, I managed to have a working django setup with Postgresql in docker-compose :为了截至 2020 年的记录,我设法在docker-compose中使用Postgresql进行了有效的django设置:

development.py (settings.py)开发.py (settings.py)

INSTALLED_APPS += [
    "django_extensions",
]

SHELL_PLUS = "ipython"

SHELL_PLUS_PRINT_SQL = True

NOTEBOOK_ARGUMENTS = [
    "--ip",
    "0.0.0.0",
    "--port",
    "8888",
    "--allow-root",
    "--no-browser",
]

IPYTHON_ARGUMENTS = [
    "--ext",
    "django_extensions.management.notebook_extension",
    "--debug",
]

IPYTHON_KERNEL_DISPLAY_NAME = "Django Shell-Plus"

SHELL_PLUS_POST_IMPORTS = [ # extra things to import in notebook
    ("module1.submodule", ("func1", "func2", "class1", "etc")),
    ("module2.submodule", ("func1", "func2", "class1", "etc"))

]

os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" # only use in development 

requirements.txt要求.txt

django-extensions
jupyter
notebook
Werkzeug  # needed for runserver_plus
...

docker-compose.yml docker-compose.yml

version: "3"

services:
  db:
    image: postgres:13
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust
    restart: always
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data/
  web:
    build: .
    environment:
      - DJANGO_SETTINGS_MODULE=settings.development
    command:
      - scripts/startup.sh
    volumes:
      - ...
    ports:
      - "8000:8000" # webserver 
      - "8888:8888" # ipython notebook
    depends_on:
      - db

volumes:
  postgres_data:

From your host terminal run this command:从您的主机终端运行以下命令:

docker-compose exec web python manage.py shell_plus --notebook

Finally navigate to http://localhost:8888/?token=<xxxx> in the web browser of host.最后在主机的web浏览器中导航到http://localhost:8888/?token=<xxxx>

Got it to work, but why it does so is beyond me.让它工作,但它为什么这样做是超出我的。 Exposing the ports in the docker-compose run command did the trick.docker-compose run命令中公开端口就可以了。

docker-compose -f local.yml run --rm -p 8888:8888 django python manage.py shell_plus --notebook

I was under the impression exposing ports in my local.yml would open them also in containers started by run .我的印象是在我的local.yml中暴露端口也会在由run启动的容器中打开它们。

The compose run command will per default not expose the defined service ports. compose run 命令默认不会公开定义的服务端口。 From the documentation at https://docs.docker.com/compose/reference/run/来自https://docs.docker.com/compose/reference/run/的文档

The [...] difference is that the docker-compose run command does not create any of the ports specified in the service configuration. [...] 不同之处在于 docker-compose run 命令不会创建服务配置中指定的任何端口。 This prevents port collisions with already-open ports.这可以防止端口与已经打开的端口发生冲突。 If you do want the service's ports to be created and mapped to the host, specify the --service-ports flag:如果您确实希望创建服务的端口并将其映射到主机,请指定 --service-ports 标志:

 docker-compose run --service-ports web python manage.py shell

You will therefore need to run因此,您需要运行

docker-compose -f local.yml run --rm --service-ports django python manage.py shell_plus --notebook

It might also be that the default 8888 port is already used by a local jupyter server (eg one spun up by VS Code's jupyter notebook implementation. I therefore usually map to a different port in the settings.py NOTEBOOK_ARGUMENTS list. (In this case the port mapping in the compose file needs to be adjusted as well, of course, and there must not be another container running in the background with the same service definition as this might also occupy the port.)也可能是默认的 8888 端口已被本地 jupyter 服务器使用(例如,由 VS Code 的 jupyter notebook 实现启动。因此,我通常将 map 连接到 settings.py NOTEBOOK_ARGUMENTS 列表中的另一个端口。(在这种情况下当然,compose 文件中的端口映射也需要调整,并且不能有另一个容器在后台运行具有相同服务定义的容器,因为这也可能占用端口。)

If you want to use jupyter notebook like separated service:如果您想使用 jupyter notebook 之类的分离服务:

jupyter_notebook:
  build:
    context: .
    dockerfile: docker/dev/web/Dockerfile
  command: python manage.py shell_plus --notebook
  depends_on:
    - web
  ports:
  - 8888:8888 # ipython notebook
  env_file:
    - .env

after:后:

docker-compose logs -f 'jupyter_notebook'

and you will get access token in logs您将在日志中获得访问令牌

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM