What you are running
The app is designed to run as a single instance. The outreach sender loop
has no distributed lock; two instances would each send. Do not scale
app to
more than one replica. (The enrichment and CRM workers are safe to overlap;
the outreach scheduler is not.)
Requirements
- PostgreSQL 16 or newer.
db:setuprefuses older servers. The schema is tested on 16, 17 and 18. - Either Docker (with Compose), or Node.js 20.9+ / Bun 1.2+ to run from source. The Docker image and the repository’s tooling use Bun.
- A public HTTPS origin if you want webhooks to reach you (Unipile, Gmail push) and email links to work for other people.
- A Resend account, only if you will invite people or need password-reset email (see Email).
Outside accounts you will need
Third-party services (Unipile, Google Workspace, Cloudflare R2, OpenRouter, enrichment providers) are not configured in the environment. You connect them from inside the app, per organization. See integrations.md. Each feature switches on once the service it needs is connected.Choose your path
Then read Going to production and keep
Troubleshooting at hand. Every environment
variable is in the configuration reference.
Order of setup
- Install with one of the paths above.
- First sign-up: create the first account and your organization (below).
- Connect integrations in Settings, one per feature you want.
- Scheduled jobs: nothing to set up; set each organization’s time zone (below).
- Go live: domain, HTTPS, Resend, backups (production).
First sign-up and the organization
- On a fresh install, open the app: the setup page creates the first admin
account and your organization (a name and a URL slug), and no email
verification is needed. You become the owner. Later accounts sign up at
/sign-up, and password sign-in for them needs a verified email (see Email); with noRESEND_API_KEYthat email is written to the server log instead, so you can copy the link from there (docker compose logs app). - A signed-in user with no organization is sent to
/onboarding. - Everything in ReachCrew belongs to an organization. Invite teammates from Settings, Members; an invitation is sent by email and expires after 7 days.
- Connect your services in Settings, Integrations (integrations.md).
AUTH_SIGNUP, the platform operator) is explained in
Going to production.
RESEND_API_KEY and AUTH_EMAIL_FROM (an address on a domain you have
verified in Resend). Without RESEND_API_KEY, they are written to the server
log instead of sent. This is separate from the email your campaigns send, which
goes out through the Gmail accounts you connect. Details:
Going to production.
Scheduled jobs
The scheduled jobs run inside the app in production, so there is no cron container and nothing to schedule: the daily rollover (email send queues, Gmail watch renewal, LinkedIn daily limits), LinkedIn outreach every 30 minutes, LinkedIn webhook replay every 10 minutes, and history pruning. The rollover happens at the start of each organization’s day, set in Settings, Organization, Defaults (Time zone and New day starts at; UTC and 00:00 by default).INTERNAL_SCHEDULER=false turns the jobs off if you prefer an external cron
calling the endpoints. The full table, the endpoints and their secrets (now
optional) are in
Going to production; crontab
examples are in From source.