93 lines
3.3 KiB
Markdown
93 lines
3.3 KiB
Markdown
# FIW Labs Homepage
|
|
|
|
The source for [fiwlabs.dev](https://fiwlabs.dev), the personal portfolio of Alex (`Fi3w0`). It presents systems and desktop projects including TideWM, Scorium, Flux, Moonlit Shell, 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
|
|
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.
|