Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f6c1c0d
first pass at a konflux dockerfile
weshayutin Mar 17, 2026
3140ae3
Merge pull request #7 from weshayutin/konflux16
openshift-merge-bot[bot] Mar 23, 2026
646364a
UPSTREAM: <carry>: Add package-lock.json for Konflux hermetic builds
mpryc Apr 8, 2026
c61d98d
Merge pull request #8 from mpryc/add-package-lock-json
openshift-merge-bot[bot] Apr 8, 2026
f8020bc
merge upstream/master into oadp-1.6
oadp-maintainers Apr 8, 2026
45d7184
UPSTREAM: <carry> Add disableUserProfile branding option
mpryc Oct 18, 2025
654a45c
UPSTREAM: <carry> Add defaultLoginUser branding option
mpryc Oct 18, 2025
61b769b
UPSTREAM: <carry> Disable delete and rename from Help
mpryc Oct 19, 2025
788b964
UPSTREAM: <carry> Containerfile to be used with UBI
mpryc Nov 12, 2025
1bb5780
UPSTREAM: <carry> Add OWNERS file
mpryc Feb 5, 2026
185c503
UPSTREAM: <carry> Fix broken rebase of branding options
mpryc Feb 9, 2026
5d06199
first pass at a konflux dockerfile
weshayutin Mar 17, 2026
3b7da96
UPSTREAM: <carry>: Add package-lock.json for Konflux hermetic builds
mpryc Apr 8, 2026
834a1e9
Merge pull request #6 from oadp-rebasebot/rebase-bot-oadp-1.6
openshift-merge-bot[bot] Apr 9, 2026
b8281c7
Use npm instead of pnpm for hermetic Konflux builds
mpryc Apr 9, 2026
c8d08f6
Regenerate package-lock.json with Node.js 24 / npm 11
mpryc Apr 9, 2026
3c20cb5
Merge pull request #9 from mpryc/fix-hermetic-pnpm-install
mpryc Apr 9, 2026
2c5ceaf
merge upstream/master into oadp-1.6
oadp-maintainers Apr 14, 2026
f1d8858
UPSTREAM: <carry> Add disableUserProfile branding option
mpryc Oct 18, 2025
c4213f5
UPSTREAM: <carry> Add defaultLoginUser branding option
mpryc Oct 18, 2025
b5f8905
UPSTREAM: <carry> Disable delete and rename from Help
mpryc Oct 19, 2025
383068a
UPSTREAM: <carry> Containerfile to be used with UBI
mpryc Nov 12, 2025
91f777f
UPSTREAM: <carry> Add OWNERS file
mpryc Feb 5, 2026
32843f6
UPSTREAM: <carry> Fix broken rebase of branding options
mpryc Feb 9, 2026
59af2d2
first pass at a konflux dockerfile
weshayutin Mar 17, 2026
a084690
UPSTREAM: <carry>: Add package-lock.json for Konflux hermetic builds
mpryc Apr 8, 2026
e2b5f61
Use npm instead of pnpm for hermetic Konflux builds
mpryc Apr 9, 2026
b5f4bd0
Regenerate package-lock.json with Node.js 24 / npm 11
mpryc Apr 9, 2026
71c1c28
UPSTREAM: <carry>: fix github actions
mpryc Apr 14, 2026
1d33dd8
Merge pull request #12 from oadp-rebasebot/rebase-bot-oadp-1.6
openshift-merge-bot[bot] Apr 14, 2026
f39aed0
filebrowser is not passing konflux builds
weshayutin May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- "master"
- "oadp-*"
tags:
- "v*"
pull_request:
Expand Down Expand Up @@ -52,7 +53,7 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.26.x"
go-version: "1.25.x"
- uses: golangci/golangci-lint-action@v9
with:
version: "latest"
Expand All @@ -64,7 +65,7 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.26.x"
go-version: "1.25.x"
- run: go test --race ./...

build:
Expand All @@ -76,7 +77,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.26'
go-version: '1.25'
- uses: pnpm/action-setup@v6
with:
package_json_file: "frontend/package.json"
Expand All @@ -100,7 +101,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.26'
go-version: '1.25'
- uses: pnpm/action-setup@v6
with:
package_json_file: "frontend/package.json"
Expand Down
30 changes: 2 additions & 28 deletions .github/workflows/lint-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,5 @@ jobs:
name: Validate Title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v6
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: marocchino/sticky-pull-request-comment@v3
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.

Details:

```
${{ steps.lint_pr_title.outputs.error_message }}
```

# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@v3
with:
header: pr-title-lint-error
delete: true
- name: Skip
run: echo "Validate Title is disabled for downstream"
128 changes: 128 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
## Multi-stage build for File Browser

# =============================================================================
# Stage 1: Install frontend dependencies only when needed
# =============================================================================
FROM registry.access.redhat.com/ubi9/nodejs-24:latest AS frontend-deps

USER 0
WORKDIR /app

# Install pnpm globally
RUN npm install -g pnpm@10.29.2

# Copy only dependency files for better layer caching
COPY frontend/package.json frontend/pnpm-lock.yaml ./

# Install dependencies
RUN pnpm install --frozen-lockfile

# =============================================================================
# Stage 2: Build frontend
# =============================================================================
FROM registry.access.redhat.com/ubi9/nodejs-24:latest AS frontend-builder

USER 0
WORKDIR /app

# Install pnpm (needed for build scripts)
RUN npm install -g pnpm@10.29.2

# Copy node_modules from deps stage
COPY --from=frontend-deps /app/node_modules ./node_modules

# Copy frontend source
COPY frontend/ ./

# Build the frontend
RUN pnpm run build

# =============================================================================
# Stage 3: Build Go backend
# =============================================================================
FROM --platform=$BUILDPLATFORM quay.io/konveyor/builder:ubi9-latest AS backend-builder

USER root

# Build-time arguments
ARG BUILDPLATFORM
ARG TARGETOS
ARG TARGETARCH
ARG VERSION
ARG VERSION_HASH

# Set environment for cross-compilation
ENV GOOS=${TARGETOS:-linux}
ENV GOARCH=${TARGETARCH}
ENV CGO_ENABLED=0
ENV GOTOOLCHAIN=auto

WORKDIR /src

# Copy go module files first for better layer caching
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Copy built frontend from previous stage
COPY --from=frontend-builder /app/dist ./frontend/dist

# Build the backend with embedded frontend
RUN go build -ldflags "-s -w \
-X 'github.com/filebrowser/filebrowser/v2/version.Version=${VERSION:-dev}' \
-X 'github.com/filebrowser/filebrowser/v2/version.CommitSHA=${VERSION_HASH:-unknown}'" \
-o filebrowser .

# =============================================================================
# Stage 4: Final runtime image - minimal footprint
# =============================================================================
FROM registry.access.redhat.com/ubi9-minimal:latest

# Labels for container metadata
LABEL name="filebrowser" \
summary="File Browser - Web-based file manager" \
description="A web-based file manager with support for multiple users and permissions" \
io.k8s.display-name="File Browser" \
io.k8s.description="A web-based file manager with support for multiple users and permissions" \
io.openshift.tags="filebrowser,filemanager,web"

# Install runtime dependencies and clean up in single layer
RUN microdnf install -y --nodocs \
ca-certificates \
tzdata \
shadow-utils \
curl-minimal && \
microdnf clean all && \
rm -rf /var/cache/yum

# Create non-root user and required directories
RUN groupadd -g 1001 filebrowser && \
useradd -u 1001 -g filebrowser -s /sbin/nologin -M filebrowser && \
mkdir -p /srv /config /database && \
chown -R 1001:1001 /srv /config /database

# Copy binary from builder
COPY --from=backend-builder --chown=1001:1001 /src/filebrowser /usr/local/bin/filebrowser

# Copy healthcheck script
COPY --chown=1001:1001 docker/ubi/healthcheck.sh /usr/local/bin/healthcheck.sh
RUN chmod +x /usr/local/bin/healthcheck.sh

# Switch to non-root user (using numeric ID for OpenShift compatibility)
USER 1001

# Define volumes for persistent data
VOLUME ["/srv", "/config", "/database"]

# Expose default port
EXPOSE 8080

# Healthcheck using the script
HEALTHCHECK --start-period=5s --interval=30s --timeout=3s --retries=3 \
CMD ["/usr/local/bin/healthcheck.sh"]

# Direct entrypoint - configuration via FB_* environment variables
ENTRYPOINT ["/usr/local/bin/filebrowser"]
CMD []
16 changes: 16 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
approvers:
- joeavaikath
- kaovilai
- mpryc
- rayfordj
- shawn-hurley
- shubham-pampattiwar
- sseago
- weshayutin
reviewers:
- joeavaikath
- kaovilai
- mpryc
- shubham-pampattiwar
- sseago
- weshayutin
15 changes: 12 additions & 3 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("branding.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")

