DEV_MODE设为false时Apache Superset开发镜像构建失败
自定义Apache Superset镜像构建失败问题解决
问题场景
在Ubuntu(Hyper-V环境)执行命令:
docker build -t superset-dev --target dev --build-arg DEV_MODE="false" .
构建自定义Apache Superset镜像时失败,报错多个模块无法解析;若将DEV_MODE设为true,镜像可成功构建,但未生成UI。
Dockerfile
ARG PY_VER=3.11-slim # If BUILDPLATFORM is null, set it to 'amd64' (or leave as is otherwise). ARG BUILDPLATFORM=${BUILDPLATFORM:-amd64} FROM --platform=${BUILDPLATFORM} node:20-bullseye-slim AS superset-node ARG NPM_BUILD_CMD="build" ARG DEV_MODE="false" ARG INCLUDE_CHROMIUM="true" ARG INCLUDE_FIREFOX="false" # Install system dependencies for Node.js RUN apt-get update -qq \ && apt-get install -yqq --no-install-recommends \ build-essential \ python3 \ zstd \ && rm -rf /var/lib/apt/lists/* ENV BUILD_CMD=${NPM_BUILD_CMD} \ PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true WORKDIR /app/superset-frontend # Creating empty folders to avoid errors when running COPY later on RUN mkdir -p /app/superset/static/assets /app/superset/translations # Copy package.json and package-lock.json before running npm ci COPY superset-frontend/package.json superset-frontend/package-lock.json ./ # Install Node.js dependencies RUN if [ "$DEV_MODE" = "false" ]; then \ npm install --legacy-peer-deps; \ else \ echo "Skipping 'npm install' in dev mode"; \ fi # Build frontend assets using npm COPY superset-frontend /app/superset-frontend RUN if [ "$DEV_MODE" = "false" ]; then \ npm run ${BUILD_CMD}; \ else \ echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \ fi # Copy and compile translations RUN mkdir -p /app/superset/translations COPY superset/translations /app/superset/translations RUN if [ "$DEV_MODE" = "false" ]; then \ npm run build-translation; \ else \ echo "Skipping translations in dev mode"; \ fi RUN rm /app/superset/translations/*/LC_MESSAGES/*.po RUN rm /app/superset/translations/messages.pot ###################################################################### # Base Python image with Oracle Instant Client ###################################################################### FROM python:${PY_VER} AS base WORKDIR /app 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 \ LD_LIBRARY_PATH=/opt/oracle/instantclient_19_19 \ TNS_ADMIN=/app/superset # Install system dependencies (including Oracle Instant Client dependencies) RUN apt-get update -qq \ && apt-get install -yqq --no-install-recommends \ libaio1 \ unzip \ curl \ default-libmysqlclient-dev \ libsasl2-dev \ libsasl2-modules-gssapi-mit \ libpq-dev \ libecpg-dev \ libldap2-dev \ && rm -rf /var/lib/apt/lists/* # Oracle Instant Client setup COPY instantclient-basic-linux.x64-19.19.0.0.0dbru.el9.zip /opt/oracle/ COPY instantclient-sdk-linux.x64-19.19.0.0.0dbru.el9.zip /opt/oracle/ RUN unzip /opt/oracle/instantclient-basic-linux.x64-19.19.0.0.0dbru.el9.zip -d /opt/oracle/ \ && unzip /opt/oracle/instantclient-sdk-linux.x64-19.19.0.0.0dbru.el9.zip -d /opt/oracle/ \ && rm /opt/oracle/instantclient-basic-linux.x64-19.19.0.0.0dbru.el9.zip \ && rm /opt/oracle/instantclient-sdk-linux.x64-19.19.0.0.0dbru.el9.zip # Install OracleDB Python package before running Superset commands RUN pip install oracledb # Create necessary directories and user RUN mkdir -p ${PYTHONPATH} superset/static requirements superset-frontend apache_superset.egg-info \ && useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash superset \ && touch superset/static/version_info.json # Install build-essential temporarily for pip installations that require compilation RUN apt-get update -qq && apt-get install -yqq --no-install-recommends \ build-essential \ && rm -rf /var/lib/apt/lists/* # Copy and install Python dependencies COPY pyproject.toml setup.py MANIFEST.in README.md ./ COPY superset-frontend/package.json superset-frontend/ COPY requirements/base.txt requirements/ RUN pip install --upgrade setuptools pip \ && pip install -r requirements/base.txt # Copy Superset source code COPY superset superset # Copy superset_config.py for Oracle DB configuration COPY docker/pythonpath_dev/superset_config.py /app/superset/superset_config.py # Set environment variables for Superset to point to the config file ENV SUPERSET_CONFIG_PATH=/app/superset/superset_config.py # Install Superset RUN pip install -e . # Create an admin user for Superset during build RUN superset fab create-admin --username admin --firstname Admin --lastname User \ --email admin@example.com --password admin # Initialize the Superset database RUN superset db upgrade # Remove build-essential to keep the image lean RUN apt-get purge -yqq build-essential \ && apt-get autoremove -yqq \ && rm -rf /var/lib/apt/lists/* # Change ownership of /app directory to superset user RUN chown -R superset:superset /app # Switch to superset user USER superset # Copy the compiled frontend assets from the superset-node stage COPY --chown=superset:superset --from=superset-node /app/superset/static/assets superset/static/assets COPY --chown=superset:superset --from=superset-node /app/superset/translations superset/translations # Copy and set permissions for the entrypoint script COPY --chmod=755 docker/run-server.sh /usr/bin/ # Copy translation script COPY --chown=superset:superset scripts/translations/generate_mo_files.sh scripts/translations/ # Run the translation script RUN scripts/translations/generate_mo_files.sh \ && rm superset/translations/messages.pot \ && rm superset/translations/*/LC_MESSAGES/*.po # Healthcheck to check if the app is running HEALTHCHECK CMD curl -f "http://localhost:${SUPERSET_PORT}/health" || exit 1 EXPOSE ${SUPERSET_PORT} ###################################################################### # Development Image ###################################################################### FROM base AS dev # Switch to root to install development dependencies USER root # Install development dependencies RUN apt-get update -qq \ && apt-get install -yqq --no-install-recommends \ build-essential \ git \ pkg-config \ libnss3 \ libdbus-glib-1-2 \ libgtk-3-0 \ libx11-xcb1 \ libasound2 \ libxtst6 \ default-libmysqlclient-dev \ libsasl2-dev \ libldap2-dev \ && rm -rf /var/lib/apt/lists/* # Install Playwright and its dependencies RUN pip install playwright \ && playwright install-deps RUN if [ "$INCLUDE_CHROMIUM" = "true" ]; then \ playwright install chromium; \ else \ echo "Skipping Chromium installation"; \ fi # Install Firefox and GeckoDriver if needed ARG GECKODRIVER_VERSION=v0.34.0 \ FIREFOX_VERSION=125.0.3 RUN if [ "$INCLUDE_FIREFOX" = "true" ]; then \ apt-get update -qq \ && apt-get install -yqq --no-install-recommends 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/lib/apt/lists/*; \ fi # Install development Python dependencies COPY requirements/development.txt requirements/ RUN pip install -r requirements/development.txt # Change ownership of /app directory to superset user RUN chown -R superset:superset /app # Switch back to superset user USER superset CMD ["/usr/bin/run-server.sh"]
构建错误日志
183.1 WARNING in ./src/utils/textUtils.ts 21:11-44 183.1 Module not found: Error: Can't resolve '../../../superset_text' in '/app/superset-frontend/src/utils' 183.1 183.1 ERROR in ./node_modules/@visx/react-spring/lib/axis/AnimatedTicks.js 6:11-39 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/react-spring/lib/axis' 183.1 183.1 ERROR in ./node_modules/@visx/react-spring/lib/grid/AnimatedGridLines.js 7:11-39 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/react-spring/lib/grid' 183.1 183.1 ERROR in ./node_modules/@visx/xychart/esm/components/annotation/AnimatedAnnotation.js 7:0-60 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/xychart/esm/components/annotation' 183.1 183.1 ERROR in ./node_modules/@visx/xychart/esm/components/series/private/AnimatedBars.js 7:0-60 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/xychart/esm/components/series/private' 183.1 183.1 ERROR in ./node_modules/@visx/xychart/esm/components/series/private/AnimatedGlyphs.js 3:0-64 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/xychart/esm/components/series/private' 183.1 183.1 ERROR in ./node_modules/@visx/xychart/esm/components/series/private/AnimatedPath.js 5:0-56 183.1 Module not found: Error: Can't resolve '@react-spring/web' in '/app/superset-frontend/node_modules/@visx/xychart/esm/components/series/private' 183.1 183.1 ERROR in ./node_modules/@encodable/registry/esm/models/Registry.js 4:0-39 183.1 Module not found: Error: Can't resolve 'global-box' in '/app/superset-frontend/node_modules/@encodable/registry/esm/models' 183.1 183.1 ERROR in ./plugins/plugin-chart-handlebars/node_modules/just-handlebars-helpers/lib/helpers/formatters.js 27:24-55 183.1 Module not found: Error: Can't resolve 'currencyformatter.js' in '/app/superset-frontend/plugins/plugin-chart-handlebars/node_modules/just-handlebars-helpers/lib/helpers' 183.1 183.1 ERROR in ./node_modules/encodable/esm/options/Encodable.js 3:0-38 183.1 Module not found: Error: Can't resolve 'global-box' in '/app/superset-frontend/node_modules/encodable/esm/options' 183.1 183.1 webpack 5.94.0 compiled with 9 errors and 1 warning in 169936 ms ------ Dockerfile:40 -------------------- 39 | COPY superset-frontend /app/superset-frontend 40 | >>> RUN if [ "$DEV_MODE" = "false" ]; then \ 41 | >>> npm run ${BUILD_CMD}; \ 42 | >>> else \ 43 | >>> echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \ 44 | >>> fi 45 | -------------------- ERROR: failed to solve: process "/bin/sh -c if [ \"$DEV_MODE\" = \"false\" ]; then npm run ${BUILD_CMD}; else echo \"Skipping 'npm run ${BUILD_CMD}' in dev mode\"; fi" did not complete successfully: exit code: 1
问题原因
- 前端依赖安装不完整:
npm install --legacy-peer-deps因peer依赖冲突,导致@react-spring/web、global-box等依赖包未正确安装。 - 本地化文件生成顺序错误:
superset_text是前端构建必需的本地化文件,当前Dockerfile先构建前端再处理翻译,导致构建时该文件缺失。 - Node.js版本不兼容:使用Node.js 20与Superset前端部分依赖存在版本适配问题,引发依赖安装失败。
修复方案
方案1:调整前端构建与翻译顺序
修改superset-node阶段的代码,确保本地化文件提前生成:
# 先复制翻译文件并生成本地化资源 RUN mkdir -p /app/superset/translations COPY superset/translations /app/superset/translations # 清理缓存并强制安装依赖 RUN if [ "$DEV_MODE" = "false" ]; then \ npm cache clean --force && npm install --legacy-peer-deps --force; \ else \ echo "Skipping 'npm install' in dev mode"; \ fi # 复制前端代码后,先生成翻译再构建前端 COPY superset-frontend /app/superset-frontend RUN if [ "$DEV_MODE" = "false" ]; then \ npm run build-translation && npm run ${BUILD_CMD}; \ else \ echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \ fi
方案2:手动安装缺失依赖
在superset-node阶段的依赖安装步骤后,添加手动安装缺失包的命令:
RUN if [ "$DEV_MODE" = "false" ]; then \ npm install --legacy-peer-deps @react-spring/web global-box currencyformatter.js; \ fi
方案3:切换兼容的Node.js版本
将superset-node阶段的基础镜像改为Superset官方推荐的Node.js 18:
FROM --platform=${BUILDPLATFORM} node:18-bullseye-slim AS superset-node
验证步骤
- 修改Dockerfile后,重新执行构建命令:
docker build -t superset-dev --target dev --build-arg DEV_MODE="false" . - 构建成功后启动容器:
docker run -d -p 8088:8088 superset-dev - 访问
http://localhost:8088,确认UI正常加载且功能可用。
内容的提问来源于stack exchange,提问作者yarslan
相关产品推荐
相关产品推荐

