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

gkl3eglg  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(1168)

我希望这个标题足够描述性。我试图在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"

每当我试着用 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.

我做了一点调查 gitlab-runner 正在使用mysql服务。我的理解是,如果我通过docker容器运行此设置,它们将与主机系统隔离,因此我不会有任何端口冲突。我所暴露的唯一端口是我的 Dockerfile -就我而言是3000。我的生活中有什么遗漏吗 docker-compose.yml ? 还有什么问题吗?

a9wyjsp7

a9wyjsp71#

docker compose files版本3提供的另一个选项是通过环境变量指定主机上公开的不同端口。
所以一种方法可能是这样的:

version: "3.3"
services:
  mysql:
    container_name: mysql
    image: mysql
    ports:
      - "${MYSQL_PORT_NUMBER-:3306}:3306"

然后,如果定义了环境变量,则将使用该值。否则,默认 3306 将使用。
版本3 docker的第二个特性是组成文件,它们将从 .env 文件(如果存在)。这个 .env 文件必须在您运行的目录中 docker-compose 从。
最后,要调试所有这些,可以使用 docker-compose config 发出变量扩展docker compose文件。使用 .env 看起来是这样的:

MYSQL_PORT_NUMBER=3307

给出以下结果:

$ docker-compose -f mysql-port-conflict.yaml config
services:
  mysql:
    container_name: mysql
    image: mysql
    ports:
    - published: 3307
      target: 3306
version: '3.3'

这表明mysql将在端口上可用 3307 主人的名字。当然,任何想要连接到mysql的应用程序也需要知道 ${MYSQL_PORT_NUMBER} .
hth公司

gz5pxeao

gz5pxeao2#

停止绑定到本地端口并让 docker-compose 为你挑选一个短暂的港口。在您的情况下,您的应用程序可以在没有任何帮助的情况下访问默认端口。如果您遵循的是12-factor应用程序方法,那么请使用以下代码段中的环境变量。

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

这是通过环境变量或命令行标志配置应用程序的主要原因。
如果需要从主机访问docker应用程序,可以使用docker compose port获取临时端口。我通常使用如下shell函数:

get_exposed_port() {  # SERVICE PORT
    docker-compose port $1 $2 | cut -d: -f2
}
avwztpqn

avwztpqn3#

在docker-compose.yml文件中,通过在 ports 数组,例如:

ports:
  - "3306:3306"

如果省略了配置的这一部分,容器之间仍然可以私下访问,但是端口不会绑定到主机中,从而避免了所面临的端口冲突。
如果您需要为某些或所有服务向主机公开端口,则必须通过更改主机端的绑定端口来自行处理冲突。例如,要避免端口3306上的端口冲突,您只需执行以下操作:

ports:
  - "3307:3306"

相关问题