diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6572d8b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +ockerfile +.dockerignore +node_modules +npm-debug.log +README.md +**/.next +**/*.db diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..a2c5721 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,141 @@ +################# Base Builder ############## +FROM node:22-alpine AS base + +WORKDIR /app +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable + +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat make g++ py3-pip linux-headers + +COPY . . +ENV NEXT_TELEMETRY_DISABLED 1 +ENV PUPPETEER_SKIP_DOWNLOAD true +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile + +# Build the db migration script +RUN cd packages/db && \ + pnpm dlx @vercel/ncc build migrate.ts -o /db_migrations && \ + cp -R migrations /db_migrations + + +# Compile the web app +RUN (cd apps/web && pnpm exec next build --experimental-build-mode compile) + +# Build the worker code +# RUN --mount=type=cache,id=pnpm_workers,target=/pnpm/store pnpm deploy --node-linker=isolated --filter @lifetracker/workers --prod /prod/workers + +# Build the cli +RUN (cd apps/cli && pnpm build) + +################# The All-in-one builder ############## + +FROM node:22-alpine AS aio_builder +LABEL org.opencontainers.image.source="https://git.ryanpandya.com/ryan/lifetracker" +WORKDIR /app + +ARG SERVER_VERSION=nightly +ENV SERVER_VERSION=${SERVER_VERSION} + +USER root + +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" +EXPOSE 3000 + +###################### +# Prepare s6-overlay +###################### +ARG S6_OVERLAY_VERSION=3.2.0.0 +ARG TARGETARCH + +ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp +RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz \ + && case ${TARGETARCH} in \ + "amd64") S6_ARCH=x86_64 ;; \ + "arm64") S6_ARCH=aarch64 ;; \ + esac \ + && echo https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz -O /tmp/s6-overlay-${S6_ARCH}.tar.xz \ + && wget https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz -O /tmp/s6-overlay-${S6_ARCH}.tar.xz \ + && tar -C / -Jxpf /tmp/s6-overlay-${S6_ARCH}.tar.xz \ + && rm -f /tmp/s6-overlay-${S6_ARCH}.tar.xz + +# Copy the s6-overlay config +COPY --chmod=755 ./docker/root/etc/s6-overlay /etc/s6-overlay + +###################### +# Install runtime deps +###################### +# RUN apk add --no-cache monolith yt-dlp + +###################### +# Prepare the web app +###################### + +ENV NODE_ENV production +ENV NEXT_TELEMETRY_DISABLED 1 + +COPY --from=base --chown=node:node /app/apps/web/.next/standalone ./ +COPY --from=base /app/apps/web/public ./apps/web/public +COPY --from=base /db_migrations /db_migrations + +# Set the correct permission for prerender cache +RUN mkdir -p ./apps/web/.next && chown node:node ./apps/web/.next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=base --chown=node:node /app/apps/web/.next/static ./apps/web/.next/static + +###################### +# Prepare the workers app +###################### +COPY --from=base /prod/workers /app/apps/workers +RUN corepack enable && corepack pack + +ENTRYPOINT ["/init"] + +################# The AIO ############## + +FROM aio_builder AS aio + +RUN touch /etc/s6-overlay/s6-rc.d/user/contents.d/init-db-migration \ + /etc/s6-overlay/s6-rc.d/user/contents.d/svc-web \ + /etc/s6-overlay/s6-rc.d/user/contents.d/svc-workers + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/api/health || exit 1 + +################# The web container ############## + +FROM aio_builder AS web + +RUN touch /etc/s6-overlay/s6-rc.d/user/contents.d/init-db-migration \ + /etc/s6-overlay/s6-rc.d/user/contents.d/svc-web +ENV USING_LEGACY_SEPARATE_CONTAINERS=true + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/api/health || exit 1 + +################# The workers container ############## + +FROM aio_builder AS workers + +# In the current implemtation, the workers assume the migration +# is done for them. +RUN rm /etc/s6-overlay/s6-rc.d/svc-workers/dependencies.d/init-db-migration \ + && touch /etc/s6-overlay/s6-rc.d/user/contents.d/svc-workers +ENV USING_LEGACY_SEPARATE_CONTAINERS=true + +################# The cli ############## + +FROM node:22-alpine AS cli +LABEL org.opencontainers.image.source="https://github.com/hoarder-app/hoarder" +WORKDIR /app + +COPY --from=base /app/apps/cli/dist/index.mjs apps/cli/index.mjs + +WORKDIR /app/apps/cli + +ARG SERVER_VERSION=nightly +ENV SERVER_VERSION=${SERVER_VERSION} + +ENTRYPOINT ["node", "index.mjs"] \ No newline at end of file