如何正确设置环境变量 Gitlab CI/CD 和 Docker

Posted

技术标签:

【中文标题】如何正确设置环境变量 Gitlab CI/CD 和 Docker【英文标题】:How to set environmental variables properly Gitlab CI/CD and Docker 【发布时间】:2020-01-10 03:02:15 【问题描述】:

我是 Docker 和带有 Gitlab CI/CD 的 CI/CD 的新手。我的 Django 项目的根目录中有 .env 文件,其中包含我的环境变量,例如 SECRET_KEY=198191891.env 文件包含在 .gitignore 中。我已经在 Gitlab 设置中为 CI/CD 设置了这些变量。但是Gitlab CI/CD设置中设置的环境变量好像不可用

另外,Gitlab CI/CD 自动化流程应该如何创建用户和数据库来连接和运行测试?在我的本地机器上为数据库创建数据库和用户时,我登录到容器docker exec -it <postgres_container_name> /bin/sh 并创建了 Postgres 用户和数据库。

这是我的相关文件。

docker-compose.yml

version: "3"
services:
  postgres:
    image: postgres
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data/
  web:
    build: .
    command: /usr/local/bin/gunicorn writer.wsgi:application -w 2 -b :8000
    environment:
      DEBUG: $DEBUG
      DB_HOST: $DB_HOST
      DB_NAME: $DB_NAME
      DB_USER: $DB_USER
      DB_PORT: $DB_PORT
      DB_PASSWORD: $DB_PASSWORD
      SENDGRID_API_KEY: $SENDGRID_API_KEY
      AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
      AWS_STORAGE_BUCKET_NAME: $AWS_STORAGE_BUCKET_NAME
    depends_on:
      - postgres
      - redis
    expose:
      - "8000"
    volumes:
      - .:/writer-api
  redis:
    image: "redis:alpine"
  celery:
    build: .
    command: celery -A writer worker -l info
    volumes:
      - .:/writer-api
    depends_on:
      - postgres
      - redis
  celery-beat:
    build: .
    command: celery -A writer beat -l info
    volumes:
      - .:/writer-api
    depends_on:
      - postgres
      - redis
  nginx:
    restart: always
    build: ./nginx/
    ports:
      - "80:80"
    depends_on:
      - web
volumes:
  pgdata:

.gitlab-ci.yml

image: tmaier/docker-compose:latest

services:
  - docker:dind

before_script:
  - docker info
  - docker-compose --version

stages:
  - build
  - test
  - deploy

build:
  stage: build
  script:
    - echo "Building the app"
    - docker-compose build

test:
  stage: test
  variables:
  script:
    - echo "Testing"
    - docker-compose run web coverage run manage.py test

deploy-staging:
  stage: deploy
  only:
    - develop
  script:
    - echo "Deploying staging"
    - docker-compose up -d

deploy-production:
  stage: deploy
  only:
    - master
  script:
    - echo "Deploying production"
    - docker-compose up -d

这是我的变量设置

这是我失败的管道工作

【问题讨论】:

【参考方案1】:

SECRET_KEY 变量将可用于配置的所有 CI 作业。但是,我在您的 Docker Compose 文件中没有看到对它的任何引用,以将其传递给您的一个或多个服务。要让 Web 服务使用它,您需要像已有的其他变量一样映射它。

  web:
    build: .
    command: /usr/local/bin/gunicorn writer.wsgi:application -w 2 -b :8000
    environment:
      SECRET_KEY: $SECRET_KEY
      DEBUG: $DEBUG
      …

至于创建数据库,您应该将您当前在 postgres 容器中交互运行的任何内容包装在 SQL 文件或 shell 脚本中,然后将其绑定挂载到容器的初始化脚本目录中 /docker-entrypoint-initdb.d 下。有关详细信息,请参阅 postgres 图像描述的 Initialization scripts 部分。

【讨论】:

非常感谢。后来我更改了我的代码,删除了硬编码的密钥并忘记在docker-compose.yml 中访问它。这意味着如果你没有在 web 容器中声明变量,那么你不能在 .gitlab-ci.yml 中设置它? 好吧,GitLab CI 变量更多的是在跑步者的环境中设置值。您可以随心所欲地使用它。在这种情况下,将其传递给 Web 服务的环境规范。 来自我手动执行 ssh 到远程服务器的环境,执行 git pull 并创建我的.env,我如何分离开发.env 和生产.env。我使用 docker-machine 创建了一个 AWS EC2 实例。我创建了一个production.yml 并做了docker-compose -f production.yml up -d。 EC2 机器中的容器接收了我的开发 .env 这不是我想要的。【参考方案2】:

根据我的经验,将环境变量传递给容器 docker 的最佳方法是创建一个环境文件,该文件适用于开发环境和生产环境:

GitLab CI/CD variables

您必须在 GitLab CI/CD 上创建一个环境文件,按照接下来的步骤,在您的项目 GitLab 上您必须转到:

settings > CI/CD > Variables

你必须创建一个ENV_FILE

演示图片

接下来在 .gitlab-ci.yml 的构建阶段将 ENV_FILE 复制到本地进程

.gitlab-ci.yml

build:
  stage: build
  script:
    - cp $ENV_FILE .env
    - echo "Building the app"
    - docker-compose build

您的Dockerfile 应该保持正常,因此不必更改

Dockerfile

FROM python:3.8.6-slim

# Rest of setup goes here...

COPY .env .env

【讨论】:

以上是关于如何正确设置环境变量 Gitlab CI/CD 和 Docker的主要内容,如果未能解决你的问题,请参考以下文章

在 GitLab CI/CD 作业中将环境变量传递给 docker run 返回无效的参考格式?

GitLab CI/CD中的常用预设变量

Gitlab CI/CD 中设置 Python 虚拟环境的最佳实践是啥

带有 gitlab CI/CD 的 Rails .env

如何将 gitlab ci/cd 变量传递给 kubernetes(AKS) deployment.yaml

GItLab CI/CD 只为开发分支添加变量