我们有许多 selenium 测试在我们的 web 应用程序的类似生产的设置上运行。问题在于,某些测试在应用程序中会影响数据库。
是否有可能有一个数据卷或类似的数据,我们可以在每次测试之前“克隆”并附加到容器上?
我们真的只需要一个可以在每次测试之前快速重新创建的 MySQL 数据库。偶尔我们会运行模式迁移到该数据库。
还是有另一种方法更适合于此?
最佳答案
这是一个很好的问题,并且可能是 Docker 的一个非常好的用例。有很多方法可以做到这一点,因为有很多方法可以备份 MySQL 数据库。我将在下面解释其中的一些。
但是请注意,您正在权衡利弊。这种方法的缺点是您的图像可能会变得非常大,并且需要更长的时间来拉取。
此外,您会遇到的一个问题是大多数 MySQL 容器使用 /var/lib/mysql
的卷。 (存储数据的地方)。所以销毁容器不足以清除数据 - 您还需要清除卷。所以当你在做 docker rm
要清理旧容器,请通过 -v
标志也删除卷。
选项 1:将数据构建到容器中
可以将数据构建到容器中。这样做的好处是你的容器不会在每次运行时花费任何时间设置数据。对于需要很长时间设置或拆除的大数据集,这种优势变得更加重要。换句话说,“重置”这个数据库几乎是瞬时 .
在基本层面上,我们想要这样的东西:
ADD mysql_data.tar.gz /var/lib/mysql
这里棘手的部分是创建
mysql_data.tar.gz
文件(这只是/var/lib/mysql 的 tar.gz 备份)。我们可以这样做:mysql:latest
)。请注意,我们使用的是命名卷,并且正在转发端口 3306。$ docker run -d --name my-mysql -v my-mysql-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql:latest
backup.sql
.$ cat backup.sql | mysql -u root -ppassword -h 127.0.0.1
$ docker stop my-mysql
/var/lib/mysql
的备份.请注意,我们使用的是同名卷。$ docker run --rm -v my-mysql-data:/var/lib/mysql -v $(pwd):/backup mysql:latest tar czvf /backup/mysql_data.tar.gz /var/lib/mysql
/var/lib/mysql
的 gzip 数据,在您的 Dockerfile 中使用它。请注意,我们需要将其复制到 /
因为我们压缩它的方式:ADD mysql_data.tar.gz /
如果您还没有 Dockerfile,请使用第一行创建一个
FROM mysql:5.7
$ docker build -t my-data-image:latest .
$ docker run -d -p 3306:3306 my-data-image:latest
Docker 将自动提取文件作为构建的一部分。你完成了。来自 Dockerfile 的容器将始终包含您的干净数据。要“重置”容器,只需停止它并删除它用于
/var/lib/mysql
的卷。 .要编辑数据,请重复该过程,但替换第 1 步中的现有容器。对于第 2 步,进行更改。您将生成一个新的 mysql_data.tar.gz,如果您愿意,您可以对其进行版本控制。重建 Dockerfile 后,您可以根据需要在新标签下发布它。
选项 2:使用 docker-entrypoint-initdb.d
MySQL Docker 镜像有一个特性,它将运行
/docker-entrypoint-initdb.d
中的 SQL 文件。当容器第一次运行时。这样做的好处是它可以使用常规的 MySQL 转储来创建数据。缺点是它是较慢 让数据库启动,因为它每次都在恢复您的所有数据。如果您在
./backup.sql
处有数据的 mysqldump ,你可以这样做:$ docker run -e MYSQL_DATABASE=DB_NAME -e MYSQL_ROOT_PASSWORD=password -d --name my-mysql -v $(pwd)/backup.sql:/docker-entrypoint-initdb.d/backup.sql -p 3306:3306 mysql:latest
完成后,移除容器及其卷。
$ docker rm -v my-mysql
关于mysql - 使用Docker创建 "restorable"MySQL数据库进行UI测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41965815/