使用docker时如何避免“端口冲突”?

Cro*_*ind 5 mysql port docker

我希望标题具有足够的描述性。我正在尝试在docker中执行我的节点应用程序(使用mongo和mysql)。我正在docker-compose用来启动以下应用程序和docker-compose.yml文件:

version: "3.3"
services:
  app:
    container_name: app
    restart: always
    build: .
    volumes:
      - ./:/app
    ports:
      - "3000:3000"
    links:
      - mongo
      - mysql
  mongo:
    container_name: mongo
    image: mongo
   ports:
      - "27017:27017"
  mysql:
    container_name: mysql
    image: mysql
    ports:
      - "3306:3306"
Run Code Online (Sandbox Code Playgroud)

每当我尝试使用进行启动时,docker-compose up都会出现以下错误:

ERROR: for mysql  Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (785b03daaa662bb3c344025f89fd28f49eabb43104b1c9a16ab425ab5120309f): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use

ERROR: for mysql  Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (785b03daaa662bb3c344025f89fd28f49eabb43104b1c9a16ab425ab5120309f): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use
ERROR: Encountered errors while bringing up the project.
Run Code Online (Sandbox Code Playgroud)

我做了一些研究,似乎gitlab-runner正在使用mysql服务。我的理解是,如果我通过docker容器运行此设置,则它们与主机系统是隔离的,因此我不会有任何端口冲突。我要暴露的唯一端口是我的端口Dockerfile-在我的情况下为3000。我是否丢失了某些端口docker-compose.yml?还有什么可能是错的?

D.S*_*ley 5

停止绑定到本地端口,然后docker-compose为您选择一个临时端口。就您而言,您的应用程序无需任何帮助即可进入默认端口。如果您遵循12因子应用方法,请使用以下代码段中的环境变量。

version: "3.3"
services:
  app:
    restart: always
    build: .
    volumes:
      - ./:/app
    ports:
      - 3000  # will be bound to an ephemeral port
    environment:
      MONGODB_URL: mongodb://mongo/db  # can reach port 27017 without help
  mongo:
    image: mongo
    ports:
      - 27017
Run Code Online (Sandbox Code Playgroud)

这是使您的应用程序可以通过环境变量或命令行标志进行配置的主要原因。

如果需要从主机访问Docker应用程序,则可以使用docker-compose端口获取临时端口。我通常使用如下的shell函数:

get_exposed_port() {  # SERVICE PORT
    docker-compose port $1 $2 | cut -d: -f2
}
Run Code Online (Sandbox Code Playgroud)


jef*_*mcc 5

从docker compose版本3开始可用的另一个选项是通过环境变量指定在主机上公开的不同端口。

因此,一种实现方法可能是这样的:

version: "3.3"
services:
  mysql:
    container_name: mysql
    image: mysql
    ports:
      - "${MYSQL_PORT_NUMBER-:3306}:3306"
Run Code Online (Sandbox Code Playgroud)

然后,如果定义了环境变量,则将使用该值。否则,3306将使用默认值。

版本3泊坞窗撰写文件的第二个特点,他们会从读取环境变量.env文件(如果存在)。该.env文件必须位于您docker-compose从中运行的目录中。

最后,要调试所有这些,可以使用它docker-compose config来发出变量扩展的docker compose文件。这样做的.env样子如下:

MYSQL_PORT_NUMBER=3307
Run Code Online (Sandbox Code Playgroud)

给出以下结果:

$ docker-compose -f mysql-port-conflict.yaml config
services:
  mysql:
    container_name: mysql
    image: mysql
    ports:
    - published: 3307
      target: 3306
version: '3.3'
Run Code Online (Sandbox Code Playgroud)

这表明mysql将3307在主机的端口上可用。当然,任何想要连接到mysql的应用程序也都需要了解${MYSQL_PORT_NUMBER}

高温超导


whi*_*s11 3

在 docker-compose.yml 文件中,您通过在数组中声明端口来公开主机网络空间上 pod 的端口ports,例如:

ports:
  - "3306:3306"
Run Code Online (Sandbox Code Playgroud)

如果省略这部分配置,您的容器仍然可以私下相互访问,但端口不会绑定在您的主机中,从而避免您面临的端口冲突。

如果您需要将端口公开给主机以提供部分或全部服务,则必须通过更改主机端的绑定端口来自行处理冲突。例如,为了避免端口 3306 上的端口冲突,您可以简单地执行以下操作:

ports:
  - "3307:3306"
Run Code Online (Sandbox Code Playgroud)