所以我有以下docker-compose.yml
文件.env
。
version: "3"
services:
cx_cache:
container_name: ${APP_NAME}_cache
image: redis:7.2.2-alpine
networks:
- ${APP_NAME}_directus
cx_mysql:
container_name: ${APP_NAME}_mysql
image: mysql:8.2
command: mysqld --default-authentication-plugin=mysql_native_password
restart: always
expose:
- 3306
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST}
MYSQL_HOST: ${MYSQL_HOST}
MYSQL_DATABASE: ${APP_NAME}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_TCP_PORT: 3306
directus:
container_name: ${APP_NAME}_directus
build:
dockerfile: "Dockerfile"
ports:
- 8055:8055
volumes:
- ./uploads:/directus/uploads
- ./extensions:/directus/extensions
networks:
- ${APP_NAME}_directus
depends_on:
- ${APP_NAME}_cache
- ${APP_NAME}_mysql
environment:
HOST: 0.0.0.0
PORT: 8055
KEY: "${APP_KEY}"
SECRET: "${APP_SECRET}"
DB_CLIENT: "mysql"
DB_HOST: "localhost"
DB_PORT: "3306"
DB_DATABASE: "${APP_NAME}"
DB_USER: "${MYSQL_USER}"
DB_PASSWORD: "${MYSQL_PASSWORD}"
DB_EXCLUDE_TABLES: "spatial_ref_sys,sysdiagrams"
CACHE_ENABLED: "true"
CACHE_STORE: "redis"
CACHE_REDIS: "redis://${APP_NAME}_cache:6379"
ADMIN_EMAIL: "mondo+${APP_NAME}@$(APP_EMAIL_DOMAIN)"
ADMIN_PASSWORD: "${APP_ADMIN_PASSWORD}"
ROBOTS_TXT: "User-agent: *\nDisallow: /"
LOG_LEVEL: "debug"
LOG_STYLE: "pretty"
TELEMETRY: "false"
QUERY_LIMIT_MAX: -1
networks:
cx_directus:
APP_NAME=cx
APP_KEY=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
APP_SECRET=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
APP_ADMIN_PASSWORD=XXXX
APP_EMAIL_DOMAIN=myDomain.com
MYSQL_ROOT_PASSWORD=XXXXXXXXXX
MYSQL_ROOT_HOST=127.0.0.1
MYSQL_HOST=*
MYSQL_DATABASE=cx
MYSQL_USER=directus
MYSQL_PASSWORD=XXXXXXX
当我运行并且docker-compose up
容器构建正常时。然而,Directus 在尝试连接到 mysql 时失败。redis
mysql
我尝试了ports
和MYSQL_HOST
/ 的各种值MYSQL_ROOT_HOST
:
*
%
localhost
0.0.0.0
127.0.0.1
什么都没起作用。我继续收到相同的错误:
cx_directus | node:internal/process/promises:288
cx_directus | triggerUncaughtException(err, true /* fromPromise */);
cx_directus | ^
cx_directus |
cx_directus | Error: connect ECONNREFUSED 127.0.0.1:3306
cx_directus | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)
cx_directus | --------------------
cx_directus | at Protocol._enqueue (/directus/node_modules/.pnpm/[email protected]/node_modules/mysql/lib/protocol/Protocol.js:144:48)
cx_directus | at Protocol.handshake (/directus/node_modules/.pnpm/[email protected]/node_modules/mysql/lib/protocol/Protocol.js:51:23)
cx_directus | at Connection.connect (/directus/node_modules/.pnpm/[email protected]/node_modules/mysql/lib/Connection.js:116:18)
cx_directus | at /directus/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected]/node_modules/knex/lib/dialects/mysql/index.js:66:18
cx_directus | at new Promise (<anonymous>)
cx_directus | at Client_MySQL.acquireRawConnection (/directus/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected]/node_modules/knex/lib/dialects/mysql/index.js:61:12)
cx_directus | at create (/directus/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected]/node_modules/knex/lib/client.js:254:39) {
cx_directus | errno: -111,
cx_directus | code: 'ECONNREFUSED',
cx_directus | syscall: 'connect',
cx_directus | address: '127.0.0.1',
cx_directus | port: 3306,
cx_directus | fatal: true
cx_directus | }
cx_directus |
cx_directus | Node.js v18.18.2
cx_directus exited with code 1
我已经验证容器mysql
正在运行,并且我确实能够使用以下命令登录directus user
:
> docker exec -it cx_mysql bash
bash-4.4# mysql -u directus -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.2.0 MySQL Community Server - GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
下一步该怎么做才能解决/解决这个问题?我确信这最终会是一件愚蠢的事情。
答案1
这里的问题是,当通过 docker compose 启动单个容器时,它们的行为就像位于不同的计算机上一样。也就是说,它们在您的 cx_directus 网络上各自拥有一个单独的 IP 地址。
如果你运行 docker network inspect cx_directus 你应该会看到这个。
不过,令人高兴的是,docker compose 为您的自定义桥接网络创建了一个内部 DNS 解析器 - cx_directus。因此,如果您在 directus 服务中使用 cx_mysql 作为数据库主机名,它应该可以工作。
干杯
答案2
遗憾的是,经过更多排列,甚至在 ChatGPT 的帮助下,还是无法解决。我启动了一个全新的实例,这次成功了。大部分内容都是一样的,但使用了 mysqllatest
而不是8.2
,你可能会认为它们是相同的……但它确实成功了。
我也将cx_mysql
其用作主机,利用内部 DNS(正如 @tuneLinux 指出的那样)……但在此更改之前也是如此。也许组合就是解决办法?