#Setting up multi-stage builds with base container

1 messages · Page 1 of 1 (latest)

neat obsidian
#

Hi,
I'm trying to port this dockerfile to nodejs/ts dagger code.
how should I set up the base container so that builder, installer containers etc can be created based on it?

ie if I created the base like this

        const base = client
          .container({ platform: 'linux/amd64' as Platform })
          .from('node:18');

is creating additional containers like this is enough?

const builder = base.withExec(,,,)
...

Or is should it be something like

const installer = client.container().from(base) // I know that from() doesn't take such parameter but just to illustrate the assumption.
...

here's the dockerfile I'm porting;

FROM node:18-alpine AS base

FROM --platform=linux/amd64 base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
# Set working directory
WORKDIR /app
RUN npm install -g turbo
COPY . .
RUN turbo prune --scope=web --docker

# Add lockfile and package.json's of isolated subworkspace
FROM --platform=linux/amd64 base AS installer
RUN apk add --no-cache libc6-compat python3 make g++
RUN apk update
WORKDIR /app

# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/package-lock.json ./package-lock.json
RUN npm ci install

# Build the project
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json

ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build --filter=web...

FROM --platform=linux/amd64 base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

COPY --from=installer /app/apps/web/next.config.js .
COPY --from=installer /app/apps/web/package.json .

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public

CMD node apps/web/server.js
neat obsidian
#

or would this be better practice?

creating a function that creates a base container

function fromBaseContainer(client: Client) {
  return client
    .container({ platform: 'linux/amd64' as Platform })
    .from('node:18');
}

then using it to create additional containers for steps

const builder = fromBaseContainer(client)
...
const installer = fromBaseContainer(client)
...
const runner = fromBaseContainer(client)
hardy sentinel
#

base.withExec is good 🙂

#

you can also create higher-level functions if it helps you reason about your code

#

but it’s not mandatory

neat obsidian
#

thanks!

neat obsidian
#

about chown parameter

COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static

is there a parameter for withDirectory for passing chown as well?
or should I run chown command separately with withExec ?

neat obsidian
#

please nevermind the question above, found it!

.withFile('.', installer.file('/app/package-lock.json'), {
  owner: 'nodejs:app',
})
hardy sentinel
#

@neat obsidian looks like you’re getting the hang of things 🙂 Do you have a specific use case in mind, or just kicking the tires?

neat obsidian
#

yes :) Thanks for the help! I heard about dagger recently, learning how to use it on my sideproject.
For now just trying to port my existing nextjs google cloud run and jobs containers deployment scripts in turborepo
eventually want to try to build this idea i posted earlier using dagger, it's bit odd use case but hopefully I'll figure something out
#general message

hardy sentinel
#

oh yeah I remember. Yes solid use case for Dagger IMO 🙂

neat obsidian
#

also I want to modernize our ci/cd stuff at my day job as well, studying dagger for that as well.
We are building react-native mobile apps as internal tools and several web services around it. Would be nice to get rid of the duplicated code in yaml/bash/gradle files.
Liked the idea about dagger so much, thanks for building it!