Docker撰写:确保在运行CMD之前安装了卷

时间:2017-04-28 22:35:34

标签: docker docker-compose

我已经构建了一个容器,其中包含nginx和一些HTTPS配置。 证书由另一个容器使用https://letsencrypt.org/自动生成。 nginx容器还提供了一些默认的自签名证书,直到certbot容器生成了好的证书。这就是我的配置的外观:

version: '2'

services:
  # Nginx, the master of puppets, listens in port 80
  nginx:
    image: mycompany/nginx:v1.2.8
    depends_on: [api, admin, front, postgres, redis, certbot]
    ports: ["80:80", "443:443"]
    volumes:
      - acme_challenge:/var/www/acme_challenge
      - ssl_certs:/var/certs
    environment:
      ACME_CHALLENGE_PATH: /var/www/acme_challenge

      # Where will the container put the default certs
      DEFAULT_SSL_CERTS_PATH: /var/default_certs

      # Use temporary self signed keys by default
      SSL_CERTIFICATE:     /var/default_certs/selfsigned.crt
      SSL_CERTIFICATE_KEY: /var/default_certs/selfsigned.key

      # Once certbot generates certs I change config to this and recreate the container
      # SSL_CERTIFICATE:     /var/cerst/mycompany.com/fullchain.pem
      # SSL_CERTIFICATE_KEY: /var/certs/mycompany.com/privkey.pem

  # Certbot renews SSL certificates periodically
  certbot:
    image: mycompany/certbot:v1.0.9
    restart: on-failure:3
    environment:
      - WEBROOT_PATH=/var/www/acme_challenge
      - SIGNING_EMAIL=info@yavende.com
      - DOMAINS=mycompany.com, api.mycompany.com
    volumes:
      - acme_challenge:/var/www/acme_challenge
      - ssl_certs:/etc/letsencrypt/live

volumes:
  acme_challenge:
  ssl_certs:

这或多或少是有效的方式:

  • nginx容器配置为使用一些自签名证书
  • docker compose up -d在并行上启动certbot和nginx。
  • 同时,certbot运行一个生成证书的过程。假设这成功了。
  • 过了一会儿,我附加到nginx容器并运行ls /var/certs并且certbot生成的证书就在那里。太好了!

  • 我修改了nginx容器的配置以使用这些新证书(通过env vars SSL_CERTIFICATE *)并重新创建容器。

  • Nginx无法运行,因为文件不在那里,即使我知道文件在那里(用很多方法检查)

我怀疑图像的命令(CMD)是否运行,无论是否已连接到容器的卷。 这是真的?我应该写一些bash来等到这些文件出现吗?

1 个答案:

答案 0 :(得分:1)

免责声明:这是我自己的码头图片的插件。

为了这个目的,我已经基于nginx创建了一个非常漂亮的docker镜像,具有自动letsencrypt管理,http基本身份验证,虚拟主机等功能,通过一个简单的json配置通过环境变量进行管理。我在生产中使用它,所以它很稳定。

你可以找到它here,它位于码头工具集中的tcjn/json-webrouter

您需要做的就是将这样的内容传递给CONFIG环境变量:

{"servers": [
          {"ServerName": "example.com", "Target": "192.168.2.52:32407", "Https": true},
          {"ServerName": "*.example.com", "Target": "192.168.2.52:4444", "Https": true},
          {"ServerName": "secret.example.com", "Target": "192.168.2.52:34505", "Https": true, "Auth": {"Realm": "Login for secret stuff", "Set": "secret_users"}}
        ], "auth": {
          "secret_users": {"bob": "HASH GENERATED BY openssl passwd"}
        }}

是的,它就像"Https": true一样简单。您可以在github repo中找到所有可能的选项。