我使用 Strapi
和 Gatsby
构建了一个网站,当我尝试连接到远程数据库时一切正常,但我正在尝试在容器内创建一个数据库,但到目前为止还没有成功.
本质上,我所做的是创建以下 docker-compose
:
version: '3'
services:
backend:
container_name: myapp_backend
build: ./backend/
ports:
- '3002:3002'
volumes:
- ./backend:/usr/src/myapp/backend
- /usr/src/myapp/backend/node_modules
environment:
- APP_NAME=myapp_backend
- DATABASE_CLIENT=mysql
- DATABASE_HOST=db
- DATABASE_PORT=3307
- DATABASE_NAME=myapp_db
- DATABASE_USERNAME=johnny
- DATABASE_PASSWORD=stecchino
- DATABASE_SSL=false
- DATABASE_AUTHENTICATION_DATABASE=myapp_db
- HOST=localhost
depends_on:
- db
restart: always
db:
container_name: myapp_mysql
image: mysql:5.7
volumes:
- ./db.sql:/docker-entrypoint-initdb.d/db.sql
restart: always
ports:
- 3307:3307
environment:
MYSQL_ROOT_PASSWORD: 5!JF6!FgAkvt
MYSQL_DATABASE: myapp_db
MYSQL_USER: johnny
MYSQL_PASSWORD: stecchino
command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --init-connect='SET NAMES UTF8;' --innodb-flush-log-at-trx-commit=0
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: 'myapp_phpmyadmin'
links:
- db
environment:
PMA_HOST: db
PMA_PORT: 3307
ports:
- '8081:80'
volumes:
- /sessions
depends_on:
- db
frontend:
container_name: myapp_frontend
build: ./frontend/
ports:
- '3001:3001'
depends_on:
- backend
volumes:
- ./frontend:/usr/src/myapp/frontend
backend
服务包含 Strapi
应用程序,db
服务包含在端口 mysql
上运行的 3307
实例,因为 3306 已经在使用。
然后我还安装了 phpmyadmin
,最后但并非最不重要的是 Gastby
站点。当我使用 docker-compose up --build
运行并尝试使用以下方式访问 phpmyadmin 时:
http://localhost:8081/index.php
具有以下凭据:
用户:约翰尼 密码:stecchino
我明白了:
<块引用>MySQL mysqli::real_connect():(HY000/2002):连接被拒绝
现在,我为解决这种情况所做的是将端口 3306 而不是 3307 传递给 backend
和 phpmyadmin
服务。神奇的是,一切正常。但为什么?我已将容器和主机映射到 3307...
答案 0 :(得分:2)
这里发生了两件事。
这是因为你从来没有告诉mysql容器运行在3307端口,默认配置是运行在3306端口。
当然可以。这是因为当您在同一个 docker-compose 文件中定义多个服务时,它们在同一个网络上启动。这意味着它们可以看到并连接到彼此的内部端口,而无需像 3306:3306
我建议只为您希望在 docker 环境(如 UI)之外访问的服务保留端口绑定,而对于内部组件,只需像这样公开端口
expose:
- 3306
答案 1 :(得分:2)
两个答案都很有用,我特别喜欢Manish's answer
我想添加一些额外的措辞:
有外部无法访问的内部 docker 网络。从任何给定的服务(或容器)内部,您可以通过以下方式访问所有其他服务(或容器):
<service-name>:<port>/path/of/resources
<container-name>:<port>/path/of/resources
为了从 docker 外部访问 docker 网络内部的资源,无论是来自您的主机环境,还是更远的互联网上游,docker 守护进程需要绑定到主机端口,然后转发在这些端口上接收到的信息到一个 docker 服务(最终是一个 docker 容器)。
在您的 docker-compose.yml 中,当您执行 3307:3307
时,您告诉 docker 守护程序侦听端口 3307,并在其端口 3307 上内部转发到您的 db
服务。
然而,从我们所见,mysql 仍在内部(即容器内部)侦听端口 3306 上的流量。与您的 db
服务 (mysql正在运行的容器)将能够通过以下方式访问 mysql:
<driver>:mysql://db:3306/<dbname>
如果您希望所有主机流量和 docker 网络流量在端口 3307 上访问 mysql,您还需要将 mysql 配置为在端口 3307 而不是 3306 上侦听。写作时间。
我希望额外的信息有帮助!这是我在与人们谈论 docker 时经常谈论的话题。
答案 2 :(得分:1)
因为 3306
是 official Dockerfile 公开的端口。
您可以做的是将运行 MySQL 的端口映射到主机上的另一个端口:例如 3307:3306
(始终为 host:container
)