From da7de130f68ea58181742196c527bfed806d4559 Mon Sep 17 00:00:00 2001 From: Dread <34528298+islandbitcoin@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:27:45 -0500 Subject: [PATCH 1/2] docs: improve dev onboarding experience MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite DEV.md with clearer quick-start, architecture overview, troubleshooting section, and useful commands reference - Add dev/setup.sh — interactive script that validates prerequisites, configures Ibex credentials, installs deps, and starts Docker - Fix package.json engine spec: '20' → '>=20.18.1 <21' (cheerio requires >=20.18.1, bare '20' matched 20.10.0 which fails) --- DEV.md | 376 +++++++++++++++++++++++---------------------------- dev/setup.sh | 150 ++++++++++++++++++++ package.json | 2 +- 3 files changed, 319 insertions(+), 209 deletions(-) create mode 100755 dev/setup.sh diff --git a/DEV.md b/DEV.md index 60ded5fa7..b0d3762cb 100644 --- a/DEV.md +++ b/DEV.md @@ -1,309 +1,269 @@ -# Dev environment - -- [Dev environment](#dev-environment) - - [Setup](#setup) - - [Runtime dependencies](#runtime-dependencies) - - [Development](#development) - - [Config](#config) - - [Using GraphQL Playground](#using-graphql-playground) - - [Honeycomb](#honeycomb) - - [Docker compose](#docker-compose) - - [Testing](#testing) - - [Run unit tests](#run-unit-tests) - - [Run integration tests](#run-integration-tests) - - [Run specific test file](#run-specific-test-file) - - [Unit](#unit) - - [Integration](#integration) - - [Migrations](#migrations) - - [Testing migrations](#testing-migrations) - - [Create a new migration](#create-a-new-migration) - - [Known issues](#known-issues) - - [Running checks](#running-checks) - - [Contributing](#contributing) - -## Setup - -This setup was last tested with the following tools: +# Dev Environment -``` -$ node --version -v20.10.0 -$ yarn --version -1.22.21 -$ direnv --version -2.28.0 -$ jq --version -jq-1.6 -$ docker --version -Docker version 20.10.8, build f0df350 -$ docker compose version -Docker Compose version 2.0.0 -``` - -To use the correct node version, you can install nvm and run `nvm use 20`. Then enable and inititialize yarn using the [yarn docs](https://yarnpkg.com/getting-started/install) - -### Clone the repo: - -``` -$ git clone git@github.com:lnflash/flash.git -$ cd flash -``` +## Quick Start -*Flash is a fork of [Blink](https://github.com/GaloyMoney/blink) at commit `0a52b0673` (tag: 0.13.92)* - -### Set the Environment - -[direnv](https://direnv.net) is required to load environment variables. Make sure it is installed and that the [direnv hook](https://direnv.net/docs/hook.html) is added to your `shell.rc` file. - -Create a `.env.local` to add local environment overrides. For the Flash project, the IBEX_PASSWORD is required. E.g: - - `echo "export IBEX_EMAIL=''" >> .env.local` - `echo "export IBEX_PASSWORD=''" >> .env.local` +```bash +# 1. Clone and enter +git clone git@github.com:lnflash/flash.git && cd flash -Make sure to allow direnv and reload: +# 2. Run the setup script (validates env, installs deps, configures credentials) +./dev/setup.sh -``` -$ direnv allow -$ direnv reload -(...) +# 3. Start the server +make start ``` -### Configure the app +The setup script will check your prerequisites, prompt for Ibex sandbox credentials, install dependencies, and start Docker containers. After that, `make start` launches all four backend services. -A base configuration for development purposes is provided in the `./dev/config/base-config.yaml` file. This file does excludes some values which are kept out of source control (e.g secrets). To add these values, you can either: +**GraphQL playground:** http://localhost:4002/graphql +**Admin API:** http://localhost:4002/admin/graphql +**Test login:** phone `+16505554328`, code `000000` -1. Copy an existing overrides file to the `$CONFIG_PATH/dev-overrides.yaml`, or: -2. Run the `set-overrides.sh` script which will generate the `dev-overrides.yaml` with user-defined values. -``` -chmod +x ./dev/config/set-overrides.sh -./dev/config/set-overrides.sh -``` -3. To override invidual config values, use the `set-value.sh` script. E.g: -``` -./set-value sendGrid.apiKey -``` +--- -#### Configure ErpNext +## Manual Setup -Flash uses Frappe's ErpNext application for accounting purposes. +If you prefer to set things up yourself, or if the setup script fails: -By default, the development configuration uses the Frappe Bench server running in the [Flash test environment](https://erp.test.flashapp.me). You may need to update your yaml config with proper credentials and account information. +### Prerequisites -When testing and developing features, it is recommended to run the Frappe Bench server locally. [See here](https://github.com/frappe/bench) for installation instructions. Once the server is running, update your FrappeConfig set in the dev yamls. +| Tool | Required Version | Install | +|------|-----------------|---------| +| Node.js | 20.x (20.18.1+ recommended) | [nvm](https://github.com/nvm-sh/nvm): `nvm install 20` | +| yarn | 1.x | `corepack enable && corepack prepare yarn@1 --activate` | +| Docker | 20+ with compose v2 | [Docker Desktop](https://www.docker.com/products/docker-desktop) | +| direnv | any (optional) | [direnv.net](https://direnv.net) | -#### Testing the ibex-webhook +> **Note:** The project specifies `"node": "20"` in `package.json`. Node 22+ will fail on `yarn install` due to transitive dependency engine checks. Use `--ignore-engines` if you need to override, but Node 20.x is recommended. -You'll need a web gateway that forwards traffic to your local server (default http://localhost:4008). This can be done with Ngrok. After installing the ngrok cli and creating an account, do the following: +### 1. Environment Variables -1. Start ngrok tunnel: - - ``` - ngrok http http://localhost:4008 - ``` +The project loads environment variables from `.env` (committed) and `.env.local` (git-ignored, for secrets). -2. Copy the provided URL ("forwarding" field) +Create `.env.local` with your Ibex sandbox credentials: -3. Add the URL to your `$CONFIG_PATH/dev-overrides.yaml` environment variable. E.g - - Note: To avoid repeating steps 2 & 3 everytime you restart the web gateway, you can get a static domain (e.g [ngrok domains](https://dashboard.ngrok.com/cloud-edge/domains)) +```bash +echo "export IBEX_EMAIL='your-ibex-email'" >> .env.local +echo "export IBEX_PASSWORD='your-ibex-password'" >> .env.local +``` -### Install dependencies +If you use direnv, allow it: -``` -$ yarn install +```bash +direnv allow ``` -### Start the runtime dependencies +If not using direnv, source the env files manually before running commands: ```bash -$ make start-deps -# or -$ make reset-deps +source .env && source .env.local ``` -Everytime the dependencies are re-started the environment must be reloaded via `direnv reload`. When using the [make command](../Makefile) this will happen automatically. +### 2. App Config Overrides -## Development +Flash uses YAML config files. The base config is at `dev/config/base-config.yaml`. Secrets and local overrides go in `$CONFIG_PATH/dev-overrides.yaml` (default: `~/.config/flash/dev-overrides.yaml`). -To start the GraphQL server and its dependencies: +**Option A — Run the interactive script:** -``` -$ make start +```bash +./dev/config/set-overrides.sh ``` -To run in debug mode: +**Option B — Create manually:** -``` -DEBUG=* make start +```yaml +# ~/.config/flash/dev-overrides.yaml +ibex: + email: your-ibex-email + password: your-ibex-password ``` -After running `make start-deps` or `make reset-deps`, the lightning network - running on regtest - will not have any channel, and the mongodb database - that includes some mandatory accounts for Galoy to work - will be empty. +Additional overrides you might need: -You can then login with the following credentials to get an account with an existing balance: `phone: +16505554328`, `code: 000000` +```yaml +ibex: + webhook: + uri: https://your-ngrok-domain.ngrok-free.app # for webhook testing -### Using GraphQL Playground +sendgrid: + apiKey: SG.your-sendgrid-key # for email notifications -You can load the Apollo GraphQL Playground, a web GUI for GraphQL. Start the server and open the following url: +cashout: + email: + to: your-email@example.com # for cashout notification testing +``` -- http://localhost:4002/admin/graphql (admin API, proxied thru oathkeeper) -- http://localhost:4002/graphql (end user API, proxied thru oathkeeper) +### 3. Install Dependencies -### Honeycomb +```bash +yarn install +``` -To test the effect of a change on open telemetry locally, `HONEYCOMB_API_KEY` and `HONEYCOMB_DATASET` values needs to be set. +> If you hit engine compatibility errors, use `yarn install --ignore-engines`. -`HONEYCOMB_API_KEY` can be found in Account > Team settings > Environments and API Keys > Manage > copy the dev key -`HONEYCOMB_DATASET` can be any string, pick something like `myusername-dev` +### 4. Start Docker Dependencies -### Docker compose +```bash +make start-deps +``` -The docker compose files are split into `docker-compose.yml` and `docker-compose.override.yml`. +This starts: MongoDB, Redis, Kratos (auth), Oathkeeper (API gateway), Apollo Router, price service, and OpenTelemetry collector. -By default, with `docker compose up`, docker will merge both files. The `docker-compose.override.yml` will expose ports on your host machine to various containers. +If you need a clean slate: -During CI testing we ignore the override file in order to contain tests within a docker network. This is achieved by specifically calling out the docker compose file to use ex: `docker compose -f docker-compose.yml up`. +```bash +make reset-deps +``` -## Testing +> **Note:** After restarting dependencies, reload environment variables with `direnv reload` (or re-source your `.env` files). -To run the full test suite you can run: +### 5. Start the Server ```bash -$ make test +make start ``` -Executing the full test suite requires [runtime dependencies](#runtime-dependencies). +This runs four processes in parallel: -### Run unit tests +| Process | Port | Description | +|---------|------|-------------| +| `start-main` | 4012 (direct), 4002 (via oathkeeper) | Main GraphQL API | +| `start-trigger` | — | Event trigger processor | +| `start-ws` | 4000 | WebSocket server for subscriptions | +| `start-ibex-wh` | 4008 | Ibex webhook receiver | -```bash -$ yarn test:unit -# or -$ make unit -``` +Access the API through the oathkeeper proxy at **http://localhost:4002/graphql** (not the direct 4012 port, which requires a JWT). -Runtime dependencies are not required for unit tests +--- -### Run integration tests +## Testing Ibex Webhooks -To execute the integration tests [runtime dependencies](#runtime-dependencies) must be running. +For payment event testing, you need a public URL that forwards to your local webhook server (port 4008). ```bash -$ yarn test:integration -# or -$ make integration +# Install ngrok: https://ngrok.com +ngrok http 4008 ``` -The integration tests are *not* fully idempotent (yet) so currently to re-run the tests, run: +Copy the forwarding URL and add it to your `dev-overrides.yaml`: -``` -$ make reset-integration +```yaml +ibex: + webhook: + uri: https://your-domain.ngrok-free.app ``` -### Run specific test file +**Tip:** Use a [static ngrok domain](https://dashboard.ngrok.com/cloud-edge/domains) so you don't have to update the config every restart. -To execute a specific test file: +--- -#### Unit +## ERPNext (Frappe) -Example to run `test/unit/config.spec.ts` +Flash uses ERPNext for accounting. The dev config defaults to the Flash test environment at `https://erp.test.flashapp.me`. + +To run Frappe locally: ```bash -$ TEST=utils yarn test:unit -# or -$ TEST=utils make unit +make start-frappe # start local Frappe +make reset-frappe # clean + start + restore from backup +make stop-frappe # stop local Frappe ``` -where `utils` is the name of the file `utils.spec.ts` +Update your `dev-overrides.yaml` with local Frappe credentials if running locally. -#### Integration +--- -Example to run `test/integration/01-setup/01-connection.spec.ts` +## Testing ```bash -$ TEST=01-connection yarn test:integration -# or -$ TEST=01-connection make integration +make test # full suite (unit + integration) +make unit # unit tests only (no Docker deps needed) +make integration # integration tests (needs Docker deps) +make reset-integration # reset state + run integration tests ``` -if within a specific test suite you want to run/debug only a describe or it(test) block please use: +Run a specific test file: -* [describe.only](https://jestjs.io/docs/api#describeonlyname-fn): just for debug purposes -* [it.only](https://jestjs.io/docs/api#testonlyname-fn-timeout): just for debug purposes -* [it.skip](https://jestjs.io/docs/api#testskipname-fn): use it when a test is temporarily broken. Please don't commit commented test cases +```bash +TEST=utils make unit # runs utils.spec.ts +TEST=01-connection make integration # runs 01-connection.spec.ts +``` -## Migrations +**Known issues:** +- Integration tests are not fully idempotent — use `make reset-integration` between runs +- If tests timeout, increase: `JEST_TIMEOUT=120000 yarn test:integration` +- Use an SSD for Docker volumes (tests are disk-intensive) -### Testing migrations +--- -Migrations are stored in the `src/migrations` folder. -When developing migrations the best way to test them on a clean database is: +## Architecture Overview ``` -make test-migrate +Client → Oathkeeper (4002) → GraphQL Main (4012) + → Admin API (4001) + WebSocket (4000) + Ibex Webhook (4008) ← Ibex payment events + +Docker deps: + MongoDB (27017) — primary database + Redis (6378→6379) — caching, pub/sub + Kratos (4433/4434) — identity/auth + Price (50051) — gRPC price service + Apollo Router (4004) — federation + OTEL Collector (4318) — telemetry ``` -#### Create a new migration +--- -Create the migration file +## Useful Commands -```bash -npx migrate-mongo create \ - -f src/migrations/migrate-mongo-config.js -``` +| Command | Description | +|---------|-------------| +| `make start` | Start all servers | +| `make start-main` | Start only the main GraphQL server | +| `make start-deps` | Start Docker dependencies | +| `make clean-deps` | Stop and remove Docker containers | +| `make reset-deps` | Clean + restart Docker deps | +| `make watch` | Start with file watching (auto-restart on changes) | +| `make check-code` | Run all linting/type checks | +| `yarn prettier -w .` | Format all files | +| `DEBUG=* make start` | Start in debug mode | -Write the migration in the newly created migration file and then test/run with the following: +--- -```bash -# Migrate -npx migrate-mongo up \ - -f src/migrations/migrate-mongo-config.js +## Troubleshooting -# Rollback -npx migrate-mongo down \ - -f src/migrations/migrate-mongo-config.js -``` +### `UnauthorizedError: No authorization token was found` -When testing, to isolate just the current migration being worked on in local dev you can temporarily move the other migrations to another dir. +You're hitting the GraphQL server directly (port 4012). Use the oathkeeper proxy at **http://localhost:4002/graphql** instead, which handles auth for anonymous/public queries. -### Known issues +### `The engine "node" is incompatible` -* **Test suite timeouts**: increase jest timeout value. Example: - - ```bash - # 120 seconds - $ JEST_TIMEOUT=120000 yarn test:integration - ``` +Flash requires Node 20.x. Switch with `nvm use 20` or run `yarn install --ignore-engines`. -* **Integration tests running slow**: we use docker to run dependencies (redis, mongodb, bitcoind and 4 lnds) so the entire test suite is disk-intensive. - - * Please make sure that you are running docker containers in a solid state drive (SSD) - - * Reduce lnd log disk usage: change debuglevel to critical - - ``` - # ./dev/lnd/lnd.conf - debuglevel=critical - ``` +### Docker warnings about unset variables -## Running checks +`IBEX_URL`, `HONEYCOMB_DATASET`, `HONEYCOMB_API_KEY` warnings in docker compose output are harmless in dev — these are only needed for the Docker-based server (not used by `make start`). -It's recommended that you use plugins in your editor to run ESLint checks and perform Prettier formatting on-save. +### `API key does not start with "SG."` -To run all the checks required for the code to pass GitHub actions check: +SendGrid isn't configured — email notifications won't work. Safe to ignore in dev unless you're testing email features. Add a real key to your `dev-overrides.yaml` if needed. -``` -$ make check-code -(...) -$ echo $? -0 -``` +### Server starts but crashes immediately -If you need to run Prettier through the command line, you can use: +Check that all Docker deps are healthy: `docker compose ps`. If MongoDB or Redis failed to start, run `make reset-deps`. -``` -$ yarn prettier -w . -``` +--- ## Contributing -See the [CONTRIBUTING.md](./CONTRIBUTING.md) +See [CONTRIBUTING.md](./CONTRIBUTING.md). + +### Code Quality + +```bash +make check-code # ESLint + TypeScript checks +yarn prettier -w . # auto-format +``` + +Use editor plugins for ESLint and Prettier for best experience. diff --git a/dev/setup.sh b/dev/setup.sh new file mode 100755 index 000000000..3b001bef7 --- /dev/null +++ b/dev/setup.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# Flash Dev Environment Setup +# Usage: ./dev/setup.sh +# +# This script validates your environment, installs dependencies, +# configures credentials, and starts the development server. + +set -euo pipefail + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +info() { echo -e "${GREEN}✓${NC} $1"; } +warn() { echo -e "${YELLOW}⚠${NC} $1"; } +fail() { echo -e "${RED}✗${NC} $1"; exit 1; } + +echo "" +echo "═══════════════════════════════════════════════════" +echo " Flash Backend — Development Environment Setup" +echo "═══════════════════════════════════════════════════" +echo "" + +# ── 1. Check Node.js version ────────────────────────── +echo "Checking prerequisites..." + +NODE_VERSION=$(node --version 2>/dev/null || echo "none") +if [[ "$NODE_VERSION" == "none" ]]; then + fail "Node.js is not installed. Install via nvm: https://github.com/nvm-sh/nvm" +fi + +NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1) +if [[ "$NODE_MAJOR" != "20" ]]; then + warn "Node.js $NODE_VERSION detected — Flash requires Node 20.x" + if command -v nvm &>/dev/null || [ -f "$HOME/.nvm/nvm.sh" ]; then + echo " Attempting: nvm use 20..." + export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" + [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" + nvm use 20 2>/dev/null || nvm install 20 + info "Now using $(node --version)" + else + fail "Please install Node 20.x. Recommended: use nvm (https://github.com/nvm-sh/nvm)" + fi +else + info "Node.js $NODE_VERSION" +fi + +# ── 2. Check yarn ───────────────────────────────────── +if ! command -v yarn &>/dev/null; then + fail "yarn is not installed. Run: corepack enable && corepack prepare yarn@1 --activate" +fi +info "yarn $(yarn --version)" + +# ── 3. Check Docker ─────────────────────────────────── +if ! command -v docker &>/dev/null; then + fail "Docker is not installed. Install Docker Desktop: https://www.docker.com/products/docker-desktop" +fi +if ! docker info &>/dev/null 2>&1; then + fail "Docker daemon is not running. Please start Docker Desktop." +fi +info "Docker $(docker --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" + +# ── 4. Check direnv (optional but recommended) ─────── +if command -v direnv &>/dev/null; then + info "direnv $(direnv --version)" +else + warn "direnv not found (optional but recommended). Install: https://direnv.net" +fi + +echo "" + +# ── 5. Configure Ibex credentials ──────────────────── +echo "Checking Ibex credentials..." + +if [ -f .env.local ] && grep -q "IBEX_PASSWORD" .env.local 2>/dev/null; then + info "Ibex credentials found in .env.local" +else + echo "" + echo "Flash requires Ibex sandbox credentials to connect to the payment backend." + echo "If you don't have credentials, ask your team lead." + echo "" + read -rp "Ibex email (or press Enter to skip): " IBEX_EMAIL + if [ -n "$IBEX_EMAIL" ]; then + read -rsp "Ibex password: " IBEX_PASSWORD + echo "" + cat > .env.local << EOF +export IBEX_EMAIL='${IBEX_EMAIL}' +export IBEX_PASSWORD='${IBEX_PASSWORD}' +EOF + info "Credentials saved to .env.local (git-ignored)" + else + warn "Skipped — you'll need to create .env.local with IBEX_EMAIL and IBEX_PASSWORD before starting" + fi +fi + +# ── 6. Configure app overrides ─────────────────────── +echo "" +echo "Checking app config overrides..." + +CONFIG_DIR="${CONFIG_PATH:-$HOME/.config/flash}" +OVERRIDES="$CONFIG_DIR/dev-overrides.yaml" + +if [ -f "$OVERRIDES" ]; then + info "Config overrides found at $OVERRIDES" +else + mkdir -p "$CONFIG_DIR" + # Read from .env.local if it exists + if [ -f .env.local ]; then + source .env.local 2>/dev/null || true + fi + if [ -n "${IBEX_EMAIL:-}" ] && [ -n "${IBEX_PASSWORD:-}" ]; then + cat > "$OVERRIDES" << EOF +ibex: + email: ${IBEX_EMAIL} + password: ${IBEX_PASSWORD} +EOF + info "Generated $OVERRIDES with Ibex credentials" + else + warn "Could not generate overrides — run ./dev/config/set-overrides.sh manually" + fi +fi + +echo "" + +# ── 7. Install dependencies ────────────────────────── +echo "Installing Node.js dependencies..." +yarn install --ignore-engines 2>&1 | tail -3 +info "Dependencies installed" + +echo "" + +# ── 8. Start Docker dependencies ───────────────────── +echo "Starting Docker dependencies..." +docker compose up bats-deps -d 2>&1 | grep -E '(Created|Started|Running)' || true +info "Docker dependencies running" + +echo "" +echo "═══════════════════════════════════════════════════" +echo " ✅ Setup complete!" +echo "" +echo " Start the dev server: make start" +echo " GraphQL playground: http://localhost:4002/graphql" +echo " Admin playground: http://localhost:4002/admin/graphql" +echo " Test login: phone: +16505554328 code: 000000" +echo "" +echo " Stop everything: make clean-deps" +echo " Run tests: make test" +echo "═══════════════════════════════════════════════════" +echo "" diff --git a/package.json b/package.json index 26d1d39f2..b48d43be7 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "gen-test-jwt": "ts-node ./dev/bin/gen-test-jwt.ts" }, "engines": { - "node": "20" + "node": ">=20.18.1 <21" }, "dependencies": { "@aws-sdk/client-s3": "^3.968.0", From 12d6aebd1bc857895494fb0925c8a12c557b17c2 Mon Sep 17 00:00:00 2001 From: Dread <34528298+islandbitcoin@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:39:45 -0500 Subject: [PATCH 2/2] docs: add Apple Silicon note, fix IBEX_URL docker warning - Add troubleshooting entry for price service amd64 platform warning on ARM Macs - Add IBEX_URL, IBEX_EMAIL, IBEX_PASSWORD defaults to .env to suppress docker compose warnings about unset variables --- .env | 5 +++++ DEV.md | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/.env b/.env index 18e922e67..cbce6645a 100644 --- a/.env +++ b/.env @@ -122,3 +122,8 @@ export CONFIG_PATH="$HOME/.config/flash" export ERPNEXT_JWT_SECRET="not-so-secret" COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml:docker-compose.local.yml + +# Ibex API (used by docker compose; app reads from yaml config) +export IBEX_URL="https://api-sandbox.poweredbyibex.io" +export IBEX_EMAIL="" +export IBEX_PASSWORD="" diff --git a/DEV.md b/DEV.md index b0d3762cb..0b17a2e58 100644 --- a/DEV.md +++ b/DEV.md @@ -249,6 +249,14 @@ Flash requires Node 20.x. Switch with `nvm use 20` or run `yarn install --ignore SendGrid isn't configured — email notifications won't work. Safe to ignore in dev unless you're testing email features. Add a real key to your `dev-overrides.yaml` if needed. +### Price service platform warning (Apple Silicon) + +``` +The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) +``` + +The `lnflash/price:edge` image is amd64-only. On Apple Silicon Macs it runs under Rosetta emulation — this is harmless but slow. The warning is safe to ignore. + ### Server starts but crashes immediately Check that all Docker deps are healthy: `docker compose ps`. If MongoDB or Redis failed to start, run `make reset-deps`.