gpt4 book ai didi

mysql - 如何在基于 mysql/mysql-server 的 Docker 容器中启动 MySQL 服务器

转载 作者:行者123 更新时间:2023-11-29 07:28:03 28 4
gpt4 key购买 nike

我想制作一个基于 mysql/mysql-server 的 docker 镜像。我有一个应用程序(golang),它应该使用 MySQL 来存储数据。我想在 docker 中运行这个应用程序

我的 Docker 文件看起来像

FROM mysql/mysql-server
ENV MYSQL_ROOT_PASSWORD rootpass
ENV MYSQL_DATABASE mydb
ENV MYSQL_USER dbuser
ENV MYSQL_PASSWORD dbpass

ADD myapp / # compiled colang app connecting to localhost:3306 mysql server
CMD ["myapp"]

我构建这个镜像并运行它时出现错误

docker run --name mycont -it myimage
dial tcp [::1]:3306: getsockopt: connection refused

这里有什么问题?

也许我必须先以某种方式启动 mysql 服务器才能执行我的应用程序?

我的应用程序尝试使用用户 dbuser/dbpassword 和数据库 mydb 连接到 localhost:3306 上的 mysql。然后会在数据库中创建一些表

最佳答案

嗯,这是有可能实现的,但这不是一个好的做法。推荐的方法是运行两个不同的容器:一个运行 mysql,另一个运行您的应用程序。除此之外,您还需要一个编排工具来运行容器。

因此,冒着获得一些反对票的风险 :-),与其直接回答您的问题并展示如何创建一个可以运行两种功能的容器,我更愿意展示双容器方法我考虑一个更好的做法。

在我的示例中,我使用 docker compose 进行编排。如果您还没有安装它,则需要安装它。下面是我用来运行两个容器的 docker-compose.yml 文件:

version: '3'
services:
mysqlserver:
image: mysql/mysql-server
command: --default-authentication-plugin=mysql_native_password
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "rootpass"
MYSQL_DATABASE: "mydb"
MYSQL_USER: "dbuser"
MYSQL_PASSWORD: "dbpass"

myapp:
image: myimage
environment:
MYSQL_SERVER: "mysqlserver"
MYSQL_DATABASE: "mydb"
MYSQL_USER: "dbuser"
MYSQL_PASSWORD: "dbpass"

该文件定义了两个服务:mysqlservermyapp,它们将作为单独的容器运行。这两个服务中的每一个都定义了两个元素:

  • 用于创建容器的image
  • 传递给该容器的环境变量

mysqlserver 服务定义了两个额外的属性:

  • command,它指定了在运行时传递给 mysql 服务的额外参数。简而言之:--default-authentication-plugin 是 mysql 8 所必需的。尝试在没有它的情况下运行容器,最终可能会出现一些连接错误。您可以在官方 mysql docker 页面上阅读更多相关信息。
  • ports,指定容器对外暴露哪些端口

现在,让我们定义您的应用图像。我不会说 golang,但我准备了一个使用 Linux shell 脚本的简单示例。

myapp 代码如下:

#!/bin/sh

echo ">> Waiting for $MYSQL_SERVER to start"
while ! `nc -z $MYSQL_SERVER 3306`; do sleep 3; done
echo ">> $MYSQL_SERVER has started"

mysql --host=$MYSQL_SERVER --user=$MYSQL_USER --password=$MYSQL_PASSWORD --database=$MYSQL_DATABASE<<EOFMYSQL
drop table if exists test;
create table test(id int, name varchar(20));
insert into test values (5, 'a'), (12, 'b');
select * from test;
EOFMYSQL

该应用程序将首先在一个 while 循环中运行 nc 命令,每 3 秒检查一次 mysql 服务器的状态,并且仅在 mysqlserver 完全启动时退出循环并接受端口 3306 上的连接。我们需要确保数据库服务器在尝试连接之前正在运行,对吗?

服务器启动后,myapp 使用在 docker compose 文件中作为环境变量传递的凭据连接到它。连接后,它运行一些sql语句(删除表、创建表、插入、选择)。所有这些环境参数都可以硬编码在 myapp 的代码中,但我认为将它们传递到 docker compose 文件中会更好。

用于创建myapp镜像的Dockerfile如下:

FROM alpine

RUN apk add netcat-openbsd mysql-client
ADD myapp /
RUN chmod +x /myapp
CMD /myapp

我通常使用 alpine linux 作为我测试的基础,因为它非常轻量级。我需要运行 apk add netcat-openbsd mysql-client 以将 ncmysql-client 添加到图像中。您只需要添加 golang myapp 文件,而不是 myapp shell 脚本。

现在,让我们组装所有东西。进一步执行以下步骤:

  • Dockerfilemyapp 文件放在同一文件夹中并构建 myapp 镜像:

docker image build -t myimage .

  • 以上述 docker-compose.yml 文件作为输入运行 docker compose:

docker-compose -f docker-compose.yml up

此时两个容器都将启动。 myapp 将等待 mysqlserver 准备就绪,然后连接到它并运行简单的查询。

我不确定您对 linux、shell 脚本、yaml 语法等有多熟悉。但我希望我提供了足够的细节让您理解。

关于mysql - 如何在基于 mysql/mysql-server 的 Docker 容器中启动 MySQL 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52913449/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com