如何在Docker compose中运行一次命令

Iva*_*van 16 go mongodb docker

所以我正在使用docker compose文件来部署我的Go web服务器.我的服务器使用mongo,所以我在docker compose中添加了一个数据卷容器和mongo服务.然后我写了一个Dockerfile来构建我的Go项目,最后运行它.

但是,还有另一个必须完成的步骤.编译完项目后,我必须运行以下命令: ./my-project -setup

这将向数据库添加一些必要的信息,并且只需添加一次信息.但是我不能在Dockerfile上添加这一步(在构建过程中),因为mongo必须已经启动.

那么,我怎样才能做到这一点?即使我重新启动服务器然后再次运行,docker-compose up我也不希望再次执行此命令.

我想我错过了一些Docker的理解,因为我实际上并不了解数据量容器的所有内容(他们只是停止了装载卷的容器吗?).另外,如果我重新启动服务器,然后运行docker-compose up,将运行哪些命令?它是否会启动与现在使用给定CMD停止的相同容器?

无论如何,这是我的docker-compose.yml:

version: '2'
services:
  mongodata:
    image: mongo:latest
    volumes:
      - /data/db
    command: --break-mongo
  mongo:
    image: mongo:latest
    volumes_from:
      - mongodata
    ports:
      - "28001:27017"
    command: --smallfiles --rest --auth
  my_project:
    build: .
    ports:
      - "6060:8080"
    depends_on:
      - mongo
      - mongodata
    links:
      - mongo
Run Code Online (Sandbox Code Playgroud)

这是我的Dockerfile来构建我的项目图像:

FROM golang

ADD . /go/src/my_project
RUN cd /go/src/my_project && go get
RUN go install my_project
RUN my_project -setup
ENTRYPOINT /go/bin/my_project

EXPOSE 8080
Run Code Online (Sandbox Code Playgroud)

tha*_*tah 8

我建议在你的容器中添加一个入口点脚本; 在此入口点脚本中,您可以检查数据库是否已初始化,如果未初始化,请执行所需的步骤.

正如您在问题中所注意到的那样,服务/容器的启动顺序不应该被视为理所当然,因此您的应用程序容器可能在数据库容器之前启动,因此脚本应该考虑到这一点.

作为一个例子,看一下官方的WordPress图像,它在它的入口点脚本中执行数据库的一次性初始化.该脚本尝试连接到数据库(如果无法联系数据库,则重试),并检查是否需要初始化; https://github.com/docker-library/wordpress/blob/df190dc9c5752fd09317d836bd2bdcd09ee379a5/apache/docker-entrypoint.sh#L146-L171

注意

我注意到你创建了一个"数据专用容器"来附加你的卷.自docker 1.9以来,docker具有卷管理功能,包括命名卷.因此,您不再需要使用"仅数据"容器.

您可以从撰写文件中删除仅数据容器,并将您的mongo服务更改为如下所示;

  mongo:
    image: mongo:latest
    volumes:
      - mongodata:/data/db
    ports:
      - "28001:27017"
    command: --smallfiles --rest --auth
Run Code Online (Sandbox Code Playgroud)

这应该创建一个新卷,mongodata如果它不存在则命名,或者重新使用具有该名称的现有卷.如果您不再需要,可以使用docker volume ls和删除卷列出所有卷docker volume rm <some-volume>