Ctrl K
ComunidadGuías…

Dockerfile.standalone-infisical

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
ARG POSTHOG_HOST=https://app.posthog.com
ARG POSTHOG_API_KEY=posthog-api-key
ARG INTERCOM_ID=intercom-id

ARG INFISICAL_CLI_VERSION=0.45.4

FROM node:26.12.1-trixie-slim AS base

# Node 26.12.1 bundles npm 11.20.0, whose own dependencies are outdated. 11.21.1 updates them
# and stays on the npm major that Node ships. Its bundled ip-address and undici are swapped for
# in-range patch releases. The swap fails if npm bundles other versions; drop it once an npm
# release bundles the patched ones.
RUN npm install -g npm@11.21.1 \
    && cd /tmp \
    && NPM_DEPS=/usr/local/lib/node_modules/npm/node_modules \
    && for dep in ip-address@10.7.2 undici@6.29.0; do \
         bundled="$(node -p "require('$NPM_DEPS/${dep%@*}/package.json').version")"; \
         [ "$bundled" = "${dep##*@}" ] || { echo "npm bundles ${dep%@*} $bundled, expected ${dep##*@}" >&2; exit 1; }; \
       done \
    && npm pack ip-address@10.7.4 undici@6.29.1 --silent \
    && rm -rf "$NPM_DEPS/ip-address" "$NPM_DEPS/undici" \
    && mkdir "$NPM_DEPS/ip-address" "$NPM_DEPS/undici" \
    && tar -xzf ip-address-10.7.4.tgz -C "$NPM_DEPS/ip-address" --strip-components=1 --no-same-owner \
    && tar -xzf undici-6.29.1.tgz -C "$NPM_DEPS/undici" --strip-components=1 --no-same-owner \
    && rm ip-address-10.7.4.tgz undici-6.29.1.tgz \
    && npm cache clean --force

FROM base AS frontend-dependencies

WORKDIR /app

COPY frontend/package.json frontend/package-lock.json  ./

# Install dependencies
RUN npm ci --ignore-scripts

# Rebuild the source code only when needed
FROM base AS frontend-builder
WORKDIR /app

# Copy dependencies
COPY --from=frontend-dependencies /app/node_modules ./node_modules
# Copy all files
COPY /frontend .

ENV NODE_ENV production
ARG POSTHOG_HOST
ENV VITE_POSTHOG_HOST $POSTHOG_HOST
ARG POSTHOG_API_KEY
ENV VITE_POSTHOG_API_KEY $POSTHOG_API_KEY
ARG INTERCOM_ID
ENV VITE_INTERCOM_ID $INTERCOM_ID
ARG INFISICAL_PLATFORM_VERSION
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
ENV NODE_OPTIONS="--max-old-space-size=8192"

# Build
RUN npm run build

# Production image
FROM base AS frontend-runner
WORKDIR /app

RUN groupadd --system --gid 1001 nodejs
RUN useradd --system --uid 1001 --gid nodejs non-root-user

COPY --from=frontend-builder --chown=non-root-user:nodejs /app/dist ./

USER 1001

##
## BACKEND
##

# Oracle Instant Client (parallel stage — downloads while other stages build)
FROM debian:trixie-slim AS oracle
RUN apt-get update && apt-get install -y unzip wget ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN ARCH=$(dpkg --print-architecture) && \
    if [ "$ARCH" = "amd64" ]; then \
        ORACLE_ZIP="instantclient-basic-linux.x64-23.26.0.0.0.zip" && \
        EXPECTED_SHA="d6c79cbcf0ff209363e779855c690d4fc730aed847e9198a2c439bcf34760af5"; \
    elif [ "$ARCH" = "arm64" ]; then \
        ORACLE_ZIP="instantclient-basic-linux.arm64-23.26.0.0.0.zip" && \
        EXPECTED_SHA="9c9a32051e97f087016fb334b7ad5c0aea8511ca8363afd8e0dc6ec4fc515c32"; \
    fi && \
    ORACLE_URL="https://download.oracle.com/otn_software/linux/instantclient/2326000/${ORACLE_ZIP}" && \
    wget -q "$ORACLE_URL" && \
    echo "$EXPECTED_SHA  $ORACLE_ZIP" | sha256sum -c - && \
    mkdir -p /opt/oracle && \
    unzip "$ORACLE_ZIP" -d /opt/oracle && \
    rm "$ORACLE_ZIP"

FROM base AS backend-build

ENV ChrystokiConfigurationPath=/usr/safenet/lunaclient/

WORKDIR /app

