fiws-page/README.md

102 lines
4.4 KiB
Markdown

# FIW Labs Homepage
The source for [fiwlabs.dev](https://fiwlabs.dev), the personal portfolio of Alex (`Fi3w0`). It presents selected systems and desktop projects including TideWM, Scorium, Flux, Moonlit Shell, Prismarine, FiwNode, Nereus, and the FIW Minecraft tooling collection.
The site is intentionally framework-light: semantic HTML, hand-written CSS, and vanilla JavaScript are compiled into a static production bundle. There is no analytics, telemetry, backend, database, or runtime dependency on third-party fonts, icons, or scripts.
## Highlights
- Responsive editorial interface with accessible navigation and reduced-motion support.
- Interactive liquid ASCII artwork with graceful text fallbacks.
- Self-contained assets and strict browser security headers.
- Reproducible Webpack production build.
- Unprivileged, read-only Nginx container designed to sit behind Traefik.
## Technology
| Area | Choice |
| --- | --- |
| Interface | HTML, CSS, vanilla JavaScript |
| Build | Node.js 24, Webpack 5 |
| Runtime | Unprivileged Nginx on port `8080` |
| Deployment | Docker Compose and Traefik |
| Privacy | No analytics or third-party runtime requests |
## Local development
Requirements: Node.js 24 and npm.
```sh
npm ci
npm start
```
Create the production bundle with:
```sh
npm run build
```
Webpack writes the static site to `dist/`.
## Production deployment
The Compose stack expects an existing external Docker network shared with Traefik. Copy the example environment file and adjust it for the target host:
```sh
cp .env.example .env
docker network create proxy
docker compose config
docker compose up --build -d
```
The network only needs to be created once. If Traefik already owns it, skip that command.
| Variable | Default | Purpose |
| --- | --- | --- |
| `DOMAIN` | `fiwlabs.dev` | Traefik host rule |
| `TRAEFIK_NETWORK` | `proxy` | Shared external network |
| `TRAEFIK_HTTPS_ENTRYPOINT` | `websecure` | HTTPS entrypoint |
| `TRAEFIK_CERT_RESOLVER` | `porkbun` | Configured certificate resolver |
| `IMAGE_NAME` | `fiws-page` | Local/container registry image name |
| `IMAGE_TAG` | `latest` | Image tag to deploy |
Check the deployment with:
```sh
docker compose ps
docker compose logs --tail=100 fiws-page
```
Docker monitors `/healthz` inside the container. The service is exposed only to the shared Docker network; it does not publish a host port.
## Security posture
The production container runs as an unprivileged user with a read-only filesystem, all Linux capabilities dropped, privilege escalation disabled, and bounded CPU, memory, process, temporary-storage, and log usage. Nginx serves only static files and applies CSP, HSTS, referrer, permissions, framing, and content-type protections.
Keep secrets out of the frontend and out of Docker build arguments. Everything delivered to a browser is public by definition.
## Repository layout
```text
css/ Site styles
commissions/ Commission services page
deploy/nginx.conf Static server and security headers
img/ Optimized project artwork
js/app.js Interaction and visual effects
Dockerfile Multi-stage production image
docker-compose.yml Traefik-connected runtime
webpack.*.js Development and production builds
```
## License
The website source is available under the [MIT License](LICENSE.txt). Product names, screenshots, logos, and third-party marks retain their respective rights.
## Keeping the portfolio current
The homepage is a curated portfolio, not a release feed. Project descriptions focus on what each tool does; versions, download totals, supported Minecraft versions, and release roadmaps belong in the linked repositories or Modrinth pages. Scorium links to its organization so its implementations can grow without adding more homepage cards.
Keep the four illustrated projects as the main showcase. Use the compact project rows for other substantial work, and replace entries rather than continually adding sections. Small utilities belong in the short workbench list; archived prototypes remain discoverable through the all-repositories link.
The GitHub avatar is a local snapshot in `img/avatar.png`, with a cache version on its image URL. Replace it and increment that version when changing the profile picture. The browser needs no GitHub API access, tokens, or scheduled refreshes to display the portfolio. Routine project releases do not require a website update.