Skip to content

Commit

Permalink
feat: allow docker image use for non-root users
Browse files Browse the repository at this point in the history
The Dockerfile has been updated to install the `phylum` package in a
Python virtual environment, which is accessible by non-root users of the
image. The `phylum-init` script was updated to provide a hidden option
for installing the CLI in a globally accessible directory. That option
is meant to be used in very limited circumstances, namely the Dockerfile
for image creation.

Closes #118
  • Loading branch information
maxrake committed Sep 13, 2022
1 parent bdcd78e commit 8147881
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
34 changes: 19 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ ARG PKG_NAME
ENV APP_PATH="/app"
ENV POETRY_VENV="${APP_PATH}/.venv"
ENV POETRY_PATH="${POETRY_VENV}/bin/poetry"
ENV PHYLUM_VENV="/opt/venv"
ENV PHYLUM_VENV_PIP="${PHYLUM_VENV}/bin/pip"
ENV PIP_NO_COMPILE=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

WORKDIR ${APP_PATH}

RUN pip install --no-cache-dir --upgrade pip setuptools
RUN set -eux; \
python -m venv ${PHYLUM_VENV}; \
${PHYLUM_VENV_PIP} install --no-cache-dir --upgrade pip setuptools
RUN set -eux; \
python -m venv ${POETRY_VENV}; \
${POETRY_VENV}/bin/pip install --no-cache-dir --upgrade pip setuptools; \
Expand All @@ -81,19 +85,19 @@ RUN set -eux; \
COPY pyproject.toml poetry.lock ./
RUN ${POETRY_PATH} export --without-hashes --format requirements.txt --output requirements.txt

# Cache the pip installed dependencies
# Cache the pip installed dependencies for faster builds when iterating locally.
# NOTE: This `--mount` feature requires BUILDKIT to be used
RUN --mount=type=cache,id=pip,target=/root/.cache/pip \
set -eux; \
pip cache info; \
pip cache list; \
pip install --user -r requirements.txt
${PHYLUM_VENV_PIP} cache info; \
${PHYLUM_VENV_PIP} cache list; \
${PHYLUM_VENV_PIP} install -r requirements.txt
COPY "${PKG_SRC:-.}" .
RUN pip install --user --no-cache-dir ${PKG_NAME:-.}
RUN find /root/.local -type f -name '*.pyc' -delete
RUN ${PHYLUM_VENV_PIP} install --no-cache-dir ${PKG_NAME:-.}
RUN find ${PHYLUM_VENV} -type f -name '*.pyc' -delete

# Place in a directory included in the final layer and also known to be part of the $PATH
COPY entrypoint.sh /root/.local/bin/
COPY entrypoint.sh ${PHYLUM_VENV}/bin/

FROM python:3.10-slim-bullseye

Expand All @@ -105,19 +109,19 @@ ARG CLI_VER
LABEL maintainer="Phylum, Inc. <engineering@phylum.io>"
LABEL org.opencontainers.image.source="https://github.com/phylum-dev/phylum-ci"

# Copy only Python packages to limit the image size
COPY --from=builder /root/.local /root/.local
ENV PHYLUM_VENV="/opt/venv"
ENV PATH=${PHYLUM_VENV}/bin:$PATH
ENV PYTHONDONTWRITEBYTECODE=1

ENV PATH=/root/.local/bin:$PATH \
PYTHONPATH=/root/.local/lib/python3.10/site-packages \
PYTHONDONTWRITEBYTECODE=1
# Copy only Python packages to limit the image size
COPY --from=builder ${PHYLUM_VENV} ${PHYLUM_VENV}

RUN set -eux; \
apt-get update; \
apt-get upgrade --yes; \
apt-get install --yes --no-install-recommends git; \
chmod +x /root/.local/bin/entrypoint.sh; \
phylum-init --phylum-release ${CLI_VER:-latest}; \
chmod +x ${PHYLUM_VENV}/bin/entrypoint.sh; \
phylum-init --phylum-release ${CLI_VER:-latest} --global-install; \
apt-get purge --yes --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \
find / -type f -name '*.pyc' -delete
Expand Down
21 changes: 19 additions & 2 deletions src/phylum/init/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ def get_args(args=None):
default=get_target_triple(),
help="The target platform type where the CLI will be installed.",
)
parser.add_argument(
"-g",
"--global-install",
action="store_true",
# Specify this flag to install the Phylum CLI to a globally accessible directory.
# NOTE: This option is hidden from help output b/c it is meant to be used internally, for Docker image creation.
help=argparse.SUPPRESS,
)
parser.add_argument(
"-k",
"--phylum-token",
Expand Down Expand Up @@ -365,7 +373,6 @@ def main(args=None):
minisig_name = f"{archive_name}.minisig"
archive_url = get_archive_url(tag_name, archive_name)
minisig_url = f"{archive_url}.minisig"
phylum_bin_path = get_expected_phylum_bin_path()

with tempfile.TemporaryDirectory() as temp_dir:
temp_dir_path = pathlib.Path(temp_dir)
Expand All @@ -383,12 +390,22 @@ def main(args=None):
extracted_dir = temp_dir_path / f"phylum-{target_triple}"
zip_file.extractall(path=temp_dir)

cmd = "sh install.sh".split()
# This may look wrong, but a decision was made to manually handle global installs
# in the places it is required instead of updating the CLI's install script.
# Reference: https://github.com/phylum-dev/cli/pull/671
if args.global_install:
# Current assumptions for this method:
# * the /usr/local/bin directory exists, has proper permissions, is on the PATH for all users
# * the install is on a system with glibc
cmd = "install -m 0755 phylum /usr/local/bin/phylum".split()
else:
cmd = "sh install.sh".split()
subprocess.run(cmd, check=True, cwd=extracted_dir)

process_token_option(args)

# Check to ensure everything is working
phylum_bin_path, _ = get_phylum_bin_path()
cmd = f"{phylum_bin_path} --help".split()
subprocess.run(cmd, check=True)

Expand Down

0 comments on commit 8147881

Please sign in to comment.