close
Skip to content

Development Setup

This guide covers setting up a development environment for contributing to Faraday. If you want to use Faraday (not develop it), see the installation guide instead.

Prerequisites

Requirement Minimum Recommended Notes
Python 3.9 3.11 Docker uses 3.11; setuptools classifiers list 3.7–3.9 but 3.7/3.8 are EOL
PostgreSQL 12 14+ Docker Compose uses 12.7-alpine
Redis 4.x 7+ Docker Compose uses 8.4-alpine
Git 2.x Latest For cloning and contributing
OS Linux (64-bit) Debian 12 / Ubuntu 22.04+ macOS works for development; Windows not supported

Note: The setup.py declares python_requires='>=3.7', but Python 3.7 and 3.8 reached end-of-life in June 2023 and October 2024 respectively. Many dependencies no longer support them. Use Python 3.9+ (ideally 3.11 to match the Docker image).


The fastest way to get a working development environment is Docker Compose with local source mounting.

1. Clone the Repository

git clone https://github.com/infobyte/faraday.git faraday-dev
cd faraday-dev

2. Enable Development Mode in Docker Compose

Edit docker-compose.yaml:

# Uncomment the local image line and comment out the official one:
# x-faraday-image: &faraday-image index.docker.io/faradaysec/faraday:latest
x-faraday-image: &faraday-image faraday-local

# Under x-faraday-volumes, uncomment the source mount:
x-faraday-volumes: &faraday-volumes
  - "faraday:/home/faraday/.faraday:rw"
  - "./:/src"  # Mount local source for live code changes

# Under faraday-server build args, uncomment DEV_ENV:
    build:
      context: .
      args:
        - DEV_ENV=1  # Installs in editable mode

3. Build and Start

docker compose build faraday-server
docker compose up -d

This starts all required services:

Service Container Purpose
db faraday_db PostgreSQL 12.7 (postgres:postgres@faraday)
redis faraday_redis Redis 8.4 message broker
faraday-server faraday_server API server on port 5985
faraday-default-worker faraday_worker Celery task worker

4. Access the Web UI

Open http://localhost:5985/ in your browser. The initial admin password is generated during first startup — check the server logs:

docker compose logs faraday-server | grep -i password

To reset the password:

docker compose run --rm change-password

5. Run Management Commands

docker compose run --rm faraday-manage <command>

Full Source Setup (Bare-Metal)

For full development with debugging, testing, and IDE integration.

1. Install System Dependencies

Debian / Ubuntu (22.04+)

sudo apt update
sudo apt install -y \
    build-essential python3-dev python3-pip python3-venv \
    libssl-dev libffi-dev pkg-config \
    libxml2-dev libxslt1-dev libfreetype6-dev libpng-dev \
    libpq-dev libsasl2-dev libldap2-dev \
    libgdk-pixbuf2.0-0 libmagic1 \
    postgresql redis-server \
    git curl zsh

RHEL / CentOS / Fedora

sudo dnf install -y \
    gcc gcc-c++ python3-devel openssl-devel libffi-devel \
    libxml2-devel libxslt-devel freetype-devel libpng-devel \
    postgresql-devel openldap-devel \
    postgresql-server redis \
    git curl zsh

2. Clone the Repository

git clone https://github.com/infobyte/faraday.git faraday-dev
cd faraday-dev

3. Create a Python Virtual Environment

uv venv faraday_venv
source faraday_venv/bin/activate

4. Install Dependencies

# Install main + dev dependencies in editable mode
uv pip install -e .
uv pip install -r requirements_dev.txt

This installs the package in editable mode (-e), so code changes take effect immediately without reinstalling. It also creates the CLI entry points:

Command Entry Point Purpose
faraday-server faraday.start_server:main Start the API server
faraday-manage faraday.manage:cli Administration CLI
faraday-worker faraday.server.celery_worker:main Celery worker (prefork)
faraday-worker-gevent faraday.server.celery_worker_gevent:main Celery worker (gevent, for reports)
faraday-start-all faraday.start_all:main Start server + workers together

5. Set Up PostgreSQL

# Start PostgreSQL
sudo systemctl start postgresql

# Create the database (automatic method)
faraday-manage initdb

Important: initdb generates a random admin password — copy it immediately. Use faraday-manage change-password to reset it later.

Manual PostgreSQL Setup (Advanced)

If you need a custom database name, user, or remote host:

sudo -u postgres psql -c "CREATE ROLE faraday_dev WITH LOGIN PASSWORD 'changeme'"
sudo -u postgres createdb -O faraday_dev faraday_dev

