# Multi-stage build: compile frontend + backend, then package # This is a full build Dockerfile for filebrowser from source ############################################################################## # Stage 1: Build frontend (Node.js / pnpm) ############################################################################## FROM node:20-alpine AS frontend-builder RUN corepack enable && corepack prepare pnpm@latest --activate WORKDIR /app/frontend COPY frontend/package.json frontend/pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile COPY frontend/ ./ RUN pnpm run build ############################################################################## # Stage 2: Build backend (Go) ############################################################################## FROM golang:1.25-alpine AS backend-builder RUN apk add --no-cache git WORKDIR /app COPY . . COPY --from=frontend-builder /app/frontend/dist ./frontend/dist RUN go mod tidy && go mod download ARG VERSION=dev ARG GIT_COMMIT=unknown RUN CGO_ENABLED=0 go build \ -ldflags="-s -w -X 'github.com/filebrowser/filebrowser/v2/version.Version=${VERSION}' -X 'github.com/filebrowser/filebrowser/v2/version.CommitSHA=${GIT_COMMIT}'" \ -o filebrowser . ############################################################################## # Stage 3: Fetch runtime dependencies ############################################################################## FROM alpine:3.23 AS fetcher RUN apk update && \ apk --no-cache add ca-certificates mailcap tini-static && \ wget -O /JSON.sh https://raw.githubusercontent.com/dominictarr/JSON.sh/0d5e5c77365f63809bf6e77ef44a1f34b0e05840/JSON.sh ############################################################################## # Stage 4: Final runtime image (Alpine with ffmpeg) ############################################################################## FROM alpine:3.23 ENV UID=1000 ENV GID=1000 RUN addgroup -g $GID user && \ adduser -D -u $UID -G user user && \ apk add --no-cache ffmpeg flac # Copy compiled binary from backend-builder COPY --from=backend-builder --chown=user:user /app/filebrowser /bin/filebrowser # Copy scripts and configs from repo COPY --chown=user:user docker/common/ / COPY --chown=user:user docker/alpine/ / # Copy runtime deps from fetcher COPY --chown=user:user --from=fetcher /sbin/tini-static /bin/tini COPY --from=fetcher /JSON.sh /JSON.sh COPY --from=fetcher /etc/ca-certificates.conf /etc/ca-certificates.conf COPY --from=fetcher /etc/ca-certificates /etc/ca-certificates COPY --from=fetcher /etc/mime.types /etc/mime.types COPY --from=fetcher /etc/ssl /etc/ssl RUN mkdir -p /config /database /srv && \ chown -R user:user /config /database /srv && \ chmod +x /healthcheck.sh HEALTHCHECK --start-period=2s --interval=5s --timeout=3s CMD /healthcheck.sh USER user VOLUME /srv /config /database EXPOSE 80 ENTRYPOINT [ "tini", "--", "/init.sh" ]