#6654·formbricks

Shrink the Docker build context and make the install layer cacheable (.dockerignore + Dockerfile)

Author: tomokinakamaruCreated Oct 6, 2025Updated Sep 11, 2026
Labelsrefactor

Scope (widened 2026-09-03)

Originally opened from GitHub issue #6654, which pointed out that .dockerignore was written with .gitignore semantics (for example npm-debug.log* only matches at the top level in Docker; it needs **/npm-debug.log*). A configuration scan on 2026-09-03 found the same file has bigger gaps, and that the Dockerfile layering makes every image build slower than it needs to be. Fix all of it in one pass.

Four things in .dockerignore and apps/web/Dockerfile:

  • .dockerignore never excludes .git (92 MB), docs/ (19 MB), charts/, .github/, apps/storybook or apps/web/playwright. All of it is uploaded as build context and copied into the installer layer on every build.
  • It lists packages/database/migrations (see ENG-2410 for whether that path is still generated) and re-includes packages/database/.env, a file that is no longer tracked. Patterns copied from .gitignore need the **/ prefix to match below the root.
  • The Dockerfile runs COPY . . before pnpm install, so a one-line source edit re-runs the full install. docker-build-validation.yml documents that layer caching was measured as useless for exactly this reason ("reorder the Dockerfile so the install layer survives a source change").
  • The installer stage installs cmake, g++, gcc, make, python3 and openssl-dev, then runs pnpm install --ignore-scripts, so no native module is ever compiled with them.

Done when

  • .dockerignore extended with the paths above, **/ prefixes fixed, stale entries removed.
  • Dockerfile copies pnpm-lock.yaml, pnpm-workspace.yaml, patches/ and the package manifests first, runs pnpm fetch with a BuildKit cache mount, then copies sources and installs offline.
  • apk toolchain verified unused (sharp ships prebuilt linuxmusl binaries) and dropped.
  • docker-build-validation.yml passes; image size and build time before/after recorded in the PR.
  • Follow-up: revisit the registry cache the workflow comment describes, now that the install layer can survive a source change.

Surfaced in a configuration scan with Claude Fable 5.1 on 2026-09-03 (main @ 8c3b9ec). Full audit: https://claude.ai/code/artifact/e052d7a8-49f3-4d7a-8f02-e05be278920b


Original report (GitHub #6654)

Hello, and thank you for your work on this repository!

As part of my research, I am analyzing how developers configure .dockerignore in popular repositories.

During my analysis, I noticed that /.dockerignore might have been written under the assumption that .dockerignore and .gitignore follow the same pattern semantics, while they actually differ. In particular, the following pattern drew my attention:

https://github.com/formbricks/formbricks/blob/84294f9df2199236d2ffee0758165c804737369d/.dockerignore#L26

According to Docker's specification, this pattern matches npm-debug.log* only in the top-level directory. (To ignore npm-debug.log* in any directory, the .dockerignore file needs to list **/npm-debug.log*)

See the .gitignore doc, the .dockerignore doc, and a blog post about the differences.