即使容器正在运行,也无法访问该容器。

huangapple go评论81阅读模式
英文:

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中,exposeport之间有一点区别,其中一个将端口暴露给其他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.

huangapple
  • 本文由 发表于 2023年8月9日 01:00:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76861731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定