英文:
Can't access to the container even if it is running
问题
我有一个在Docker容器中的Flask API。它与其他容器进行交互,所以我把所有东西都放在了一个docker-compose中。
当我运行docker-compose up
时,容器成功构建和运行,但我无法访问我的API,无论是从浏览器还是使用Python的requests
模块。
我现在将在这里粘贴包含API容器配置的Dockerfile:
FROM python:3.8.16-bullseye
RUN apt-get update
COPY requirements.txt requirements.txt
RUN pip install --upgrade pip && pip install -r requirements.txt
RUN mkdir "jobs"
COPY . /counter_sairus
WORKDIR /counter_sairus
EXPOSE 5000
ENTRYPOINT ["python", "api.py"]
这是docker-compose.yml
:
version: "2.3"
services:
api:
container_name: api
build:
context: .
dockerfile: Dockerfile
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redislistening on
depends_on:
- worker
- redis
volumes:
- ./jobs:/counter_sairus/jobs
worker:
container_name: celery
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redis
build:
context: .
dockerfile: Dockerfile_worker
depends_on:
- redis
volumes:
- ./jobs:/counter_sairus/jobs
redis:
image: "redis:alpine3.17"
ports:
- 6379
networks:
default:
external:
name: rete1
最后,这是api.py
中的代码:
api = Api(title="API", version="0.1", description="API")
application = Flask(__name__)
api.init_app(application)
if __name__ == '__main__':
application.run(host='0.0.0.0', port=5000, debug=True)
在运行docker-compose之后,会出现一些日志消息。其中三个来自API容器,内容如下:
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.9:5000
但是,正如我所说的,这两个地址都无法工作。如果我尝试从浏览器访问它们,在这两种情况下,我都会收到一个错误,说无法访问该页面。
我在Windows上运行这个代码。但是如果我在Ubuntu上运行完全相同的代码,会出现完全相同的日志(只有IP地址不同),一切都正常工作。我不知道如何解决这个问题,任何帮助将不胜感激。
英文:
I have a Flask API in a docker container. It interacts with other containers so I put everything in a docker-compose.
When I run docker-compose up
the containers are successfully built and run, but I am not able to access to my API, neither from the browser nor with Python's requests
module.
I will now paste here the Dockerfile with the configuration for the API's container:
FROM python:3.8.16-bullseye
RUN apt-get update
COPY requirements.txt requirements.txt
RUN pip install --upgrade pip && pip install -r requirements.txt
RUN mkdir "jobs"
COPY . /counter_sairus
WORKDIR /counter_sairus
EXPOSE 5000
ENTRYPOINT ["python", "api.py"]
And this is the docker-compose.yml
:
version: "2.3"
services:
api:
container_name: api
build:
context: .
dockerfile: Dockerfile
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redislistening on
depends_on:
- worker
- redis
volumes:
- ./jobs:/counter_sairus/jobs
worker:
container_name: celery
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redis
build:
context: .
dockerfile: Dockerfile_worker
depends_on:
- redis
volumes:
- ./jobs:/counter_sairus/jobs
redis:
image: "redis:alpine3.17"
ports:
- 6379
networks:
default:
external:
name: rete1
Lastly, this is the doce in api.py
:
api = Api(title="API", version="0.1", description="API")
application = Flask(__name__)
api.init_app(application)
if __name__ == '__main__':
application.run(host='0.0.0.0', port=5000, debug=True)
After running the docker-compose, some log messages appear. Three of them come from the API container and are the following:
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.9:5000
But, as I said, neither one of the two addresses work. If I try to reach them from the browser, in both the cases I get an error saying that the page cannot be reached.
I am running this on windows. But if I run the very same code on Ubuntu, the very same logs will appear (only the IP addresses change), and everything works well. I have no idea on how to solve this, any help would be much appreciated
答案1
得分: 0
默认情况下,一切都包含在容器中。因此,如果你想让任何东西可访问,比如一个端口,你需要明确指定。
docker-compose
基本上只是一种更结构化的方式来运行docker命令。现在,如果你考虑一下你的容器以及如何运行它们,你可以将每个容器都转换为一个docker run
命令(如果你指定了一个Dockerfile而不是一个镜像,则还需要一个build
命令)。例如,你的api容器:
docker build -t something . && docker run -d --rm celery -e ROKER_URI=redis://redis something
这只是为了更易读而略微简化了一下。
因此,如果你想要暴露一个可用的端口,你需要以某种方式在命令中告诉它。有多种选项,其中一种是暴露一个端口。你可以这样做:
docker run -p 5000:5000 celery something:latest
你需要在compose文件中做同样的事情。(请注意,在compose中,expose
和port
之间有一点区别,其中一个将端口暴露给其他compose服务,另一个将端口发布到主机)。
所以你需要调整你的compose文件,像这样:
version: "2.3"
services:
api:
container_name: api
build:
context: .
dockerfile: Dockerfile
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redislistening on
depends_on:
- worker
- redis
volumes:
- ./jobs:/counter_sairus/jobs
ports:
- 5000:5000
worker:
container_name: celery
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redis
build:
context: .
dockerfile: Dockerfile_worker
depends_on:
- redis
volumes:
- ./jobs:/counter_sairus/jobs
ports:
- 5000:5000
redis:
image: "redis:alpine3.17"
ports:
- 6379
networks:
default:
external:
name: rete1
这与你已经为redis服务所做的操作相同。
英文:
Everything is contained by default in a container. So if you want to anything to be accessible such as a port, you need to be explicit about it.
docker-compose
is basically just a more structured way for you to run docker commands. Now if you think about your containers and how you run them, like that, you can translate each into a docker run
(and a build
if you specify a dockerfile instead of anb image) command. For example your api:
docker build -t something . && docker run -d --rm celery -e ROKER_URI=redis://redis something
That's a little shortened, for readability.
So if you want to expose a port to be available, you'd need to tell that in the command in some way. There are multiple options, one is to expose a port. Which you would do like
docker run -p 5000:5000 celery something:latest
You will have to do the same in your compose file. (Note that there's a bit of a difference in compose between expose
and port
where one exposes ports to other compose services and the other publishes them to the host machine).
So you need to adapt your compose file like so:
version: "2.3"
services:
api:
container_name: api
build:
context: .
dockerfile: Dockerfile
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redislistening on
depends_on:
- worker
- redis
volumes:
- ./jobs:/counter_sairus/jobs
ports:
- 5000:5000
worker:
container_name: celery
environment:
- BROKER_URI=redis://redis
- BACKEND_URI=redis://redis
build:
context: .
dockerfile: Dockerfile_worker
depends_on:
- redis
volumes:
- ./jobs:/counter_sairus/jobs
ports:
- 5000:5000
redis:
image: "redis:alpine3.17"
ports:
- 6379
networks:
default:
external:
name: rete1
Which is what you had done for the redis service already as well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论