Harbor: Mobile-responsive CSS via nginx sub_filter injection #345

Closed
opened 2026-05-06 00:09:57 +00:00 by forgejo_admin · 0 comments
Contributor

Type

Feature

Lineage

Standalone -- discovered during SSO wiring session (2026-05-05). Phase 2.5: mobile access for SSO'd services.

Repo

ldraney/pal-e-platform

User Story

As a platform admin on mobile,
I want Harbor's UI to be usable on my phone
So that I can check image repos and scan results without a laptop.

Context

Harbor portal is an Angular app served by nginx from /usr/share/nginx/html/. Its global.scss (481 lines) has zero responsive breakpoints -- it was never designed for mobile.

How the fix works: nginx sub_filter is a text-replacement directive that modifies the HTML response before it reaches the browser. We configure Harbor's portal nginx to find </head> and replace it with <link rel="stylesheet" href="/custom.css"></head>. The browser then loads our custom CSS on top of Harbor's existing styles. Our CSS adds @media queries that only activate on narrow screens -- desktop stays identical. Requires proxy_set_header Accept-Encoding "" because sub_filter can't search gzipped responses.

Two viable approaches confirmed by investigation:

  1. Nginx sub_filter (recommended): Override portal nginx ConfigMap to inject CSS link. Mount custom CSS file at /usr/share/nginx/html/custom.css.
  2. Custom portal image (durable): Fork goharbor/harbor-portal, add media queries to src/portal/src/global.scss, set portal.image.repository in Helm values.

Branding config at setting.json supports headerBgColor, loginBgImg, product.name, product.logo but no custom CSS field. Helm chart (v1.18.2) exposes portal.initContainers but lacks extraVolumes/extraVolumeMounts.

File Targets

Files the agent should modify or create:

  • terraform/modules/harbor/main.tf -- add nginx config override and/or custom CSS volume mount to Helm values
  • terraform/modules/harbor/variables.tf -- new variables if needed for CSS config

Files the agent should NOT touch:

  • terraform/modules/storage/main.tf -- MinIO is a separate ticket
  • terraform/modules/forgejo/main.tf -- Forgejo is a separate ticket

Acceptance Criteria

  • Harbor UI is usable on 390px mobile viewport (navigation, project list, image list, scan results)
  • CSS injection wired through Terraform Helm values (not manual kubectl patch)
  • Mobile-first responsive CSS: base styles for phone, @media (min-width: 600px) for desktop
  • No regressions on desktop layout
  • Approach survives Helm upgrades without manual intervention

Test Expectations

  • tofu validate passes
  • tofu plan -lock=false shows expected changes to Harbor Helm release
  • Manual: verify Harbor UI on mobile browser after apply

Constraints

  • Must use nginx sub_filter approach or custom image -- no kubectl patch
  • Follow existing Terraform module patterns in terraform/modules/harbor/
  • CSS must target navigation, sidebar, tables, and form layouts for narrow viewports
  • Mobile-first breakpoint at 600px per platform CSS philosophy

Checklist

  • PR opened
  • tofu validate passes
  • No unrelated changes
  • project-pal-e-platform -- platform project
  • #338 -- SSO: Wire Harbor OIDC (completed)
### Type Feature ### Lineage Standalone -- discovered during SSO wiring session (2026-05-05). Phase 2.5: mobile access for SSO'd services. ### Repo `ldraney/pal-e-platform` ### User Story As a platform admin on mobile, I want Harbor's UI to be usable on my phone So that I can check image repos and scan results without a laptop. ### Context Harbor portal is an Angular app served by nginx from `/usr/share/nginx/html/`. Its `global.scss` (481 lines) has zero responsive breakpoints -- it was never designed for mobile. **How the fix works:** nginx `sub_filter` is a text-replacement directive that modifies the HTML response before it reaches the browser. We configure Harbor's portal nginx to find `</head>` and replace it with `<link rel="stylesheet" href="/custom.css"></head>`. The browser then loads our custom CSS on top of Harbor's existing styles. Our CSS adds `@media` queries that only activate on narrow screens -- desktop stays identical. Requires `proxy_set_header Accept-Encoding ""` because sub_filter can't search gzipped responses. Two viable approaches confirmed by investigation: 1. **Nginx sub_filter** (recommended): Override portal nginx ConfigMap to inject CSS link. Mount custom CSS file at `/usr/share/nginx/html/custom.css`. 2. **Custom portal image** (durable): Fork `goharbor/harbor-portal`, add media queries to `src/portal/src/global.scss`, set `portal.image.repository` in Helm values. Branding config at `setting.json` supports `headerBgColor`, `loginBgImg`, `product.name`, `product.logo` but no custom CSS field. Helm chart (v1.18.2) exposes `portal.initContainers` but lacks `extraVolumes`/`extraVolumeMounts`. ### File Targets Files the agent should modify or create: - `terraform/modules/harbor/main.tf` -- add nginx config override and/or custom CSS volume mount to Helm values - `terraform/modules/harbor/variables.tf` -- new variables if needed for CSS config Files the agent should NOT touch: - `terraform/modules/storage/main.tf` -- MinIO is a separate ticket - `terraform/modules/forgejo/main.tf` -- Forgejo is a separate ticket ### Acceptance Criteria - [ ] Harbor UI is usable on 390px mobile viewport (navigation, project list, image list, scan results) - [ ] CSS injection wired through Terraform Helm values (not manual kubectl patch) - [ ] Mobile-first responsive CSS: base styles for phone, `@media (min-width: 600px)` for desktop - [ ] No regressions on desktop layout - [ ] Approach survives Helm upgrades without manual intervention ### Test Expectations - [ ] `tofu validate` passes - [ ] `tofu plan -lock=false` shows expected changes to Harbor Helm release - [ ] Manual: verify Harbor UI on mobile browser after apply ### Constraints - Must use nginx sub_filter approach or custom image -- no kubectl patch - Follow existing Terraform module patterns in `terraform/modules/harbor/` - CSS must target navigation, sidebar, tables, and form layouts for narrow viewports - Mobile-first breakpoint at 600px per platform CSS philosophy ### Checklist - [ ] PR opened - [ ] `tofu validate` passes - [ ] No unrelated changes ### Related - `project-pal-e-platform` -- platform project - `#338` -- SSO: Wire Harbor OIDC (completed)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/pal-e-platform#345
No description provided.