Skip to content

Install Dependencies

This guide covers machine prerequisites (PHP, Node, mobile SDKs) and per-package installs (composer, yarn). You do not need every toolchain if you only work in one package — see What you need below.

If you work in…Install
api/PHP 8.4+, Composer, Node (for Vite assets in api/)
ui/, www/, docs/Node.js 22+ (nvm)
mobile/JDK 17, Android Studio; Xcode on macOS for iOS
Any contributionGit, Sign Off Commits configured, git setup (hooks)

Production planning targets PostgreSQL and Redis (Deployment); the API scaffold defaults to SQLite locally so you can run without Docker on day one.

The repo ships bin/setup, bin/start, bin/stop, and bin/check to run a production-like stack locally:

LayerHow it runs
API, Postgres, Redis, Traefik (TLS)Docker Compose (compose.dev.yml)
ui/, docs/, www/ (optional)Native yarn dev on the host

Default URLs (HTTPS) — add hosts once (see below), run bin/setup, then bin/start:

ServiceURL
APIhttps://api.garrison.test
Web apphttps://app.garrison.test
WebSocket (Reverb)wss://ws.garrison.test
Docs sitehttps://docs.garrison.test
Marketing (--www)https://www.garrison.test (apex https://garrison.test redirects here)

Traefik terminates TLS on port 443 using mkcert certs in .certs/ (generated by bin/setup). Frontends listen on 5173 / 4322 / 4321; Traefik proxies to them via host.docker.internal.

bin/setup also creates ui/.env from ui/.env.example with VITE_API_URL=https://api.garrison.test so the SPA calls the API host directly (required for Sanctum cookies on .garrison.test). Override that value if your API origin differs.

Terminal window
bin/check # prerequisites only; exit 1 if anything missing
bin/setup # once: mkcert, Docker build, composer, migrate
bin/start # foreground: docker compose + ui + docs
bin/start --preview # ui: production build + vite preview (no HMR)
bin/start --www # also start www/
bin/stop # docker compose down
bin/stop --purge # down + remove postgres volume

On Windows (PowerShell from the repo root), use the same flags with the bin\*.ps1 scripts: bin\check.ps1, bin\setup.ps1, bin\start.ps1, bin\stop.ps1, bin\lint.ps1, and bin\install-git-hooks.ps1. The hosts file is %SystemRoot%\System32\drivers\etc\hosts (the setup/start scripts can append the dev hostnames when you confirm, with elevation).

FlagEffect
--no-promptFail with instructions instead of interactive install offers (bin/start, bin/setup)
--previewBuild ui/ once, then vite preview on port 5173 (no HMR; recommended for Playwright)
--httpSkip TLS checks / Traefik; use http://localhost:8000, :5173, :4322 (OAuth and Secure cookies may not work)
--wwwInclude marketing site

bin/start runs everything in one terminal via concurrently; Ctrl+C stops Docker and frontends. Compose services use restart: unless-stopped; the API container is watched for api/.env.docker and docker/api image changes (composer.lock is bind-mounted — run composer install in the container after lockfile updates). Frontends restart automatically if their dev server exits.

Prerequisites checked by bin/check / bin/start

Section titled “Prerequisites checked by bin/check / bin/start”
  • Docker + Compose v2 (docker compose), daemon running
  • Node 22 (.nvmrc) and npm
  • ui/node_modules, docs/node_modules (and www/node_modules with --www) — prompts for yarn install when missing
  • mkcert, .certs/ (after bin/setup)
  • hosts file (/etc/hosts on Unix; %SystemRoot%\System32\drivers\etc\hosts on Windows) — one line mapping dev hostnames to 127.0.0.1 (scripts can append when you confirm)

Not required on the host for Docker dev: PHP and Composer (run inside the api container via bin/setup).

Add to /etc/hosts (macOS/Linux) or C:\Windows\System32\drivers\etc\hosts (Windows, edit as Administrator):

127.0.0.1 garrison.test api.garrison.test app.garrison.test docs.garrison.test www.garrison.test ws.garrison.test

Browser tests live in tests/web/ and target the running SPA at https://app.garrison.test (same stack as bin/start).

Terminal window
cd tests/web
yarn install
yarn install:browsers
yarn test

Requires bin/start (or equivalent) so the API and UI are reachable. Copy tests/web/.env.example to .env only if you need a non-default BASE_URL. See tests/web/README.md for project layout (setup, smoke, chromium) and worktree workflow.

Contributors can still run the API on the host with SQLite:

Terminal window
cd api && composer run setup && composer run dev

See PHP and Composer below.

When APP_ENV=local, seed a dev account and sample studies:

Terminal window
docker compose -f compose.dev.yml run --rm --no-deps api php artisan db:seed
FieldValue
Emaildev@garrison.test
Passwordpassword

