如何在Docker Compose中运行一次命令 [英] How to run a command once in Docker compose

查看:402
本文介绍了如何在Docker Compose中运行一次命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm working on a docker compose file to deploy my Go web server. My server uses mongo, so I added a data volume container and the mongo service in docker compose. Then I wrote a Dockerfile in order to build my Go project, and finally run it.

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

However, there is another step that must be done. Once my project has been compiled, I have to run the following command: ./my-project -setup

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

This will add some necessary information to the database, and the information only needs to be added once. I can't however add this step on the Dockerfile (in the build process) because mongo must already be started.

那么,我该如何实现呢?即使重新启动服务器然后再次运行docker-compose up,我也不想再次执行此命令.

So, how can I achieve this? Even if I restart the server and then run again docker-compose up I don't want this command to be executed again.

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

I think I'm missing some Docker understanding, because I don't actually understand everything about data volume containers (are they just stopped containers that mount a volume?). Also, if I restart the server, and then run docker-compose up, which commands will be run? Will it just start the same container that was now stopped with the given CMD?

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

In any case, here is my 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

这是构建我的项目映像的Dockerfile:

And here is my Dockerfile to build my project image:

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

推荐答案

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

I suggest to add an entrypoint-script to your container; in this entrypoint-script, you can check if the database has been initialized, and if it isn't, perform the required steps.

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

As you noticed in your question, the order in which services / containers are started should not be taken for granted, so it's possible your application container is started before the database container, so the script should take that into account.

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

As an example, have a look at the official WordPress image, which performs a one-time initialization of the database in it's entrypoint-script. The script attempts to connect to the database (and retries if the database cannot be contacted (yet)), and checks if initialization is needed; https://github.com/docker-library/wordpress/blob/df190dc9c5752fd09317d836bd2bdcd09ee379a5/apache/docker-entrypoint.sh#L146-L171

注意

我注意到您创建了一个仅数据容器"以将卷附加到该容器.从Docker 1.9开始,Docker具有卷管理功能,包括命名卷.因此,您不再需要使用仅数据"容器.

I notice you created a "data-only container" to attach your volume to. Since docker 1.9, docker has volume management, including naming volumes. Because of this, you no longer need to use "data-only" containers.

您可以从撰写文件中删除仅数据容器,并更改mongo服务以使其看起来像这样;

You can remove the data-only container from your compose file, and change your mongo service to look something like this;

  mongo:
    image: mongo:latest
    volumes:
      - mongodata:/data/db
    ports:
      - "28001:27017"
    command: --smallfiles --rest --auth

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

This should create a new volume, named mongodata if it doesn't exist, or re-use the existing volume with that name. You can list all volumes using docker volume ls and remove a volume with docker volume rm <some-volume> if you no longer need it

这篇关于如何在Docker Compose中运行一次命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