Getting Started

This guide gets you from zero to a working Apostol CRM backend with 418 REST API endpoints, OAuth 2.0 authentication, and a workflow engine.

Prerequisites

RequirementNotes
Docker & Docker ComposeRecommended for quick start
GitTo clone the repository

For building from source, you also need:

RequirementVersionNotes
C++ compilerGCC 12+ or Clang 16+Must support C++20
CMake3.25+Build system
PostgreSQL12+Database server
OpenSSLanyTLS, JWT, SMTP
libcurlanyHTTP client
zlibanyLog compression

Debian/Ubuntu:

sudo apt-get install build-essential libssl-dev libcurl4-openssl-dev \
    libpq-dev zlib1g-dev make cmake gcc g++

Quick Start with Docker

The fastest way to get a working environment:

git clone --recurse-submodules https://github.com/apostoldevel/apostol-crm.git
cd apostol-crm/backend
./docker-build.sh
./docker-up.sh

This starts five services: PostgreSQL 18, PgBouncer, Nginx, PgWeb, and the Backend.

URLWhat you get
localhost:8080Frontend
localhost:8080/docsSwagger UI (418 endpoints)
localhost:8081PgWeb -- database admin

Default credentials: admin / admin

To stop or reset:

./docker-down.sh           # stop all services
./docker-new-database.sh   # recreate PostgreSQL volume (destructive)

Build from Source

Clone and build

git clone --recurse-submodules https://github.com/apostoldevel/apostol-crm.git
cd apostol-crm/backend
./configure
cmake --build cmake-build-release --parallel $(nproc)
sudo cmake --install cmake-build-release

Set up the database

# 1. Configure passwords
echo '*:*:*:kernel:kernel' >> ~/.pgpass
echo '*:*:*:admin:admin'   >> ~/.pgpass
echo '*:*:*:daemon:daemon' >> ~/.pgpass
chmod 600 ~/.pgpass

# 2. Add to postgresql.conf, then restart PostgreSQL:
#    search_path = '"$user", kernel, public'

# 3. Initialize
cd db/
./runme.sh --init

Run the server

sudo service apostol-crm start

Development mode

For local development without installing system-wide:

./configure --debug
cmake --build cmake-build-debug --parallel $(nproc)
mkdir -p logs
./cmake-build-debug/apostol-crm -p . -c conf/default.json

Your First API Call

Once the server is running, verify it works:

# Health check
curl http://localhost:4977/api/v1/ping
# {"ok": true}

# Authenticate (get a session token)
curl -X POST http://localhost:4977/oauth2/token \
  -d 'grant_type=password&username=admin&password=admin&client_id=web'
# {"access_token": "eyJ...", "token_type": "Bearer", ...}

# Use the token to list clients
curl http://localhost:4977/api/v1/client/list \
  -H 'Authorization: Bearer eyJ...'

With Docker, use port 8080 instead of 4977 (Nginx proxy).

Database Commands

All commands run from the db/ directory:

CommandEffect
./runme.sh --updateSafe: update routines and views only
./runme.sh --patchUpdate tables + routines + views
./runme.sh --installDestructive: drop/recreate DB with seed data
./runme.sh --initDestructive: first-time setup (create users + install)

Configuration

The main configuration file is conf/default.json:

{
  "prefix": ".",
  "server": {
    "listen": "127.0.0.1",
    "port": 4977
  },
  "module": {
    "AuthServer": { "enable": true },
    "AppServer": { "enable": true },
    "FileServer": { "enable": true },
    "WebSocketAPI": { "enable": true }
  },
  "postgres": {
    "connect": true,
    "worker": { "user": "daemon" },
    "helper": { "user": "apibot" },
    "kernel": { "user": "kernel" }
  }
}

Next Steps