Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: docker refactor #31385

Merged
merged 42 commits into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
af54c21
fix: docker-compose up ModuleNotFoundError: {...} superset
mistercrunch Dec 10, 2024
9d9fef1
rm uv
mistercrunch Dec 10, 2024
cb04472
rm --system
mistercrunch Dec 10, 2024
842e1ba
fix: simplify dockerfile with chown/chmod right before USER superset …
mistercrunch Dec 10, 2024
93f0761
bring uv back
mistercrunch Dec 10, 2024
08b048c
conditional playwright
mistercrunch Dec 10, 2024
6c42edf
kill FF install in favor of playwright
mistercrunch Dec 10, 2024
2a8f4f0
mv script from /usr/bin to /app/docker/run-server.sh
mistercrunch Dec 11, 2024
f55203f
/usr/bin
mistercrunch Dec 11, 2024
33ca069
usr.bin
mistercrunch Dec 11, 2024
f38af7b
more specific about venv location
mistercrunch Dec 11, 2024
e505d5c
move headless browsers up
mistercrunch Dec 11, 2024
9563d9b
login, why not?
mistercrunch Dec 11, 2024
3cf8fb7
fix pkg_resources
mistercrunch Dec 11, 2024
b3a1bd1
copy .env file
mistercrunch Dec 11, 2024
442e161
only sh files
mistercrunch Dec 11, 2024
d7e35b2
reinstall
mistercrunch Dec 11, 2024
cd1869e
dev mode uv install
mistercrunch Dec 11, 2024
6ea9994
fixin'
mistercrunch Dec 11, 2024
078f0a1
run -e . on startup
mistercrunch Dec 11, 2024
fbf2de1
volume back
mistercrunch Dec 11, 2024
9b7bf6a
splitting layers
mistercrunch Dec 11, 2024
728c3d9
750
mistercrunch Dec 11, 2024
4be6cff
reordering
mistercrunch Dec 11, 2024
235e750
more progress
mistercrunch Dec 11, 2024
c96fb87
more tweaks
mistercrunch Dec 11, 2024
be27ce8
add docker/docker-translate.sh
mistercrunch Dec 11, 2024
ca3687e
moving back to chown on the fly
mistercrunch Dec 11, 2024
93a8f14
compile
mistercrunch Dec 11, 2024
11beaa7
remove chown
mistercrunch Dec 11, 2024
3d36305
alter perms
mistercrunch Dec 11, 2024
74a86bd
updating.md
mistercrunch Dec 11, 2024
7a52adf
progress
mistercrunch Dec 12, 2024
4a7bd04
fix
mistercrunch Dec 12, 2024
5fb4bbe
translate
mistercrunch Dec 13, 2024
926b702
close to finish line
mistercrunch Dec 13, 2024
a211f7a
add missing reqs files
mistercrunch Dec 13, 2024
f5d6e25
tweaksies
mistercrunch Dec 13, 2024
13de8a1
translations
mistercrunch Dec 13, 2024
9318c28
remove unused bash script
mistercrunch Dec 13, 2024
e718d32
LAST TWEAKS DAMMIT
mistercrunch Dec 13, 2024
a95f546
cache\!
mistercrunch Dec 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ superset-frontend/coverage/
superset/static/assets/
superset-websocket/dist/
venv
.venv
11 changes: 11 additions & 0 deletions .github/workflows/ephemeral-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,20 @@ jobs:
- name: Setup supersetbot
uses: ./.github/actions/setup-supersetbot/

- name: Try to login to DockerHub
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
continue-on-error: true
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build ephemeral env image
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
supersetbot docker \
--preset ci \
Expand Down
257 changes: 125 additions & 132 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,39 @@ ARG PY_VER=3.10-slim-bookworm

# If BUILDPLATFORM is null, set it to 'amd64' (or leave as is otherwise).
ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64}

######################################################################
# superset-node used for building frontend assets
######################################################################
FROM --platform=${BUILDPLATFORM} node:20-bullseye-slim AS superset-node
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}