Re-running the seeder resets that user’s studies, log entries, and notes. The web sign-in page (yarn dev) shows Use dev account to fill these credentials. Not run in production.

Terminal window
git clone https://gitlab.com/ChurchTechHelp/garrison.git
cd garrison

Recommended next steps for contributors: Git setup (once per clone), then sign off commits (Git identity and commit.signoff), then install only the toolchains you need below.

The repository ships shared pre-commit hooks under .githooks/. They call bin/pre-commit, which inspects staged files and runs checks only for the packages you touched.

From the repository root:

Terminal window
bin/install-git-hooks

This sets core.hooksPath to .githooks for this clone only (stored in .git/config, not committed). Re-run the installer after cloning again or if hooks stop running.

Confirm hooks are active:

Terminal window
git config core.hooksPath # should print: .githooks
Staged pathsCheckRequires
api/**/*.phpLaravel Pint (--test, staged files only)cd api && composer install
ui/**/*.{vue,ts,tsx,js,mjs,cjs}ESLint (staged files)cd ui && npm install
ui/**/*.{vue,ts,tsx,js,mjs,cjs,css,json,md,html}Prettier --check (staged files)cd ui && npm install
ui/** with any .vue or .ts changevue-tsc (full UI typecheck)cd ui && npm install
Any pathBlock .env and common key files (allow *.example)
api/routes/**, api/graphql/schema.graphql, api/app/GraphQL/**, api/app/Models/**, api/database/migrations/**, ui/graphql/**CodeSight wiki regen + stage .codesight/npx (Node.js) on the host

Changes under www/, docs/, or mobile/ do not trigger package linters yet; install hooks anyway so secret checks and future rules still apply.

Same script Git invokes on commit:

Terminal window
bin/pre-commit

With nothing staged, it prints No staged files and exits successfully. Stage changes first to mirror a real commit:

Terminal window
git add ui/src/App.vue
bin/pre-commit

Lint from the repository root (package name first; remaining args go to the linter):

Terminal window
bin/lint ui
bin/lint ui --fix src/pages/index.vue
bin/lint api
bin/lint api --test app/Models/User.php

Supported packages: api (Pint), ui (ESLint). With no extra args, bin/lint api runs pint --test . and bin/lint ui runs eslint ..

Other checks (run inside the package directory):

Terminal window
cd ui && npm run format:check && npm run typecheck
cd api && ./vendor/bin/pint # fix style (omit --test)
  1. Read the pre-commit: message — it names the failing tool.
  2. Fix formatting or lint issues, or run the package commands above.
  3. Ensure dependencies are installed for the package you changed (see Troubleshooting).

To skip hooks in exceptional cases (not for routine use):

Terminal window
git commit --no-verify

Implementation details live in bin/pre-commit and bin/lib/common.sh in the repository root. Policy summary: CONTRIBUTING.

Run the API in Docker (PostgreSQL + Redis) with native frontends (ui, docs). HTTPS is provided by Traefik and certificates from mkcert so local dev matches production TLS, Sanctum cookies, OAuth, and WebSockets.

ToolPurpose
Docker + Compose v2.22+API, Postgres, Redis, Traefik; Compose Watch for API rebuilds
Node.js 22+ (nvm)ui, docs, optional www
mkcertTrusted local TLS certificates
/etc/hostsMap *.garrison.test to 127.0.0.1 (scripts can prompt to append)

bin/start and bin/setup check these tools and can offer interactive installs (Homebrew on macOS where available). Use bin/check or bin/start --no-prompt in CI.

ScriptPurpose
bin/setupOnce per clone: mkcert certs, Docker image, Composer, migrations
bin/startOne terminal: Docker + ui + docs (Ctrl+C stops everything)
bin/stopStop containers (--purge removes Postgres volume)
bin/checkVerify prerequisites only (exit 1 if missing)
Terminal window
bin/setup
bin/start

HTTPS URLs (default):

ServiceURL
APIhttps://api.garrison.test
Web apphttps://app.garrison.test
WebSocket (Reverb)wss://ws.garrison.test
Docs sitehttps://docs.garrison.test
Marketing (--www)https://www.garrison.test (apex https://garrison.test redirects here)

Options: bin/start --www (marketing site); bin/start --http (plain localhost ports, no Traefik — limited OAuth/cookie testing); bin/setup --http (skip mkcert).

Resilience: bin/start brings Compose up detached (up -d) with restart: unless-stopped, then runs docker compose watch api so changes to api/.env.docker restart the API and changes under docker/api/ rebuild the image — without stopping ui/docs. After api/composer.lock changes (e.g. git pull), run docker compose -f compose.dev.yml run --rm --no-deps api composer install (or restart the API once vendor is updated). Vite/Astro still need a manual restart after yarn install when lockfiles change.

Native API (no Docker): use SQLite and composer run dev in api/ as documented under PHP and Composer below.

JavaScript packages (ui/, www/, docs/, and Laravel Vite assets in api/) use Yarn (via Corepack). CI and www/package.json expect Node 22 (LTS).

Follow the official nvm install guide. On macOS with Homebrew:

Terminal window
brew install nvm

Add nvm to your shell profile as described in the install output, then open a new terminal.

The repo root includes .nvmrc (Node 22). From the repository root:

Terminal window
nvm install # reads .nvmrc
nvm use
node -v # should report v22.x
npm -v

Without nvm, install Node 22 from nodejs.org or your system package manager and ensure node and npm are on your PATH.

Run yarn install inside each package you work on:

Terminal window
cd ui && yarn install && cd ..
cd www && yarn install && cd ..
cd docs && yarn install && cd ..
cd api && yarn install && cd ..

Use yarn install --immutable in CI and Docker when you want a clean reproducible tree from the committed lockfile.

The API requires PHP ^8.4 (see api/composer.json).

Terminal window
brew install php@8.4 composer

Ensure php on your PATH is 8.4+ (php -v). You may need to link the formula or adjust your shell PATH per Homebrew’s post-install notes.

Use your distribution’s packages, phpbrew, or asdf with the PHP plugin. Install Composer globally or use the composer phar.

Terminal window
cd api
composer install
cp .env.example .env # skip if .env already exists
php artisan key:generate
php artisan migrate
yarn install # Vite / Tailwind for Laravel assets

Quick bootstrap (copies .env, generates key, migrates, installs Yarn deps, builds assets):

Terminal window
cd api
composer run setup

Run the API locally:

Terminal window
php artisan serve

For the full dev stack (server, queue, logs, Vite) after dependencies are installed:

Terminal window
composer run dev

Run tests:

Terminal window
php artisan test
# or
composer test

Not required for the default SQLite scaffold. When you work against production-like services:

ServiceTypical local install
PostgreSQLbrew install postgresql@16 (macOS) or distro packages
Redisbrew install redis (macOS) or distro packages

Update api/.env (DB_CONNECTION, QUEUE_CONNECTION, CACHE_STORE, REDIS_*) per Laravel’s configuration. See Deployment for v1 infrastructure choices.

Kotlin Multiplatform uses the Gradle wrapper (./gradlew); you do not install Gradle globally.

RequirementVersion / notes
JDK17 (see shared/build.gradle.kts jvmToolchain(17))
Android SDKVia Android Studio; compileSdk 34
XcodemacOS only, for iosApp/ builds and simulator
Kotlin / AGP / ComposePinned in mobile/gradle.properties; wrapper uses Gradle 8.2.1

macOS:

Terminal window
brew install openjdk@17

Set JAVA_HOME to JDK 17. Android Studio’s embedded JBR also works when launched from the IDE.

From mobile/:

Terminal window
./gradlew :androidApp:assembleDebug
./gradlew :desktopApp:run

Open the mobile/ directory in Android Studio for device selection, iOS targets, and run configurations. iOS builds require Xcode and CocoaPods/tooling as prompted by the IDE.

CheckCommand
Nodenode -v → v22.x
PHPphp -v → 8.4+
Composercomposer -V
APIcd api && php artisan test
UIcd ui && npm run typecheck
Docs sitecd docs && npm run build
Hooksbin/pre-commit (with staged files, or expect “No staged files”)
Dev stackbin/check

Each package’s AGENTS.md lists day-to-day commands. Common entry points:

PackageDev serverBuild
api/php artisan serve or composer run devyarn run build (in api/)
ui/npm run devnpm run build
www/yarn devyarn build
docs/npm run devnpm run build
mobile/Android Studio / ./gradlew :desktopApp:run./gradlew :androidApp:assembleDebug
  • Hooks not running — Run bin/install-git-hooks from the repo root; confirm git config core.hooksPath is .githooks.
  • Pre-commit: Pint missing — Run composer install in api/.
  • Pre-commit: ui dependencies missing — Run npm install in ui/.
  • Pre-commit: ESLint or Prettier failed — Run npm run lint / npm run format:check in ui/; fix with npm run lint:fix and npm run format as needed.
  • Pre-commit: TypeScript failed — Run npm run typecheck in ui/.
  • Wrong Node version — Run nvm use from the repo root (with .nvmrc present).
  • Permission errors on vendor/ or node_modules/ — Avoid sudo with Composer/npm; fix directory ownership instead.
  • Do not commit secrets — Use .env.example templates; real .env files are blocked by pre-commit.
  • bin/start: certificates missing — Run bin/setup (or mkcert -install and re-run setup).
  • bin/start: /etc/hosts — Add 127.0.0.1 garrison.test api.garrison.test app.garrison.test docs.garrison.test www.garrison.test ws.garrison.test or accept the script’s sudo prompt.
  • Vite HMR over HTTPS — If hot reload fails, try bin/start --http for UI-only work or see Traefik websocket notes in the repo.