CircleCI 作业创建 docker MySQL 8 但无法连接
CircleCI job creates docker MySQL 8 but nothing can connect
(请参阅 post 末尾的更新以获得可能有用的调试信息。)
我有一个通过 - setup_remote_docker
+docker-compose
部署 MySQL 8 的 CircleCI 作业,然后尝试启动 Java 应用程序与 MySQL 通信8. 不幸的是,即使 docker ps
显示容器已启动并且 运行ning,任何与 MySQL 通信的尝试——无论是通过 Java 应用程序还是 docker exec
--失败,表示容器不是 运行ning(并且 Java 抛出“通信 Link 失败”异常)。这有点令人困惑,因为容器似乎已启动,并且完全相同的命令在我的本地计算机上运行。
这是我的 CircleCI config.yml
:
Build and Test:
<<: *configure_machine
steps:
- *load_repo
- ... other unrelated stuff ...
- *load_gradle_wrapper
- run:
name: Install Docker Compose
environment:
COMPOSE_VERSION: '1.29.2'
command: |
curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o ~/docker-compose
chmod +x ~/docker-compose
sudo mv ~/docker-compose /usr/local/bin/docker-compose
- setup_remote_docker
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Query MySQL #test that fails
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
这是我的 docker-compose.yml
,其中一个步骤是 运行:
version: "3.1"
services:
# MySQL Dev Image
mysql-migrate:
container_name: mysql8_test_mysql
image: mysql:8.0
command:
mysqld --default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
--log-bin-trust-function-creators=true
environment:
MYSQL_DATABASE: test_db
MYSQL_ROOT_PASSWORD: rootpass
ports:
- "3306:3306"
volumes:
- "./docker/mysql/data:/var/lib/mysql"
- "./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf"
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
这是一个相当简单的设置,CircleCI 的输出是正的 ,直到 它到达 docker exec
,我添加它来测试连接。这是 CircleCI 每一步的输出:
Start MySQL Docker
:
#!/bin/bash -eo pipefail
docker-compose up -d
Creating network "project_default" with the default driver
Pulling mysql-migrate (mysql:8.0)...
8.0: Pulling from library/mysql
5158dd02: Pulling fs layer
f6778b18: Pulling fs layer
a6c74a04: Pulling fs layer
4028a805: Pulling fs layer
7163f0f6: Pulling fs layer
cb7f57e0: Pulling fs layer
7a431703: Pulling fs layer
5fe86aaf: Pulling fs layer
add93486: Pulling fs layer
960383f3: Pulling fs layer
80965951: Pulling fs layer
Digest: sha256:b17a66b49277a68066559416cf44a185cfee538d0e16b5624781019bc716c122 121B/121BkBBB
Status: Downloaded newer image for mysql:8.0
Creating mysql8_******_mysql ...
Creating mysql8_******_mysql ... done
所以我们知道 MySQL 8 被拉得很好(因此上一步有效)。下一步是询问 Docker 什么是 运行ning.
Check Docker MySQL
:
#!/bin/bash -eo pipefail
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb6b7941ad65 mysql:8.0 "docker-entrypoint.s…" 1 second ago Up Less than a second 0.0.0.0:3306->3306/tcp, 33060/tcp mysql8_test_mysql
CircleCI received exit code 0
到目前为止看起来还不错。但是现在让我们实际尝试通过 docker exec
.
运行 一个针对它的命令
Query MySQL
:
#!/bin/bash -eo pipefail
docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)
Exited with code exit status 1
CircleCI received exit code 1
所以现在我们无法连接到 MySQL,即使 docker ps
显示它并 运行ning。我什至尝试添加一个荒谬的步骤来等待,以防 MySQL 需要更多时间:
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Wait Until Ready
command: sleep 120
- run:
name: Query MySQL
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
当然,增加 2 分钟等待 MySQL 启动并没有帮助。关于为什么这在 CircleCI 中如此困难有什么想法吗?
提前致谢。
更新 1:我可以成功启动 MySQL 如果我 SSH 进入作业的服务器并且 运行 我自己执行相同的命令:
docker-compose up
然后在另一个终端运行这个:
docker exec -it mysql8_test_mysql mysql mysql -h localhost --port 3306 -u root -prootpass -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| test_db |
| mysql |
| performance_schema |
| sys |
+--------------------+
所以可以开始MySQL。只是在完成工作步骤时无法正常工作。
更新 2:我在 docker-compose up -d
和 docker ps
和 now 之间移动了两分钟的等待没有什么是 运行ning。因此容器必须启动然后崩溃,这就是为什么稍后它不可用的原因。
问题的原因是我的 docker-compose.yml
中的 volumes
条目包含以下行:
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
当我在 docker-compose up -d
之后立即检查时,容器似乎启动了,但实际上它会在几秒钟后崩溃,因为 CircleCI 似乎有 Docker 卷的问题,可能与此有关:https://discuss.circleci.com/t/docker-compose-doesnt-mount-volumes-with-host-files-with-circle-ci/19099.
为了使其正常工作,我删除了 volume
条目并添加了 运行 命令来复制和导入架构,如下所示:
- run:
name: Start MySQL docker
command: docker-compose up -d
# Manually copy schema file instead of using docker-compose volumes (has issues with CircleCI)
- run:
name: Copy Schema
command: docker cp mysql_schema_v1.sql mysql8_mobile_mysql:docker-entrypoint-initdb.d/mysql_schema_v1.sql
- run:
name: Import Schema
command: docker exec mysql8_mobile_mysql /bin/sh -c 'mysql -u root -prootpass < docker-entrypoint-initdb.d/mysql_schema_v1.sql'
通过这个新设置,我已经能够创建表并连接到 MySQL。但是,运行ning 测试 MySQL 似乎有一个问题导致挂断,但这可能无关紧要。我会跟进更多信息,但至少我希望这可以帮助其他人。
(请参阅 post 末尾的更新以获得可能有用的调试信息。)
我有一个通过 - setup_remote_docker
+docker-compose
部署 MySQL 8 的 CircleCI 作业,然后尝试启动 Java 应用程序与 MySQL 通信8. 不幸的是,即使 docker ps
显示容器已启动并且 运行ning,任何与 MySQL 通信的尝试——无论是通过 Java 应用程序还是 docker exec
--失败,表示容器不是 运行ning(并且 Java 抛出“通信 Link 失败”异常)。这有点令人困惑,因为容器似乎已启动,并且完全相同的命令在我的本地计算机上运行。
这是我的 CircleCI config.yml
:
Build and Test:
<<: *configure_machine
steps:
- *load_repo
- ... other unrelated stuff ...
- *load_gradle_wrapper
- run:
name: Install Docker Compose
environment:
COMPOSE_VERSION: '1.29.2'
command: |
curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o ~/docker-compose
chmod +x ~/docker-compose
sudo mv ~/docker-compose /usr/local/bin/docker-compose
- setup_remote_docker
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Query MySQL #test that fails
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
这是我的 docker-compose.yml
,其中一个步骤是 运行:
version: "3.1"
services:
# MySQL Dev Image
mysql-migrate:
container_name: mysql8_test_mysql
image: mysql:8.0
command:
mysqld --default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
--log-bin-trust-function-creators=true
environment:
MYSQL_DATABASE: test_db
MYSQL_ROOT_PASSWORD: rootpass
ports:
- "3306:3306"
volumes:
- "./docker/mysql/data:/var/lib/mysql"
- "./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf"
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
这是一个相当简单的设置,CircleCI 的输出是正的 ,直到 它到达 docker exec
,我添加它来测试连接。这是 CircleCI 每一步的输出:
Start MySQL Docker
:
#!/bin/bash -eo pipefail
docker-compose up -d
Creating network "project_default" with the default driver
Pulling mysql-migrate (mysql:8.0)...
8.0: Pulling from library/mysql
5158dd02: Pulling fs layer
f6778b18: Pulling fs layer
a6c74a04: Pulling fs layer
4028a805: Pulling fs layer
7163f0f6: Pulling fs layer
cb7f57e0: Pulling fs layer
7a431703: Pulling fs layer
5fe86aaf: Pulling fs layer
add93486: Pulling fs layer
960383f3: Pulling fs layer
80965951: Pulling fs layer
Digest: sha256:b17a66b49277a68066559416cf44a185cfee538d0e16b5624781019bc716c122 121B/121BkBBB
Status: Downloaded newer image for mysql:8.0
Creating mysql8_******_mysql ...
Creating mysql8_******_mysql ... done
所以我们知道 MySQL 8 被拉得很好(因此上一步有效)。下一步是询问 Docker 什么是 运行ning.
Check Docker MySQL
:
#!/bin/bash -eo pipefail
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb6b7941ad65 mysql:8.0 "docker-entrypoint.s…" 1 second ago Up Less than a second 0.0.0.0:3306->3306/tcp, 33060/tcp mysql8_test_mysql
CircleCI received exit code 0
到目前为止看起来还不错。但是现在让我们实际尝试通过 docker exec
.
Query MySQL
:
#!/bin/bash -eo pipefail
docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)
Exited with code exit status 1
CircleCI received exit code 1
所以现在我们无法连接到 MySQL,即使 docker ps
显示它并 运行ning。我什至尝试添加一个荒谬的步骤来等待,以防 MySQL 需要更多时间:
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Wait Until Ready
command: sleep 120
- run:
name: Query MySQL
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
当然,增加 2 分钟等待 MySQL 启动并没有帮助。关于为什么这在 CircleCI 中如此困难有什么想法吗?
提前致谢。
更新 1:我可以成功启动 MySQL 如果我 SSH 进入作业的服务器并且 运行 我自己执行相同的命令:
docker-compose up
然后在另一个终端运行这个:
docker exec -it mysql8_test_mysql mysql mysql -h localhost --port 3306 -u root -prootpass -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| test_db |
| mysql |
| performance_schema |
| sys |
+--------------------+
所以可以开始MySQL。只是在完成工作步骤时无法正常工作。
更新 2:我在 docker-compose up -d
和 docker ps
和 now 之间移动了两分钟的等待没有什么是 运行ning。因此容器必须启动然后崩溃,这就是为什么稍后它不可用的原因。
问题的原因是我的 docker-compose.yml
中的 volumes
条目包含以下行:
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
当我在 docker-compose up -d
之后立即检查时,容器似乎启动了,但实际上它会在几秒钟后崩溃,因为 CircleCI 似乎有 Docker 卷的问题,可能与此有关:https://discuss.circleci.com/t/docker-compose-doesnt-mount-volumes-with-host-files-with-circle-ci/19099.
为了使其正常工作,我删除了 volume
条目并添加了 运行 命令来复制和导入架构,如下所示:
- run:
name: Start MySQL docker
command: docker-compose up -d
# Manually copy schema file instead of using docker-compose volumes (has issues with CircleCI)
- run:
name: Copy Schema
command: docker cp mysql_schema_v1.sql mysql8_mobile_mysql:docker-entrypoint-initdb.d/mysql_schema_v1.sql
- run:
name: Import Schema
command: docker exec mysql8_mobile_mysql /bin/sh -c 'mysql -u root -prootpass < docker-entrypoint-initdb.d/mysql_schema_v1.sql'
通过这个新设置,我已经能够创建表并连接到 MySQL。但是,运行ning 测试 MySQL 似乎有一个问题导致挂断,但这可能无关紧要。我会跟进更多信息,但至少我希望这可以帮助其他人。