COPY docker/ /app/docker/
# Arguments for build configuration
ARG NPM_BUILD_CMD="build"
ARG BUILD_TRANSLATIONS="false" # Include translations in the final build
ARG DEV_MODE="false" # Skip frontend build in dev mode
ARG INCLUDE_CHROMIUM="true" # Include headless Chromium for alerts & reports
ARG INCLUDE_FIREFOX="false" # Include headless Firefox if enabled

# Install system dependencies required for node-gyp
RUN --mount=type=bind,source=./docker,target=/docker \
/docker/apt-install.sh build-essential python3 zstd
RUN /app/docker/apt-install.sh build-essential python3 zstd

# Define environment variables for frontend build
ENV BUILD_CMD=${NPM_BUILD_CMD} \
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

# Run the frontend memory monitoring script
RUN --mount=type=bind,source=./docker,target=/docker \
/docker/frontend-mem-nag.sh
RUN /app/docker/frontend-mem-nag.sh

WORKDIR /app/superset-frontend

# Create necessary folders to avoid errors in subsequent steps
RUN mkdir -p /app/superset/static/assets \
/app/superset/translations

# Copy translation files
COPY superset/translations /app/superset/translations

# Mount package files and install dependencies if not in dev mode
RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.json \
--mount=type=bind,source=./superset-frontend/package-lock.json,target=./package-lock.json \
Expand All @@ -61,41 +67,28 @@ RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.j
# Runs the webpack build process
COPY superset-frontend /app/superset-frontend


# Copy translation files
COPY superset/translations /app/superset/translations

# Build the frontend if not in dev mode
RUN if [ "$DEV_MODE" = "false" ]; then \
BUILD_TRANSLATIONS=$BUILD_TRANSLATIONS npm run ${BUILD_CMD}; \
echo "Running 'npm run ${BUILD_CMD}'"; \
if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
npm run build-translation; \
fi; \
npm run ${BUILD_CMD}; \
else \
echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \
fi

