Edit history

Dockerfile doesn't build from source for self-hosted deployment has not been edited, so there are no earlier versions.

Current version | Original by Rex
Show

Dockerfile doesn't build from source for self-hosted deployment

Description

I used Claude to find and track all of its fixes, but I do not want to push AI generated code into a public repo, and felt it would be better to solve the issues in the way the project owners want to. Hell these may be by design I dont know, but I think it points to valuable details to get the self-hosting side up and running faster. Building fluxer-server from source using the refactor branch's fluxer_server/Dockerfile fails at multiple stages. The Dockerfile appears to be designed for CI/CD with pre-built artifacts or a private registry, and several steps are missing or broken for building from a fresh clone. The GHCR image (ghcr.io/fluxerapp/fluxer-server:stable) requires authentication, so building from source is the only option for self-hosters.

Environment

  • Branch: refactor
  • Build command: docker build -t fluxer-server:local -f fluxer_server/Dockerfile .
  • Host OS: Ubuntu 24.04

Issue 1: Missing ca-certificates in build stage

Symptom: The app-build stage needs to download the Rust toolchain (rustup) for WASM compilation, but curl fails with SSL certificate verification errors. Root cause: The slim Debian base image used in the deps stage doesn't include the ca-certificates package. Without it, any HTTPS request from within the build container fails.

Issue 2: .dockerignore excludes files needed for the build

Symptom: TypeScript compilation fails with errors about missing locale message files (messages.js), missing emojis.json, and missing build scripts. Root cause: The .dockerignore file has overly aggressive exclusion patterns:
  • **/build catches fluxer_app/scripts/build/rspack/lingui.mjs (needed for locale compilation)
  • Locale files (/fluxer_app/src/locales/*/messages.js) are excluded but TypeScript imports reference them
  • /fluxer_app/src/data/emojis.json is excluded but imported by the app
These exclusions are likely intended for production deployment (where these files are pre-built), but they break building from a fresh source clone.

Issue 3: FLUXER_CONFIG environment variable not set during frontend build

Symptom: The rspack build crashes immediately with FLUXER_CONFIG must be set. Root cause: The rspack config (fluxer_app/rspack.config.mjs) imports the Fluxer config to derive API endpoint URLs that get baked into the frontend bundle. The Dockerfile doesn't set this environment variable or copy the config template before running the frontend build. The config template at config/config.production.template.json exists in the repo and should be used, with the domain placeholder (chat.example.com) replaced via a build arg.

Issue 4: CDN endpoint || fallback ignores empty string

Symptom: After building, all JavaScript and CSS asset URLs point to https://fluxerstatic.com instead of being served from the same origin. The self-hosted instance tries to load bundles from the public CDN, which either fails or serves the wrong version. Root cause: In fluxer_app/rspack.config.mjs, the CDN endpoint defaults using JavaScript's || operator:
const CDN_ENDPOINT = process.env.FLUXER_CDN_ENDPOINT || 'https://fluxerstatic.com';
Setting FLUXER_CDN_ENDPOINT="" (empty string, correct for self-hosting) still falls through to the CDN URL because "" is falsy in JavaScript. The in operator or nullish coalescing (?? with explicit undefined) should be used instead.

Issue 5: Dockerfile COPY list doesn't match actual packages

Symptom: Build fails with "package.json not found" errors for packages that have been added or renamed since the Dockerfile was last updated. Root cause: The deps stage has hardcoded COPY lines for each package's package.json. The actual packages in the monorepo (ls packages/) don't match the list in the Dockerfile. Some packages referenced in the Dockerfile don't exist, and some packages in the repo are missing from the Dockerfile.

Issue 6: Wrong ENTRYPOINT

Symptom: Container starts but immediately fails with Missing script: start or runs the wrong package. Root cause: The ENTRYPOINT is ["pnpm", "start"] which tries to run the start script from the root workspace. The root package.json has no start script. It should be ["pnpm", "--filter", "fluxer_server", "start"].

Issue 7: Admin panel CSS not built

Symptom: The admin panel at /admin loads but is completely unstyled — /admin/static/app.css returns 404. Root cause: The Dockerfile builds the marketing CSS (pnpm --filter @fluxer/marketing build:css) but doesn't build the admin panel CSS. A pnpm --filter @fluxer/admin build:css step is needed.

Steps to Reproduce

  1. Clone the refactor branch
  2. Run docker build -t fluxer-server:local -f fluxer_server/Dockerfile .
  3. Observe failures at each stage (in the order listed above — fixing each reveals the next)

Suggestion

A self-hosting section in the README or a dedicated Dockerfile.selfhost that handles the full build from source would be very helpful for the community. I've successfully built and deployed from source after working through all of these issues and can confirm the application works well once built correctly.

Reference

Full deployment guide with all 20 gotchas: https://gist.github.com/PaulMColeman/e7ef82e05035b24300d2ea1954527f10