当外部链接容器实际上是 运行 使用 docker-compose 时如何避免 "Docker cannot link to a non running container" 错误
How to avoid the "Docker cannot link to a non running container" error when the external-linked container is actually running using docker-compose
我们想做的事情:
我们想使用docker-compose到link一个已经运行的容器(A)到另一个容器(B)按容器名称。我们使用“external-link”,因为两个容器都是从不同的 docker-compose.yml 文件启动的。
问题:
容器 B 无法启动并出现错误,尽管具有该名称的容器是 运行。
ERROR: for container_b Cannot start service container_b: Cannot link to a non running container: /PREVIOUSLY_LINKED_ID_container_a_1 AS /container_b_1/container_a_1
"docker ps"的输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
RUNNING_ID container_a "/docker-entrypoint.s" 15 minutes ago Up 15 minutes 5432/tcp container_a_1
示例代码:
docker-compose.yml 容器 B:
container_b:
external_links:
- container_a_1
此问题与其他 "how to fix" 问题有何不同:
- 我们不能使用 "sudo service docker restart"(有效),因为这是生产环境
- 我们不想每次都手动修复此问题,但找到原因以便我们可以
- 明白我们做错了什么
- 了解如何避免这种情况
假设:
- 似乎存在 container_a 的两个实例(RUNNING_ID 和 PREVIOUSLY_LINKED_ID)
- 这可能会发生,因为我们
- 通过docker-compose 构建和
重建容器
- 更改了容器的转发外部端口(808
01:8080)
评论
- 不要按照评论中的建议使用
docker-compose down
,这会删除音量!
Docker links are deprecated 所以除非你需要他们提供的某些功能或者使用的是非常旧的 docker 版本,否则我建议切换到 docker 网络。
由于您要连接的容器似乎是在单独的组合文件中启动的,因此您可以在外部创建该网络:
docker network create app_net
然后在您的 docker-compose.yml 文件中,将您的容器连接到该网络:
version: '3'
networks:
app_net:
external:
name: app_net
services:
container_a:
# ...
networks:
- app_net
然后在您的 container_b 中,您将连接到 container_a 作为 "container_a",而不是 "container_a_1"。
顺便说一句,除非您传递 -v
标志,否则没有记录 docker-compose down
删除卷。也许您正在使用匿名卷,在这种情况下,我不确定 docker-compose up
是否知道在哪里可以找到您的数据。首选命名卷。您的数据很可能没有存储在卷中,这很危险,并且您无法更新容器:
$ docker-compose down --help
By default, the only things removed are:
- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used
Networks and volumes defined as `external` are never removed.
Usage: down [options]
Options:
--rmi type Remove images. Type must be one of:
'all': Remove all images used by any service.
'local': Remove only images that don't have a custom tag
set by the `image` field.
-v, --volumes Remove named volumes declared in the `volumes` section
of the Compose file and anonymous volumes
attached to containers.
--remove-orphans Remove containers for services not defined in the
Compose file
我们想做的事情:
我们想使用docker-compose到link一个已经运行的容器(A)到另一个容器(B)按容器名称。我们使用“external-link”,因为两个容器都是从不同的 docker-compose.yml 文件启动的。
问题:
容器 B 无法启动并出现错误,尽管具有该名称的容器是 运行。
ERROR: for container_b Cannot start service container_b: Cannot link to a non running container: /PREVIOUSLY_LINKED_ID_container_a_1 AS /container_b_1/container_a_1
"docker ps"的输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
RUNNING_ID container_a "/docker-entrypoint.s" 15 minutes ago Up 15 minutes 5432/tcp container_a_1
示例代码:
docker-compose.yml 容器 B:
container_b:
external_links:
- container_a_1
此问题与其他 "how to fix" 问题有何不同:
- 我们不能使用 "sudo service docker restart"(有效),因为这是生产环境
- 我们不想每次都手动修复此问题,但找到原因以便我们可以
- 明白我们做错了什么
- 了解如何避免这种情况
假设:
- 似乎存在 container_a 的两个实例(RUNNING_ID 和 PREVIOUSLY_LINKED_ID)
- 这可能会发生,因为我们
- 通过docker-compose 构建和 重建容器
- 更改了容器的转发外部端口(808
01:8080)
评论
- 不要按照评论中的建议使用
docker-compose down
,这会删除音量!
Docker links are deprecated 所以除非你需要他们提供的某些功能或者使用的是非常旧的 docker 版本,否则我建议切换到 docker 网络。
由于您要连接的容器似乎是在单独的组合文件中启动的,因此您可以在外部创建该网络:
docker network create app_net
然后在您的 docker-compose.yml 文件中,将您的容器连接到该网络:
version: '3'
networks:
app_net:
external:
name: app_net
services:
container_a:
# ...
networks:
- app_net
然后在您的 container_b 中,您将连接到 container_a 作为 "container_a",而不是 "container_a_1"。
顺便说一句,除非您传递 -v
标志,否则没有记录 docker-compose down
删除卷。也许您正在使用匿名卷,在这种情况下,我不确定 docker-compose up
是否知道在哪里可以找到您的数据。首选命名卷。您的数据很可能没有存储在卷中,这很危险,并且您无法更新容器:
$ docker-compose down --help
By default, the only things removed are:
- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used
Networks and volumes defined as `external` are never removed.
Usage: down [options]
Options:
--rmi type Remove images. Type must be one of:
'all': Remove all images used by any service.
'local': Remove only images that don't have a custom tag
set by the `image` field.
-v, --volumes Remove named volumes declared in the `volumes` section
of the Compose file and anonymous volumes
attached to containers.
--remove-orphans Remove containers for services not defined in the
Compose file