{"id":24433733,"url":"https://github.com/gowebprod/k8s-static-server","last_synced_at":"2026-04-22T18:32:38.114Z","repository":{"id":272183723,"uuid":"915759896","full_name":"GoWebProd/k8s-static-server","owner":"GoWebProd","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-30T18:15:34.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-28T06:14:25.298Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoWebProd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-12T18:18:28.000Z","updated_at":"2025-10-30T18:15:39.000Z","dependencies_parsed_at":"2025-01-12T19:32:02.709Z","dependency_job_id":"9f21eea2-6235-4974-b9c9-7e1fa5a3a58c","html_url":"https://github.com/GoWebProd/k8s-static-server","commit_stats":null,"previous_names":["gowebprod/k8s-static-server"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/GoWebProd/k8s-static-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoWebProd%2Fk8s-static-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoWebProd%2Fk8s-static-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoWebProd%2Fk8s-static-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoWebProd%2Fk8s-static-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoWebProd","download_url":"https://codeload.github.com/GoWebProd/k8s-static-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoWebProd%2Fk8s-static-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32149481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T17:06:48.269Z","status":"ssl_error","status_checked_at":"2026-04-22T17:06:19.037Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-20T16:50:41.344Z","updated_at":"2026-04-22T18:32:38.099Z","avatar_url":"https://github.com/GoWebProd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# k8s-static-server\n\n## Installation\n\n```bash\ngit clone https://github.com/GoWebProd/k8s-static-server.git\nhelm install -n static --create-namespace static-server ./k8s-static-server\n```\n\n## Creating static server\n\n```yaml\napiVersion: static-server.webprod.io/v1\nkind: StaticRepo\nmetadata:\n  name: roubi\n  namespace: static\nspec:\n  hostname: roubi.fake.com\n  git:\n    repo: SOME_REPO\n    commit: SOME_COMMIT\n\n---\n\napiVersion: static-server.webprod.io/v1\nkind: StaticRepo\nmetadata:\n  name: voyah\n  namespace: static\nspec:\n  hostname: voyah.fake.com\n  cmd:\n    image: alpine/git:latest\n    command:\n      - /bin/sh\n      - -c\n      - echo $DATA_DIR \u0026\u0026 mkdir -p $DATA_DIR/cunbaemul/otan/ \u0026\u0026 echo \"999999999\" \u003e $DATA_DIR/cunbaemul/otan/activate3\n\n---\n\napiVersion: static-server.webprod.io/v1\nkind: StaticRepo\nmetadata:\n  name: wiki\n  namespace: static\nspec:\n  hostname: docmost.fake.com\n  imageDir:\n    image: docmost/docmost:0.6.2\n    path: /app/apps/client/dist/\n```\n\n## Server-Side Rendering (SSR)\n\nThe static-server supports Server-Side Rendering with Node.js for dynamic content. When SSR is enabled, a Node.js sidecar container is automatically added to handle SSR requests while nginx serves static assets.\n\n### Prerequisites\n\n- Your SSR application should be pre-built and include a `server.js` (or custom entrypoint) that exports a request handler\n- The handler should be compatible with Express.js middleware signature: `(req, res, next) =\u003e {}`\n- All dependencies should be bundled with your application code\n\n### Example: Next.js with SSR\n\n```yaml\napiVersion: static-server.webprod.io/v1\nkind: StaticRepo\nmetadata:\n  name: nextjs-app\n  namespace: static\nspec:\n  hostname: app.example.com\n  imageDir:\n    image: registry.example.com/my-nextjs-app:v1.0.0\n    path: /app/.next/standalone\n  imagePullSecrets:\n    - name: regcred\n  ssr:\n    enabled: true\n    entryPoint: server.js  # Optional, defaults to \"server.js\"\n    envVars:\n      - name: PORT\n        value: \"3000\"\n      - name: NEXT_PUBLIC_API_URL\n        value: \"https://api.example.com\"\n```\n\n### How it works\n\n1. **Routing**: nginx tries to serve static files first, then falls back to the Node.js SSR server\n2. **Static assets** (`.js`, `.css`, images) are always served by nginx for performance\n3. **API routes** (e.g., `/api/*`, `/_next/*`) are proxied directly to Node.js (never cached)\n4. **Dynamic pages** that don't have static files are handled by SSR\n\n### SSR Response Caching\n\nSSR responses are cached by nginx to reduce Node.js load and improve performance:\n\n- **Cache size**: 100MB by default (configurable via `ssr.cache.size`)\n- **Cache TTL**: 60 seconds for successful responses (configurable via `ssr.cache.ttl`)\n- **Cache key**: `$scheme$host$request_uri` (varies by protocol, hostname, and path)\n\n**Cache is bypassed for:**\n- Requests with `Authorization` header (authenticated users)\n- Non-GET/HEAD requests (POST, PUT, DELETE, PATCH)\n- Requests with `X-No-Cache` header\n\n**Debugging cache:**\nCheck the `X-Cache-Status` response header:\n- `HIT` - served from cache\n- `MISS` - not in cache, proxied to Node.js\n- `BYPASS` - cache bypassed due to conditions\n- `EXPIRED` - cache expired, updating\n\n**Disable caching:**\n```yaml\n# values.yaml\nssr:\n  cache:\n    enabled: false\n```\n\n### SSR Server Requirements\n\nYour `server.js` should export a handler function:\n\n```javascript\n// CommonJS\nmodule.exports = function(req, res, next) {\n  // Your SSR logic here\n  res.send('\u003chtml\u003e...\u003c/html\u003e');\n};\n\n// or ES modules\nexport default function(req, res, next) {\n  // Your SSR logic here\n};\n\n// or Next.js standalone server\nconst NextServer = require('next/dist/server/next-server').default;\nmodule.exports = function(req, res) {\n  const server = new NextServer({...});\n  return server.getRequestHandler()(req, res);\n};\n```\n\n### Multiple SSR Sites\n\nMultiple StaticRepo resources can have SSR enabled. A single Node.js process handles all SSR-enabled sites, routing requests based on the `Host` header.\n\nSee [examples/staticrepo-with-ssr.yaml](examples/staticrepo-with-ssr.yaml) for more examples.\n\n## Creating ingress\n\n```yaml\nkind: Service\napiVersion: v1\nmetadata:\n  name: static-server\n  namespace: application\nspec:\n  type: ExternalName\n  externalName: static-server.static.svc.cluster.local\n\n---\n\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: static-server\n  namespace: application\nspec:\n  rules:\n    - host: roubi.fake.com\n      http: \u0026httpTemplate\n        paths:\n          - pathType: Prefix\n            path: /\n            backend:\n              service:\n                name: static-server\n                port:\n                  number: 80\n    - host: voyah.fake.com\n      http: *httpTemplate\n    - host: docmost.fake.com\n      http: *httpTemplate\n  tls:\n    - hosts:\n        - roubi.fake.com\n        - voyah.fake.com\n        - docmost.fake.com\n      secretName: static-server-cert\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgowebprod%2Fk8s-static-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgowebprod%2Fk8s-static-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgowebprod%2Fk8s-static-server/lists"}