Sign inSign up

d3strukt0r/portfolio

By d3strukt0r

Updated 2 days ago

Personal portfolio site — Terminal Aurora glassmorphism, EN/DE, dark/light, terminal easter egg

Image
Web servers
0

6.2K

d3strukt0r/portfolio repository overview

D3strukt0r's Portfolio

Personal portfolio site for Manuele — React Router v7 (Remix successor), Tailwind v4, Sass, Node 24. Shipped two ways: GitHub Pages (SPA) and a Docker image (SSR via react-router-serve).

License Contributor Covenant Docker Stars Docker Pulls

Running the container

The published image serves the SSR build on port 3000.

Prerequisites

You need Docker installed.

Usage

Pull and run the latest image:

docker run --rm -p 3000:3000 d3strukt0r/portfolio:latest

Then open http://localhost:3000.

Pin to a specific version (recommended for production):

docker run --rm -p 3000:3000 d3strukt0r/portfolio:1.0.0

Run on a different host port:

docker run --rm -p 8080:3000 d3strukt0r/portfolio:latest

Get a shell inside the container:

docker run --rm -it --entrypoint sh d3strukt0r/portfolio:latest
docker compose
services:
  web:
    image: d3strukt0r/portfolio:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      SEAL_DATA_KEY: ${SEAL_DATA_KEY}
      REVEAL_PASSWORDS: ${REVEAL_PASSWORDS}
Environment variables
  • SEAL_DATA_KEYrequired. Long-lived 32-byte base64 secret. Must match the value the image was built with (the published d3strukt0r/portfolio image is built with the maintainer's key). Generate a fresh one for your own builds: openssl rand -base64 32.
  • REVEAL_PASSWORDSrequired. Comma-separated list of unlock passwords (e.g. alice,bob). Freely rotatable: change the value, restart the container, the new list is in effect on the next page load. Old sessionStorage unlocks in already-open tabs aren't invalidated until those tabs close.
  • PORT — port react-router-serve listens on. Default 3000.
  • NODE_ENV — set to production in the image. Don't override.

The server refuses to start if SEAL_DATA_KEY or REVEAL_PASSWORDS is missing.

docker run --rm -p 3000:3000 \
  -e SEAL_DATA_KEY="$SEAL_DATA_KEY" \
  -e REVEAL_PASSWORDS="alice,bob" \
  d3strukt0r/portfolio:latest
Building your own image

The image is built by flake.nix, not a Dockerfile. See Development → Building the OCI image locally for the full recipe (works on Windows / macOS / Linux via a throwaway nixos/nix container; no host Nix install required).

Save the SEAL_DATA_KEY you build with somewhere safe — you'll need to pass the same value at docker run. Rotating the data key requires re-encrypting the content, which means a rebuild; passwords don't.

Image details
  • Base: distroless (Nix-built, no shell as PID 1, runs as nonroot:65532)
  • Server: @react-router/serve (SSR)
  • Exposed port: 3000
  • Healthcheck: curl against / every 30 s
  • Architectures: linux/amd64, linux/arm64, linux/riscv64
Tags
  • latest — current master
  • <major>.<minor> and <major>.<minor>.<patch> — semver releases
  • sha-<short> — exact commit
  • master, develop — branch tips

Full list at hub.docker.com/r/d3strukt0r/portfolio.

Development

For working on the site itself (not just running the published image).

Prerequisites

Or use the included devcontainer (.devcontainer/devcontainer.json) — works in VS Code Dev Containers and GitHub Codespaces.

Setup
git clone [email protected]:Team-MaRo/d3strukt0r-portfolio.git
cd d3strukt0r-portfolio
pnpm install
pnpm run dev

The dev server runs on http://localhost:5173 with HMR.

Common commands
  • pnpm run dev — Vite dev server (5173) with HMR
  • pnpm run build — production build → build/
  • pnpm run typecheckreact-router typegen && tsc --noEmit
  • pnpm run lint / pnpm run lint:fix — ESLint
  • pnpm run preview — serve the built client on 4173

LinkedIn data sync (see bin/linkedin/):

  • pnpm run sync:linkedin:csv — import from a "Download your data" CSV export
  • pnpm run sync:linkedin:api — fetch live via the LinkedIn Member Data Portability API (needs LINKEDIN_DMA_TOKEN in .env)
Building the OCI image locally

The production image is Nix-built (flake.nix); there is no Dockerfile. If you have Nix installed, nix build --impure .#dockerImage is enough. Otherwise — and on Windows in particular — run Nix inside a throwaway nixos/nix container; everything else lives in your existing Docker daemon.

PowerShell (Windows / macOS Docker Desktop):

$env:SEAL_DATA_KEY = [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
docker run --rm `
  -e SEAL_DATA_KEY=$env:SEAL_DATA_KEY `
  -v "${PWD}:/work" -w /work `
  nixos/nix:2.34.6 `
  nix --extra-experimental-features "nix-command flakes" `
      build --impure .#dockerImage
docker load --input result
docker run --rm -p 3000:3000 `
  -e SEAL_DATA_KEY=$env:SEAL_DATA_KEY `
  -e REVEAL_PASSWORDS=alice,bob `
  d3strukt0r/portfolio:latest

Bash (Linux / WSL / macOS):

export SEAL_DATA_KEY=$(openssl rand -base64 32)
docker run --rm \
  -e SEAL_DATA_KEY \
  -v "$PWD:/work" -w /work \
  nixos/nix:2.34.6 \
  nix --extra-experimental-features "nix-command flakes" \
      build --impure .#dockerImage
docker load --input result
docker run --rm -p 3000:3000 \
  -e SEAL_DATA_KEY \
  -e REVEAL_PASSWORDS=alice,bob \
  d3strukt0r/portfolio:latest

Notes:

  • --impure is mandatory. flake.nix reads SEAL_DATA_KEY (and DOCKER_LABELS_JSON) from the build environment via builtins.getEnv; without --impure they come back empty and the bundle silently builds with no seal key.
  • For repeated builds, add -v nix-store:/nix to the docker run flags so the Nix store survives across container restarts (mirrors what compose.yml already does for the dev shell). First build: 5–10 min. Subsequent rebuilds: seconds.

For a containerized dev server with HMR (no image build, just pnpm run dev inside Nix), use compose.yml:

docker compose up --build

Built with

Contributing

Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

This project uses Conventional Commits.

Versioning

We use SemVer for versioning. For available versions, see the tags on this repository.

Authors

Special thanks for all the people who had helped this project so far

See also the full list of contributors who participated in this project.

I would like to join this list. How can I help the project?

We're currently looking for contributions for the following:

  • Bug fixes
  • Translations
  • etc...

For more information, please refer to our CONTRIBUTING.md guide.

License

This project is licensed under the MIT License - see the LICENSE.txt file for details.

Acknowledgments

This project currently uses no third-party libraries or copied code.

Tag summary

Content type

Image

Digest

sha256:818863580

Size

97 MB

Last updated

3 months ago

docker pull d3strukt0r/portfolio