如何在虚拟机中访问 Django Docker 应用程序?

How to access Django Docker app in a Virtual Machine?

目前,我正在尝试访问我在 Azure 虚拟机中创建的简单 Django 应用程序。由于应用程序仍然很简单,我只想通过访问 http://VM_IP:PORT/ 从我的本地计算机访问 "The install worked successfully! Congratulations!" 页面。我能够做到这一点,但是当我尝试 Docker 化项目并从我的本地计算机访问构建的图像时,它没有工作

我已经在我的 Azure 门户中进行了一些设置,以便虚拟机能够侦听特定端口;在这种情况下是 8080(所以 http://VM_IP:8080/)。我是 Docker 的新手,所以我假设我为项目创建的 Docker 文件中缺少某些内容。

Docker文件

RUN mkdir /app
WORKDIR /app

# Add current directory code to working directory
ADD . /app/

# set default environment variables
ENV PYTHONUNBUFFERED 1
ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive

# set project environment variables
# grab these via Python's os.environ# these are 100% optional here
ENV PORT=8080
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        tzdata \
        python3-setuptools \
        python3-pip \        python3-dev \
        python3-venv \
        git \
        && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# install environment dependencies
RUN pip3 install --upgrade pip
RUN pip3 install pipenv

# Install project dependencies
RUN pipenv install --skip-lock --system --dev

EXPOSE 8888
CMD gunicorn simple_project.wsgi:application --bind 0.0.0.0:$PORT

我不确定发生了什么。如果有人能指出我遗漏了什么,将不胜感激?提前致谢。

我怀疑问题可能是您将 EXPOSE 构建时指令与 publish 运行time 标志混淆了。如果没有后者,主机将无法访问 VM 上的任何容器。

一些背景:

EXPOSE 指令是 最好的文档;它对容器网络没有影响。来自 docs:

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published.

乍一看似乎有点奇怪,但这是有充分理由的:图像本身没有声明主机端口映射的权限——这取决于容器 运行time 和操作它的人(你!)。

这样做的方法是将--publish-p标志传递给docker run命令,允许您定义容器网络中打开的端口与主机上的一个端口。因此,例如,如果我想 运行 一个 nginx 容器,可以在我的本地主机上的端口 8080 访问,我会 运行: docker run --rm -d -p 8080:80 nginx。 运行ning 容器随后可在主机上的 localhost:8080 处访问。当然,您也可以使用它来将容器端口从一台主机公开到另一台主机。 否则,Dockerfile 中的任何网络配置都会在容器网络的上下文中执行,主机基本上无法访问。

TL;DR:您可能只需要在 创建和 运行 VM 上的容器时发布您的端口:docker run -p {vm_host_port}:{container_port} {image_name}。请注意,不能为现有容器添加或更改端口映射;你必须销毁容器并重新创建它。


旁注:虽然 docker run 快速简单,但随着项目的增长以及您添加环境变量、附加卷、定义容器间依赖关系等,它很快就会变得难以管理。原生的替代方案支持是 docker-compose,它允许您在 YAML 中以声明方式定义容器(或多个容器)的 运行time 配置——基本上是从 Dockerfile 停止的地方开始。一旦设置完成,您只需 运行 docker-compose up,而不必输入冗长的 docker 命令,也不必在忘记包含标志时浪费时间进行调试,等等。就像我们使用 Dockerfiles 对如何 构建 我们的图像进行声明性的、版本控制的描述,我喜欢将 docker-compose 视为创建图像的一种方式关于如何 运行 和编排我们的图像的声明性、版本控制的描述。


希望对您有所帮助!