Skip to content

Commit

Permalink
Dockerfile: create "dependabot" user
Browse files Browse the repository at this point in the history
Previously the `Dockerfile` would install dependencies as the root user,
then a subsequent `Dockerfile` would create and delegate to a
`dependabot` user.

Chowning files in a downstream layer is expensive and slow!

Let's encourage the best practice of non-root containers by creating
`dependabot` directly in the `Dockerfile`.

Co-authored-by: Pete Wagner <thepwagner@github.com>
  • Loading branch information
2 people authored and feelepxyz committed Apr 12, 2021
1 parent b0416b0 commit 89e6f47
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 228 deletions.
118 changes: 0 additions & 118 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,126 +85,8 @@ jobs:
- name: Run ${{ matrix.suite.name }} tests
run: |
docker run \
-v "$(pwd)/.rubocop.yml:$CODE_DIR/.rubocop.yml" \
-v "$(pwd)/bin:$CODE_DIR/bin" \
-v "$(pwd)/common/.rubocop.yml:$CODE_DIR/common/.rubocop.yml" \
-v "$(pwd)/common/Gemfile:$CODE_DIR/common/Gemfile" \
-v "$(pwd)/common/dependabot-common.gemspec:$CODE_DIR/common/dependabot-common.gemspec" \
-v "$(pwd)/common/bin:$CODE_DIR/common/bin" \
-v "$(pwd)/common/lib:$CODE_DIR/common/lib" \
-v "$(pwd)/common/spec:$CODE_DIR/common/spec" \
-v "$(pwd)/common/script:$CODE_DIR/common/script" \
-v "$(pwd)/terraform/.rubocop.yml:$CODE_DIR/terraform/.rubocop.yml" \
-v "$(pwd)/terraform/Gemfile:$CODE_DIR/terraform/Gemfile" \
-v "$(pwd)/terraform/dependabot-terraform.gemspec:$CODE_DIR/terraform/dependabot-terraform.gemspec" \
-v "$(pwd)/terraform/lib:$CODE_DIR/terraform/lib" \
-v "$(pwd)/terraform/spec:$CODE_DIR/terraform/spec" \
-v "$(pwd)/terraform/script:$CODE_DIR/terraform/script" \
-v "$(pwd)/elm/.rubocop.yml:$CODE_DIR/elm/.rubocop.yml" \
-v "$(pwd)/elm/Gemfile:$CODE_DIR/elm/Gemfile" \
-v "$(pwd)/elm/dependabot-elm.gemspec:$CODE_DIR/elm/dependabot-elm.gemspec" \
-v "$(pwd)/elm/lib:$CODE_DIR/elm/lib" \
-v "$(pwd)/elm/spec:$CODE_DIR/elm/spec" \
-v "$(pwd)/elm/script:$CODE_DIR/elm/script" \
-v "$(pwd)/docker/.rubocop.yml:$CODE_DIR/docker/.rubocop.yml" \
-v "$(pwd)/docker/Gemfile:$CODE_DIR/docker/Gemfile" \
-v "$(pwd)/docker/dependabot-docker.gemspec:$CODE_DIR/docker/dependabot-docker.gemspec" \
-v "$(pwd)/docker/lib:$CODE_DIR/docker/lib" \
-v "$(pwd)/docker/spec:$CODE_DIR/docker/spec" \
-v "$(pwd)/docker/script:$CODE_DIR/docker/script" \
-v "$(pwd)/git_submodules/.rubocop.yml:$CODE_DIR/git_submodules/.rubocop.yml" \
-v "$(pwd)/git_submodules/Gemfile:$CODE_DIR/git_submodules/Gemfile" \
-v "$(pwd)/git_submodules/dependabot-git_submodules.gemspec:$CODE_DIR/git_submodules/dependabot-core.gemspec" \
-v "$(pwd)/git_submodules/lib:$CODE_DIR/git_submodules/lib" \
-v "$(pwd)/git_submodules/spec:$CODE_DIR/git_submodules/spec" \
-v "$(pwd)/git_submodules/script:$CODE_DIR/git_submodules/script" \
-v "$(pwd)/github_actions/.rubocop.yml:$CODE_DIR/github_actions/.rubocop.yml" \
-v "$(pwd)/github_actions/Gemfile:$CODE_DIR/github_actions/Gemfile" \
-v "$(pwd)/github_actions/dependabot-github_actions.gemspec:$CODE_DIR/github_actions/dependabot-core.gemspec" \
-v "$(pwd)/github_actions/lib:$CODE_DIR/github_actions/lib" \
-v "$(pwd)/github_actions/spec:$CODE_DIR/github_actions/spec" \
-v "$(pwd)/github_actions/script:$CODE_DIR/github_actions/script" \
-v "$(pwd)/python/.rubocop.yml:$CODE_DIR/python/.rubocop.yml" \
-v "$(pwd)/python/Gemfile:$CODE_DIR/python/Gemfile" \
-v "$(pwd)/python/dependabot-python.gemspec:$CODE_DIR/python/dependabot-python.gemspec" \
-v "$(pwd)/python/helpers:/opt/python" \
-v "$(pwd)/python/helpers:/opt/python/helpers" \
-v "$(pwd)/python/lib:$CODE_DIR/python/lib" \
-v "$(pwd)/python/spec:$CODE_DIR/python/spec" \
-v "$(pwd)/python/script:$CODE_DIR/python/script" \
-v "$(pwd)/nuget/.rubocop.yml:$CODE_DIR/nuget/.rubocop.yml" \
-v "$(pwd)/nuget/Gemfile:$CODE_DIR/nuget/Gemfile" \
-v "$(pwd)/nuget/dependabot-nuget.gemspec:$CODE_DIR/nuget/dependabot-core.gemspec" \
-v "$(pwd)/nuget/lib:$CODE_DIR/nuget/lib" \
-v "$(pwd)/nuget/spec:$CODE_DIR/nuget/spec" \
-v "$(pwd)/nuget/script:$CODE_DIR/nuget/script" \
-v "$(pwd)/maven/.rubocop.yml:$CODE_DIR/maven/.rubocop.yml" \
-v "$(pwd)/maven/Gemfile:$CODE_DIR/maven/Gemfile" \
-v "$(pwd)/maven/dependabot-maven.gemspec:$CODE_DIR/maven/dependabot-core.gemspec" \
-v "$(pwd)/maven/lib:$CODE_DIR/maven/lib" \
-v "$(pwd)/maven/spec:$CODE_DIR/maven/spec" \
-v "$(pwd)/maven/script:$CODE_DIR/maven/script" \
-v "$(pwd)/gradle/.rubocop.yml:$CODE_DIR/gradle/.rubocop.yml" \
-v "$(pwd)/gradle/Gemfile:$CODE_DIR/gradle/Gemfile" \
-v "$(pwd)/gradle/dependabot-gradle.gemspec:$CODE_DIR/gradle/dependabot-gradle.gemspec" \
-v "$(pwd)/gradle/lib:$CODE_DIR/gradle/lib" \
-v "$(pwd)/gradle/spec:$CODE_DIR/gradle/spec" \
-v "$(pwd)/gradle/script:$CODE_DIR/gradle/script" \
-v "$(pwd)/hex/.rubocop.yml:$CODE_DIR/hex/.rubocop.yml" \
-v "$(pwd)/hex/Gemfile:$CODE_DIR/hex/Gemfile" \
-v "$(pwd)/hex/dependabot-hex.gemspec:$CODE_DIR/hex/dependabot-hex.gemspec" \
-v "$(pwd)/hex/lib:$CODE_DIR/hex/lib" \
-v "$(pwd)/hex/spec:$CODE_DIR/hex/spec" \
-v "$(pwd)/hex/script:$CODE_DIR/hex/script" \
-v "$(pwd)/cargo/.rubocop.yml:$CODE_DIR/cargo/.rubocop.yml" \
-v "$(pwd)/cargo/Gemfile:$CODE_DIR/cargo/Gemfile" \
-v "$(pwd)/cargo/dependabot-cargo.gemspec:$CODE_DIR/cargo/dependabot-core.gemspec" \
-v "$(pwd)/cargo/lib:$CODE_DIR/cargo/lib" \
-v "$(pwd)/cargo/spec:$CODE_DIR/cargo/spec" \
-v "$(pwd)/cargo/script:$CODE_DIR/cargo/script" \
-v "$(pwd)/dep/.rubocop.yml:$CODE_DIR/dep/.rubocop.yml" \
-v "$(pwd)/dep/Gemfile:$CODE_DIR/dep/Gemfile" \
-v "$(pwd)/dep/dependabot-dep.gemspec:$CODE_DIR/dep/dependabot-dep.gemspec" \
-v "$(pwd)/dep/lib:$CODE_DIR/dep/lib" \
-v "$(pwd)/dep/spec:$CODE_DIR/dep/spec" \
-v "$(pwd)/dep/script:$CODE_DIR/dep/script" \
-v "$(pwd)/go_modules/.rubocop.yml:$CODE_DIR/go_modules/.rubocop.yml" \
-v "$(pwd)/go_modules/Gemfile:$CODE_DIR/go_modules/Gemfile" \
-v "$(pwd)/go_modules/dependabot-go_modules.gemspec:$CODE_DIR/go_modules/dependabot-go_modules.gemspec" \
-v "$(pwd)/go_modules/lib:$CODE_DIR/go_modules/lib" \
-v "$(pwd)/go_modules/spec:$CODE_DIR/go_modules/spec" \
-v "$(pwd)/go_modules/script:$CODE_DIR/go_modules/script" \
-v "$(pwd)/npm_and_yarn/.rubocop.yml:$CODE_DIR/npm_and_yarn/.rubocop.yml" \
-v "$(pwd)/npm_and_yarn/Gemfile:$CODE_DIR/npm_and_yarn/Gemfile" \
-v "$(pwd)/npm_and_yarn/dependabot-npm_and_yarn.gemspec:$CODE_DIR/npm_and_yarn/dependabot-npm_and_yarn.gemspec" \
-v "$(pwd)/npm_and_yarn/lib:$CODE_DIR/npm_and_yarn/lib" \
-v "$(pwd)/npm_and_yarn/spec:$CODE_DIR/npm_and_yarn/spec" \
-v "$(pwd)/npm_and_yarn/script:$CODE_DIR/npm_and_yarn/script" \
-v "$(pwd)/composer/.rubocop.yml:$CODE_DIR/composer/.rubocop.yml" \
-v "$(pwd)/composer/Gemfile:$CODE_DIR/composer/Gemfile" \
-v "$(pwd)/composer/dependabot-composer.gemspec:$CODE_DIR/composer/dependabot-composer.gemspec" \
-v "$(pwd)/composer/lib:$CODE_DIR/composer/lib" \
-v "$(pwd)/composer/spec:$CODE_DIR/composer/spec" \
-v "$(pwd)/composer/script:$CODE_DIR/composer/script" \
-v "$(pwd)/bundler/.rubocop.yml:$CODE_DIR/bundler/.rubocop.yml" \
-v "$(pwd)/bundler/Gemfile:$CODE_DIR/bundler/Gemfile" \
-v "$(pwd)/bundler/dependabot-bundler.gemspec:$CODE_DIR/bundler/dependabot-bundler.gemspec" \
-v "$(pwd)/bundler/lib:$CODE_DIR/bundler/lib" \
-v "$(pwd)/bundler/helpers:$CODE_DIR/bundler/helpers" \
-v "$(pwd)/bundler/spec:$CODE_DIR/bundler/spec" \
-v "$(pwd)/bundler/helpers:/opt/bundler" \
-v "$(pwd)/bundler/helpers:/opt/bundler/helpers" \
-v "$(pwd)/bundler/script:$CODE_DIR/bundler/script" \
-v "$(pwd)/omnibus/.rubocop.yml:$CODE_DIR/omnibus/.rubocop.yml" \
-v "$(pwd)/omnibus/Gemfile:$CODE_DIR/omnibus/Gemfile" \
-v "$(pwd)/omnibus/dependabot-omnibus.gemspec:$CODE_DIR/omnibus/dependabot-omnibus.gemspec" \
-v "$(pwd)/omnibus/lib:$CODE_DIR/omnibus/lib" \
-v "$(pwd)/omnibus/spec:$CODE_DIR/omnibus/spec" \
-v "$(pwd)/omnibus/script:$CODE_DIR/omnibus/script" \
--env "CI=true" \
--env "DEPENDABOT_TEST_ACCESS_TOKEN=${{ secrets.GITHUB_TOKEN }}" \
--env "SUITE_NAME=${{ matrix.suite.name }}" \
--env "BUNDLE_PATH=/home/dependabot/.bundle" \
-w "$CODE_DIR" \
--rm "$CORE_CI_IMAGE" bash -c \
"cd /home/dependabot/dependabot-core/${{ matrix.suite.path }} && ./script/ci-test"
85 changes: 55 additions & 30 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ RUN apt-get update \
python3-enchant \
&& locale-gen en_US.UTF-8

ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN GROUP_NAME=$(getent group $USER_GID | awk -F':' '{print $1}') \
&& if [ -z $GROUP_NAME ]; then groupadd --gid $USER_GID dependabot ; \
else groupmod -n dependabot $GROUP_NAME ; fi \
&& useradd --uid "${USER_UID}" --gid "${USER_GID}" -m dependabot \
&& mkdir -p /opt && chown dependabot:dependabot /opt