Then edit ~/.faraday/config/server.ini:

[database]
connection_string = postgresql+psycopg2://faraday_dev:changeme@localhost/faraday_dev

Then create tables and an admin user:

faraday-manage create-tables
faraday-manage create-superuser

6. Start Redis

sudo systemctl start redis

Redis is required as the Celery message broker. Default configuration expects Redis at redis://127.0.0.1:6379/0.

7. Start the Server and Workers

# Start the server in the foreground
faraday-server

Useful server options:

Flag Description
--debug Enable Flask debug mode with auto-reload
--port PORT Override configured port (default: 5985)
--bind_address ADDR Override bind address (default: 127.0.0.1)
--with-workers Also start Celery prefork workers
--with-workers-gevent Also start Celery gevent workers
--nodeps Skip dependency checks on startup

The server runs on http://localhost:5985/ by default.

8. Start Workers (Optional — Separate Terminal)

Workers are needed for asynchronous tasks (report imports, stats, workflows):

# Default worker (prefork pool, handles stats/workflows/host-creation)
faraday-worker

# Gevent worker (handles report imports/parsing — separate queue)
faraday-worker-gevent

Configuration Reference

Server Configuration

The server reads configuration from ~/.faraday/config/server.ini. Key sections:

[faraday_server]
port = 5985                     # API port
bind_address = 127.0.0.1        # Use 0.0.0.0 to expose externally
debug = false                   # Flask debug mode
session_timeout = 12            # Session timeout in hours
api_token_expiration = 86400    # API token TTL in seconds (24h)

# Celery/Redis — these are the default values; omit them if your setup matches
celery_enabled = true
celery_broker_url = redis://127.0.0.1:6379/0
celery_backend_url = redis://127.0.0.1:6379/0

[database]
connection_string = postgresql+psycopg2://user:pass@localhost/faraday

[logger]
use_rfc5424_formatter = false

Note: The Celery and Redis settings above reflect the default values. If you are running Redis locally on the default port, you do not need to add them to server.ini.

Directory Structure

After first run, Faraday creates ~/.faraday/ (or $FARADAY_HOME/.faraday/ if set):

~/.faraday/
├── config/
│   └── server.ini          # Server configuration
├── logs/                   # Server log files
├── session/                # Session storage
└── storage/                # Uploaded file storage (reports, attachments)

Environment Variables (Docker)

When running in Docker Compose, configuration is passed via environment variables:

Variable Default Description
PGSQL_USER postgres PostgreSQL username
PGSQL_PASSWD postgres PostgreSQL password
PGSQL_HOST db PostgreSQL host
PGSQL_DBNAME faraday PostgreSQL database name
REDIS_SERVER redis Redis host
FARADAY_HOME /home/faraday Faraday data directory

Running Tests

Faraday uses pytest with factory_boy for test data generation.

Test Dependencies

uv pip install -r requirements_dev.txt

Test Database Setup

Tests require a running PostgreSQL instance. Set these environment variables:

export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=postgres
export POSTGRES_HOST=localhost

The test suite automatically creates a random temporary database for each session and drops it on teardown — your development database is not affected.

Running Tests

# Run all tests
pytest

# Run tests in parallel (faster)
pytest -n auto

# Run a specific test file
pytest tests/test_api_vulns.py

# Run a specific test
pytest tests/test_api_vulns.py::test_create_vuln

# Run with coverage
pytest --cov=faraday --cov-report=html

# Run property-based (hypothesis) tests
pytest --with-hypothesis

# Ignore N+1 query warnings
pytest --ignore-nplusone

Test Structure

tests/
├── conftest.py                 # Fixtures: app, database, session, factories
├── factories.py                # factory_boy model factories
├── data/                       # Test data files (sample reports, etc.)
├── models/                     # ORM model tests
│   ├── test_host.py
│   ├── test_vulnerability.py
│   └── test_workspace.py
├── celery/                     # Celery task tests
│   └── test_api_bulk_create.py
├── test_api_*.py               # API endpoint tests (majority of test suite)
├── test_faraday_manage.py      # CLI management command tests
├── test_migrations.py          # Database migration tests
└── test_server.py              # Server startup/config tests

Code Quality & Pre-Commit Hooks

Pre-Commit Setup

The repository includes a .pre-commit-config.yaml with these checks:

# Install pre-commit hooks
uv pip install pre-commit
pre-commit install

Note: The faraday/server/www/ directory (bundled frontend) is excluded from all pre-commit checks.

Linting

# Flake8 (configured in setup.cfg)
flake8 faraday/

# Pylint (configured in .pylintrc)
pylint faraday/

Key Management Commands for Development

The faraday-manage CLI provides essential tools for development:

Command Description
initdb Create database, tables, indexes, and admin user
migrate Run Alembic database migrations
create-tables Create tables on a manually-configured database
create-superuser Create an admin user (Pro/Corp)
change-password Change a user's password
change-username Change a user's username
sql-shell Open an interactive PostgreSQL shell
show-urls Display all registered Flask API routes
openapi-swagger Generate the OpenAPI/Swagger specification
database-schema Generate a PNG diagram of the database schema
manage-settings View/update application settings
add-custom-field Add a custom field to a model
delete-custom-field Remove a custom field
nginx-config Generate NGINX reverse proxy configuration
import-vulnerability-templates Import vulnerability template data

Project Structure

faraday/
├── __init__.py                 # Version: __version__ = '5.19.0'
├── manage.py                   # faraday-manage CLI (Click-based)
├── start_server.py             # faraday-server entry point
├── start_all.py                # faraday-start-all entry point
├── server/
│   ├── app.py                  # Flask application factory
│   ├── config.py               # Configuration objects
│   ├── default.ini             # Default configuration values
│   ├── models.py               # SQLAlchemy ORM models
│   ├── celery_worker.py        # Celery prefork worker
│   ├── celery_worker_gevent.py # Celery gevent worker
│   ├── api/
│   │   └── modules/            # 38 API modules (hosts, vulns, workspaces, etc.)
│   ├── websocket/              # Flask-SocketIO WebSocket service
│   ├── tasks/                  # Celery task definitions
│   └── www/                    # Bundled frontend (do not edit directly)
├── migrations/                 # Alembic database migrations
│   └── versions/               # Migration scripts
└── openapi/
    └── faraday_swagger.json    # OpenAPI specification

Common Development Workflows

Adding a New API Endpoint

  1. Create or modify a module in faraday/server/api/modules/
  2. Define the SQLAlchemy model in faraday/server/models.py (if new entity)
  3. Create a marshmallow schema for serialization
  4. Register routes in the module's blueprint
  5. Add tests in tests/test_api_<module>.py
  6. Run faraday-manage show-urls to verify route registration

Creating a Database Migration

# After modifying models.py, generate an Alembic migration
cd faraday  # must be in the faraday package directory
alembic -c faraday/alembic.ini revision --autogenerate -m "description of change"

# Apply the migration
faraday-manage migrate

Regenerating the OpenAPI Spec

faraday-manage openapi-swagger --server http://localhost:5985

Deprecated Components

The following components are no longer part of the Faraday server repository and should not be referenced in new development:

Component Status Replacement
GTK+3 Client (faraday-client) Removed in v3.3.0, moved to separate repo Web UI (React.js) at http://localhost:5985/
CouchDB backend Removed in v3.0 PostgreSQL
import-from-couchdb command Removed N/A
user.xml configuration Removed server.ini
Python 2 support Removed Python 3.9+
vext / vext.pygtk packages Not needed Only relevant for removed GTK client

Ecosystem Repositories

For full-stack development, you may also need these related repositories:

Repository Purpose Install
faraday_plugins Report parsers (120+ tools) pip install faraday-plugins
faraday-cli Terminal client pip install faraday-cli
faraday_agent_dispatcher Agent framework pip install faraday-agent-dispatcher
faraday_burp Burp Suite extension See repo README

Developing Custom Plugins

See Basic Plugin Development for creating custom report parsers and command plugins.


Troubleshooting

psycopg2 build fails

Install the PostgreSQL development headers:

# Debian/Ubuntu
sudo apt install libpq-dev

# RHEL/CentOS
sudo dnf install postgresql-devel

faraday-manage initdb fails with permission error

Ensure PostgreSQL is running and your user has permission to create databases:

sudo systemctl start postgresql
# Check the PostgreSQL log for auth errors
sudo journalctl -u postgresql

If you don't have sudo installed, install it first:

apt install sudo

Server reports "schema not up to date"

Run database migrations:

faraday-manage migrate

Redis connection refused

Ensure Redis is running:

sudo systemctl start redis
# Verify
redis-cli ping   # Should respond: PONG

Port 5985 already in use

Another Faraday instance may be running. Check and stop it:

lsof -i :5985
kill <PID>

Or use a different port:

faraday-server --port 5986

Further Reading