在另一个容器的构建过程中无法解析Docker容器

时间:2019-10-11 21:27:06

标签: docker docker-compose

我有两个Dockerfile,一个用于数据库,一个用于Web服务器。 Web服务器的Dockerfile具有RUN语句,该语句需要与数据库容器的连接。 Web服务器无法解析数据库的IP,然后出错。但是,如果我注释掉RUN行,然后在容器中手动运行它,它将成功解析数据库。 Web服务器是否应该能够在其构建过程中解析数据库?

# Web server
FROM tomcat:9.0.26-jdk13-openjdk-oracle

# The database container cannot be resolved when myscript runs.  "Unable to connect to the database." is thrown.
RUN myscript

CMD catalina.sh run
# But if I comment out the RUN line then connect to web server container and run myscript, the database container is resolved
docker exec ... bash

# This works
./myscript

1 个答案:

答案 0 :(得分:2)

I ran into the same problem on database migrations and NuGet pushes。您可能要在数据库上运行类似的内容,例如迁移,初始/测试数据等。它可以通过两种方式解决:

  1. 将您的数据库操作移至ENTRYPOINT,以便在运行时(数据库容器已启动且可访问)执行它们。

  2. Build your image using docker build而不是docker-compose up --build之类的东西,因为docker build有一个名为--network的开关。因此,您可以在撰写文件中创建一个网络,使用docker-compose up -d db-container启动数据库,然后在构建期间使用docker build --network db-container-network -t your-image .

  3. 访问它们

如果可能的话,我会选择#1而不是#2,因为

  • 更简单:网络仅存在于docker-compose文件中,而不存在于多个位置
  • 您可以指定relations usind depends_on并确保它们得到正确尊重,而无需手动照顾

但是根据您要执行的操作,您需要注意它不会被多次执行,因为它是在每次上运行的,而不仅仅是在构建过程中运行的(当缓存被文件清除时)变化)。

但是,在运行此类自动数据库操作以期望它们可以执行多个操作并且无论如何都要产生预期结果时(例如,通过检查是否存在迁移版本或变更),我还是认为这是最佳做法。