### RUBY

Expand All @@ -60,19 +69,23 @@ RUN apt-add-repository ppa:brightbox/ruby-ng \
&& apt-get install -y ruby2.6 ruby2.6-dev \
&& gem update --system 3.2.14 \
&& gem install bundler -v 1.17.3 --no-document \
&& gem install bundler -v 2.2.15 --no-document
&& gem install bundler -v 2.2.15 --no-document \
&& rm -Rf /var/lib/gems/2.6.0/cache/*


### PYTHON

# Install Python 2.7 and 3.9 with pyenv. Using pyenv lets us support multiple Pythons
ENV PYENV_ROOT=/usr/local/.pyenv \
PATH="/usr/local/.pyenv/bin:$PATH"
RUN mkdir -p "$PYENV_ROOT" && chown dependabot:dependabot "$PYENV_ROOT"
USER dependabot
RUN git clone https://github.com/pyenv/pyenv.git /usr/local/.pyenv \
&& cd /usr/local/.pyenv && git checkout 1.2.26 && cd - \
&& pyenv install 3.9.4 \
&& pyenv install 2.7.18 \
&& pyenv global 3.9.4
USER root


### JAVASCRIPT
Expand Down Expand Up @@ -140,14 +153,17 @@ RUN add-apt-repository ppa:ondrej/php \
# Install Go and dep
ARG GOLANG_VERSION=1.16.2
ARG GOLANG_CHECKSUM=542e936b19542e62679766194364f45141fde55169db2d8d01046555ca9eb4b8
RUN curl --http1.1 -o go.tar.gz https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz \
ENV PATH=/opt/go/bin:$PATH \
GOPATH=/opt/go/gopath
RUN cd /tmp \
&& curl --http1.1 -o go.tar.gz https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz \
&& echo "$GOLANG_CHECKSUM go.tar.gz" | sha256sum -c - \
&& tar -xzf go.tar.gz -C /opt \
&& mkdir /opt/go/gopath \
&& rm go.tar.gz \
&& mkdir "$GOPATH" \
&& chown dependabot:dependabot "$GOPATH" \
&& wget -O /opt/go/bin/dep https://github.com/golang/dep/releases/download/v0.5.4/dep-linux-amd64 \
&& chmod +x /opt/go/bin/dep \
&& rm go.tar.gz
ENV PATH=/opt/go/bin:$PATH GOPATH=/opt/go/gopath
&& chmod +x /opt/go/bin/dep


### ELIXIR
Expand All @@ -172,33 +188,42 @@ RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb \

# Install Rust 1.51.0
ENV RUSTUP_HOME=/opt/rust \
CARGO_HOME=/opt/rust \
PATH="${PATH}:/opt/rust/bin"
RUN export CARGO_HOME=/opt/rust ; curl https://sh.rustup.rs -sSf | sh -s -- -y
RUN export CARGO_HOME=/opt/rust ; rustup toolchain install 1.51.0 && rustup default 1.51.0


### NEW NATIVE HELPERS

COPY composer/helpers /opt/composer/helpers
COPY dep/helpers /opt/dep/helpers
COPY bundler/helpers /opt/bundler/helpers
COPY go_modules/helpers /opt/go_modules/helpers
COPY hex/helpers /opt/hex/helpers
COPY npm_and_yarn/helpers /opt/npm_and_yarn/helpers
COPY python/helpers /opt/python/helpers
COPY terraform/helpers /opt/terraform/helpers
RUN mkdir -p "$RUSTUP_HOME" && chown dependabot:dependabot "$RUSTUP_HOME"
USER dependabot
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y \
&& rustup toolchain install 1.51.0 && rustup default 1.51.0
USER root

COPY --chown=dependabot:dependabot composer/helpers /opt/composer/helpers
COPY --chown=dependabot:dependabot dep/helpers /opt/dep/helpers
COPY --chown=dependabot:dependabot bundler/helpers /opt/bundler/helpers
COPY --chown=dependabot:dependabot go_modules/helpers /opt/go_modules/helpers
COPY --chown=dependabot:dependabot hex/helpers /opt/hex/helpers
COPY --chown=dependabot:dependabot npm_and_yarn/helpers /opt/npm_and_yarn/helpers
COPY --chown=dependabot:dependabot python/helpers /opt/python/helpers
COPY --chown=dependabot:dependabot terraform/helpers /opt/terraform/helpers

ENV DEPENDABOT_NATIVE_HELPERS_PATH="/opt" \
PATH="$PATH:/opt/terraform/bin:/opt/python/bin:/opt/go_modules/bin:/opt/dep/bin" \
MIX_HOME="/opt/hex/mix"

RUN bash /opt/terraform/helpers/build /opt/terraform && \
bash /opt/python/helpers/build /opt/python && \
bash /opt/dep/helpers/build /opt/dep && \
mkdir -p /opt/bundler/v1 && bash /opt/bundler/helpers/v1/build /opt/bundler/v1 && \
mkdir -p /opt/bundler/v2 && bash /opt/bundler/helpers/v2/build /opt/bundler/v2 && \
bash /opt/go_modules/helpers/build /opt/go_modules && \
bash /opt/npm_and_yarn/helpers/build /opt/npm_and_yarn && \
bash /opt/hex/helpers/build /opt/hex && \
bash /opt/composer/helpers/v2/build /opt/composer/v2 && \
bash /opt/composer/helpers/v1/build /opt/composer/v1
USER dependabot
RUN mkdir -p /opt/bundler/v1 \
&& mkdir -p /opt/bundler/v2 \
&& bash /opt/bundler/helpers/v1/build /opt/bundler/v1 \
&& bash /opt/bundler/helpers/v2/build /opt/bundler/v2 \
&& bash /opt/dep/helpers/build /opt/dep \
&& bash /opt/go_modules/helpers/build /opt/go_modules \
&& bash /opt/hex/helpers/build /opt/hex \
&& bash /opt/npm_and_yarn/helpers/build /opt/npm_and_yarn \
&& bash /opt/python/helpers/build /opt/python \
&& bash /opt/terraform/helpers/build /opt/terraform \
&& bash /opt/composer/helpers/v1/build /opt/composer/v1 \
&& bash /opt/composer/helpers/v2/build /opt/composer/v2

# Allow further gem installs as the dependabot user
ENV BUNDLE_PATH="/home/dependabot/.bundle" \
BUNDLE_BIN=".bundle/bin" \
PATH=".bundle/bin:$PATH:/home/dependabot/.bundle/bin"
12 changes: 8 additions & 4 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ FROM dependabot/dependabot-core
# We pre-install these versions of python as they're known to be used in the
# test suite. These used to be installed in-line, and pre-installing them helps
# with the performance of the python test suite.
RUN pyenv install -s 3.6.13
RUN pyenv install -s 3.7.1
RUN pyenv install -s 3.7.10
RUN pyenv install -s 3.6.13 \
&& pyenv install -s 3.7.1 \
&& pyenv install -s 3.7.10 \
&& git config --global user.name dependabot-ci \
&& git config --global user.email no-reply@github.com

RUN git config --global user.name dependabot-ci && git config --global user.email no-reply@github.com
ARG CODE_DIR=/home/dependabot/dependabot-core
WORKDIR ${CODE_DIR}
COPY --chown=dependabot:dependabot . ${CODE_DIR}
Loading

0 comments on commit 89e6f47

Please sign in to comment.