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: