diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 34316a7e43e..d6b6434483f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,6 +40,7 @@ utilities/ @WordPress/openverse-maintainers .git-blame-ignore-revs @WordPress/openverse-maintainers .gitattributes @WordPress/openverse-maintainers .gitignore @WordPress/openverse-maintainers +.hadolint.yaml @WordPress/openverse-maintainers .pre-commit-config.yaml @WordPress/openverse-maintainers CONTRIBUTING.md @WordPress/openverse-maintainers LICENSE @WordPress/openverse-maintainers diff --git a/.hadolint.yaml b/.hadolint.yaml new file mode 100644 index 00000000000..e8130e547f1 --- /dev/null +++ b/.hadolint.yaml @@ -0,0 +1,6 @@ +ignored: + - DL3008 # pin versions in apt get install + - DL3013 # pin versions in pip + - DL3016 # pin versions in npm + - DL3018 # pin versions in apk add + - DL3041 # specify version in dnf install diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85811ef3a94..fc9a3865dd4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -160,3 +160,8 @@ repos: - id: renovate-config-validator args: - --strict + + - repo: https://github.com/hadolint/hadolint + rev: v2.12.0 + hooks: + - id: hadolint-docker diff --git a/api/Dockerfile b/api/Dockerfile index dcaa167439f..cbe67a82692 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -12,8 +12,17 @@ FROM docker.io/realies/audiowaveform:1.10.1 AS awf # Identify dependencies of the `audiowaveform` binary and move them to `/deps`, # while retaining their folder structure -RUN ldd /usr/local/bin/audiowaveform | tr -s '[:blank:]' '\n' | grep '^/' | \ - xargs -I % sh -c 'mkdir -p $(dirname deps%); cp % deps%;' + +# Enable pipefail before `RUN` that contains pipes +SHELL ["/bin/ash", "-eo", "pipefail", "-c"] + +# The script is intentionally single quoted below so that it is not +# expanded too eagerly and in the wrong context. +# hadolint ignore=SC2016 +RUN ldd /usr/local/bin/audiowaveform \ + | tr -s '[:blank:]' '\n' \ + | grep '^/' \ + | xargs -I % sh -c 'mkdir -p $(dirname deps%); cp % deps%;' ################## # Python builder # @@ -30,15 +39,18 @@ ENV PIP_NO_COLOR=1 # - Create a virtualenv inside `/venv` # - Install PDM to install Python dependencies RUN apt-get update \ - && apt-get install -y python3-dev \ + && apt-get install -yqq --no-install-recommends \ + python3-dev \ + && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* \ && pip install pdm~=2.14 # Copy subpackages from additional build-context 'packages' -COPY --from=packages openverse-attribution ./packages/python/openverse-attribution +# hadolint ignore=DL3022 +COPY --from=packages openverse-attribution /packages/python/openverse-attribution # Copy the Python project manifest and PDM lockfile into the container -COPY pyproject.toml pdm.lock ./ +COPY pyproject.toml pdm.lock / # Pass additional arguments when installing Python packages with PDM ARG PDM_INSTALL_ARGS='--no-editable' @@ -64,7 +76,7 @@ ENV PATH="/.venv/bin:$PATH" WORKDIR /api -ADD api/utils/fonts/SourceSansPro-Bold.ttf /usr/share/fonts/truetype/SourceSansPro-Bold.ttf +COPY api/utils/fonts/SourceSansPro-Bold.ttf /usr/share/fonts/truetype/SourceSansPro-Bold.ttf # Copy virtualenv from the builder image COPY --from=builder /.venv /.venv @@ -85,7 +97,11 @@ COPY --from=awf /usr/local/bin/audiowaveform /usr/local/bin # - libexempi8: required for watermarking # - Create directory for dumping API logs RUN apt-get update \ - && apt-get install -y curl libexempi8 postgresql-client \ + && apt-get install -yqq --no-install-recommends \ + curl \ + libexempi8 \ + postgresql-client \ + && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* \ && mkdir -p /var/log/openverse_api/openverse_api.log @@ -97,8 +113,11 @@ RUN useradd --create-home opener \ && chown -R opener /static USER opener -# Copy code into the final image +# Copy subpackages from additional build-context 'packages' +# hadolint ignore=DL3022 COPY --chown=opener --from=packages openverse-attribution /packages/python/openverse-attribution/ + +# Copy code into the final image COPY --chown=opener . /api/ # Collect static assets, these are used by the next stage, `nginx` diff --git a/catalog/Dockerfile b/catalog/Dockerfile index 7a164fd52b3..b29aa207cbf 100644 --- a/catalog/Dockerfile +++ b/catalog/Dockerfile @@ -40,7 +40,7 @@ ENV AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER=s3://openverse-airflow-logs USER root RUN apt-get update \ - && apt-get -yqq install \ + && apt-get install -yqq --no-install-recommends \ build-essential \ libpq-dev \ libffi-dev \ diff --git a/docker/dev_env/Dockerfile b/docker/dev_env/Dockerfile index 6548619451b..f324d13c72a 100644 --- a/docker/dev_env/Dockerfile +++ b/docker/dev_env/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/fedora:latest +FROM docker.io/library/fedora:40 # We want to keep all important things in `/opt` as we will preserve the # `/opt` directory as a volume. @@ -50,6 +50,7 @@ RUN dnf -y install dnf-plugins-core \ nodejs npm \ python3.12 pipx \ docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \ + && dnf clean all \ && pipx install \ httpie \ pdm pipenv \ diff --git a/docker/upstream_db/Dockerfile b/docker/upstream_db/Dockerfile index 5097bd6601d..85e0d603387 100644 --- a/docker/upstream_db/Dockerfile +++ b/docker/upstream_db/Dockerfile @@ -15,7 +15,7 @@ ENV PIP_NO_COLOR=1 RUN echo "\set ON_ERROR_STOP on" >> /root/.psqlrc RUN apt-get update \ - && apt-get -yqq install \ + && apt-get install -yqq --no-install-recommends \ python3-boto3 \ postgresql-plpython3-13 \ python3-pip \ diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 0bcecf68561..8863b45a6d4 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -22,7 +22,9 @@ WORKDIR /home/node/ # Copy monorepo mocking files into `/home/node`, which pretends to be the monorepo root. # Note: these files must be manually un-ignored in the root .dockerignore +# hadolint ignore=DL3022 COPY --from=repo_root --chown=node:node .npmrc .pnpmfile.cjs pnpm-lock.yaml tsconfig.base.json ./ + RUN echo '{"packages":["frontend/"]}' > pnpm-workspace.yaml # Copy the `frontend/` directory into `/home/node/frontend`, as a package in the monorepo. diff --git a/frontend/Dockerfile.playwright b/frontend/Dockerfile.playwright index 615097955d1..4142abf833c 100644 --- a/frontend/Dockerfile.playwright +++ b/frontend/Dockerfile.playwright @@ -6,7 +6,7 @@ FROM mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-jammy ARG PACKAGE_MANAGER -COPY package.json . +COPY package.json / # Requires `packageManager` field to be present in `frontend/package.json`. RUN npm install -g $PACKAGE_MANAGER diff --git a/indexer_worker/Dockerfile b/indexer_worker/Dockerfile index 8f23685c453..e2c7465a681 100644 --- a/indexer_worker/Dockerfile +++ b/indexer_worker/Dockerfile @@ -17,12 +17,14 @@ ENV PIP_NO_COLOR=1 # - Install system packages needed for building Python dependencies # - Install PDM to install Python dependencies RUN apt-get update \ - && apt-get install -y python3-dev \ - && rm -rf /var/lib/apt/lists/* \ + && apt-get install -yqq --no-install-recommends \ + python3-dev \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ && pip install pdm~=2.14 # Copy the Pipenv files into the container -COPY pyproject.toml pdm.lock ./ +COPY pyproject.toml pdm.lock / # Pass additional arguments when installing Python packages with PDM ARG PDM_INSTALL_ARGS='--no-editable' @@ -59,13 +61,17 @@ COPY --from=builder /.venv /.venv # - libpq-dev: required by `psycopg2` # - Create directory for holding worker state RUN apt-get update \ - && apt-get install -y curl libpq-dev \ - && rm -rf /var/lib/apt/lists/* \ - && mkdir /worker_state + && apt-get install -yqq --no-install-recommends \ + curl \ + libpq-dev \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir /worker_state # Create a non-root user -RUN useradd ingestionu -RUN chown ingestionu /worker_state +RUN useradd ingestionu \ + && chown ingestionu /worker_state + USER ingestionu # Copy code into the final image diff --git a/ingestion_server/Dockerfile b/ingestion_server/Dockerfile index 8a876c3e2e0..9d390a0e8cd 100644 --- a/ingestion_server/Dockerfile +++ b/ingestion_server/Dockerfile @@ -21,13 +21,15 @@ ENV PATH="/venv/bin:$PATH" # - Create a virtualenv inside `/venv` # - Install Pipenv to install Python dependencies RUN apt-get update \ - && apt-get install -y python3-dev \ - && rm -rf /var/lib/apt/lists/* \ + && apt-get install -yqq --no-install-recommends \ + python3-dev \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ && python -m venv /venv \ && pip install --upgrade pipenv # Copy the Pipenv files into the container -COPY Pipfile Pipfile.lock ./ +COPY Pipfile Pipfile.lock / # Install Python dependencies system-wide (uses the active virtualenv) RUN pipenv install --system --deploy --dev @@ -61,13 +63,17 @@ COPY --from=builder /venv /venv # - libpq-dev: required by `psycopg2` # - Create directory for holding worker state RUN apt-get update \ - && apt-get install -y curl libpq-dev \ - && rm -rf /var/lib/apt/lists/* \ - && mkdir /worker_state + && apt-get install -yqq --no-install-recommends \ + curl \ + libpq-dev \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir /worker_state # Create a non-root user -RUN useradd ingestionu -RUN chown ingestionu /worker_state +RUN useradd ingestionu \ + && chown ingestionu /worker_state + USER ingestionu # Copy code into the final image diff --git a/utilities/load_testing/Dockerfile b/utilities/load_testing/Dockerfile index 62a0870871d..ab1605b83a4 100644 --- a/utilities/load_testing/Dockerfile +++ b/utilities/load_testing/Dockerfile @@ -4,7 +4,7 @@ # K6 # ###### -FROM docker.io/grafana/k6:latest as k6 +FROM docker.io/grafana/k6:v0.51.0 as k6 ############### # Observation # @@ -22,7 +22,10 @@ COPY --from=k6 /usr/bin/k6 /usr/bin/k6 # - apache2-utils: Apache HTTP server benchmarking tool `ab` # - gnupg2: TODO why? RUN apt-get update \ - && apt-get install -y wamerican apache2-utils gnupg2 \ + && apt-get install -yqq --no-install-recommends \ + wamerican \ + apache2-utils gnupg2 \ + && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* WORKDIR /app