# Compile .json files from .po translations (if required) and clean up .po files
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
npm run build-translation; \
else \
echo "Skipping translations as requested by build flag"; \
fi \
# removing translations files regardless
&& rm -rf /app/superset/translations/*/LC_MESSAGES/*.po \
/app/superset/translations/messages.pot

fi && \
rm -rf /app/superset/translations/*/*/*.po

# Transition to Python base image
FROM python:${PY_VER} AS python-base
RUN pip install --no-cache-dir --upgrade setuptools pip uv

######################################################################
# Final lean image...
# Base python layer
######################################################################
FROM python-base AS lean

# Build argument for including translations
ARG BUILD_TRANSLATIONS="false"
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}

WORKDIR /app
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
SUPERSET_ENV=production \
Expand All @@ -104,126 +97,128 @@ ENV LANG=C.UTF-8 \
SUPERSET_HOME="/app/superset_home" \
SUPERSET_PORT=8088


RUN useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset

# Some bash scripts needed throughout the layers
COPY --chmod=755 docker/*.sh /app/docker/

RUN pip install --no-cache-dir --upgrade setuptools pip uv

# Using uv as it's faster/simpler than pip
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/pip \
if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \
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
######################################################################
FROM python-base AS python-translation-compiler

# Install Python dependencies using docker/pip-install.sh
COPY requirements/translations.txt requirements/
RUN --mount=type=cache,target=/root/.cache/pip \
/app/docker/pip-install.sh -r requirements/translations.txt

COPY superset/translations/ /app/translations_mo/
RUN pybabel compile -d /app/translations_mo | true && \
rm -f /app/translations_mo/*/*/*.po

######################################################################
# Python APP common layer
######################################################################
FROM python-base AS python-common
# 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 --mount=type=bind,source=./docker,target=/docker \
mkdir -p ${PYTHONPATH} \
RUN mkdir -p \
${SUPERSET_HOME} \
${PYTHONPATH} \
superset/static \
requirements \
superset-frontend \
apache_superset.egg-info \
requirements \
&& useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset \
&& /docker/apt-install.sh \
curl \
libsasl2-dev \
libsasl2-modules-gssapi-mit \
libpq-dev \
libecpg-dev \
libldap2-dev \
&& touch superset/static/version_info.json \
&& chown -R superset:superset ./* \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
&& touch superset/static/version_info.json

# Copy required files for Python build
COPY --chown=superset:superset pyproject.toml setup.py MANIFEST.in README.md ./
COPY --chown=superset:superset superset-frontend/package.json superset-frontend/
COPY --chown=superset:superset requirements/base.txt requirements/
COPY --chown=superset:superset scripts/check-env.py scripts/

# Install Python dependencies using docker/pip-install.sh
RUN --mount=type=bind,source=./docker,target=/docker \
--mount=type=cache,target=/root/.cache/pip \
/docker/pip-install.sh --requires-build-essential -r requirements/base.txt

# Copy the compiled frontend assets from the node image
COPY --chown=superset:superset --from=superset-node /app/superset/static/assets superset/static/assets
COPY pyproject.toml setup.py MANIFEST.in README.md ./
COPY superset-frontend/package.json superset-frontend/
COPY scripts/check-env.py scripts/

# Copy the main Superset source code
COPY --chown=superset:superset superset superset
# keeping for backward compatibility
COPY --chmod=755 ./docker/entrypoints/run-server.sh /usr/bin/

# Install Superset itself using docker/pip-install.sh
RUN --mount=type=bind,source=./docker,target=/docker \
--mount=type=cache,target=/root/.cache/pip \
/docker/pip-install.sh -e .
# Some debian libs
RUN /app/docker/apt-install.sh \
curl \
libsasl2-dev \
libsasl2-modules-gssapi-mit \
libpq-dev \
libecpg-dev \
libldap2-dev

# Copy .json translations from the node image
COPY --chown=superset:superset --from=superset-node /app/superset/translations superset/translations
# Copy compiled things from previous stages
COPY --from=superset-node /app/superset/static/assets superset/static/assets

# Compile backend translations and clean up
COPY ./scripts/translations/generate_mo_files.sh ./scripts/translations/
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
./scripts/translations/generate_mo_files.sh \
&& chown -R superset:superset superset/translations; \
fi \
&& rm -rf superset/translations/messages.pot \
superset/translations/*/LC_MESSAGES/*.po
# Merging translations from backend and frontend stages
COPY --from=superset-node /app/superset/translations superset/translations
COPY --from=python-translation-compiler /app/translations_mo superset/translations

# Add server run script
COPY --chmod=755 ./docker/run-server.sh /usr/bin/

# Set user and healthcheck
USER superset
HEALTHCHECK CMD curl -f "http://localhost:${SUPERSET_PORT}/health"

# Expose port and set CMD
CMD ["/app/docker/entrypoints/run-server.sh"]
EXPOSE ${SUPERSET_PORT}
CMD ["/usr/bin/run-server.sh"]


######################################################################
# Dev image...
# Final lean image...
######################################################################
FROM lean AS dev

USER root
FROM python-common AS lean
COPY superset superset

# Install dev dependencies
RUN --mount=type=bind,source=./docker,target=/docker \
/docker/apt-install.sh \
libnss3 \
libdbus-glib-1-2 \
libgtk-3-0 \
libx11-xcb1 \
libasound2 \
libxtst6 \
git \
pkg-config

# Install Playwright and its dependencies
# Install Python dependencies using docker/pip-install.sh
COPY requirements/base.txt requirements/
RUN --mount=type=cache,target=/root/.cache/pip \
uv pip install --system playwright \
&& playwright install-deps
/app/docker/pip-install.sh --requires-build-essential -r requirements/base.txt && \
uv pip install .

# Optionally install Chromium
RUN if [ "$INCLUDE_CHROMIUM" = "true" ]; then \
playwright install chromium; \
else \
echo "Skipping Chromium installation in dev mode"; \
fi
RUN python -m compileall /app/superset

# Install GeckoDriver WebDriver and Firefox (if required)
ARG GECKODRIVER_VERSION=v0.34.0
ARG FIREFOX_VERSION=125.0.3
RUN --mount=type=bind,source=./docker,target=/docker \
if [ "$INCLUDE_FIREFOX" = "true" ]; then \
/docker/apt-install.sh wget bzip2 \
&& wget -q https://github.com/mozilla/geckodriver/releases/download/${GECKODRIVER_VERSION}/geckodriver-${GECKODRIVER_VERSION}-linux64.tar.gz -O - | tar xfz - -C /usr/local/bin \
&& wget -q https://download-installer.cdn.mozilla.net/pub/firefox/releases/${FIREFOX_VERSION}/linux-x86_64/en-US/firefox-${FIREFOX_VERSION}.tar.bz2 -O - | tar xfj - -C /opt \
&& ln -s /opt/firefox/firefox /usr/local/bin/firefox \
&& apt-get autoremove -yqq --purge wget bzip2 && rm -rf /var/[log,tmp]/* /tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*; \
else \
echo "Skipping Firefox installation in dev mode"; \
fi
USER superset

######################################################################
# Dev image...
######################################################################
FROM python-common AS dev
COPY superset superset

# Install MySQL client dependencies
RUN --mount=type=bind,source=./docker,target=/docker \
/docker/apt-install.sh default-libmysqlclient-dev
# Debian libs needed for dev
RUN /app/docker/apt-install.sh \
git \
pkg-config \
default-libmysqlclient-dev

# Copy development requirements and install them
COPY --chown=superset:superset requirements/development.txt requirements/
RUN --mount=type=bind,source=./docker,target=/docker \
--mount=type=cache,target=/root/.cache/pip \
/docker/pip-install.sh --requires-build-essential -r requirements/development.txt
COPY requirements/*.txt requirements/
# Install Python dependencies using docker/pip-install.sh
RUN --mount=type=cache,target=/root/.cache/pip \
/app/docker/pip-install.sh --requires-build-essential -r requirements/development.txt && \
uv pip install .

RUN python -m compileall /app/superset

USER superset

Expand All @@ -232,6 +227,4 @@ USER superset
######################################################################
FROM lean AS ci

COPY --chown=superset:superset --chmod=755 ./docker/*.sh /app/docker/

CMD ["/app/docker/docker-ci.sh"]
CMD ["/app/docker/entrypoints/docker-ci.sh"]
1 change: 1 addition & 0 deletions UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ assists people when migrating to a new version.
- [30021](https://github.com/apache/superset/pull/30021) The `dev` layer in our Dockerfile no long includes firefox binaries, only Chromium to reduce bloat/docker-build-time.
- [30099](https://github.com/apache/superset/pull/30099) Translations are no longer included in the default docker image builds. If your environment requires translations, you'll want to set the docker build arg `BUILD_TRANSACTION=true`.
- [31173](https://github.com/apache/superset/pull/31173) Modified `fetch_csrf_token` to align with HTTP standards, particularly regarding how cookies are handled. If you encounter any issues related to CSRF functionality, please report them as a new issue and reference this PR for context.
- [31385](https://github.com/apache/superset/pull/31385) Significant docker refactor, reducing access levels for the `superset` user, streamlining layer building, ...

### Potential Downtime

Expand Down
1 change: 1 addition & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@


COMPOSE_PROJECT_NAME=superset
DEV_MODE=true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything that needs to be done for official docker images built during releases to remove this flag?


# database configurations (do not modify)
DATABASE_DB=superset
Expand Down
5 changes: 5 additions & 0 deletions docker/docker-bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

set -eo pipefail

# Make python interactive
if [ "$DEV_MODE" == "true" ]; then
echo "Reinstalling the app in editable mode"
uv pip install -e .
fi
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
# If Cypress run – overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
Expand Down
File renamed without changes.
File renamed without changes.
Loading
Loading