# syntax=docker/dockerfile:1.7

# Base Node image
FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 AS base

# Set for base and all layer that inherit from it
ENV HOST="0.0.0.0"
ENV PORT="8080"
ENV NODE_ENV="production"
WORKDIR /src

# Install openssl for Prisma and pnpm
RUN apk add --no-cache libc6-compat openssl tini && \
    corepack enable && corepack prepare pnpm@9.15.9 --activate

# Install dependencies using turbo prune for minimal install
FROM base AS pruner

RUN npm install --global turbo@2.9.14
COPY . .
RUN turbo prune @shelf/webapp --docker

# Install all node_modules (including devDependencies for build)
FROM base AS deps

COPY --from=pruner /src/out/json/ .
RUN --mount=type=cache,id=depot-pnpm-store,target=/root/.local/share/pnpm/store/v3,sharing=locked \
    NODE_ENV=development pnpm install --frozen-lockfile

# Build the app
FROM deps AS build

COPY --from=pruner /src/out/full/ .

RUN --mount=type=cache,id=depot-turbo-cache,target=/src/.turbo,sharing=locked \
    pnpm --filter @shelf/webapp run build

# Install production dependencies independently from application source so
# ordinary code changes do not invalidate this expensive layer.
FROM base AS prod-deps

COPY --from=pruner /src/out/json/ .
RUN --mount=type=cache,id=depot-pnpm-store,target=/root/.local/share/pnpm/store/v3,sharing=locked \
    NODE_ENV=production pnpm install --prod --frozen-lockfile --ignore-scripts && \
    node -e "import('sharp')"

COPY --from=pruner /src/out/full/packages/database/prisma/schema.prisma /src/packages/database/prisma/schema.prisma
COPY --from=pruner /src/out/full/packages/database/prisma.config.ts /src/packages/database/prisma.config.ts
RUN /src/node_modules/.bin/prisma generate --schema /src/packages/database/prisma/schema.prisma

COPY --from=pruner /src/out/full/packages/database/ /src/packages/database/

# Finally, build the production image with minimal footprint
FROM base AS release

RUN addgroup --system --gid 10001 depot && \
    adduser --system --uid 10001 --ingroup depot --home /nonexistent --shell /sbin/nologin depot && \
    rm -rf /root/.cache /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack && \
    rm -f /usr/local/bin/corepack /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/pnpm /usr/local/bin/pnpx

COPY --link --from=prod-deps --chown=10001:10001 /src/node_modules /src/node_modules
COPY --link --from=prod-deps --chown=10001:10001 /src/apps/webapp/node_modules /src/apps/webapp/node_modules
COPY --link --from=prod-deps --chown=10001:10001 /src/packages/database /src/packages/database
COPY --link --from=build --chown=10001:10001 /src/apps/webapp/build /src/apps/webapp/build
COPY --link --from=build --chown=10001:10001 /src/apps/webapp/package.json /src/apps/webapp/package.json
COPY --link --from=build --chown=10001:10001 /src/package.json /src/package.json
COPY --link --from=build --chown=10001:10001 /src/apps/webapp/prisma.config.ts /src/apps/webapp/prisma.config.ts
COPY --link --from=build --chown=10001:10001 /src/apps/webapp/migrate-deploy.sh /src/apps/webapp/migrate-deploy.sh
COPY --link --from=build --chown=10001:10001 /src/apps/webapp/start.sh /src/apps/webapp/start.sh

WORKDIR /src/apps/webapp

RUN chmod +x /src/apps/webapp/migrate-deploy.sh /src/apps/webapp/start.sh

ARG RELEASE_SHA="development"
ENV RELEASE_SHA=${RELEASE_SHA}

USER depot:depot

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
  CMD ["node", "-e", "fetch('http://127.0.0.1:8080/healthcheck').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]

ENTRYPOINT [ "/sbin/tini", "--", "/src/apps/webapp/start.sh" ]
