简体   繁体   English

从 docker 镜像连接到 docker-compose 容器

[英]Connect to docker-compose container from docker image

I've got a Docker image which accepts a DATABASE_URL env and start the container with我有一个 Docker 图像,它接受DATABASE_URL env 并启动容器

docker run -p 3000:3000 -e DATABASE_URL=mysql://root:foobar@localhost:3309/app app_image

On startup the container should run migrations on a database bootstraped from a docker-compose.yml file:在启动时,容器应该在从docker-compose.yml文件引导的数据库上运行迁移:

version: '3'

services:
  database:
    image: mysql:8.0
    environment:
      - MYSQL_DATABASE=app
      - MYSQL_ROOT_PASSWORD=foobar
    ports:
      - "3309:3306"
    volumes:
      - db:/var/lib/mysql

  volumes:
    db:

Unfortunately, I always get Can't reach database at localhost:3309 .不幸的是,我总是Can't reach database at localhost:3309 I assume it has something to do with the network settings - but how to configure these settings in order to make it work?我认为它与网络设置有关 - 但如何配置这些设置才能使其正常工作?

I've tried many different configurations (eg database , 127.0.0.1 , etc. instead of localhost ) but couldn't make it work and I'm honestly running out of ideas.我已经尝试了许多不同的配置(例如database127.0.0.1等而不是localhost )但无法使其工作,老实说我的想法已经用完了。

Thanks!谢谢!

Some clarifications: Unless you specifically bind containers to the same host eg --network host or link them together in docker compose using links Links documentation , container A will not be able to reach anything on container B via localhost .一些说明:除非您专门将容器绑定到同一主机,例如--network host或使用links链接文档在 docker compose 中将它们链接在一起,否则容器 A 将无法通过localhost访问容器 B 上的任何内容。

Docker compose, unless specified differently in the docker-compose.yaml file, automatically creates a separate network for all of the containers that are managed by that compose file, its name is usually based on the folder the file is in. You can view it using docker network ls Docker compose,除非在docker-compose.yaml文件中另有指定,否则会自动为该 compose 文件管理的所有容器创建一个单独的网络,其名称通常基于文件所在的文件夹。您可以查看它使用docker network ls

that means, any container not managed by that compose file, is not part of the same network by default.这意味着,任何不受该组合文件管理的容器,默认情况下都不属于同一网络。

One option easy enough option that you have (among many probably):您有一个足够简单的选项(可能有很多):

  1. Decide on a network name which the compose file and you container will agree on确定撰写文件和您的容器同意的网络名称
  2. create this network beforehand (before starting the standalone container and the compose file), the network will probably be in bridge mode docker network docs docker network create -d bridge my-bridge-network预先创建此网络(在启动独立容器和撰写文件之前),网络可能处于桥接模式docker network docs docker network create -d bridge my-bridge-network
  3. add it to the compose file so that docker compose uses it instead of the auto-created one将它添加到 compose 文件中,以便 docker compose 使用它而不是自动创建的
networks:
  - my-bridge-network
  1. when starting the stand-alone container, specify which network to attach it to启动独立容器时,指定将其附加到哪个网络
docker run -p 3000:3000 -e DATABASE_URL=mysql://root:foobar@database:3309/app --network my-bridge-network app_image
  1. notice that the IP/HOSTNAME for the database container is according to the service name in the compose file, you can change that using hostname: some-other-hostname in the yaml.请注意,数据库容器的 IP/HOSTNAME 是根据撰写文件中的服务名称确定的,您可以使用hostname: some-other-hostname更改它。

all containers should now be on the same network, each one has a different IP/Hostname using this method (so cant use localhost for inter-container communication)所有容器现在都应该在同一个网络上,每个容器使用这种方法都有不同的 IP/主机名(因此不能使用 localhost 进行容器间通信)

Alternative option: use network: host for both the compose file and the stand-alone container, they can talk to each other using localhost.备选方案:使用network: host作为组合文件和独立容器,它们可以使用 localhost 相互通信。 i dont recommend this option, and cant find a good enough reason to use it over other options.我不推荐这个选项,也找不到足够好的理由来使用它而不是其他选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM