[英]How to access Django Docker app in a Virtual Machine?
Currently, I'm trying to access a simple Django application, which I created in an Azure Virtual Machine.目前,我正在尝试访问我在 Azure 虚拟机中创建的简单 Django 应用程序。 As the application is still simple, I only want to access the "The install worked successfully! Congratulations!"
由于应用程序还很简单,我只想访问“安装成功!恭喜!” page from my local machine by accessing
http://VM_IP:PORT/
.通过访问
http://VM_IP:PORT/
从我的本地机器页面。 I was able to do just that, but when I tried to Dockerize the project and access the built image from my local machine, it didn't work .我能够做到这一点,但是当我尝试 Dockerize 项目并从我的本地机器访问构建的图像时,它不起作用。
I've already made some setup in my Azure portal so that the Virtual Machine is able to listen to a specific port;我已经在 Azure 门户中进行了一些设置,以便虚拟机能够侦听特定端口; in this case is 8080 (so
http://VM_IP:8080/
).在这种情况下是 8080(所以
http://VM_IP:8080/
)。 I'm quite new to Docker, so I'm assuming there was something missing in the Dockerfile I've created for the project.我对 Docker 很陌生,所以我假设我为该项目创建的 Dockerfile 中缺少一些东西。
Dockerfile文件
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
I'm not sure what's happening.我不确定发生了什么。 It will be very appreciated if someone could point out what I was missing?
如果有人能指出我遗漏了什么,将不胜感激? Thanks in advance.
提前致谢。
I suspect the problem may be that you're confusing the EXPOSE
build-time instruction with the publish
runtime flag.我怀疑问题可能是您将
EXPOSE
构建时指令与publish
运行时标志混淆了。 Without the latter, any containers on your VM would be inaccessible to the host machine.如果没有后者,主机将无法访问 VM 上的任何容器。
Some background:一些背景:
The EXPOSE
instruction is best thought of as documentation; EXPOSE
指令最好被认为是文档; it has no effect on container networking .它对容器网络没有影响。 From the docs :
从文档:
The EXPOSE instruction does not actually publish the port.
EXPOSE 指令实际上并不发布端口。 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.
它充当构建镜像的人和运行容器的人之间的一种文档,关于打算发布哪些端口。
Seems kind of odd at first glance, but it's for good reason: the image itself does not have the permissions to declare host port-mappings — that's up to the container runtime and whoever is operating it (you!).乍一看似乎有点奇怪,但这是有充分理由的:图像本身没有声明主机端口映射的权限——这取决于容器运行时和操作它的人(你!)。
The way to do this is by passing the --publish
or -p
flag to the docker run
command, allowing you to define a mapping between the port open in the container network and a port on the host machine.这样做的方法是将
--publish
或-p
标志传递给--publish
docker run
命令,允许您定义容器网络中打开的端口和主机上的端口之间的映射。 So, for example, if I wanted to run an nginx
container that can be accessed at port 8080 on my localhost, I'd run: docker run --rm -d -p 8080:80 nginx
.因此,例如,如果我想运行一个可以在本地主机的 8080 端口访问的
nginx
容器,我会运行: docker run --rm -d -p 8080:80 nginx
。 The running container is then accessible at localhost:8080
on the host.然后可以在
localhost:8080
上的localhost:8080
访问正在运行的容器。 Of course, you can also use this to expose container ports from one host to another.当然,您也可以使用它来将容器端口从一台主机暴露到另一台主机。 Without this, any networking configuration in your Dockerfile is executed in the context of the container network, and is basically inaccessible to the host.
如果没有这个,Dockerfile 中的任何网络配置都会在容器网络的上下文中执行,并且主机基本上无法访问。
TL;DR: you probably just need to publish your ports when you create and run the container on your VM: docker run -p {vm_host_port}:{container_port} {image_name}
. TL;DR:您可能只需要在 VM 上创建和运行容器时发布端口:
docker run -p {vm_host_port}:{container_port} {image_name}
。 Note that port mappings cannot be added or changed for existing containers;请注意,不能为现有容器添加或更改端口映射; you'd have to destroy the container and recreate it.
您必须销毁容器并重新创建它。
Side note: while docker run
is quick and easy, it can quickly become unmanageable as your project grows and you add in environment variables, attach volumes, define inter-container dependencies, etc. An alternative with native support is docker-compose
, which lets you define the runtime configuration of your container (or containers) declaratively in YAML — basically picking up where the Dockerfile leaves off.旁注:虽然
docker run
既快速又简单,但随着项目的增长和添加环境变量、附加卷、定义容器间依赖等,它很快就会变得无法管理。 具有本机支持的替代方案是docker-compose
,它可以让您可以在 YAML 中声明性地定义容器(或多个容器)的运行时配置——基本上是从 Dockerfile 离开的地方开始。 And once it's set up, you can just run docker-compose up
, instead of having to type out lengthy docker
commands, and waste time debugging when you forgot to include a flag, etc. Just like we use Dockerfile
s to have a declarative, version-controlled description of how to build our image, I like to think of docker-compose
as one way to create a declarative, version-controlled description for how to run and orchestrate our image(s).一旦设置好,您就可以运行
docker-compose up
,而不必输入冗长的docker
命令,并且在忘记包含标志等时浪费时间进行调试。 就像我们使用Dockerfile
来进行声明一样,关于如何构建镜像的版本控制描述,我喜欢将docker-compose
视为一种创建声明性、版本控制描述的方法,用于如何运行和编排我们的镜像。
Hope this helps!希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.