Version: 1.0 Date: November 10, 2025
This guide describes the installation and configuration process for Accellens in local development and production environments.
If other Docker projects (e.g., ai-test-hub) are already running on your system, Accellens uses alternative ports to avoid conflicts:
| Service | Standard Port | Accellens Port | Reason |
|---|---|---|---|
| PostgreSQL | 5432 | 5433 | Conflict avoidance |
| Redis | 6379 | 6380 | Conflict avoidance |
| MinIO | 9000-9001 | 9010-9011 | Conflict avoidance |
| RabbitMQ | 5672, 15672 | 5672, 15672 | Standard ports |
Check occupied ports before starting:
docker ps --format "table {{.Names}}\t{{.Ports}}"| Component | Minimum Version | Recommended Version | LTS/Status |
|---|---|---|---|
| Node.js | 24.13.0 LTS | 24.13.0+ LTS | ✅ LTS |
| Python | 3.13.0 | 3.13+ | ✅ Stable version |
| Docker | 24.0 | 24.10+ | ✅ Stable version |
| Docker Compose | 2.0 | 2.27+ | ✅ Stable version |
| pnpm | 9.0 | 9.15+ | ✅ Stable version |
| Helm | 3.15.0 | 3.15.2+ | ✅ Stable version |
| PostgreSQL | 16.0 | 16.6+ | ✅ Stable version |
| Redis | 8.0 | 8.2+ | ✅ Stable version |
- macOS: 13.0+ (Ventura)
- Linux: Ubuntu 22.04+, Debian 12+, RHEL 9+
- Windows: Windows 11 (WSL2 recommended)
# Clone the repository
git clone <repository-url>
cd accellens
# Check the branch
git checkout develop# Install pnpm (if not installed)
npm install -g pnpm
# Install dependencies
pnpm install# Create a virtual environment
python3.13 -m venv venv
# Activate the virtual environment
source venv/bin/activate # Linux/macOS
# or
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Install dev dependencies (including pre-commit)
pip install -e ".[dev]"Helm is required for deploying the application in Kubernetes environments (test, pre-prod, prod).
Option 1: Using the installation script (recommended)
# Run the installation script
./scripts/install-helm.sh
# Add to PATH (if not added automatically)
export PATH="${PATH}:${HOME}/.local/bin"Option 2: Installation via package manager
macOS (Homebrew):
brew install helmLinux (apt):
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helmVerification:
helm version --client
# Should show: version.BuildInfo{Version:"v3.15.2", ...}Using Helm for Local Development:
To verify the Helm chart locally:
# Lint check
helm lint infra/k8s/accellens --values infra/k8s/environments/dev/values.yaml
# Template validation
helm template accellens infra/k8s/accellens \
--values infra/k8s/environments/dev/values.yaml \
--set-string global.imageRegistry=ghcr.io/test \
--set-string global.imageTag=testPre-commit hooks automatically check code before committing. Configuration is mandatory for all developers.
# Install pre-commit
pip install pre-commit
# Install hooks
pre-commit install
# Check all files (first run)
pre-commit run --all-filesPython pre-commit hooks:
- Black — automatic formatting.
- isort — import sorting.
- flake8 — code style check.
- mypy — type checking.
- detect-secrets — secrets check.
- check-added-large-files — large files check (>1000KB).
Husky and lint-staged are automatically configured during dependency installation:
# Husky is initialized automatically via npm prepare script
# Check if hooks are installed
ls -la .husky/TypeScript/JavaScript hooks:
- ESLint — check and autofix via lint-staged.
- Prettier — automatic formatting via lint-staged.
- TypeScript — type checking (
tsc --noEmit) via lint-staged.
Automatically checked for all files:
- YAML — validation via yamllint.
- JSON — JSON file validation.
- Markdown — check via markdownlint.
- Dockerfile — check via hadolint.
- Commit message — Conventional Commits format check.
If you need to temporarily skip hooks:
# Skip pre-commit hooks
git commit --no-verify
# Skip only commit-msg hook
git commit --no-verify -m "message"Important: Skipping hooks is not recommended unless necessary. All checks must pass before committing.
# Copy configuration example from the project root
cp .env.example .env
# Edit .env file
nano .envMinimal configuration for local development:
APP_ENV=dev
APP_SECRET_KEY=dev-secret-key-change-in-production
GATEWAY_HOST=0.0.0.0
GATEWAY_PORT=3000
GATEWAY_LOG_LEVEL=info
NODE_ENV=development
DATABASE_URL=postgresql+asyncpg://<DB_USER>:<DB_PASSWORD>@localhost:5433/accellens
REDIS_URL=redis://:<REDIS_PASSWORD>@localhost:6380/0
RABBITMQ_URL=amqp://<RABBITMQ_USER>:<RABBITMQ_PASSWORD>@localhost:5672/
S3_ENDPOINT=http://localhost:9010
S3_BUCKET=accellens-artifacts
S3_ACCESS_KEY=accellens
S3_SECRET_KEY=<MINIO_SECRET_KEY>
LOG_LEVEL=DEBUG
AUDIT_LOG_USE_POSTGRESQL=true
PYTHON_SERVICE_URL=http://localhost:8001Note: The frontend application (
apps/frontend) will be created according to the roadmap. Currently, the structure is in the development stage.
# After apps/frontend is created, copy configuration example from root
# NEXT_PUBLIC_* variables should be in .env.local for Next.js
cp .env.example .env.local
# Edit .env.local file
nano .env.localMinimal configuration (after frontend creation):
NEXT_PUBLIC_API_URL=http://localhost:3000
NEXT_PUBLIC_GRAPHQL_URL=http://localhost:3000/graphqlImportant: If other Docker projects are running on your system, check for port conflicts before starting.
Start basic services (PostgreSQL, Redis, RabbitMQ, MinIO):
# Start infrastructure
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f
# Stop infrastructure
docker compose down
# Stop and delete volumes (clear data)
docker compose down -vStart infrastructure along with applications (gateway, services, scanner-web):
# Start infrastructure and services
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Check status of all services
docker compose -f docker-compose.yml -f docker-compose.dev.yml ps
# View logs of a specific service
docker compose logs -f gateway
docker compose logs -f services
docker compose logs -f scanner-web
# Restart a specific service
docker compose restart gateway
# Stop all services
docker compose -f docker-compose.yml -f docker-compose.dev.yml downAfter first MinIO launch, a bucket for artifacts must be created:
# Run MinIO initialization
docker compose --profile init up minio-init
# Or manually via MinIO client
docker compose exec minio mc alias set local http://minio:9000 accellens accellens_minio_dev
docker compose exec minio mc mb local/accellens-artifacts
docker compose exec minio mc anonymous set download local/accellens-artifactsImportant: After a Docker factory reset or first launch, the Ollama model must be downloaded for AI recommendations to work.
Check which model is used in the configuration:
# Check current models
docker exec accellens-services python -c "from config import settings; print(f'Qwen model: {settings.qwen_model}'); print(f'Phi model: {settings.phi_model}'); print(f'Llama model: {settings.llama_model}')"Download the model to Ollama:
# Download models (automatically via ollama-init container during docker-compose up)
# Or manually:
docker exec accellens-ollama ollama pull qwen2.5-coder:3b-instruct
docker exec accellens-ollama ollama pull phi3:mini
docker exec accellens-ollama ollama pull llama3.2:3b
# Check that models are downloaded
docker exec accellens-ollama ollama listAutomation: Models are automatically downloaded via the ollama-init container during docker-compose up. The ollama-init container waits for Ollama to be ready and then downloads all three models:
qwen2.5-coder:3b-instruct(main provider)phi3:mini(first fallback)llama3.2:3b(second fallback)
Or use an init script in the container entrypoint.
Note: If AI recommendations are not being generated, check Celery worker logs for 404 Not Found errors for /api/generate - this indicates the model is missing in Ollama.
After launch, services are available at the following addresses:
| Service | URL | Description |
|---|---|---|
| PostgreSQL | localhost:5433 |
Database |
| Redis | localhost:6380 |
Cache and Celery backend |
| RabbitMQ | localhost:5672 |
Message broker |
| RabbitMQ UI | http://localhost:15672 |
Management UI (accellens/accellens_rabbitmq_dev) |
| MinIO | http://localhost:9010 |
Object Storage API |
| MinIO UI | http://localhost:9011 |
MinIO Console (accellens/accellens_minio_dev) |
| Gateway | http://localhost:3000 |
API Gateway (in dev mode) |
| Services | http://localhost:8001 |
Python microservices (in dev mode) |
Note: Ports have been changed (5433, 6380, 9010, 9011) to avoid conflicts with other containers. If ports are free, you can change them in docker-compose.yml.
To change service configuration, use environment variables in docker-compose.yml or create a .env file:
# PostgreSQL
POSTGRES_USER=accellens
POSTGRES_PASSWORD=<POSTGRES_PASSWORD>
POSTGRES_DB=accellens
# Redis
REDIS_PASSWORD=accellens_redis_dev
# RabbitMQ
RABBITMQ_DEFAULT_USER=accellens
RABBITMQ_DEFAULT_PASS=accellens_rabbitmq_dev
# MinIO
MINIO_ROOT_USER=accellens
MINIO_ROOT_PASSWORD=accellens_minio_dev
# Gateway Audit Log Configuration
AUDIT_LOG_USE_POSTGRESQL=true
PYTHON_SERVICE_URL=http://localhost:8001Docker Compose creates named volumes for persistent data storage:
# View volumes
docker volume ls | grep accellens
# View volume content
docker volume inspect accellens-postgres_data
# Delete all volumes (clear data)
docker compose down -vVolumes:
postgres_data— PostgreSQL data.redis_data— Redis data (AOF).rabbitmq_data— RabbitMQ data.minio_data— MinIO data.
All services are connected to the accellens-network:
# View network
docker network inspect accellens-network
# Services can call each other by name:
# - postgres:5432
# - redis:6379
# - rabbitmq:5672
# - minio:9000Problem: Port already occupied by another Docker project
# Check which ports are occupied by other containers
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Check which process is using the port
lsof -i :5432 # macOS/Linux
netstat -ano | findstr :5432 # Windows
# Change port in docker-compose.yml
ports:
- "5433:5432" # Use different external portNote: Accellens uses alternative ports by default:
- PostgreSQL:
5433(instead of 5432) - Redis:
6380(instead of 6379) - MinIO:
9010-9011(instead of 9000-9001) - RabbitMQ:
5672, 15672(standard ports)
This allows running Accellens alongside other projects (e.g., ai-test-hub).
Problem: Service does not start
# Check logs
docker compose logs <service-name>
# Check healthcheck
docker compose ps
# Recreate container
docker compose up -d --force-recreate <service-name>Problem: Data not persisting
# Check that volume is created
docker volume ls | grep accellens
# Check access permissions
docker compose exec postgres ls -la /var/lib/postgresql/data
# Volumes use project prefix (accellens_)
# To change: docker compose -p custom-name upProblem: Network or volume conflict with other projects
# Check existing networks
docker network ls
# Check existing volumes
docker volume ls
# Use different project name for isolation
docker compose -p accellens-dev up
# Or change network/volume name in docker-compose.ymlTo launch the test environment:
# Start test infrastructure
docker compose -f docker-compose.yml -f docker-compose.test.yml up -d
# Test services use different ports:
# - PostgreSQL: 5434
# - Redis: 6381
# - RabbitMQ: 5673, UI: 15673
# - MinIO: 9020, UI: 9021
# Stop test environment
docker compose -f docker-compose.yml -f docker-compose.test.yml down -v# Apply migrations (after apps/services creation)
# Use migration script (recommended)
./scripts/migrate.sh upgrade head
# Or directly via alembic in container
cd apps/services
docker compose -f docker-compose.yml -f docker-compose.dev.yml exec \
-w /app/apps/services -e PYTHONPATH=/app/apps/services \
-e DATABASE_URL="postgresql+asyncpg://<DB_USER>:<DB_PASSWORD>@postgres:5432/accellens" \
services python -m alembic upgrade head
# Create initial data (optional)
python scripts/seed_data.pyTo simplify working with migrations, the scripts/migrate.sh script was created. it automatically configures the environment and executes Alembic commands in a Docker container.
Script advantages:
- Automatically determines project path and configures environment variables.
- Checks for docker-compose and starts the service if not running.
- Simplifies migration command execution without needing to remember long docker-compose commands.
- Colored output for convenience.
Main commands:
# Show current migration version
./scripts/migrate.sh current
# Show migration history
./scripts/migrate.sh history
# Show current migration heads
./scripts/migrate.sh heads
# Show branch points
./scripts/migrate.sh branches
# Apply all migrations (to head)
./scripts/migrate.sh upgrade head
# Apply migrations to specific version
./scripts/migrate.sh upgrade <revision>
# Roll back one migration
./scripts/migrate.sh downgrade -1
# Roll back to specific version
./scripts/migrate.sh downgrade <revision>
# Show migration details
./scripts/migrate.sh show <revision>
# Stamp DB with version without running migrations
./scripts/migrate.sh stamp <revision>
# Create new migration (autogenerate)
./scripts/migrate.sh revision "Add new table" --autogenerate
# Create new migration (empty)
./scripts/migrate.sh revision "Add new table"
# Merge two migrations
./scripts/migrate.sh merge <rev1> <rev2> [message]
# Show help
./scripts/migrate.sh helpUsage examples:
# On first application launch
./scripts/migrate.sh upgrade head
# After model changes (create new migration)
./scripts/migrate.sh revision "Add user table" --autogenerate
# Apply new migration
./scripts/migrate.sh upgrade head
# Check current version before update
./scripts/migrate.sh current
# Roll back last migration in case of problems
./scripts/migrate.sh downgrade -1
# View migration history
./scripts/migrate.sh historyWhen to run migrations:
- On first application launch (table creation).
- After model changes (new fields/tables).
- When updating code from the repository (new migrations).
Note: The script automatically uses settings from docker-compose.yml and docker-compose.dev.yml. For production environments, environment variable configuration may be required.
# Start gateway server (after apps/gateway creation)
cd apps/gateway
npm run dev
# or
npm start# Start services server (after apps/services creation)
cd apps/services
uvicorn main:app --reload --host 0.0.0.0 --port 8000Note: Frontend application will be created according to roadmap.
# After apps/frontend is created, start frontend server
cd apps/frontend
npm run dev
# or
pnpm dev# Start Celery worker (after apps/services creation)
cd apps/services
celery -A tasks worker --loglevel=info# Start Celery beat for periodic tasks (after apps/services creation)
cd apps/services
celery -A tasks beat --loglevel=infoReport Archive Cleanup Task Configuration:
The cleanup_report_archives task is automatically configured in apps/services/celery_app.py and runs daily at 02:00 UTC:
beat_schedule["cleanup-report-archives"] = {
"task": "apps.services.tasks.cleanup_report_archives",
"schedule": crontab(hour=2, minute=0), # Daily at 02:00 UTC
}The task performs:
- Expired reports cleanup (lifecycle policy) — deletes reports with
expires_at < current_timestamp. - Redundant reports cleanup (FIFO policy) — deletes oldest reports if
report_archive_max_countis exceeded.
To change the schedule, edit apps/services/celery_app.py:
from celery.schedules import crontab
beat_schedule["cleanup-report-archives"] = {
"task": "apps.services.tasks.cleanup_report_archives",
"schedule": crontab(hour=3, minute=0), # Change execution time
}Task Monitoring:
- Prometheus metrics:
report_archive_cleanup_total,report_archive_cleanup_size_bytes. - Logs: structured logs with detailed statistics.
- Audit log: entry on mass cleanup (> 100 files).
- Kubernetes cluster (EKS, GKE, AKS).
- Helm 3.0+.
- kubectl configured for cluster access.
# Add Helm repository (if used)
helm repo add accellens https://charts.accellens.dev
helm repo update
# Install Accellens
helm install accellens accellens/accellens \
--namespace accellens-prod \
--create-namespace \
--values infra/k8s/environments/prod/values.yaml# Check pod status
kubectl get pods -n accellens-prod
# Check services
kubectl get svc -n accellens-prod
# Check ingress
kubectl get ingress -n accellens-prodFor small production environments, you can use Docker Compose:
# Use production compose file
docker compose -f docker-compose.prod.yml up -d
# Check status
docker compose -f docker-compose.prod.yml ps-- Create database
CREATE DATABASE accellens;
-- Create user
CREATE USER accellens WITH PASSWORD 'secure-password';
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE accellens TO accellens;# Use migration script (recommended)
./scripts/migrate.sh upgrade head
# Or directly via alembic
cd apps/services
alembic upgrade head# Check connection
redis-cli ping
# Set password (optional)
redis-cli CONFIG SET requirepass "secure-password"# Use Docker Compose for local installation
docker compose -f docker-compose.milvus.yml up -d
# Or use a managed service (Zilliz Cloud)
# Configure connection via environment variables# Legacy providers (OpenAI, Anthropic) are no longer supported
# Use new Ollama-based providers: Qwen, Phi, LlamaAI_PRIMARY_PROVIDER=qwen
AI_FALLBACK_PROVIDER=phi
OLLAMA_HOST=http://localhost:11434
QWEN_MODEL=qwen2.5-coder:3b-instruct
PHI_MODEL=phi3:mini
LLAMA_MODEL=llama3.2:3b# MinIO is started via Docker Compose
# Access: http://localhost:9010
# Credentials: accellens / accellens_minio_devS3_ENDPOINT=https://s3.amazonaws.com
S3_BUCKET=accellens-artifacts-prod
S3_ACCESS_KEY=AKIA...
S3_SECRET_KEY=...
S3_REGION=us-east-1OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
OTEL_SERVICE_NAME=accellens-backend
OTEL_RESOURCE_ATTRIBUTES=service.name=accellens-backend,service.version=1.0.0# prometheus.yml
scrape_configs:
- job_name: 'accellens'
static_configs:
- targets: ['backend:8000']# Start Grafana via Docker
docker run -d -p 3000:3000 grafana/grafana
# Import dashboards from infra/monitoring/grafana/# Use cert-manager for automatic certificate issuance
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Configure ClusterIssuer for Let's Encrypt
kubectl apply -f infra/k8s/cert-manager/cluster-issuer.yamlmTLS for Internal Services:
- Create a secret with the internal CA and Python service certificates (
kubectl create secret generic accellens-prod-internal-tls --from-file=...). - Enable mounting via Helm (see
infra/k8s/environments/prod/values.yaml→services.tls,celeryWorker.tls,celeryBeat.tls). - Add
TLS_*andCELERY_TLS_*variables so that FastAPI (uvicorn) and Celery start with TLS/AMQPS. - For RabbitMQ/Redis, enable TLS at the broker level and use the
amqps:///rediss://DSN.
- FastAPI exports
/health/liveand/health/ready. In Helm (services.livenessProbe,services.readinessProbe), HTTP probes are enabled by default. - Celery worker/beat use
python -m apps.services.healthcheck celery --timeout 5for readiness/liveness (values.yaml->celeryWorker|celeryBeat). - HorizontalPodAutoscaler (
templates/celery-worker-hpa.yaml) scales workers by CPU + (optional) by thequeue_depthmetric. Activated viaceleryWorker.autoscaling.
For Single Sign-On (OIDC/SAML) configuration for enterprise clients, see sso-setup.md.
Quick Start:
- Select a provider (Google, Azure AD, Okta, etc.).
- Configure the application in the IdP.
- Set environment variables (see
environment-variables.md). - Verify the configuration:
python scripts/validate-sso-config.py. - Restart the Gateway.
Local Development Example with Keycloak:
# Start Keycloak
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:latest start-dev
# Configure in Keycloak:
# - Realm: accellens-dev
# - Client ID: accellens-dev
# - Redirect URI: http://localhost:3000/api/v1/auth/sso/oidc/callback# Create secret
aws secretsmanager create-secret \
--name accellens/prod/database \
--secret-string '{"username":"accellens","password":"secure-password"}'# Install Vault
helm install vault hashicorp/vault
# Configure secrets
vault kv put secret/accellens/prod database_url="postgresql://..."# Check backend
curl http://localhost:3000/healthz
# Check frontend
curl http://localhost:3000
# Check API
curl http://localhost:3000/api/v1/health# Run smoke tests
make test:smoke
# Or manually
accellens scan https://example.com --project smoke-testProblem: Connection refused or timeout.
Solution:
- Ensure PostgreSQL is running:
docker compose ps. - Check DATABASE_URL in the .env file.
- Check network settings and firewall.
Problem: Connection refused.
Solution:
- Ensure Redis is running:
redis-cli ping. - Check REDIS_URL in the .env file.
- Check password if configured.
Problem: Migration failed.
Solution:
# Check current version
./scripts/migrate.sh current
# View migration history
./scripts/migrate.sh history
# Roll back last migration
./scripts/migrate.sh downgrade -1
# Apply migrations again
./scripts/migrate.sh upgrade head
# Show details of problematic migration
./scripts/migrate.sh show <revision>If the script is unavailable, use direct Alembic commands:
cd apps/services
docker compose -f docker-compose.yml -f docker-compose.dev.yml exec \
-w /app/apps/services -e PYTHONPATH=/app/apps/services \
-e DATABASE_URL="postgresql+asyncpg://<DB_USER>:<DB_PASSWORD>@postgres:5432/accellens" \
services python -m alembic current
docker compose -f docker-compose.yml -f docker-compose.dev.yml exec \
-w /app/apps/services -e PYTHONPATH=/app/apps/services \
-e DATABASE_URL="postgresql+asyncpg://<DB_USER>:<DB_PASSWORD>@postgres:5432/accellens" \
services python -m alembic downgrade -1Problem: Module not found.
Solution:
# Reinstall dependencies
pnpm install # for Node.js
pip install -r requirements.txt # for Python# Get latest changes
git pull origin develop
# Update dependencies
pnpm install
pip install -r requirements.txt
# Apply migrations
./scripts/migrate.sh upgrade head
# Restart services
docker compose restart# Update Helm chart
helm upgrade accellens accellens/accellens \
--namespace accellens-prod \
--values infra/k8s/environments/prod/values.yaml \
--version 1.1.0
# Check status
kubectl rollout status deployment/backend -n accellens-prod