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

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

Can't access to the container even if it is running

问题

我有一个在Docker容器中的Flask API。它与其他容器进行交互,所以我把所有东西都放在了一个docker-compose中。
当我运行docker-compose up时,容器成功构建和运行,但我无法访问我的API,无论是从浏览器还是使用Python的requests模块。

我现在将在这里粘贴包含API容器配置的Dockerfile:

  1. FROM python:3.8.16-bullseye
  2. RUN apt-get update
  3. COPY requirements.txt requirements.txt
  4. RUN pip install --upgrade pip && pip install -r requirements.txt
  5. RUN mkdir "jobs"
  6. COPY . /counter_sairus
  7. WORKDIR /counter_sairus
  8. EXPOSE 5000
  9. ENTRYPOINT ["python", "api.py"]

这是docker-compose.yml

  1. version: "2.3"
  2. services:
  3. api:
  4. container_name: api
  5. build:
  6. context: .
  7. dockerfile: Dockerfile
  8. environment:
  9. - BROKER_URI=redis://redis
  10. - BACKEND_URI=redis://redislistening on
  11. depends_on:
  12. - worker
  13. - redis
  14. volumes:
  15. - ./jobs:/counter_sairus/jobs
  16. worker:
  17. container_name: celery
  18. environment:
  19. - BROKER_URI=redis://redis
  20. - BACKEND_URI=redis://redis
  21. build:
  22. context: .
  23. dockerfile: Dockerfile_worker
  24. depends_on:
  25. - redis
  26. volumes:
  27. - ./jobs:/counter_sairus/jobs
  28. redis:
  29. image: "redis:alpine3.17"
  30. ports:
  31. - 6379
  32. networks:
  33. default:
  34. external:
  35. name: rete1

最后,这是api.py中的代码:

  1. api = Api(title="API", version="0.1", description="API")
  2. application = Flask(__name__)
  3. api.init_app(application)
  4. if __name__ == '__main__':
  5. application.run(host='0.0.0.0', port=5000, debug=True)

在运行docker-compose之后,会出现一些日志消息。其中三个来自API容器,内容如下:

  1. * Running on all addresses (0.0.0.0)
  2. * Running on http://127.0.0.1:5000
  3. * 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:

  1. FROM python:3.8.16-bullseye
  2. RUN apt-get update
  3. COPY requirements.txt requirements.txt
  4. RUN pip install --upgrade pip && pip install -r requirements.txt
  5. RUN mkdir "jobs"
  6. COPY . /counter_sairus
  7. WORKDIR /counter_sairus
  8. EXPOSE 5000
  9. ENTRYPOINT ["python", "api.py"]

And this is the docker-compose.yml:

  1. version: "2.3"
  2. services:
  3. api:
  4. container_name: api
  5. build:
  6. context: .
  7. dockerfile: Dockerfile
  8. environment:
  9. - BROKER_URI=redis://redis
  10. - BACKEND_URI=redis://redislistening on
  11. depends_on:
  12. - worker
  13. - redis
  14. volumes:
  15. - ./jobs:/counter_sairus/jobs
  16. worker:
  17. container_name: celery
  18. environment:
  19. - BROKER_URI=redis://redis
  20. - BACKEND_URI=redis://redis
  21. build:
  22. context: .
  23. dockerfile: Dockerfile_worker
  24. depends_on:
  25. - redis
  26. volumes:
  27. - ./jobs:/counter_sairus/jobs
  28. redis:
  29. image: "redis:alpine3.17"
  30. ports:
  31. - 6379
  32. networks:
  33. default:
  34. external:
  35. name: rete1

Lastly, this is the doce in api.py :

  1. api = Api(title="API", version="0.1", description="API")
  2. application = Flask(__name__)
  3. api.init_app(application)
  4. if __name__ == '__main__':
  5. 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:

  1. * Running on all addresses (0.0.0.0)
  2. * Running on http://127.0.0.1:5000
  3. * 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容器:

  1. docker build -t something . && docker run -d --rm celery -e ROKER_URI=redis://redis something

这只是为了更易读而略微简化了一下。

因此,如果你想要暴露一个可用的端口,你需要以某种方式在命令中告诉它。有多种选项,其中一种是暴露一个端口。你可以这样做:

  1. docker run -p 5000:5000 celery something:latest

你需要在compose文件中做同样的事情。(请注意,在compose中,exposeport之间有一点区别,其中一个将端口暴露给其他compose服务,另一个将端口发布到主机)。

所以你需要调整你的compose文件,像这样:

  1. version: "2.3"
  2. services:
  3. api:
  4. container_name: api
  5. build:
  6. context: .
  7. dockerfile: Dockerfile
  8. environment:
  9. - BROKER_URI=redis://redis
  10. - BACKEND_URI=redis://redislistening on
  11. depends_on:
  12. - worker
  13. - redis
  14. volumes:
  15. - ./jobs:/counter_sairus/jobs
  16. ports:
  17. - 5000:5000
  18. worker:
  19. container_name: celery
  20. environment:
  21. - BROKER_URI=redis://redis
  22. - BACKEND_URI=redis://redis
  23. build:
  24. context: .
  25. dockerfile: Dockerfile_worker
  26. depends_on:
  27. - redis
  28. volumes:
  29. - ./jobs:/counter_sairus/jobs
  30. ports:
  31. - 5000:5000
  32. redis:
  33. image: "redis:alpine3.17"
  34. ports:
  35. - 6379
  36. networks:
  37. default:
  38. external:
  39. 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:

  1. 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

  1. 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:

  1. version: "2.3"
  2. services:
  3. api:
  4. container_name: api
  5. build:
  6. context: .
  7. dockerfile: Dockerfile
  8. environment:
  9. - BROKER_URI=redis://redis
  10. - BACKEND_URI=redis://redislistening on
  11. depends_on:
  12. - worker
  13. - redis
  14. volumes:
  15. - ./jobs:/counter_sairus/jobs
  16. ports:
  17. - 5000:5000
  18. worker:
  19. container_name: celery
  20. environment:
  21. - BROKER_URI=redis://redis
  22. - BACKEND_URI=redis://redis
  23. build:
  24. context: .
  25. dockerfile: Dockerfile_worker
  26. depends_on:
  27. - redis
  28. volumes:
  29. - ./jobs:/counter_sairus/jobs
  30. ports:
  31. - 5000:5000
  32. redis:
  33. image: "redis:alpine3.17"
  34. ports:
  35. - 6379
  36. networks:
  37. default:
  38. external:
  39. 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:

确定