flags.Uint64("tus.chunkSize", settings.DefaultTusChunkSize, "the tus chunk size")
flags.Uint16("tus.retryCount", settings.DefaultTusRetryCount, "the tus retry count")
flags.Bool("branding.disableUserProfile", false, "disable user profile in sidebar and settings/profile page")
flags.String("branding.defaultLoginUser", "", "default username for login (hides username field)")
// NB: these are string so they can be presented as octal in the help text
// as that's the conventional representation for modes in Unix.
flags.String("file-mode", fmt.Sprintf("%O", settings.DefaultFileMode), "Mode bits that new files are created with")
flags.String("dir-mode", fmt.Sprintf("%O", settings.DefaultDirMode), "Mode bits that new directories are created with")
}

func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
Expand Down Expand Up @@ -212,6 +215,8 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal)
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
fmt.Fprintf(w, "\tDisable user profile:\t%t\n", set.Branding.DisableUserProfile)
fmt.Fprintf(w, "\tDefault login user:\t%s\n", set.Branding.DefaultLoginUser)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
fmt.Fprintf(w, "\tTheme:\t%s\n", set.Branding.Theme)

Expand Down Expand Up @@ -349,6 +354,10 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
set.Branding.DisableExternal, err = flags.GetBool(flag.Name)
case "branding.disableUsedPercentage":
set.Branding.DisableUsedPercentage, err = flags.GetBool(flag.Name)
case "branding.disableUserProfile":
set.Branding.DisableUserProfile, err = flags.GetBool(flag.Name)
case "branding.defaultLoginUser":
set.Branding.DefaultLoginUser, err = flags.GetString(flag.Name)
case "tus.chunkSize":
set.Tus.ChunkSize, err = flags.GetUint64(flag.Name)
case "tus.retryCount":
Expand Down
44 changes: 44 additions & 0 deletions doc/eliminate-es5-ext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Eliminate es5-ext via pnpm Override

## Background

- **Problem:** `es5-ext@0.10.64` is a transitive dependency pulled in via `vue-reader` -> `epubjs@0.3.93` -> `event-emitter` -> `es5-ext`
- **CVE-2024-27088** (ReDoS, CVSS 0.0) is already patched in the installed version, but eliminating es5-ext entirely removes future risk

## Chosen Approach: pnpm Override with @likecoin/epub-ts

[@likecoin/epub-ts](https://github.com/likecoin/epub.ts) (v0.6.3, Apr 2026) is a TypeScript rewrite of epubjs v0.3.93 that:
- Has the **exact same API** (drop-in replacement, "change one import line")
- Has only **1 runtime dependency** (`jszip`) -- no es5-ext, no event-emitter, no d, no es6-iterator
- Is 56.7% smaller bundle, significantly faster
- Exports all the same classes: `Book`, `Rendition`, `Themes`, `Contents`, etc.
- Supports `requestCredentials`, `getRendition`, `themes.override` -- everything used in `frontend/src/views/files/Preview.vue`

## Implementation

Add to `frontend/package.json`:

```json
"pnpm": {
"overrides": {
"epubjs": "npm:@likecoin/epub-ts@^0.6.3"
}
}
```

Then run `pnpm install` to regenerate the lockfile.

## What This Does

- When `vue-reader` (or any other package) imports `epubjs`, pnpm resolves it to `@likecoin/epub-ts` instead
- The existing `import type { Rendition } from "epubjs"` in Preview.vue continues to work (the alias covers type resolution too)
- No code changes needed in any `.vue` or `.ts` files
- The entire es5-ext dependency tree (`es5-ext`, `es6-iterator`, `es6-symbol`, `esniff`, `event-emitter`, `d`, `next-tick`) is removed from the lockfile

## Why Not vue-book-reader

After deeper research, `vue-book-reader` is **not viable** for this project:
- Does not support `requestCredentials` (needed for authenticated EPUB fetching)
- Does not expose `getRendition` (needed for theme/font-size control)
- Only 12 GitHub stars (low adoption for production use)
- Completely different rendering engine (foliate-js) requiring significant code rewrite
10 changes: 10 additions & 0 deletions docker/ubi/healthcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
PORT=${FB_PORT:-8080}
ADDRESS=${FB_ADDRESS:-0.0.0.0}

# Use localhost for healthcheck when binding to 0.0.0.0
if [ "${ADDRESS}" = "0.0.0.0" ]; then
ADDRESS="localhost"
fi

curl -f -s "http://${ADDRESS}:${PORT}/health" > /dev/null || exit 1
1 change: 1 addition & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
Color: "",
DisableExternal: false,
DisableUsedPercentage: false,
DisableUserProfile: false,
EnableExec: true,
EnableThumbs: true,
LogoutPage: "",
Expand Down
Loading
Loading