ARG UBUNTU_VERSION=24.04

# use native build platform for build js files only once
FROM --platform=${BUILDPLATFORM} ubuntu:${UBUNTU_VERSION} AS native-build-stage

ARG BUILDARCH
ARG NODE_MAJOR=22
ARG PNPM_VERSION=10.17.1

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get -y upgrade && apt-get -y install ca-certificates curl gnupg

# node
RUN mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list

RUN apt-get update && apt-get -y install nodejs g++ make

RUN npm install -g pnpm@${PNPM_VERSION}

RUN useradd -m -u 1001 app && mkdir /opt/app && chown app:app /opt/app

WORKDIR /opt/app

COPY package.json pnpm-lock.yaml .npmrc /opt/app/
RUN --mount=type=cache,id=pnpm-store-${BUILDARCH},target=/pnpm_store \
    pnpm config set store-dir=/pnpm_store --location=project && \
    pnpm config set cache-dir=/pnpm_cache --location=project && \
    pnpm config delete virtual-store-dir --location=project && \
    pnpm install --frozen-lockfile --prefer-offline

COPY ./dist /opt/app/dist
COPY ./src /opt/app/src
COPY app-builder.config.ts tsconfig.json /opt/app/

RUN pnpm run build && chown app /opt/app/dist/run

# runtime base image for both platform
FROM ubuntu:${UBUNTU_VERSION} AS base-stage

ARG NODE_MAJOR=22
ARG PNPM_VERSION=10.17.1

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get -y upgrade && apt-get -y install ca-certificates curl gnupg

# node
RUN mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list

RUN apt-get update && apt-get -y install nginx supervisor nodejs

RUN npm install -g pnpm@${PNPM_VERSION}

# remove unnecessary packages
RUN apt-get -y purge curl gnupg gnupg2 && \
    apt-get -y autoremove && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf /etc/apt/sources.list.d/nodesource.list && \
    rm -rf /etc/apt/keyrings/nodesource.gpg

# timezone setting
ENV TZ="Etc/UTC"
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# user app
RUN useradd -m -u 1001 app && mkdir /opt/app && chown app:app /opt/app

# install package dependencies for production
FROM base-stage AS install-stage

ARG TARGETARCH

# install system dependencies
RUN apt-get update && apt-get -y install g++ make

WORKDIR /opt/app

COPY package.json pnpm-lock.yaml .npmrc /opt/app/

RUN --mount=type=cache,id=pnpm-store-${TARGETARCH},target=/pnpm_store \
    pnpm config set store-dir=/pnpm_store --location=project && \
    pnpm config set cache-dir=/pnpm_cache --location=project && \
    pnpm config delete virtual-store-dir --location=project && \
    pnpm install --frozen-lockfile --prefer-offline --prod

# production running stage
FROM base-stage AS runtime-stage

COPY deploy/nginx /etc/nginx
COPY deploy/supervisor/supervisord.conf /etc/supervisor/supervisord.conf

# prepare rootless permissions for supervisor and nginx
ARG USER=app
RUN chmod +x /etc/nginx/entrypoint.sh && \
    chown -R ${USER} /etc/nginx && \
    chown -R ${USER} /etc/supervisor && \
    rm -rf  /etc/supervisor/conf.d && \
    rm -rf  /etc/nginx/sites-available && \
    rm -rf  /etc/nginx/sites-enabled && \
    rm -rf  /etc/nginx/nginx-default.conf

ARG app_version
ENV APP_VERSION=$app_version
ENV TMPDIR=/tmp

WORKDIR /opt/app

COPY --from=install-stage /opt/app/package.json /opt/app/pnpm-lock.yaml /opt/app/
COPY --from=install-stage /opt/app/node_modules /opt/app/node_modules
COPY --from=native-build-stage /opt/app/dist /opt/app/dist

RUN chown -R ${USER} /opt/app/dist/run

USER app

ENV NODE_ENV=production

ENV APP_BUILDER_CDN=false
ENV UI_CORE_CDN=false

ENV APP_MODE=full
ENV APP_ENV=production
ENV APP_INSTALLATION=opensource
ENV APP_PORT=3030

EXPOSE 8080

ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
