【问题标题】:How to properly connect containers created with multiple docker-compose files with isolated networks如何正确连接使用多个 docker-compose 文件创建的容器与隔离网络
【发布时间】:2017-07-10 14:27:19
【问题描述】:

我正在尝试为虚拟机上的几个项目设置可扩展的 docker 生产环境。

我的设置如下:

前端:(按预期工作:感谢Tevin Jeffery for this

# ~/proxy/docker-compose.yml
version: '2'  
services:  
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - '/etc/nginx/vhost.d'
      - '/usr/share/nginx/html'
      - '/etc/nginx/certs:/etc/nginx/certs:ro' 
      - '/var/run/docker.sock:/tmp/docker.sock:ro'
    networks:
      - nginx
  letsencrypt-nginx-proxy:
    container_name: letsencrypt-nginx-proxy
    image: 'jrcs/letsencrypt-nginx-proxy-companion'
    volumes:
      - '/etc/nginx/certs:/etc/nginx/certs'
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
    volumes_from:
      - nginx-proxy
    networks:
      - nginx
networks:  
  nginx:
    driver: bridge

数据库:(计划添加 postgres 以支持 Rails 应用程序)

# ~/mysql/docker-compose.yml
version: '2'
services:
  db:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
#   ports:
#     - 3036:3036
    networks:
      - db
networks:
  db:
    driver: bridge

最后是一个 wordpress 博客来测试是否一切正常:

# ~/wp/docker-compose.yml
version: '2'
services:
  wordpress:
    image: wordpress
    # external_links:
    #   - mysql_db_1:mysql
    ports:
      - 8080:80
    networks:
      - proxy_nginx
      - mysql_db
    environment:
      # for nginx and dockergen
      VIRTUAL_HOST: gizmotronic.ca
      # wordpress setup
      WORDPRESS_DB_HOST: mysql_db_1 
#     WORDPRESS_DB_HOST: mysql_db_1:3036  
#     WORDPRESS_DB_HOST: mysql 
#     WORDPRESS_DB_HOST: mysql:3036  
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: wordpress
networks:
  proxy_nginx:
    external: true
  mysql_db:
    external: true

我的问题是 Wordpress 容器无法连接到数据库。当我尝试启动 (docker-compose up) Wordpress 容器时出现以下错误:

wordpress_1  | Warning: mysqli::mysqli(): (HY000/2002): Connection refused in - on line 22
wordpress_1  |
wordpress_1  | MySQL Connection Error: (2002) Connection refused
wp_wordpress_1 exited with code 1

更新:

我终于能够得到这个工作。我的主要问题是依赖于环境变量的容器默认值。这创建了一个自动数据卷,没有数据库或用户用于 word press。在向 mysql 和 Wordpress 容器添加显式环境变量后,我删除了数据卷并重新启动了两个容器。这迫使 mysql 容器重新创建数据库和用户。

~/mysql/docker-compose.yml

environment:
  MYSQL_ROOT_PASSWORD: wordpress
  MYSQL_USER: wordpress
  MYSQL_PASSWORD: wordpress
  MYSQL_DATABASE: wordpress

~/wp/docker-compose.yml:

environment:
  # for nginx and dockergen
  VIRTUAL_HOST: gizmotronic.ca
  # wordpress setup
  WORDPRESS_DB_HOST: mysql_db_1
  WORDPRESS_DB_USER: wordpress
  WORDPRESS_DB_PASSWORD: wordpress
  WORDPRESS_DB_NAME: wordpress

【问题讨论】:

  • 主机名应该是服务名,例如“db”而不是“mysql_db_1”。您可以检查数据库是否已启动并正在运行并正在侦听端口? docker run -it --rm --net container:mysql_db_1 nicolaka/netshoot netstat -lnt
  • docker-compose 创建的容器名称被破坏:__。 netstat 命令显示容器监听 44225 和 3036。容器日志还显示 mariadb 监听连接。
  • 使用 compose 为您提供的唯一名称会阻止您使用该服务,如果它稍后被缩放或您稍后重命名项目。别名可以用docker inspect -f '{{range .NetworkSettings.Networks}}{{index .Aliases 0}}{{end}}' $container_name看到
  • 我不希望在相当长的一段时间内扩展我的数据库。我只是不明白为什么我看不到 wp 容器中的数据库。当我检查网络时,两者都在上面。 nginx 代理工作。我目前正在检查数据库的绑定地址配置。这可能会阻止连接。
  • 为什么不在同一个撰写文件中包含所有服务?然后你就不用担心不同的 docker 网络了。您可以通过使用“wait-for-it.sh”docs.docker.com/compose/startup-order 来解决启动问题(确保 wordpress 等待 mysql 第一次启动)如果这不令人满意,您将需要一种方法来解析两者之间的主机名网络(又名 DNS 网关服务器)并通过 env 变量传入实际的主机名/ips。

标签: docker docker-compose docker-networking


【解决方案1】:

docker-compose 的一个问题是,尽管有时您的应用程序链接到您的数据库,但该应用程序不会等待您的数据库启动并准备好。这是官方的 Docker 阅读: https://docs.docker.com/compose/startup-order/

我遇到过类似的问题,我的测试应用程序会失败,因为它无法连接到我的服务器,因为它还没有启动和运行。

我通过运行 shell 脚本来 ping 数据库的地址,直到它可以使用为止,对上面链接中发布的文章进行了类似的解决方法。该脚本应该是您应用程序中的最后一个 CMD 命令。

RESPONSE=$(curl --write-out "%{http_code}\n" --silent --output /dev/null "YOUR_MYSQL_DATABASE:3306")

# Until the mysql sends a 200 HTTP response, we're going to keep checking
until [ $RESPONSE -eq "200" ]; do
  sleep 2
  echo "MySQL is not ready yet.. retrying... RESPONSE: ${RESPONSE}"
  RESPONSE=$(curl --write-out "%{http_code}\n" --silent --output /dev/null "YOUR_MYSQL_DATABASE:3306")
done

# Once we know the server's up, we can start run our application 
enter code to start your application here

我不能 100% 确定这是否是您遇到的问题。调试问题的另一种方法是使用 -d 标志以分离模式运行 docker-compose 并运行 docker ps 以查看您的数据库是否正在运行。如果它正在运行,请运行docker logs $YOUR_DB_CONTAINER_ID 以查看 MySQL 在启动时是否给您任何错误

【讨论】:

  • 数据库启动不是这里的问题。我先启动代理和数据库服务,然后在我准备好时添加其他应用程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多