在Gitlab中的两步Dockerfile中传递--build-arg或使用环境变量

我的最低测试项目布局如下所示。

├── deployment
│   ├── build.sh
│   └── nginx
│       └── nginx.conf
├── Dockerfile
├── next.config.js
├── package.json
├── package-lock.json
└── pages
    ├── _app.js
    └── index.js

Dockerfile的内容:

FROM node as build-stage

ARG K8S_SECRET_PUB
ENV K8S_SECRET_PUB ${K8S_SECRET_PUB}

ARG SRV
ENV SRV ${SRV}

WORKDIR /app
COPY package*json /app/
RUN npm install --production
COPY ./ /app/
RUN npm run export


FROM nginx:1.15-alpine

RUN rm /etc/nginx/nginx.conf
COPY --from=build-stage /app/out /www
COPY deployment/nginx/nginx.conf /etc/nginx/
EXPOSE 5000

目标是将环境变量K8S_SECRET_PUB和SRV传递到构建过程。npm run export执行next build && next export以获取nginx服务器应提供的静态文件。

next.config.js的内容:

require('dotenv').config();

module.exports = {
  serverRuntimeConfig: {
    srv: process.env.SRV
  },
  publicRuntimeConfig: {
    pub: process.env.K8S_SECRET_PUB
  }
};

页面/_app.js的内容:

import App from 'next/app';
import getConfig from 'next/config';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

class MyApp extends App {
  render() {
    return (
      <div>
        <h1>
          {serverRuntimeConfig.srv || 'SRV not accessible from client :p'}
        </h1>
        <h1>{publicRuntimeConfig.pub || 'PUB not set'}</h1>
      </div>
    );
  }
}

export default MyApp;

通过本地构建docker映像时docker build --build-arg K8S_SECRET_PUB=puppy --build-arg SRV=serverval -t my_image .,我可以通过启动容器docker run -p 5000:5000 my_image

访问正在运行的容器具有预期的结果。检查文件系统进一步表明,已拾取传递的构建参数,并相应地写入了文件。

在本地测试Docker映像

但是,当我将此代码推送到Gitlab时,已部署的nginx如下所示:

在Gitlab上运行

What I would like to accomplish is to have the Environment variables that I defined via Gitlab UI under Settings -> CI/CD be picked up and used in the build-stage defined in the Dockerfile. As we've been otherwise happy with the Auto Dev, we have not created and checked in a .gitlab-ci.yml file yet.


Update #1

After tinkering for a little bit, I now have access to the environment variables, but I lost the convenience of Auto DevOps.

I added a deployment/build.sh with this content:

#!/bin/sh
docker build --build-arg K8S_SECRET_PUB="${K8S_SECRET_PUB}" --build-arg SRV="${SRV}" -t my_image .

I also started on a .gitlab-ci.yml which contains this:

stages:
    - build
    - review
    - deploy
    - clean

image: docker:latest

services:
    - docker:dind

build:
    stage: build
    script:
        - sh ./deployment/build.sh
        - mkdir image
        - docker save my_image > image/my_image.tar
    artifacts:
        paths:
            - image

After pushing the repository to Gitlab, the pipeline succeeds and I can download the artifact, unzip it, load it via docker load -i image/my_image.tar and run it. And sure enough, the page loads with the defined variables from the Gitlab CI/CD UI. However, now I've lost all of the other steps of the deployment process (which is the main reason I didn't want to write the .gitlab-ci.yml in the first place).


Update #2

Working off the Auto DevOps template, which I found at https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml I made these changes:

  • commenting out the line - template: Jobs/Build.gitlab-ci.yml
  • replace the alpine with the docker image
  • added CODE_QUALITY_DISABLED: "true" to the variables section, because the code quality check was taking too long
  • 从上述我之前的尝试中添加服务并构建部分

现在,我处于审查阶段。

Application should be accessible at: http://*my_image_url*
Waiting for deployment "review-branchname-abcxyz" rollout to finish: 0 of 1 updated replicas are available...