{"id":51144232,"url":"https://github.com/asm0dey/fb2cng-web","last_synced_at":"2026-06-26T01:30:46.429Z","repository":{"id":362937782,"uuid":"1261357413","full_name":"asm0dey/fb2cng-web","owner":"asm0dey","description":"Self-hosted web UI for fb2cng: drop fb2/fb2.zip, get EPUB/kepub/kfx/azw8/pdf back. Multi-arch (amd64+arm64) Docker image, optional Authelia forward-auth.","archived":false,"fork":false,"pushed_at":"2026-06-24T07:05:54.000Z","size":109,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-26T01:30:44.578Z","etag":null,"topics":["docker","ebook","ebook-converter","epub","fb2","fb2cng","fictionbook","golang","kepub","kindle","multi-arch","self-hosted"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asm0dey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2026-06-06T15:22:43.000Z","updated_at":"2026-06-24T07:05:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/asm0dey/fb2cng-web","commit_stats":null,"previous_names":["asm0dey/fb2cng-web"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/asm0dey/fb2cng-web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asm0dey%2Ffb2cng-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asm0dey%2Ffb2cng-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asm0dey%2Ffb2cng-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asm0dey%2Ffb2cng-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asm0dey","download_url":"https://codeload.github.com/asm0dey/fb2cng-web/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asm0dey%2Ffb2cng-web/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34799570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["docker","ebook","ebook-converter","epub","fb2","fb2cng","fictionbook","golang","kepub","kindle","multi-arch","self-hosted"],"created_at":"2026-06-26T01:30:43.060Z","updated_at":"2026-06-26T01:30:46.414Z","avatar_url":"https://github.com/asm0dey.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fb2cng-web\n\nWeb interface for [fb2cng](https://github.com/rupor-github/fb2cng): drop `fb2` / `fb2.zip`\nfiles, get EPUB (or kepub/kfx/azw8/pdf) back automatically.\n\n## Run\n\n    docker build -t fb2cng-web .\n    docker run --rm -p 8080:8080 fb2cng-web\n\n\u003e The image is built on BellSoft Alpaquita Linux (musl); the production runtime stage uses\n\u003e the hardened Alpaquita base (`bellsoft/hardened-base:musl`) — minimal, non-root (UID 65532),\n\u003e no shell or package manager. The app writes conversion temp files to `/tmp`; the hardened\n\u003e base ships a writable `/tmp`, so this works out of the box. If you run with a read-only root\n\u003e filesystem, mount a writable `/tmp` (e.g. `--tmpfs /tmp:rw,mode=1777`, as the compose example shows).\n\nOpen http://localhost:8080. Defaults work out of the box; expand **Settings** to change\nformat, ToC, images, footnotes, or paste/upload a full fbc YAML config.\n\n## Versioning \u0026 images\n\nImages are published to GitHub Container Registry on every push to `main` and\nwhenever a new [`fbc`](https://github.com/rupor-github/fb2cng) release appears.\n\nTags follow `\u003capp-version\u003e-\u003cfbc-version\u003e` (the `fbc` tag's leading `v` is dropped),\ne.g. `1-1.4.5`, plus a moving `latest`:\n\n    docker pull ghcr.io/\u003cowner\u003e/fb2cng-web:latest\n    docker pull ghcr.io/\u003cowner\u003e/fb2cng-web:1-1.4.5\n\n- **`VERSION`** holds the integer app version. Bump it by hand when the app code changes.\n- **`FBC_VERSION`** holds the pinned `fbc` release. A daily GitHub Actions job\n  (`fbc-update`) checks upstream; on a new release it rewrites `FBC_VERSION`,\n  commits the bump, and publishes a fresh `\u003cVERSION\u003e-\u003cnew-fbc\u003e` image (and `latest`).\n\nImages are multi-arch (`linux/amd64`, `linux/arm64`); Docker pulls the right one\nautomatically.\n\n\u003e First-time setup: the GHCR package is created on the first successful push and\n\u003e defaults to **private**. Make it public (or grant pull access) in the repo's\n\u003e Packages settings if anonymous pulls are wanted.\n\n### Local development\n\nVersion bumps are automated with [lefthook](https://github.com/evilmartians/lefthook).\nAfter cloning, run once:\n\n    lefthook install\n\nThen any commit that touches app or build code (`*.go`, `go.mod`/`go.sum`,\n`Dockerfile`, `internal/web/*`) auto-increments `VERSION`. Doc-, CI-, and\n`FBC_VERSION`-only commits leave it untouched. The hook is local-only — it does\nnot run in CI, so install it after cloning.\n\n## Configuration (env)\n\n| Var | Default | Meaning |\n|-----|---------|---------|\n| `PORT` | `8080` | listen port |\n| `FBC_BIN` | `fbc` | path to the fbc binary |\n| `MAX_CONCURRENT` | `3` | max simultaneous conversions |\n| `AUTH_FORWARD_AUTH` | `false` | trust reverse-proxy `Remote-*` headers |\n| `TRUSTED_PROXIES` | (empty) | comma-separated source IPs allowed to set `Remote-*` |\n\n\u003e In the Docker image, `FBC_BIN` is preset to `/usr/local/bin/fbc`.\n\n## Optional authentication (Authelia forward-auth)\n\nThe app has no built-in login. To require auth, run it behind a reverse proxy that\ndelegates to **Authelia**, with `AUTH_FORWARD_AUTH=true`.\n\n\u003e **Security:** when auth is on, never expose the app port directly. Publish only the\n\u003e proxy and keep the app on an internal network. Optionally set `TRUSTED_PROXIES` so the\n\u003e app ignores `Remote-*` headers from any other source.\n\nAuthelia forward-auth endpoint: `/api/authz/forward-auth`. Copy headers\n`Remote-User`, `Remote-Groups`, `Remote-Email`, `Remote-Name` to the app.\n\n### Caddy (`Caddyfile`)\n\n```caddyfile\nfb2.example.com {\n    forward_auth authelia:9091 {\n        uri /api/authz/forward-auth\n        copy_headers Remote-User Remote-Groups Remote-Email Remote-Name\n    }\n    reverse_proxy fb2cng-web:8080\n}\n```\n\n### Traefik (dynamic config)\n\n```yaml\nhttp:\n  middlewares:\n    authelia:\n      forwardAuth:\n        address: \"http://authelia:9091/api/authz/forward-auth\"\n        authResponseHeaders:\n          - \"Remote-User\"\n          - \"Remote-Groups\"\n          - \"Remote-Email\"\n          - \"Remote-Name\"\n  routers:\n    fb2:\n      rule: \"Host(`fb2.example.com`)\"\n      middlewares: [\"authelia\"]\n      service: fb2cng-web\n  services:\n    fb2cng-web:\n      loadBalancer:\n        servers:\n          - url: \"http://fb2cng-web:8080\"\n```\n\n### Nginx Proxy Manager (Proxy Host → Advanced tab)\n\n```nginx\nlocation /authelia {\n    # nginx uses Authelia's auth-request endpoint (not the forward-auth one used by Caddy/Traefik)\n    internal;\n    proxy_pass http://authelia:9091/api/authz/auth-request;\n    proxy_pass_request_body off;\n    proxy_set_header Content-Length \"\";\n    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;\n    proxy_set_header X-Original-Method $request_method;\n    proxy_set_header X-Forwarded-For $remote_addr;\n}\nlocation / {\n    auth_request /authelia;\n    auth_request_set $user  $upstream_http_remote_user;\n    auth_request_set $groups $upstream_http_remote_groups;\n    auth_request_set $name  $upstream_http_remote_name;\n    auth_request_set $email $upstream_http_remote_email;\n    proxy_set_header Remote-User   $user;\n    proxy_set_header Remote-Groups $groups;\n    proxy_set_header Remote-Name   $name;\n    proxy_set_header Remote-Email  $email;\n    error_page 401 =302 https://auth.example.com/?rd=$scheme://$http_host$request_uri;\n    proxy_pass http://fb2cng-web:8080;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasm0dey%2Ffb2cng-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasm0dey%2Ffb2cng-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasm0dey%2Ffb2cng-web/lists"}