Docker DB Migration/Deployment 到 DigitalOcean
Docker DB Migration/Deployment to DigitalOcean
警告:我对 docker 和云托管还很陌生,这可能是个愚蠢的问题。
我有一个本地网络应用程序,它有 3 个关联的图像、应用程序本身、数据库和一个 phpmyadmin 图像。一切都在本地运行良好,如果我将所有文件传输到我的数字海洋 Droplet 并调出我的容器,它在那里也能正常工作,但这不是我想要部署的方式,让每个库中的每个文件都驻留在我的 Droplet 中。
我一直在尝试在我的 Droplet 上创建一个 docker 机器,并将我的容器远程部署到它。除了我的数据库映像不引用我的数据库而只是一个空数据库之外,这似乎工作正常。我尝试以我在教程中看到的这种方式迁移数据库:
docker-compose run --rm web db:create db:migrate
但出现以下错误,我认为这是因为我的开发机器是 运行 Windows 10 而不是 Linux,但我无法在任何地方找到等效命令的用途一台 Windows 机器。
Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"db:create\": executable file not found in $PATH": unknown
我知道我可能遗漏了一些非常愚蠢和简单的东西,但我很难弄清楚如何为我的数据库映像迁移数据。提前致谢。
更新:
根据要求,这里是我的 docker-compose:
version: "3.4"
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
restart: always
ports:
- 80:80
volumes:
- /sessions
depends_on:
- db
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- ./data:/docker-entrypoint-initdb.d
restart: always
web:
depends_on:
- db
build: .
ports:
- "8080:8080"
restart: always
volumes:
data:
更新#2:
将 db 文件传输到 /docker-entrypoint-initdb.d (我昨天也尝试过但无法正常工作)并创建了一个新的作品 docker-compose-prod.yml我一定还遗漏了一些东西,因为数据库仍然是空的。下面是我的新 docker-compose-prod.yml:
version: "3.4"
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
restart: always
ports:
- 80:80
volumes:
- /sessions
depends_on:
- db
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- /docker-entrypoint-initdb.d
restart: always
web:
depends_on:
- db
build: .
ports:
- "8080:8080"
restart: always
你的策略很好。
实际上,您可以更进一步,将 Droplet 配置自动化,例如使用面向容器的 OS 并访问您的 Compose 文件。但这不是这个问题 ;-)
我认为您使用的 Windows 无关紧要,可能没什么区别;它可能需要一些答案调整,但仅此而已。
挑战在于您需要移动(或重新创建)远程计算机上的数据库状态。有几种方法可以持久化数据库状态:容器内(不理想);使用卷安装(好),其他。
每个都是“可移动的”,但如果您可以将您的 Compose 文件添加到您的问题中,这样我们就可以看到正在使用哪种方法,这将有所帮助。
完全公开我不熟悉你引用的方法,但这并不意味着它不准确;我只是不熟悉它。
更新:docker-entrypoint-initdb.d
参见:MySQL
上的“初始化新实例”
因此,该目录中的任何文件都是 运行 在从图像创建数据库容器时对其进行初始化。
在您的 Compose 文件中,您将主机的 ./data
目录挂载到此文件中。据推测,该目录包含 >=1 个执行预期初始化的文件。
NB The section volumes: data:
at the end of the Compose file appears redundant. You're actually using a host-mounted directory ./data
not this volume.
当您 运行 Droplet 上的 Compose 文件时,这些文件不存在,您需要复制它们。
执行此操作的最简单方法是使用 scp,这提供了 2 个备选方案:
要么保留data
目录:
IP=[DROPLET-IP]
scp -r ./data root@${IP}:/data
NB The remote destination is /data
not ./data
. You will need to revise the Compose file on the Droplet (!) too:
volumes: - /data:/docker-entrypoint-initdb.d
或将文件直接移动到Droplet的/docker-entrypoint-initdb.d
:
scp -r ./data root@${IP}/docker-entrypointy-initdb.d
NB Now there's no need for the volume mapping. You may remove:
volumes: - ./data:/docker-entrypoint-initdb.d
更新:重现(有效)
我使用了经过调整的 docker-compose.yaml
但它本质上是一样的:
version: "3.4"
services:
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- ${PWD}/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
restart: always
adminer:
image: adminer
restart: always
ports:
- 8080:8080
然后 mkdir ${PWD}/docker-entrypoint-initdb.d
并在其中创建了一个名为 freddie.sql
:
的文件
create database if not exists frederik;
use frederik;
create table treats (
TreatID INT NOT NULL AUTO_INCREMENT,
TreatName VARCHAR(255) NOT NULL,
PRIMARY KEY (TreatId));
insert into treats (TreatName)
values
("Dried Salmon"),
("Meatballs");
然后docker-compose rm --force && docker-compose up
我能够浏览管理员 UI (:8080
)、登录 (root
|mypass
) 并浏览数据库 frederik
:
警告:我对 docker 和云托管还很陌生,这可能是个愚蠢的问题。
我有一个本地网络应用程序,它有 3 个关联的图像、应用程序本身、数据库和一个 phpmyadmin 图像。一切都在本地运行良好,如果我将所有文件传输到我的数字海洋 Droplet 并调出我的容器,它在那里也能正常工作,但这不是我想要部署的方式,让每个库中的每个文件都驻留在我的 Droplet 中。
我一直在尝试在我的 Droplet 上创建一个 docker 机器,并将我的容器远程部署到它。除了我的数据库映像不引用我的数据库而只是一个空数据库之外,这似乎工作正常。我尝试以我在教程中看到的这种方式迁移数据库:
docker-compose run --rm web db:create db:migrate
但出现以下错误,我认为这是因为我的开发机器是 运行 Windows 10 而不是 Linux,但我无法在任何地方找到等效命令的用途一台 Windows 机器。
Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"db:create\": executable file not found in $PATH": unknown
我知道我可能遗漏了一些非常愚蠢和简单的东西,但我很难弄清楚如何为我的数据库映像迁移数据。提前致谢。
更新: 根据要求,这里是我的 docker-compose:
version: "3.4"
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
restart: always
ports:
- 80:80
volumes:
- /sessions
depends_on:
- db
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- ./data:/docker-entrypoint-initdb.d
restart: always
web:
depends_on:
- db
build: .
ports:
- "8080:8080"
restart: always
volumes:
data:
更新#2: 将 db 文件传输到 /docker-entrypoint-initdb.d (我昨天也尝试过但无法正常工作)并创建了一个新的作品 docker-compose-prod.yml我一定还遗漏了一些东西,因为数据库仍然是空的。下面是我的新 docker-compose-prod.yml:
version: "3.4"
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
restart: always
ports:
- 80:80
volumes:
- /sessions
depends_on:
- db
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- /docker-entrypoint-initdb.d
restart: always
web:
depends_on:
- db
build: .
ports:
- "8080:8080"
restart: always
你的策略很好。
实际上,您可以更进一步,将 Droplet 配置自动化,例如使用面向容器的 OS 并访问您的 Compose 文件。但这不是这个问题 ;-)
我认为您使用的 Windows 无关紧要,可能没什么区别;它可能需要一些答案调整,但仅此而已。
挑战在于您需要移动(或重新创建)远程计算机上的数据库状态。有几种方法可以持久化数据库状态:容器内(不理想);使用卷安装(好),其他。
每个都是“可移动的”,但如果您可以将您的 Compose 文件添加到您的问题中,这样我们就可以看到正在使用哪种方法,这将有所帮助。
完全公开我不熟悉你引用的方法,但这并不意味着它不准确;我只是不熟悉它。
更新:docker-entrypoint-initdb.d
参见:MySQL
上的“初始化新实例”因此,该目录中的任何文件都是 运行 在从图像创建数据库容器时对其进行初始化。
在您的 Compose 文件中,您将主机的 ./data
目录挂载到此文件中。据推测,该目录包含 >=1 个执行预期初始化的文件。
NB The section
volumes: data:
at the end of the Compose file appears redundant. You're actually using a host-mounted directory./data
not this volume.
当您 运行 Droplet 上的 Compose 文件时,这些文件不存在,您需要复制它们。
执行此操作的最简单方法是使用 scp,这提供了 2 个备选方案:
要么保留data
目录:
IP=[DROPLET-IP]
scp -r ./data root@${IP}:/data
NB The remote destination is
/data
not./data
. You will need to revise the Compose file on the Droplet (!) too:volumes: - /data:/docker-entrypoint-initdb.d
或将文件直接移动到Droplet的/docker-entrypoint-initdb.d
:
scp -r ./data root@${IP}/docker-entrypointy-initdb.d
NB Now there's no need for the volume mapping. You may remove:
volumes: - ./data:/docker-entrypoint-initdb.d
更新:重现(有效)
我使用了经过调整的 docker-compose.yaml
但它本质上是一样的:
version: "3.4"
services:
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- ${PWD}/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
restart: always
adminer:
image: adminer
restart: always
ports:
- 8080:8080
然后 mkdir ${PWD}/docker-entrypoint-initdb.d
并在其中创建了一个名为 freddie.sql
:
create database if not exists frederik;
use frederik;
create table treats (
TreatID INT NOT NULL AUTO_INCREMENT,
TreatName VARCHAR(255) NOT NULL,
PRIMARY KEY (TreatId));
insert into treats (TreatName)
values
("Dried Salmon"),
("Meatballs");
然后docker-compose rm --force && docker-compose up
我能够浏览管理员 UI (:8080
)、登录 (root
|mypass
) 并浏览数据库 frederik
: