Linkurator backend allows you to explore and categorize your subscriptions from various content providers like YouTube, Spotify, Patreon or RSS.
The API is currently available at https://api.linkurator.com/docs 📚
The project is composed of two app services and supporting infrastructure.
App services:
- 🌐 api — exposes the HTTP API used to explore your subscriptions.
- ⚙️ processor — fetches content from content providers in the background.
Infrastructure:
- mongodb and rabbitmq — required.
- gluetun — optional VPN.
- 🐳 docker and docker compose (https://docs.docker.com/engine/install/)
Bring the whole stack up with a single command:
docker compose --profile init run --rm generate-env && \
docker compose --profile app --profile infra --profile vpn up -dOnce the API is running, the docs are at http://localhost:9000/docs. 📖
docker compose --profile app --profile infra --profile vpn stop.config.jsonis the source of truth for runtime settings.envis generated from.config.jsonand used bydocker compose
- 🔐 Open the login page: http://localhost:9000/login
- 👤 Log in with your Google account
- ⚙️ The processor must be running to download subscription data
- 📚 Explore via the API docs: http://localhost:9000/docs
- Make (for the convenience commands)
Alternatively, build the image locally and bring everything up via Make:
make docker-upmake docker-stopUse this path when you want hot-reload, a debugger, or to iterate on the app code without rebuilding the image.
Some infrastructure still runs in Docker.
- uv (for Python package management)
- Make (for the convenience commands)
- Docker (for the infrastructure containers)
- Install the requirements
make install-requirementsReboot is required after installing docker to run it without sudo.
- Install python dependencies in a venv:
make install- Generate the
.envfile from.config.json:
make generate-envStart infrastructure containers:
make docker-run-external-servicesThen each app service in a separate terminal:
make run-api
make run-processorRun the tests:
make testRun the linter:
make lintAuto-fix formatting issues:
make formatFirst build the image if you want to run tests in Docker:
make docker-buildRun the tests:
make docker-testRun the linter:
make docker-lintProvision a server with Docker and deploy the app. This is the recommended way to run in production.
export SSH_IP_ADDRESS=api.linkurator.com
make provisionTo allow the continuous deployment pipeline to deploy to the server run:
export SSH_IP_ADDRESS=api.linkurator.com
make create-deploy-credentialsBuild the docker images and push them to the registry:
make docker-build
make docker-pushmake docker-push requires being authenticated to the Docker registry. If you
are not already logged in (docker login), set LINKURATOR_DOCKER_TOKEN to a
Docker Hub access token and the target will log in for you:
export LINKURATOR_DOCKER_TOKEN=your_docker_hub_tokenDefine the ip address and the vault password to deploy the image to the server:
echo "YOUR_PASSWORD" > secrets/vault_password.txt
export LINKURATOR_VAULT_PASSWORD=$(cat secrets/vault_password.txt)
export SSH_IP_ADDRESS=api.linkurator.com
export LINKURATOR_ENVIRONMENT=PRODUCTION
make deployLINKURATOR_VAULT_PASSWORD is needed because the production configuration
lives in config/app_config_production.json.enc (encrypted). When
LINKURATOR_ENVIRONMENT=PRODUCTION, the env-generation step decrypts that
file with the vault password before producing the .env shipped to the
server.
Every push to the main branch will trigger the tests and the linting. If they pass, the application will be automatically deployed to the server.