# Install all required dependencies for build
RUN apt-get update && apt-get install -y \
    python3 \
    make \
    g++ \
    unixodbc \
    freetds-bin \
    unixodbc-dev \
    libc-dev \
    freetds-dev \
    && rm -rf /var/lib/apt/lists/*

RUN groupadd --system --gid 1001 nodejs
RUN useradd --system --uid 1001 --gid nodejs non-root-user

COPY backend/package*.json ./
RUN npm ci

COPY /backend .
COPY --chown=non-root-user:nodejs standalone-entrypoint.sh standalone-entrypoint.sh
ENV NODE_OPTIONS="--max-old-space-size=8192"
RUN npm run build

# Bake in-app announcements + their images at build time so self-hosted / air-gapped
# instances don't make any outbound calls to Contentful at runtime. No-ops silently
# if Contentful secrets are not supplied (cloud / dev builds). Secrets are passed
# via BuildKit --mount=type=secret so they never enter any image layer or SLSA
# provenance attestation.
RUN --mount=type=secret,id=contentful_space_id,required=false \
    --mount=type=secret,id=contentful_delivery_token,required=false \
    --mount=type=secret,id=contentful_environment,required=false \
    CONTENTFUL_SPACE_ID="$(cat /run/secrets/contentful_space_id 2>/dev/null || true)" \
    CONTENTFUL_DELIVERY_TOKEN="$(cat /run/secrets/contentful_delivery_token 2>/dev/null || true)" \
    CONTENTFUL_ENVIRONMENT="$(cat /run/secrets/contentful_environment 2>/dev/null || true)" \
    npm run bake:announcements

# Production dependencies (runs in parallel with backend-build)
FROM base AS backend-prod-deps

WORKDIR /app

# Install build tools needed to compile native modules during npm ci
RUN apt-get update && apt-get install -y \
    python3 \
    make \
    g++ \
    unixodbc \
    freetds-bin \
    unixodbc-dev \
    libc-dev \
    freetds-dev \
    && rm -rf /var/lib/apt/lists/*

COPY backend/package*.json ./
RUN npm ci --omit=dev
# Test folders these packages publish, with sample private keys that image scanners flag
RUN rm -rf node_modules/@fastify/reply-from/test node_modules/ssh2/test node_modules/universal-github-app-jwt/test

# Production stage
FROM base AS backend-runner

ENV ChrystokiConfigurationPath=/usr/safenet/lunaclient/

WORKDIR /app

# Only runtime libraries needed — no compilation happens here
RUN apt-get update && apt-get install -y \
    unixodbc \
    freetds-bin \
    && rm -rf /var/lib/apt/lists/*

# Configure ODBC
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\nSetup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so\nFileUsage = 1\n" > /etc/odbcinst.ini

COPY --from=backend-build /app .
RUN rm -rf ./node_modules ./bdd ./e2e-test ./src
COPY --from=backend-prod-deps /app/node_modules ./node_modules

RUN mkdir frontend-build

# OpenSSL 3.5.9 supplies the PQC (ML-DSA / SLH-DSA) algorithms the certificate
# stack needs. It is built here rather than in the production stage so the
# toolchain it requires does not ship in the runtime image.
FROM base AS openssl-pqc-builder

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    perl \
    wget \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /tmp/openssl-build
RUN wget -q https://github.com/openssl/openssl/releases/download/openssl-3.5.9/openssl-3.5.9.tar.gz \
    && echo "603f5602e2eef00d77fbd429d34dcd5822bb301757a1bc9cdb24c670f1eb859a  openssl-3.5.9.tar.gz" | sha256sum -c - \
    && tar -xf openssl-3.5.9.tar.gz \
    && cd openssl-3.5.9 \
    && ./Configure --prefix=/opt/openssl-pqc --openssldir=/opt/openssl-pqc/ssl no-docs \
    && make -j"$(nproc)" \
    && make install_sw \
    && cd / \
    && rm -rf /tmp/openssl-build

# Production stage
FROM base AS production

# Runtime dependencies only. The PQC OpenSSL toolchain lives in
# openssl-pqc-builder; nothing here compiles.
ARG INFISICAL_CLI_VERSION
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    bash \
    curl \
    git \
    unixodbc \
    freetds-bin \
    # the ECS container health check shells out to wget; dropping it fails the
    # probe with exit 127 even while the server is serving /api/status fine
    wget \
    openssh-client \
    libaio1t64 \
    smbclient \
    && curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | bash \
    && test -n "$INFISICAL_CLI_VERSION" \
    && apt-get update && apt-get install -y infisical="$INFISICAL_CLI_VERSION" \
    # Upgrade base-image packages that apt will not move on its own. Only packages
    # preinstalled in the base belong here; anything pulled in as a dependency
    # already installs at the candidate version. Re-check each release; a stale
    # pin holds the vulnerable version, and a withdrawn one fails the build.
    && apt-get install -y --only-upgrade \
    libgnutls30t64=3.8.9-3+deb13u4 \
    libc6=2.41-12+deb13u4 \
    libc-bin=2.41-12+deb13u4 \
    libssl3t64=3.5.7-1~deb13u3 \
    dpkg=1.22.22 \
    apt=3.0.4 \
    libapt-pkg7.0=3.0.4 \
    libcap2 \
    libnghttp2-14=1.64.0-1.1+deb13u1 \
    libngtcp2-16=1.11.0-1+deb13u1 \
    libngtcp2-crypto-gnutls8=1.11.0-1+deb13u1 \
    libsqlite3-0=3.46.1-7+deb13u2 \
    util-linux=2.41.5-0+deb13u1 \
    mount=2.41.5-0+deb13u1 \
    libblkid1=2.41.5-0+deb13u1 \
    libuuid1=2.41.5-0+deb13u1 \
    libmount1=2.41.5-0+deb13u1 \
    libsmartcols1=2.41.5-0+deb13u1 \
    liblastlog2-2=2.41.5-0+deb13u1 \
    bsdutils=1:2.41.5-0+deb13u1 \
    login=1:4.16.0-2+really2.41.5-0+deb13u1 \
    libsystemd0=257.13-1~deb13u1 \
    libudev1=257.13-1~deb13u1 \
    sed=4.9-2+deb13u1 \
    && rm -rf /var/lib/apt/lists/*

# Copy Oracle Instant Client from parallel stage
COPY --from=oracle /opt/oracle /opt/oracle
RUN ARCH=$(dpkg --print-architecture) && \
    if [ "$ARCH" = "amd64" ]; then \
        ln -sf /lib/x86_64-linux-gnu/libaio.so.1t64 /lib/x86_64-linux-gnu/libaio.so.1; \
    elif [ "$ARCH" = "arm64" ]; then \
        ln -sf /lib/aarch64-linux-gnu/libaio.so.1t64 /lib/aarch64-linux-gnu/libaio.so.1; \
    fi && \
    echo /opt/oracle/instantclient_23_26 > /etc/ld.so.conf.d/oracle-instantclient.conf && \
    ldconfig

# PQC OpenSSL, built in openssl-pqc-builder. Consumed as a self-contained
# prefix by lib/crypto/pqc (bin/openssl plus lib64:lib on the load path).
COPY --from=openssl-pqc-builder /opt/openssl-pqc /opt/openssl-pqc

WORKDIR /

# Configure ODBC in production
RUN printf "[FreeTDS]\nDescription = FreeTDS Driver\nDriver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so\nSetup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so\nFileUsage = 1\n" > /etc/odbcinst.ini

# Setup user permissions
RUN groupadd --system --gid 1001 nodejs \
  && useradd --system --uid 1001 --gid nodejs non-root-user

# Give non-root-user permission to update SSL certs
RUN chown -R non-root-user /etc/ssl/certs \
    && chmod -R u+rwx /etc/ssl/certs \
    && chown non-root-user /usr/sbin/update-ca-certificates \
    && chmod u+rx /usr/sbin/update-ca-certificates

## set pre baked keys
ARG POSTHOG_API_KEY
ENV POSTHOG_API_KEY=$POSTHOG_API_KEY
ARG INTERCOM_ID=intercom-id
ENV INTERCOM_ID=$INTERCOM_ID

COPY --from=backend-runner /app /backend
COPY --from=frontend-runner /app ./backend/frontend-build

# Make export-assets script executable for CDN asset extraction
RUN chmod +x /backend/scripts/export-assets.sh

ARG INFISICAL_PLATFORM_VERSION
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION

ARG DD_GIT_REPOSITORY_URL
ENV DD_GIT_REPOSITORY_URL $DD_GIT_REPOSITORY_URL

ARG DD_GIT_COMMIT_SHA
ENV DD_GIT_COMMIT_SHA $DD_GIT_COMMIT_SHA

# OCI Image Labels - Static metadata
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
LABEL org.opencontainers.image.title="Infisical"
LABEL org.opencontainers.image.description="Open-source secret management platform"
LABEL org.opencontainers.image.url="https://infisical.com"
LABEL org.opencontainers.image.documentation="https://infisical.com/docs"
LABEL org.opencontainers.image.source="https://github.com/Infisical/infisical"
LABEL org.opencontainers.image.vendor="Infisical"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.base.name="node:26.12.1-trixie-slim"

# OCI Image Labels - Dynamic metadata (set via build args)
LABEL org.opencontainers.image.version="${INFISICAL_PLATFORM_VERSION}"
LABEL org.opencontainers.image.revision="${DD_GIT_COMMIT_SHA}"

ENV PORT 8080
ENV HOST=0.0.0.0
ENV HTTPS_ENABLED false
ENV NODE_ENV production
ENV STANDALONE_BUILD true
ENV STANDALONE_MODE true
ENV NODE_OPTIONS="--max-old-space-size=2048"
ENV ChrystokiConfigurationPath=/usr/safenet/lunaclient/

WORKDIR /backend

ENV TELEMETRY_ENABLED true

EXPOSE 8080
EXPOSE 443

# Use numeric UID so Kubernetes can verify the image runs as non-root
USER 1001

CMD ["./standalone-entrypoint.sh"]