diff --git a/Containerfile b/Containerfile index a92bfc7e3..99ae22f91 100644 --- a/Containerfile +++ b/Containerfile @@ -1,76 +1,121 @@ -FROM quay.io/forem/ruby:3.0.2 as base +FROM ghcr.io/forem/ruby:3.0.2@sha256:04c945460e5999c0483b119074597dba62b863f5f5ea3c98bff4169e0d2f990b as base FROM base as builder +# This is provided by BuildKit +ARG TARGETARCH + USER root -RUN curl -sL https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo && \ - dnf install --setopt install_weak_deps=false -y \ - ImageMagick iproute jemalloc less libcurl libcurl-devel \ - libffi-devel libxml2-devel libxslt-devel nodejs pcre-devel \ - postgresql postgresql-devel tzdata yarn && \ - dnf -y clean all && \ - rm -rf /var/cache/yum +# pkg-config, +# libpixman-1-dev, +# libcairo2-dev, +# libpango1.0-dev +# +# are needed only on arm64: some nodejs dependency doesn't provide +# pre-built binaries for that arch, and so falls back to building +# from source, which then requires a few extra packages installed. +# +# Since we wipe out node_modules as part of this image after calling +# the bundler, we don't need these headers (or their sofile counterparts) +# in any of the other build stages. +RUN apt update && \ + apt install -y \ + build-essential \ + libcurl4-openssl-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + libpcre3-dev \ + libpq-dev \ + pkg-config \ + libpixman-1-dev \ + libcairo2-dev \ + libpango1.0-dev \ + && \ + apt clean + +ENV BUNDLER_VERSION=2.2.22 \ + BUNDLE_SILENCE_ROOT_WARNING=true \ + BUNDLE_SILENCE_DEPRECATIONS=true -ENV BUNDLER_VERSION=2.2.22 BUNDLE_SILENCE_ROOT_WARNING=true BUNDLE_SILENCE_DEPRECATIONS=true RUN gem install -N bundler:"${BUNDLER_VERSION}" ENV APP_USER=forem APP_UID=1000 APP_GID=1000 APP_HOME=/opt/apps/forem \ - LD_PRELOAD=/usr/lib64/libjemalloc.so.2 + LD_PRELOAD=libjemalloc.so.2 RUN mkdir -p ${APP_HOME} && chown "${APP_UID}":"${APP_GID}" "${APP_HOME}" && \ groupadd -g "${APP_GID}" "${APP_USER}" && \ - adduser -u "${APP_UID}" -g "${APP_GID}" -d "${APP_HOME}" "${APP_USER}" + adduser --uid "${APP_UID}" --gid "${APP_GID}" --home "${APP_HOME}" "${APP_USER}" -ENV DOCKERIZE_VERSION=v0.6.1 -RUN wget https://github.com/jwilder/dockerize/releases/download/"${DOCKERIZE_VERSION}"/dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ - && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ - && rm dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ +ENV DOCKERIZE_VERSION=v0.7.0 +RUN curl -fsSLO https://github.com/jwilder/dockerize/releases/download/"${DOCKERIZE_VERSION}"/dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ + && tar -C /usr/local/bin -xzvf dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ + && rm dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ && chown root:root /usr/local/bin/dockerize +USER "${APP_USER}" WORKDIR "${APP_HOME}" -COPY ./.ruby-version "${APP_HOME}"/ -COPY ./Gemfile ./Gemfile.lock "${APP_HOME}"/ -COPY ./vendor/cache "${APP_HOME}"/vendor/cache +COPY --chown=${APP_UID}:${APP_GID} ./.ruby-version "${APP_HOME}"/ +COPY --chown=${APP_UID}:${APP_GID} ./Gemfile ./Gemfile.lock "${APP_HOME}"/ +COPY --chown=${APP_UID}:${APP_GID} ./vendor/cache "${APP_HOME}"/vendor/cache -RUN bundle config --local build.sassc --disable-march-tune-native && \ - BUNDLE_WITHOUT="development:test" bundle install --deployment --jobs 4 --retry 5 && \ +# Have to reset APP_CONFIG, which appears to be set by upstream images, to +# avoid permission errors in the development/test images (which run bundle +# as a user and require write access to the config file for setting things +# like BUNDLE_WITHOUT (a value that is cached by root here in this builder +# layer, see https://michaelheap.com/bundler-ignoring-bundle-without/)) +ENV BUNDLE_APP_CONFIG="${APP_HOME}/.bundle" +RUN mkdir -p "${BUNDLE_APP_CONFIG}" && \ + touch "${BUNDLE_APP_CONFIG}/config" && \ + chown -R "${APP_UID}:${APP_GID}" "${BUNDLE_APP_CONFIG}" && \ + bundle config --local build.sassc --disable-march-tune-native && \ + bundle config --local without development:test && \ + BUNDLE_FROZEN=true bundle install --deployment --jobs 4 --retry 5 && \ find "${APP_HOME}"/vendor/bundle -name "*.c" -delete && \ find "${APP_HOME}"/vendor/bundle -name "*.o" -delete -COPY . "${APP_HOME}" +COPY --chown=${APP_UID}:${APP_GID} . "${APP_HOME}" RUN mkdir -p "${APP_HOME}"/public/{assets,images,packs,podcasts,uploads} -RUN NODE_ENV=production yarn install +# While it's relatively rare for bare metal builds to hit the default +# timeout, QEMU-based ones (as is the case with Docker BuildX for +# cross-compiling) quite often can. This increased timeout should help +# reduce false-negatives when building multiarch images. +RUN echo 'network-timeout 300000' >> ~/.yarnrc -RUN RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile +# This is one giant step now because previously, removing node_modules to save +# layer space was done in a later step, which is invalid in at least some +# Docker storage drivers (resulting in Directory Not Empty errors). +RUN NODE_ENV=production yarn install && \ + RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile && \ + rm -rf node_modules + +# This used to be calculated within the container build, but we then tried +# to rm -rf the .git that was copied in, which isn't valid (removing +# directories created in lower layers of an image isn't a thing (at least +# with the overlayfs drivers). Instead, we'll pass this in over CLI when +# building images (eg. in CI), but leave a default value for callers who don't +# override (perhaps docker-compose). This isn't perfect, but it'll do for now. +ARG VCS_REF=unspecified RUN echo $(date -u +'%Y-%m-%dT%H:%M:%SZ') >> "${APP_HOME}"/FOREM_BUILD_DATE && \ - echo $(git rev-parse --short HEAD) >> "${APP_HOME}"/FOREM_BUILD_SHA && \ - rm -rf "${APP_HOME}"/.git/ - -RUN rm -rf node_modules vendor/assets spec + echo "${VCS_REF}" >> "${APP_HOME}"/FOREM_BUILD_SHA ## Production FROM base as production USER root -RUN dnf install --setopt install_weak_deps=false -y bash curl ImageMagick \ - iproute jemalloc less libcurl \ - postgresql tzdata nodejs libpq \ - && dnf -y clean all \ - && rm -rf /var/cache/yum - ENV BUNDLER_VERSION=2.2.22 BUNDLE_SILENCE_ROOT_WARNING=1 RUN gem install -N bundler:"${BUNDLER_VERSION}" ENV APP_USER=forem APP_UID=1000 APP_GID=1000 APP_HOME=/opt/apps/forem \ - LD_PRELOAD=/usr/lib64/libjemalloc.so.2 + LD_PRELOAD=libjemalloc.so.2 RUN mkdir -p ${APP_HOME} && chown "${APP_UID}":"${APP_GID}" "${APP_HOME}" && \ groupadd -g "${APP_GID}" "${APP_USER}" && \ - adduser -u "${APP_UID}" -g "${APP_GID}" -d "${APP_HOME}" "${APP_USER}" + adduser --uid "${APP_UID}" --gid "${APP_GID}" --home "${APP_HOME}" "${APP_USER}" COPY --from=builder --chown="${APP_USER}":"${APP_USER}" ${APP_HOME} ${APP_HOME} @@ -86,23 +131,14 @@ CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "3000"] ## Testing FROM builder AS testing -USER root - -RUN dnf install --setopt install_weak_deps=false -y \ - chromium-headless chromedriver && \ - yum clean all && \ - rm -rf /var/cache/yum +USER "${APP_USER}" COPY --chown="${APP_USER}":"${APP_USER}" ./spec "${APP_HOME}"/spec COPY --from=builder /usr/local/bin/dockerize /usr/local/bin/dockerize -RUN chown "${APP_USER}":"${APP_USER}" -R "${APP_HOME}" - -USER "${APP_USER}" - RUN bundle config --local build.sassc --disable-march-tune-native && \ bundle config --delete without && \ - bundle install --deployment --jobs 4 --retry 5 && \ + BUNDLE_FROZEN=true bundle install --deployment --jobs 4 --retry 5 && \ find "${APP_HOME}"/vendor/bundle -name "*.c" -delete && \ find "${APP_HOME}"/vendor/bundle -name "*.o" -delete @@ -113,16 +149,14 @@ CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "3000"] ## Development FROM builder AS development +USER "${APP_USER}" + COPY --chown="${APP_USER}":"${APP_USER}" ./spec "${APP_HOME}"/spec COPY --from=builder /usr/local/bin/dockerize /usr/local/bin/dockerize -RUN chown "${APP_USER}":"${APP_USER}" -R "${APP_HOME}" - -USER "${APP_USER}" - RUN bundle config --local build.sassc --disable-march-tune-native && \ bundle config --delete without && \ - bundle install --deployment --jobs 4 --retry 5 && \ + BUNDLE_FROZEN=true bundle install --deployment --jobs 4 --retry 5 && \ find "${APP_HOME}"/vendor/bundle -name "*.c" -delete && \ find "${APP_HOME}"/vendor/bundle -name "*.o" -delete diff --git a/scripts/build_containers.sh b/scripts/build_containers.sh index 89c94903d..50dbf006d 100755 --- a/scripts/build_containers.sh +++ b/scripts/build_containers.sh @@ -5,6 +5,8 @@ set -euo pipefail : ${CONTAINER_REPO:="quay.io/forem"} : ${CONTAINER_APP:=forem} +export DOCKER_BUILDKIT=1 + function create_pr_containers { PULL_REQUEST=$1 @@ -22,6 +24,7 @@ function create_pr_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder-"${PULL_REQUEST}" \ --label quay.expires-after=8w \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":builder-"${PULL_REQUEST}" . # Build the pull request image @@ -30,6 +33,7 @@ function create_pr_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder-"${PULL_REQUEST}" \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":pr-"${PULL_REQUEST}" \ --label quay.expires-after=8w \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":pr-"${PULL_REQUEST}" . # Build the testing image @@ -39,6 +43,7 @@ function create_pr_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":pr-"${PULL_REQUEST}" \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":testing-"${PULL_REQUEST}" \ --label quay.expires-after=8w \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":testing-"${PULL_REQUEST}" . # Push images to Quay @@ -60,12 +65,14 @@ function create_production_containers { # Build the builder image docker build --target builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":builder . # Build the production image docker build --target production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":$(date +%Y%m%d) \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":latest . @@ -74,6 +81,7 @@ function create_production_containers { --label quay.expires-after=8w \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":${BUILDKITE_COMMIT:0:7} . # Build the testing image @@ -81,6 +89,7 @@ function create_production_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":testing \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":testing . # Build the development image @@ -89,6 +98,7 @@ function create_production_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":testing \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":development \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":development . # Push images to Quay @@ -114,12 +124,14 @@ function create_release_containers { # Build the builder image docker build --target builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":builder . # Build the production image docker build --target production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":${BUILDKITE_COMMIT:0:7} \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":${BRANCH} . @@ -128,6 +140,7 @@ function create_release_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":testing \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":testing-${BRANCH} . # Build the development image @@ -135,6 +148,7 @@ function create_release_containers { --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":testing \ + --build-arg "VCS_REF=${BUILDKITE_COMMIT}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":development-${BRANCH} . # If the env var for the git tag doesn't exist or is an empty string, then we @@ -144,6 +158,7 @@ function create_release_containers { docker build --target production \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":builder \ --cache-from="${CONTAINER_REPO}"/"${CONTAINER_APP}":production \ + --build-arg "VCS_REF=${BUILDKITE_TAG}" \ --tag "${CONTAINER_REPO}"/"${CONTAINER_APP}":${BUILDKITE_TAG} . fi diff --git a/uffizzi/Dockerfile b/uffizzi/Dockerfile index 7f5d6f91f..9bbf5c132 100644 --- a/uffizzi/Dockerfile +++ b/uffizzi/Dockerfile @@ -1,77 +1,124 @@ -FROM quay.io/forem/ruby:3.0.2 as base +FROM ghcr.io/forem/ruby:3.0.2@sha256:04c945460e5999c0483b119074597dba62b863f5f5ea3c98bff4169e0d2f990b as base FROM base as builder +# This is provided by BuildKit, but we'll provide a default in case Uffizi +# doesn't have that enabled by some chance. +ARG TARGETARCH=amd64 + USER root -RUN curl -sL https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo && \ - dnf install --setopt install_weak_deps=false -y \ - ImageMagick iproute jemalloc less libcurl libcurl-devel \ - libffi-devel libxml2-devel libxslt-devel nodejs pcre-devel \ - postgresql postgresql-devel tzdata yarn && \ - dnf -y clean all && \ - rm -rf /var/cache/yum +# pkg-config, +# libpixman-1-dev, +# libcairo2-dev, +# libpango1.0-dev +# +# are needed only on arm64: some nodejs dependency doesn't provide +# pre-built binaries for that arch, and so falls back to building +# from source, which then requires a few extra packages installed. +# +# Since we wipe out node_modules as part of this image after calling +# the bundler, we don't need these headers (or their sofile counterparts) +# in any of the other build stages. +RUN apt update && \ + apt install -y \ + build-essential \ + libcurl4-openssl-dev \ + libffi-dev \ + libxml2-dev \ + libxslt-dev \ + libpcre3-dev \ + libpq-dev \ + pkg-config \ + libpixman-1-dev \ + libcairo2-dev \ + libpango1.0-dev \ + && \ + apt clean + +ENV BUNDLER_VERSION=2.2.22 \ + BUNDLE_SILENCE_ROOT_WARNING=true \ + BUNDLE_SILENCE_DEPRECATIONS=true -ENV BUNDLER_VERSION=2.2.22 BUNDLE_SILENCE_ROOT_WARNING=true BUNDLE_SILENCE_DEPRECATIONS=true RUN gem install -N bundler:"${BUNDLER_VERSION}" ENV APP_USER=forem APP_UID=1000 APP_GID=1000 APP_HOME=/opt/apps/forem \ - LD_PRELOAD=/usr/lib64/libjemalloc.so.2 + LD_PRELOAD=libjemalloc.so.2 RUN mkdir -p ${APP_HOME} && chown "${APP_UID}":"${APP_GID}" "${APP_HOME}" && \ groupadd -g "${APP_GID}" "${APP_USER}" && \ - adduser -u "${APP_UID}" -g "${APP_GID}" -d "${APP_HOME}" "${APP_USER}" + adduser --uid "${APP_UID}" --gid "${APP_GID}" --home "${APP_HOME}" "${APP_USER}" -ENV DOCKERIZE_VERSION=v0.6.1 -RUN wget https://github.com/jwilder/dockerize/releases/download/"${DOCKERIZE_VERSION}"/dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ - && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ - && rm dockerize-linux-amd64-"${DOCKERIZE_VERSION}".tar.gz \ +ENV DOCKERIZE_VERSION=v0.7.0 +RUN curl -fsSLO https://github.com/jwilder/dockerize/releases/download/"${DOCKERIZE_VERSION}"/dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ + && tar -C /usr/local/bin -xzvf dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ + && rm dockerize-linux-${TARGETARCH}-"${DOCKERIZE_VERSION}".tar.gz \ && chown root:root /usr/local/bin/dockerize +USER "${APP_USER}" WORKDIR "${APP_HOME}" -COPY ./.ruby-version "${APP_HOME}"/ -COPY ./Gemfile ./Gemfile.lock "${APP_HOME}"/ -COPY ./vendor/cache "${APP_HOME}"/vendor/cache +COPY --chown=${APP_UID}:${APP_GID} ./.ruby-version "${APP_HOME}"/ +COPY --chown=${APP_UID}:${APP_GID} ./Gemfile ./Gemfile.lock "${APP_HOME}"/ +COPY --chown=${APP_UID}:${APP_GID} ./vendor/cache "${APP_HOME}"/vendor/cache -RUN bundle config --local build.sassc --disable-march-tune-native && \ - BUNDLE_WITHOUT="development:test" bundle install --deployment --jobs 4 --retry 5 && \ +# Have to reset APP_CONFIG, which appears to be set by upstream images, to +# avoid permission errors in the development/test images (which run bundle +# as a user and require write access to the config file for setting things +# like BUNDLE_WITHOUT (a value that is cached by root here in this builder +# layer, see https://michaelheap.com/bundler-ignoring-bundle-without/)) +ENV BUNDLE_APP_CONFIG="${APP_HOME}/.bundle" +RUN mkdir -p "${BUNDLE_APP_CONFIG}" && \ + touch "${BUNDLE_APP_CONFIG}/config" && \ + chown -R "${APP_UID}:${APP_GID}" "${BUNDLE_APP_CONFIG}" && \ + bundle config --local build.sassc --disable-march-tune-native && \ + bundle config --local without development:test && \ + BUNDLE_FROZEN=true bundle install --deployment --jobs 4 --retry 5 && \ find "${APP_HOME}"/vendor/bundle -name "*.c" -delete && \ find "${APP_HOME}"/vendor/bundle -name "*.o" -delete -COPY . "${APP_HOME}" +COPY --chown=${APP_UID}:${APP_GID} . "${APP_HOME}" RUN mkdir -p "${APP_HOME}"/public/{assets,images,packs,podcasts,uploads} -RUN NODE_ENV=production yarn install +# While it's relatively rare for bare metal builds to hit the default +# timeout, QEMU-based ones (as is the case with Docker BuildX for +# cross-compiling) quite often can. This increased timeout should help +# reduce false-negatives when building multiarch images. +RUN echo 'network-timeout 300000' >> ~/.yarnrc -RUN RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile +# This is one giant step now because previously, removing node_modules to save +# layer space was done in a later step, which is invalid in at least some +# Docker storage drivers (resulting in Directory Not Empty errors). +RUN NODE_ENV=production yarn install && \ + RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile && \ + rm -rf node_modules +# Unlike the main image (which is otherwise super close to identical to this +# one), we'll calculate VCS_REF inside the container build here. This isn't +# ideal (I'd love to leave .git in .dockerignore), but I'm not yet certain of +# how to pass "build args" to Uffizi. It may be the case that we'll want to +# block Uffizi on images being pushed to GHCR, and have Uffizi *only* pull +# already-built images, never build them itself. TBD. +COPY --chown="${APP_USER}":"${APP_USER}" .git/ "${APP_HOME}/.git" RUN echo $(date -u +'%Y-%m-%dT%H:%M:%SZ') >> "${APP_HOME}"/FOREM_BUILD_DATE && \ - echo $(git rev-parse --short HEAD) >> "${APP_HOME}"/FOREM_BUILD_SHA && \ - rm -rf "${APP_HOME}"/.git/ - -RUN rm -rf node_modules spec + echo $(git rev-parse --short HEAD) >> "${APP_HOME}"/FOREM_BUILD_SHA ## Development FROM builder AS development +USER "${APP_USER}" + COPY --chown="${APP_USER}":"${APP_USER}" ./spec "${APP_HOME}"/spec COPY --from=builder /usr/local/bin/dockerize /usr/local/bin/dockerize -RUN chown "${APP_USER}":"${APP_USER}" -R "${APP_HOME}" - -USER "${APP_USER}" - RUN bundle config --local build.sassc --disable-march-tune-native && \ bundle config --delete without && \ - bundle install --deployment --jobs 4 --retry 5 && \ + BUNDLE_FROZEN=true bundle install --deployment --jobs 4 --retry 5 && \ find "${APP_HOME}"/vendor/bundle -name "*.c" -delete && \ find "${APP_HOME}"/vendor/bundle -name "*.o" -delete -# Replcament for volume +# Replacement for volume COPY --from=builder --chown="${APP_USER}":"${APP_USER}" ${APP_HOME} ${APP_HOME} -# husky install / fatal: not a git repository (or any of the parent directories): .git -COPY --chown="${APP_USER}":"${APP_USER}" .git/ "${APP_HOME}/.git/" ## Bund install RUN ./scripts/bundle.sh ## Yarn install