Git 和 Docker 团队工作流程

标签 git docker workflow dev-to-production

我在一些项目中使用 Git 已有几年了,但我是 Docker 新手。
今天,我想找到一个工作流程,让我可以在我的团队项目中正确使用 Git 和 Docker。
今天
今天,没有 Docker,我们使用命名分支进行开发。当功能完成后,我们将它们 pull 向“master”。当我们想要投入生产时,我们会创建一个 master 的版本化 preprod 分支(例如 preprod-2.3.0)用于测试。如果我们有更正,我们会推送当前的 preprod 并 merge 到 master。当 preprod 分支准备好(自动和手动测试)时,我们创建一个与 preprod 版本相同的 prod 分支(例如:prod-2.3.0)。如果我们在 prod 中有紧急更正,我们会从 preprod(例如:preprod-2.3.1)创建一个新分支,然后继续正常流程(test + prod -> prod-2.3.1)。
使用 Docker
使用 Docker,为了开发,我们想要创建名为 $PROJECT_NAME/$IMAGE_NAME:dev (project/api:dev, project/db:dev, project/webui:dev...) 的本地镜像。
每次我们重建本地项目时,我们都会丢失开发镜像,否则它将变得无法管理。
为了测试,我们还将使用 dev 的版本。
但我有疑问的是生产启动。
一些博客/文章在将代码推送到 git 后创建 docker 图像,执行单元测试并最终保存有效图像。此后,一个有效的图像将被命名为“:latest”并用于生产实现。
在我们的例子中,我们可以使用这个系统来保存 prod-$VERSION 分支的有效图像,使用 $VERSION 和 latest 标签来对图像进行版本控制。
问题
我对这个系统的问题是我觉得我正在失去 Docker 的好处之一。当我在本地执行测试时,我会测试代码以及​​开发镜像。应该在 CI 和生产环境中使用此镜像。在那里,CI 为 master、preprod 和最后的 prod 重新创建了几次图像,然后被卡住。
如果集线器镜像的版本(例如 nginx:latest、node:lastest)同时发生了变化,这可能会导致问题。
见:https://nickjanetakis.com/blog/docker-tip-18-please-pin-your-docker-image-versions
另一种解决方案是使用 preprod 标签将图像直接保存在 preprod 中。经过测试,我添加了标签“prod”和“latest”。但是如果在创建 preprod 的过程中发生了更新,我有时会浪费时间来理解为什么它在 dev 而不是 prod 中起作用。但至少它避免了预生产和生产之间的问题。
我也找不到允许运行 npm build/npm ci 的 nodejs 锁(package.json/package-lock.json)的系统(下载最新版本的包并更新锁定文件,指定哪个版本是精确的使用/重建与锁定文件相同的架构)。
见:https://docs.npmjs.com/files/package-lock.json
问题
您是否有系统/想法来确保图像与前一个图像相同(作为锁)?
还是允许您在团队中工作,同时直接从开发人员(带有版本)删除图像的工作流程?

最佳答案

我终于用 bash 别名或一两个脚本制作了自己的锁系统:

bash 别名 (添加 docker ci 命令并改进 docker build):

dockeralias() {
    args=$@
    args_cat=$1
    shift
    args_without_cat_files_and_final=""    

    dockerfile="Dockerfile"
    while test $# -gt 1; do
        case "$1" in
            -f|--file)
                shift
                dockerfile=$1
                shift
                ;;
            -f=*)
                dockerfile=${1#"-f="}
                shift
                ;;
            --file=*)
                dockerfile=${1#"--file="}
                shift
                ;;
            *)
                args_without_cat_files_and_final="$args_without_cat_files_and_final $1 "
                shift
                ;;
        esac
    done
    lockfile="$dockerfile-lock"

    args_final=$@

    if [ $args_cat == "ci" ]; then
        echo "Build from $lockfile"
        command docker build $args_without_cat_files_and_final --file $lockfile $args_final
        return
    fi

    if ! command docker $args; then
        return
    fi

    if [ $args_cat == "build" ]; then
        echo "Make $lockfile from $dockerfile"

        cp $dockerfile $lockfile
    grep ^FROM $lockfile | while read -r line ; do

        image=`echo $line | cut -d" " -f2`
        digest=`command docker inspect --format='{{index .RepoDigests 0}}' $image`

        echo "$image > $digest"

        sed -i -e "s/$image/$digest/g" $lockfile
    done
    fi
}
alias docker=dockeralias

或者 docker-build.sh 在 dev 中替换 docker build
#!/bin/bash

docker build "$@"

dockerfile="Dockerfile"
while test $# -gt 0; do
    case "$1" in
        -f|--file)
            shift
            dockerfile=$1
            shift
            ;;
        -f=*)
            dockerfile=${1#"-f="}
            shift
            ;;
        --file=*)
            dockerfile=${1#"--file="}
            shift
            ;;
        *)
        shift
            ;;
    esac
done
lockfile="$dockerfile-lock"

echo "Make $lockfile from $dockerfile"

cp $dockerfile $lockfile
grep ^FROM $lockfile | while read -r line ; do

    image=`echo $line | cut -d" " -f2`
    digest=`docker inspect --format='{{index .RepoDigests 0}}' $image`

    echo "$image > $digest"

    sed -i -e "s/$image/$digest/g" $lockfile
done

docker -ci.sh 在 CI (preprod, prod...) 中替换 docker build 或只使用“ docker build --file Dockerfile-lock .
#!/bin/bash

args=""

dockerfile="Dockerfile"
while test $# -gt 1; do
    case "$1" in
        -f|--file)
            shift
            dockerfile=$1
            shift
            ;;
        -f=*)
            dockerfile=${1#"-f="}
            shift
            ;;
        --file=*)
            dockerfile=${1#"--file="}
            shift
            ;;
        *)
        args="$newargs $1 "
        shift
            ;;
    esac
done
lockfile="$dockerfile-lock"

echo "Build from $lockfile"
docker build $args --file $lockfile "$@"

这里有一个脚本做什么的例子:

来自 Dockerfile
FROM node:latest
EXPOSE 8080
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD npm start

创建 Dockerfile-lock
FROM node@sha256:d2180576a96698b0c7f0b00474c48f67a494333d9ecb57c675700395aeeb2c35
EXPOSE 8080
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD npm start

我还在 docker 论坛上写了一个功能请求:https://forums.docker.com/t/dockerfile-lock/67031

关于Git 和 Docker 团队工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54190484/

相关文章:

git - 使用 hub、github-gem 还是在使用 github repo 时坚持使用 git?

Azure 上的 GitLab 无法解析主机

workflow - CQ5/AEM5.6 工作流程 : Access workflow instance properties from inside OR Split

Java开源帮助台+工作流项目

git - 如何将子模块设置为指向特定提交而不获取它?

java - 无法将 Eclipse 项目克隆到工作区

docker - Kubernetes集群中计划作业的推荐架构是什么?

docker - 使用 docker 安装 java 8 的最佳方法?

docker - 可以以某种方式阻止 'docker-compose down'在生产中运行吗?

kubernetes - Kubernetes Job/CronJob是否支持与Pods不同的对象?