From 44262e955005748c7eb0774caad8877b117fef15 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Wed, 29 Jan 2025 10:01:40 -0800 Subject: [PATCH] fix: eph env + improve docker images to run in userspace (#32017) --- .gitignore | 1 + Dockerfile | 71 +++++++++++++++++---------------- docker/docker-bootstrap.sh | 5 ++- docker/entrypoints/docker-ci.sh | 2 +- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 2652502a02639..67bc771f84c1a 100644 --- a/.gitignore +++ b/.gitignore @@ -124,3 +124,4 @@ docker/*local* # Jest test report test-report.html superset/static/stats/statistics.html +.aider* diff --git a/Dockerfile b/Dockerfile index 76983ae773cf7..e3577c67316ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,8 +76,7 @@ COPY superset-frontend /app/superset-frontend FROM superset-node-ci AS superset-node # Build the frontend if not in dev mode -RUN --mount=type=cache,target=/app/superset-frontend/.temp_cache \ - --mount=type=cache,target=/root/.npm \ +RUN --mount=type=cache,target=/root/.npm \ if [ "$DEV_MODE" = "false" ]; then \ echo "Running 'npm run ${BUILD_CMD}'"; \ npm run ${BUILD_CMD}; \ @@ -100,21 +99,14 @@ RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \ # Base python layer ###################################################################### FROM python:${PY_VER} AS python-base -ARG BUILD_TRANSLATIONS="false" # Include translations in the final build -ENV BUILD_TRANSLATIONS=${BUILD_TRANSLATIONS} -ARG DEV_MODE="false" # Skip frontend build in dev mode -ENV DEV_MODE=${DEV_MODE} - -ENV LANG=C.UTF-8 \ - LC_ALL=C.UTF-8 \ - SUPERSET_ENV=production \ - FLASK_APP="superset.app:create_app()" \ - PYTHONPATH="/app/pythonpath" \ - SUPERSET_HOME="/app/superset_home" \ - SUPERSET_PORT=8088 +ARG SUPERSET_HOME="/app/superset_home" +ENV SUPERSET_HOME=${SUPERSET_HOME} -RUN useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset +RUN mkdir -p $SUPERSET_HOME +RUN useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset \ + && chmod -R 1777 $SUPERSET_HOME \ + && chown -R superset:superset $SUPERSET_HOME # Some bash scripts needed throughout the layers COPY --chmod=755 docker/*.sh /app/docker/ @@ -125,19 +117,6 @@ RUN pip install --no-cache-dir --upgrade uv RUN uv venv /app/.venv ENV PATH="/app/.venv/bin:${PATH}" -# Install Playwright and optionally setup headless browsers -ARG INCLUDE_CHROMIUM="true" -ARG INCLUDE_FIREFOX="false" -RUN --mount=type=cache,target=/root/.cache/uv\ - if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \ - uv pip install playwright && \ - playwright install-deps && \ - if [ "$INCLUDE_CHROMIUM" = "true" ]; then playwright install chromium; fi && \ - if [ "$INCLUDE_FIREFOX" = "true" ]; then playwright install firefox; fi; \ - else \ - echo "Skipping browser installation"; \ - fi - ###################################################################### # Python translation compiler layer ###################################################################### @@ -159,13 +138,20 @@ RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \ # Python APP common layer ###################################################################### FROM python-base AS python-common + +ENV SUPERSET_HOME="/app/superset_home" \ + HOME="/app/superset_home" \ + SUPERSET_ENV="production" \ + FLASK_APP="superset.app:create_app()" \ + PYTHONPATH="/app/pythonpath" \ + SUPERSET_PORT="8088" + # Copy the entrypoints, make them executable in userspace COPY --chmod=755 docker/entrypoints /app/docker/entrypoints WORKDIR /app # Set up necessary directories and user RUN mkdir -p \ - ${SUPERSET_HOME} \ ${PYTHONPATH} \ superset/static \ requirements \ @@ -174,6 +160,19 @@ RUN mkdir -p \ requirements \ && touch superset/static/version_info.json +# Install Playwright and optionally setup headless browsers +ARG INCLUDE_CHROMIUM="true" +ARG INCLUDE_FIREFOX="false" +RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ + if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \ + uv pip install playwright && \ + playwright install-deps && \ + if [ "$INCLUDE_CHROMIUM" = "true" ]; then playwright install chromium; fi && \ + if [ "$INCLUDE_FIREFOX" = "true" ]; then playwright install firefox; fi; \ + else \ + echo "Skipping browser installation"; \ + fi + # Copy required files for Python build COPY pyproject.toml setup.py MANIFEST.in README.md ./ COPY superset-frontend/package.json superset-frontend/ @@ -214,12 +213,11 @@ FROM python-common AS lean # Install Python dependencies using docker/pip-install.sh COPY requirements/base.txt requirements/ -RUN --mount=type=cache,target=/root/.cache/uv \ +RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ /app/docker/pip-install.sh --requires-build-essential -r requirements/base.txt # Install the superset package -RUN --mount=type=cache,target=/root/.cache/uv \ +RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ uv pip install . - RUN python -m compileall /app/superset USER superset @@ -238,12 +236,13 @@ RUN /app/docker/apt-install.sh \ # Copy development requirements and install them COPY requirements/*.txt requirements/ # Install Python dependencies using docker/pip-install.sh -RUN --mount=type=cache,target=/root/.cache/uv \ +RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ /app/docker/pip-install.sh --requires-build-essential -r requirements/development.txt # Install the superset package -RUN --mount=type=cache,target=/root/.cache/uv \ +RUN --mount=type=cache,target=${SUPERSET_HOME}/.cache/uv \ uv pip install . +RUN uv pip install .[postgres] RUN python -m compileall /app/superset USER superset @@ -252,5 +251,7 @@ USER superset # CI image... ###################################################################### FROM lean AS ci - +USER root +RUN uv pip install .[postgres] +USER superset CMD ["/app/docker/entrypoints/docker-ci.sh"] diff --git a/docker/docker-bootstrap.sh b/docker/docker-bootstrap.sh index 5bcad1f4fea6d..ebaec6c963db6 100755 --- a/docker/docker-bootstrap.sh +++ b/docker/docker-bootstrap.sh @@ -20,7 +20,7 @@ set -eo pipefail # Make python interactive if [ "$DEV_MODE" == "true" ]; then - if command -v uv > /dev/null 2>&1; then + if [ "$(whoami)" = "root" ] && command -v uv > /dev/null 2>&1; then echo "Reinstalling the app in editable mode" uv pip install -e . fi @@ -34,7 +34,8 @@ if [ "$CYPRESS_CONFIG" == "true" ]; then export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress PORT=8081 fi -if [[ "$DATABASE_DIALECT" == postgres* ]] ; then +if [[ "$DATABASE_DIALECT" == postgres* ]] && [ "$(whoami)" = "root" ]; then + # older images may not have the postgres dev requirements installed echo "Installing postgres requirements" if command -v uv > /dev/null 2>&1; then # Use uv in newer images diff --git a/docker/entrypoints/docker-ci.sh b/docker/entrypoints/docker-ci.sh index 9e97cbbad493e..198933312a0f8 100755 --- a/docker/entrypoints/docker-ci.sh +++ b/docker/entrypoints/docker-ci.sh @@ -23,4 +23,4 @@ export SERVER_THREADS_AMOUNT=8 # start up the web server -/usr/bin/run-server.sh +/app/docker/entrypoints/run-server.sh