Skip to content

APT Repo Manager β€” English Documentation

Private APT repository manager with a React web UI, FastAPI REST API, role-based access control (RBAC), and built-in security scanning (ClamAV, Grype, SBOM).


Table of Contents

  1. Architecture
  2. Features
  3. Prerequisites
  4. Installation
  5. Default Credentials
  6. Directory Structure
  7. Roles and Access
  8. Security
  9. Other Documents

Architecture

                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚             Browser              β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚           β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚  frontend :3003    β”‚   β”‚   backend :8000         β”‚
               β”‚  (Nginx + React)   β”‚   β”‚   (FastAPI + JWT auth)  β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚              apt-repo :80                β”‚
                        β”‚     (Nginx + reprepro, no auth)          β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚                  Docker Volumes                   β”‚
               β”‚  repos/pool      repos/manifests  repos/audit    β”‚
               β”‚  repos/auth      repos/security   repos/gnupg    β”‚
               β”‚  repos/logs      repos/staging                   β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

APT clients (apt-get, apt) β†’ apt-repo:80  (public access, read-only)

Features

Feature Available
React + Tailwind web UI Yes
FastAPI REST API Yes
Local SQLite/bcrypt authentication Yes
LDAP / Active Directory authentication Yes
JWT tokens (60-minute lifetime) Yes
API tokens for CI/CD pipelines Yes
5 RBAC roles (admin, maintainer, uploader, auditor, reader) Yes
ClamAV antivirus scan on every upload Yes
Grype CVE scan (policy: block / review / warn) Yes
CycloneDX v1.5 SBOM export Yes
SPDX v2.3 SBOM export Yes
Append-only audit trail (JSONL) Yes
Download statistics (Nginx log parsing) Yes
Package import from upstream APT sources Yes
Health monitoring dashboard Yes

Prerequisites

Component Minimum Version Recommended
Docker 24.0 Latest stable
Docker Compose v2 (plugin) Latest stable
RAM 2 GB 4 GB
Disk space 20 GB 50 GB+
OS Debian 11 / Ubuntu 22.04 Ubuntu 24.04 LTS

Note: Docker Compose v2 is installed as a plugin (docker compose), not as a standalone binary (docker-compose).


Installation

Step 1 β€” Clone the repository

git clone <repo-url> repod
cd repod

Step 2 β€” Configure the main environment file

cp .env.example .env

Edit .env and set at minimum:

PUBLIC_URL=http://your-domain.example.com
REACT_APP_API_URL=http://your-domain.example.com:8000

Step 3 β€” Configure the backend

cp backend.env.example backend.env

Edit backend.env and set at minimum:

# REQUIRED in production β€” generate a long random value
JWT_SECRET_KEY=replace-this-with-a-long-random-secret

# Initial admin credentials
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH=<bcrypt hash of your password>

To generate a bcrypt hash:

docker run --rm python:3.10-slim python3 -c \
  "from passlib.context import CryptContext; print(CryptContext(schemes=['bcrypt']).hash('YourPassword1!'))"

Step 4 β€” Start the containers (production)

docker compose -f docker-compose.yaml up -d

For development mode (Swagger UI enabled, hot reload):

docker compose -f docker-compose.yaml -f docker-compose.dev.yml up

Important: In production (ENV=production), the Swagger UI (/docs) returns a 404 error. This is intentional to reduce the attack surface.

Step 5 β€” Verify the deployment

# Check container status
docker compose ps

# Check backend logs
docker compose logs backend

# Test the API
curl http://localhost:8000/health

Default Credentials

SECURITY WARNING

The default credentials are: - Username: admin - Password: Admin1234!

These credentials MUST be changed before going to production. Never deploy with default credentials in a network-accessible environment.

To change the admin password:

  1. Generate a new bcrypt hash (see Step 3 above).
  2. Update ADMIN_PASSWORD_HASH in backend.env.
  3. Restart the backend: docker compose restart backend.

Directory Structure

repos/
β”œβ”€β”€ pool/           # Debian packages (.deb) managed by reprepro
β”œβ”€β”€ manifests/      # Per-package metadata (JSON files)
β”‚   └── index.json  # Global package index
β”œβ”€β”€ audit/          # Append-only audit trail (daily JSONL files)
β”‚   └── YYYY-MM-DD.jsonl
β”œβ”€β”€ auth/           # SQLite user database and API tokens
β”œβ”€β”€ security/       # Grype and ClamAV scan results
β”œβ”€β”€ gnupg/          # GPG keys used to sign the repository
β”œβ”€β”€ logs/           # Nginx logs parsed for download statistics
└── staging/        # Temporary upload zone before validation

Roles and Access

Role Upload Package Management User Management Audit Read
admin Yes Yes Yes Yes Yes
maintainer Yes Yes No Yes Yes
uploader Yes No No No Yes
auditor No No No Yes Yes
reader No No No No Yes

Security

Antivirus Scanning (ClamAV)

Every uploaded package is scanned by ClamAV before it is accepted into the repository. Infected packages are rejected and the event is recorded in the audit trail.

CVE Scanning (Grype)

Packages are analyzed by Grype. The policy is configurable:

  • block β€” The package is rejected if CVEs are detected above the configured threshold.
  • review β€” The package is held pending manual review.
  • warn β€” The package is accepted but a warning is recorded.

Audit Trail

All actions (uploads, deletions, logins, configuration changes) are recorded in daily JSONL files under repos/audit/. These files are append-only and cannot be modified through the interface.


Other Documents

Document Link
Documentation en francais Home
Root README (bilingual) Home