相同的 Dockerfile 在 Codebuild 中产生错误

Same Dockerfile produces error in Codebuild

我有一个 Dockerfile:

FROM public.ecr.aws/bitnami/node:15 AS stage-01
COPY package.json /app/package.json
COPY package-lock.json /app/package-lock.json
WORKDIR /app
RUN npm ci

FROM stage-01 AS stage-02
COPY src /app/src
COPY public /app/public
COPY tsconfig.json /app/tsconfig.json
WORKDIR /app
RUN PUBLIC_URL=/myapp/web npm run build

FROM public.ecr.aws/bitnami/nginx:1.20

USER 1001

COPY --from=stage-02 /app/build /app/build
COPY nginx.conf /opt/bitnami/nginx/conf/server_blocks/nginx.conf
COPY ./env.sh /app/build
COPY window.env /app/build

EXPOSE 8080
WORKDIR /app/build

CMD ["/bin/sh", "-c", "/app/build/env.sh && nginx -g \"daemon off;\""]

如果我在本地构建此映像,它会正常启动并执行它必须执行的操作。

我的本地docker版本:

Client: Docker Engine - Community
 Version:           20.10.7
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        f0df350
 Built:             Wed Jun  2 11:56:40 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.8
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.6
  Git commit:       75249d8
  Built:            Fri Jul 30 19:52:16 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.9
  GitCommit:        e25210fe30a0a703442421b0f60afac609f950a3
 runc:
  Version:          1.0.1
  GitCommit:        v1.0.1-0-g4144b63
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

如果我在 Codebuild 中构建它,它不会启动:

/app/build/env.sh: 4: /app/build/env.sh: cannot create ./env-config.js: Permission denied

这是我在代码构建中使用的图像:aws/codebuild/amazonlinux2-x86_64-standard:3.0

我在本地也有 运行 相同的脚本,但仍然没有错误。

这可能是什么原因造成的? 如果你有什么想法请告诉我,否则我会post更多的代码

这是我的env.sh

#!/usr/bin/env sh

# Add assignment
echo "window._env_ = {" > ./env-config.js

# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [ -n "$line" ];
do
  echo "$line"
  # Split env variables by character `=`
  if printf '%s\n' "$line" | grep -q -e '='; then
    varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
    varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
  fi

  # Read value of current variable if exists as Environment variable
  eval value=\"$"$varname"\"
  # Otherwise use value from .env file
  [ -z "$value" ] && value=${varvalue}

  echo name: "$varname", value: "$value"

  # Append configuration property to JS file
  echo "  $varname: \"$value\"," >> ./env-config.js
done < window.env

echo "}" >> ./env-config.js

构建规范:

version: 0.2
env:
  git-credential-helper: yes
  secrets-manager:
    GITHUB_TOKEN: "github:GITHUB_TOKEN"

phases:
  install:
    runtime-versions:
      nodejs: 12
    commands:
      - npm install
  build:
    commands:
      - echo Build started on `date`
      - GITHUB_USERNAME=${GITHUB_USERNAME} GITHUB_EMAIL=${GITHUB_EMAIL} GITHUB_TOKEN=${GITHUB_TOKEN} AWS_REGION=${AWS_DEFAULT_REGION} GITHUB_REPOSITORY_URL=${GITHUB_REPOSITORY_URL} ECR_REPOSITORY_URL=${ECR_REPOSITORY_URL} ENV=${ENV} node release.js

我的构建项目 terraform 配置:

resource "aws_codebuild_project" "dashboard_image" {
  name = var.project.name
  service_role = var.codebuild_role_arn
  artifacts {
    type = "CODEPIPELINE"
  }
  environment {
    compute_type = "BUILD_GENERAL1_SMALL"
    image = "aws/codebuild/amazonlinux2-x86_64-standard:3.0"
    type = "LINUX_CONTAINER"
    privileged_mode = true

    environment_variable {
      name = "GITHUB_REPOSITORY_URL"
      value = "https://github.com/${var.project.github_organization_name}/${var.project.github_repository_name}.git"
    }

    environment_variable {
      name = "ECR_REPOSITORY_URL"
      value = var.project.ecr_repository_url
    }

    environment_variable {
      name = "ECR_IMAGE_NAME"
      value = var.project.ecr_image_name
    }

    environment_variable {
      name = "ENV"
      value = "prod"
    }
  }
  source {
    type = "CODEPIPELINE"
    buildspec = "buildspec.yml"
  }
}

一切都与您的 Dockerfile 和其中的用户权限有关。尝试 运行 docker run public.ecr.aws/bitnami/nginx:1.20 whoami - 你会看到这个图像没有默认用户。如果你在这个容器中执行一些东西,它会是一样的。您必须将 --user root 添加到 runexec 命令。请参阅“为什么使用非根容器?”部分在 Bitnami Nginx image documentation

这就是您无权在 /app 文件夹中创建文件的原因。此文件夹的所有者是第一个 public.ecr.aws/bitnami/node:15 图像的 root(默认情况下具有 root 用户)。

为了使其适用于您的情况,您必须将行从 USER 1001 更改为 USER root(或具有适当权限的人) 并仔细检查 env.sh文件有执行权限chmod +x env.sh.

这是我必须对 Dockerfile 进行的更改才能使其正常工作:

FROM public.ecr.aws/bitnami/node:15 AS stage-01
COPY package.json /app/package.json
COPY package-lock.json /app/package-lock.json
WORKDIR /app
RUN npm ci

FROM stage-01 AS stage-02
COPY src /app/src
COPY public /app/public
COPY tsconfig.json /app/tsconfig.json
WORKDIR /app
RUN PUBLIC_URL=/myapp/web npm run build

FROM public.ecr.aws/bitnami/nginx:1.20

USER root

COPY --from=stage-02 /app/build /app/build
COPY nginx.conf /opt/bitnami/nginx/conf/server_blocks/nginx.conf
COPY ./env.sh /app/build
COPY window.env /app/build
RUN chmod 777 /app/build/env-config.js

EXPOSE 8080
WORKDIR /app/build
USER 1001

CMD ["/bin/sh", "-c", "/app/build/env.sh && nginx -g \"daemon off;\""]

可能是克隆仓库时的codebuild权限问题

777只是暂时的,以后我可能会测试能不能限制权限。