The Collection is a public catalogue of recommended apps, command line tools, and resources.
It gives visitors a simple way to browse published tools by search, platform, category, and tags. The private owner-only admin area is used to add, edit, draft, publish, and delete tools without exposing unpublished entries to the public site.
- Browse a public catalogue of recommended tools and resources.
- Search tools by name, description, tags, platform, and category.
- Filter published tools by platform and category.
- Manage tools through a private owner-only admin area.
- Upload or link tool logos and keep uploaded files in persistent storage.
- Node.js 22
- Next.js App Router
- TypeScript
- Tailwind CSS
- Prisma
- SQLite
- Authentik OIDC for owner-only admin sign-in
- Docker and Docker Compose
- GitHub Container Registry
- GitHub Actions
Before running this project, install:
- Node.js 22
- npm
- Docker and Docker Compose, for container testing or server deployment
- OpenSSL, for generating a local session secret
-
Create a local
.envfile from the example file:cp .env.example .env
-
Update
.envwith values for your local setup:APP_URL=http://127.0.0.1:3000 AUTHENTIK_ISSUER=https://auth.example.com/application/o/the-collection/ AUTHENTIK_CLIENT_ID=replace-with-authentik-client-id AUTHENTIK_CLIENT_SECRET=replace-with-authentik-client-secret AUTHENTIK_ADMIN_EMAIL=nathan@autonate.dev SESSION_SECRET=replace-with-a-long-random-string DATABASE_URL=file:./data/the-collection.db DATA_DIR=./data OPENROUTER_API_KEY=replace-with-openrouter-api-key
-
Generate a session secret:
openssl rand -base64 48
Environment notes:
APP_URLis the public base URL for the site. In production, use the deployed HTTPS URL.AUTHENTIK_ISSUERis the Authentik application issuer URL, usuallyhttps://auth.example.com/application/o/<application-slug>/.AUTHENTIK_CLIENT_IDandAUTHENTIK_CLIENT_SECRETcome from the Authentik OAuth2/OpenID provider.AUTHENTIK_ADMIN_EMAILis the only email address allowed to access the admin area. For this deployment it should benathan@autonate.dev.AUTHENTIK_REDIRECT_URIis optional. If omitted, the app usesAPP_URL + /admin/auth/callback.SESSION_SECRETsigns admin session cookies. Keep it long, random, and stable for a deployment.DATABASE_URLcontrols the SQLite database path. Local npm development usesfile:./data/the-collection.db.DATA_DIRis where uploaded logos and app data are stored. Local development can use./data.OPENROUTER_API_KEYenables the admin AI suggestion button for generating a short description, category, and tags from a tool URL.
The app uses OpenID Connect. In plain English, The Collection sends you to Authentik, Authentik proves who you are, and then The Collection starts its own signed admin session only if the email claim is nathan@autonate.dev.
In Authentik:
-
Go to Applications > Providers and create an OAuth2/OpenID Provider.
-
Use these provider settings:
- Name:
The Collection - Client type:
Confidential - Redirect URI:
https://your-collection-domain/admin/auth/callback - Signing key: select an RSA signing key. The app requires RS256-signed ID tokens.
- Subject mode: use the default unless you have a reason to change it.
- Include the
openid,profile, andemailscope mappings.
- Name:
-
Save the provider and copy the client ID and client secret into
.env. -
Go to Applications > Applications and create an application:
- Name:
The Collection - Slug:
the-collection - Provider: the provider you created above
- Launch URL:
https://your-collection-domain/admin/login
- Name:
-
Ensure the Authentik user for Nathan has the email address
nathan@autonate.dev. -
Set these values in the app
.env:APP_URL=https://your-collection-domain AUTHENTIK_ISSUER=https://your-authentik-domain/application/o/the-collection/ AUTHENTIK_CLIENT_ID=copy-from-authentik AUTHENTIK_CLIENT_SECRET=copy-from-authentik AUTHENTIK_ADMIN_EMAIL=nathan@autonate.dev SESSION_SECRET=generate-with-openssl-rand-base64-48
For local testing, add a second redirect URI in Authentik:
http://127.0.0.1:3000/admin/auth/callback
Then set APP_URL=http://127.0.0.1:3000 locally.
-
Install dependencies:
npm install
-
Create and update
.envusing the configuration steps above. -
Create the SQLite database and seed sample tools:
npm run db:init npm run db:seed
-
Start the app:
npm run dev
-
Open
http://127.0.0.1:3000. -
Before handing off changes, run:
npm run typecheck npm run lint npm run build
Docker is useful for checking the container before server deployment. The local Compose file builds the image from this repository, reads .env, publishes the app on 127.0.0.1:3000, and stores app data in the the-collection-data Docker volume.
-
Start the local Docker stack:
docker compose up --build
The app will be available at
http://127.0.0.1:3000. -
Stop the stack:
docker compose down
Note
The local Compose file is docker-compose.yaml. The production source Compose file is docker-compose.prod.yaml.
You can run this on your own server by pulling the latest Docker image from ghcr.io/aut0nate/the-collection:${IMAGE_TAG:-latest}.
Use the structure that fits your own environment and preferred deployment methods. For public-facing access, put the service behind HTTPS using a reverse proxy such as Nginx Proxy Manager, Caddy, Traefik, or another preferred option. In my environment, I am using Nginx Proxy Manager with a docker network named edge-net.
For most Docker-based deployments:
-
Create a directory in your chosen location on your server, for example
/opt/stacks/the-collection. -
Change into this directory.
-
Ensure the production Compose file is saved in this directory. In this repository the production source file is
docker-compose.prod.yaml, but the associated GitHub Actions CI/CD workflow should save it asdocker-compose.yaml. -
Create a
.envfile:APP_URL=https://your-collection-domain AUTHENTIK_ISSUER=https://your-authentik-domain/application/o/the-collection/ AUTHENTIK_CLIENT_ID=replace-with-authentik-client-id AUTHENTIK_CLIENT_SECRET=replace-with-authentik-client-secret AUTHENTIK_ADMIN_EMAIL=nathan@autonate.dev SESSION_SECRET=replace-with-a-long-random-string IMAGE_TAG=latest
The production Compose file sets
DATABASE_URL=file:/app/data/the-collection.dbandDATA_DIR=/app/datainside the container. Do not set local paths such as./datafor the production container.The production Compose file mounts the exact Docker volume named
the-collection-data; do not allow Compose to create a project-prefixed replacement volume or the public site will appear empty. -
Create the external Docker network or create your own and update the production Compose file accordingly.
docker network create edge-net
-
Start the public image using the Compose file name on your server:
docker compose -f docker-compose.yaml up -d
-
Configure your reverse proxy to the app container on port
3000. -
Verify the public URL after deployment.
Example production files:
docker-compose.prod.yamldocker-compose.yaml.env
After deployment, verify:
- The public homepage loads.
/admin/loginloads.- Admin login redirects to Authentik and returns to
/admin/tools. - Tool search and filters work.
- Data and logos remain available after restarting the container.
Back up the SQLite database and uploaded logos regularly from the the-collection-data Docker volume or from your chosen mounted storage location.
CI - Validate and buildshould run on pull requests and pushes tomain.- CI should install dependencies, run linting, run type checks, build the Next.js application, build a Docker image, and smoke test the container locally.
CD - Build and deployshould run only after CI succeeds onmain.- CD should build and push
ghcr.io/aut0nate/the-collection:latestandghcr.io/aut0nate/the-collection:<commit-sha>. - CD should upload
docker-compose.prod.yamlto the server asdocker-compose.yaml, updateIMAGE_TAGin the server.env, then rundocker compose pullanddocker compose up -d. - Deployment SSH details should be stored in GitHub Actions secrets:
VPS_HOST,VPS_PORT,VPS_USER, andVPS_SSH_KEY. - Production runtime values should live in the server
.env, not in the workflow files.
- Do not commit
.env. - Keep
SESSION_SECRETlong and random. - Keep the Authentik client secret in the deployment environment only.
- The admin login uses Authentik OIDC with state, nonce, PKCE, RS256 ID token verification, an owner email allow-list, and signed HTTP-only cookies. The app session cookie uses
SameSite=Laxso the session is available after returning from Authentik. - Store production secrets in the deployment environment or GitHub Actions secrets, not in the repository.
- Rotate the Authentik client secret if it is ever exposed, and rotate
SESSION_SECRETif it is ever exposed. Rotating the session secret signs every existing admin session out. - Public visitors only see published tools that are intended to be public.
The Collection was built with OpenAI Codex using GPT-5.5. This repository includes an AGENTS.md file, which provides structured instructions and context for AI coding agents. It defines expectations, constraints, and project-specific guidance to help keep contributions consistent and reliable.
Contributions, ideas, and suggestions are welcome.
If you have improvements, feature ideas, or bug fixes, feel free to open an issue or submit a pull request. All contributions are appreciated and help improve the project.
This project is licensed under the MIT License. See LICENSE for details.
