Docker compose Docker DB迁移/部署到DigitalOcean

Docker compose Docker DB迁移/部署到DigitalOcean,docker-compose,digital-ocean,docker-machine,Docker Compose,Digital Ocean,Docker Machine,警告:我对docker和云主机相当陌生,这可能是一个愚蠢的问题 我有一个本地web应用程序,它有3个与之关联的图像,应用程序本身、db和一个phpmyadmin图像。所有这些都在本地运行得很好,如果我将所有文件传输到我的digital ocean droplet并打开我的容器,那么它在那里也可以正常工作,但这不是我想要部署的方式,让每个库中的每个文件都驻留在我的droplet中 我一直在尝试在我的液滴上创建一个docker机器,并将我的容器远程部署到它上。除了我的db映像没有引用我的数据库并且只

警告:我对docker和云主机相当陌生,这可能是一个愚蠢的问题

我有一个本地web应用程序,它有3个与之关联的图像,应用程序本身、db和一个phpmyadmin图像。所有这些都在本地运行得很好,如果我将所有文件传输到我的digital ocean droplet并打开我的容器,那么它在那里也可以正常工作,但这不是我想要部署的方式,让每个库中的每个文件都驻留在我的droplet中

我一直在尝试在我的液滴上创建一个docker机器,并将我的容器远程部署到它上。除了我的db映像没有引用我的数据库并且只是一个空db之外,这似乎工作得很好。我尝试以我在教程中看到的方式迁移db:

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
我知道我可能错过了一些非常愚蠢和简单的东西,但我很难弄清楚如何为我的db映像迁移数据。提前谢谢

更新: 根据要求,这里是我的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,但由于db仍然为空,我肯定还是缺少一些东西。下面是我的新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配置,例如使用面向容器的操作系统并访问您的Compose文件。但这不是问题-

我认为这与你使用Windows无关,可能没有什么区别;它可能需要一些答案调整,但仅此而已

挑战在于您需要在远程计算机上移动或重新创建数据库状态。有几种方法可以持久化DB状态:容器中不理想;使用卷挂载很好,其他

每一个都是可移动的,但是如果您可以将您的撰写文件添加到您的问题中,这样我们就可以看到使用了哪种方法,这会有所帮助

在充分披露中,我不熟悉你提到的方法,但这并不意味着它是不准确的;我只是不太熟悉

更新:docker入口点initdb.d 请参阅:在上初始化新实例

因此,从映像创建数据库容器时,将运行该目录中的任何文件来初始化数据库容器

在Compose文件中,将主机的./data目录装载到此文件中。该目录可能包含>=1个文件,用于执行您的预期初始化

注意:组合文件末尾的卷:数据:部分显示为冗余。实际上,您使用的是主机装载的目录。/data不是此卷

在水滴上运行Compose文件时,这些文件不存在,您需要复制它们

最简单的方法是使用scp,这提供了两种选择:

保留数据目录:

IP=[液滴-IP] scp-r./data root@${IP}:/data 注意:远程目标是/数据不是/数据。您需要修改液滴上的撰写文件!太:卷:-/data:/docker入口点initdb.d

或者将文件直接移动到Droplet的/docker入口点initdb.d:

scp-r./data root@${IP}/docker entrypointy initdb.d 注意:现在不需要卷映射。您可以删除:卷:-./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的文件:

然后docker compose rm-强制和docker compose up

我可以浏览管理员UI:8080,登录root | mypass并浏览数据库frederik:


好的,我将更新我的答案,以使其更容易响应。在db服务的卷中再次更新我的帖子是无关的。请把它拿走。我很惊讶它是有效的,它可能会覆盖您复制到Droplet的文件。您主机上的数据目录中有什么?docker入口点initdb.d目录应仅包含SQL脚本。这些将用于在容器运行时创建数据库架构和内容。起初,我实际上已经删除了它并尝试了,但没有成功,然后我添加了它,正如我的问题中所显示的那样,也没有成功。无论哪种方式,仍然是空数据库:。data和docker entrypoint initdb.d目录中唯一的内容是.sqldb脚本。
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");