Docker Compose 构建顺序和/或防火墙/网络错误

时间:2021-02-04 02:12:41

标签: docker docker-compose docker-networking

请注意:尽管我在这里提到 Java 和 Spring Boot,但这 100% 是一个 Docker/Docker Compose 网络问题,因此,可以任何熟悉 Docker 生态系统的人都可以回答,无论他们是否熟悉 Java 和 Spring。


我有一个 Spring Boot (Java) Web 服务,它使用 MySQL 数据库作为其数据层。我已使用以下 Dockerfile 对其进行容器化:

FROM openjdk:8-jdk-alpine as cce

COPY application.yml application.yml
COPY my-service-local-keystore.p12 my-service-local-keystore.p12
COPY build/libs/my-service.jar my-service.jar

EXPOSE 9200

ENTRYPOINT [ \
    "java", \
    "-Dspring.config=.", \
    "-Dspring.profiles.active=${MY_ENV}", \
    "-Ddb.hostAndPort=${MY_SERVICE_DB_HOST}:${MY_SERVICE_DB_PORT}", \
    "-Ddb.name=MY_service_db_${MY_ENV}", \
    "-Ddb.username=${MY_SERVICE_DB_APP_USER}", \
    "-Ddb.password=${MY_SERVICE_DB_APP_PASSWORD}", \
    "-Dkeystore.file=my-service-local-keystore.p12", \
    "-Dkeystore.password=${MY_SERVICE_KEYSTORE_PASSWORD}", \
    "-jar", \
    "my-service.jar" \
]

为了同时管理此映像的容器及其支持的 MySQL 数据库,我编写了以下 docker-compose.yml 文件,该文件与上面的 Dockerfile 位于同一目录中(这是我的网络服务项目的根目录):

version: "3.7"
services:
  my-service-db:
    env_file:
      - .env
    image: mysql:8
    container_name: $MY_SERVICE_DB_HOST
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - $MY_SERVICE_DB_PORT:$MY_SERVICE_DB_PORT
    environment:
      MYSQL_ROOT_PASSWORD: $MY_SERVICE_DB_ROOT_PASSWORD
      MYSQL_DATABASE: my_service_db_$MY_ENV
      MYSQL_USER: $MY_SERVICE_DB_APP_USER
      MYSQL_PASSWORD: $MY_SERVICE_DB_APP_PASSWORD
    volumes:
      - ./my-service-db-data:/var/lib/mysql
  my-service:
    env_file:
      - .env
    build: .
    depends_on:
      - my-service-db

在同一个项目根目录中,我还有以下 .env 文件:

MY_ENV=local
MY_SERVICE_DB_HOST=my-service-db
MY_SERVICE_DB_PORT=3306
MY_SERVICE_DB_ROOT_PASSWORD=abc123
MY_SERVICE_DB_APP_USER=my-service-user
MY_SERVICE_DB_APP_PASSWORD=def456
MY_SERVICE_KEYSTORE_PASSWORD=abcdef123456

当我运行 docker-compose up -d 时,我看到 Web 服务和 MySQL 容器都在旋转,但不久之后 Web 服务容器死亡/停止。当我跟踪日志时(在它死之前),它抱怨无法连接到 MySQL(服务需要在启动时做到这一点)。

有趣的是,我可以从在我的主机上运行的 MySQL 客户端连接到 MySQL 数据库,并通过 0.0.0.0:3306 建立连接。所以我相信 MySQL 容器已正确配置和运行。

FWIW 我曾尝试将 MY_SERVICE_DB_HOST env var(在 .env 中)从 my-service-db 更改为 0.0.0.0,但没有任何区别。

所以我目前唯一的两个猜测是:

  1. 不知何故,Web 服务容器首先被运行/启动,由于 MySQL 容器尚不存在,它无法连接并死亡;或
  2. 此处存在 Docker 网络问题,因此另一个 Docker 容器无法通过 0.0.0.0:3306 连接到 MySQL 容器,但在主机上运行的 MySQL 客户端可以

不幸的是,我不确定如何解决这两种可能性中的任何一种,而且我确定还有其他我什至不知道要考虑的可能性!有什么想法我可能会在这里出错吗?提前致谢!

1 个答案:

答案 0 :(得分:0)

你可以configure Spring properties with environment variables。在 Docker 上下文中,这通常比尝试通过命令行注入它们要容易得多。根据它们是什么,您可以通过 Dockerfile 中的 ENV 指令或 Compose environment: 设置提供它们。

您显示的命令行还有一个语法问题。如果您使用 JSON-array form of ENTRYPOINT(或 CMDRUN),这里绝对不会发生任何类型的替换。您将 Java 属性 spring.profiles.active 设置为文字字符串 ${MY_ENV},而不是环境变量的值。 (出于几个原因,我不会在这里讨论,如果您不需要两者,我倾向于选择 CMD 而非 ENTRYPOINT。)

因此您可以将 Dockerfile 更新为:

# As in the original, mostly
FROM openjdk:8-jdk-alpine as cce
WORKDIR /app
COPY application.yml application.yml
COPY build/libs/my-service.jar my-service.jar
EXPOSE 9200

# Set fixed environment variables for Spring properties (or defaults)
ENV SPRING_CONFIG=.
ENV SPRING_PROFILES_ACTIVE=development

# Then set the main command to be run, without setting properties
CMD ["java", "-jar", "my-service.jar"]

以及相应的docker-compose.yml

version: "3.8"
services:
  my-service-db: { ... unchanged ... }
  my-service:
    env_file:
      - .env
    build: .
    depends_on:
      - my-service-db
    # Inject the keystore file
    volumes:
      - ./my-service-local-keystore.p12:/app/my-service-local-keystore.p12
    # Set Spring properties through environment variables
    environment:
      SPRING_PROFILES_ACTIVE: "${MY_ENV}"
      DB_HOSTANDPORT: "${MY_SERVICE_DB_HOST}:${MY_SERVICE_DB_PORT}"
      DB_NAME: "MY_service_db_${MY_ENV}"
      DB_USERNAME: "${MY_SERVICE_DB_APP_USER}"
      DB_PASSWORD: "${MY_SERVICE_DB_APP_PASSWORD}"
      KEYSTORE_FILE: /app/my-service-local-keystore.p12
      KEYSTORE_PASSWORD: "${MY_SERVICE_KEYSTORE_PASSWORD}"

Compose 将 substitute values from the host environment,因此这会将值传递到容器中的适当属性中。

相关问题