diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ca55db7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.jj +.git +node_modules/ +container +.idea +.next diff --git a/.github/workflows/container-build.yaml b/.github/workflows/container-build.yaml new file mode 100644 index 0000000..4cb032f --- /dev/null +++ b/.github/workflows/container-build.yaml @@ -0,0 +1,54 @@ +name: container-build.yaml +on: + push: + branches: + - prescient + pull_request: +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} +jobs: + bake: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Validate build configuration + uses: docker/bake-action@v6 + with: + files: | + ./container/docker-bake.hcl + targets: validate-build + - name: Build and push + id: push + uses: docker/bake-action@v6 + env: + SOURCE_DATE_EPOCH: 0 + with: + targets: dashboard + push: ${{ github.event_name != 'pull_request' }} # Push if not a pull request + pull: true + provenance: mode=min + sbom: true + files: | + ./container/docker-bake.hcl + cwd://${{ steps.meta.outputs.bake-file }} + set: | + *.cache-from=type=gha + *.cache-to=type=gha,mode=max diff --git a/.gitignore b/.gitignore index 5ef6a52..fd8392e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Ignore mise-en-plase config +mise.* + diff --git a/container/Dockerfile b/container/Dockerfile new file mode 100644 index 0000000..db44df1 --- /dev/null +++ b/container/Dockerfile @@ -0,0 +1,38 @@ +# see docker-bake.hcl for definition of nodejs_lts context + +# Install npm dependencies +FROM nodejs_lts AS deps +WORKDIR /app +COPY package.json package-lock.json* ./ +RUN npm ci + +# Build nextjs app using dependencies above +FROM nodejs_lts AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN npm run build + +# Build the actual container +FROM nodejs_lts AS runner + +# Create a non-root user to own the process +RUN addgroup -g 1001 -S nodejs +RUN adduser -S nextjs -u 1001 + +# Copy files from builders +COPY --from=builder /app/public ./public + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" +CMD ["node","server.js"] + diff --git a/container/docker-bake.hcl b/container/docker-bake.hcl new file mode 100644 index 0000000..be6502a --- /dev/null +++ b/container/docker-bake.hcl @@ -0,0 +1,16 @@ +// docker-bake.hcl +target "docker-metadata-action" {} + +target "dashboard" { + inherits = ["docker-metadata-action"] + context = "." + description = "Builds a containerised version of the dashboard" + contexts = { + nodejs_lts = "docker-image://node:24-alpine" + } + dockerfile = "container/Dockerfile" + tags = [ + "ghcr.io/dptools/dashboard:latest", // pseudo container name + ] +} + diff --git a/next.config.ts b/next.config.ts index e9ffa30..12cecbe 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: "standalone", }; export default nextConfig; diff --git a/package.json b/package.json index 11bffc1..f4430ec 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "dev": "next dev --turbopack", "build": "next build", + "build:container": "docker buildx bake -f container/docker-bake.hcl dashboard", "start": "next start", "lint": "next lint", "preview": "next build && next start"