Development Setup
All builds, tests, and tooling run inside Docker containers. The host machine is used only for editing source code. This page walks through the full setup from clone to running app.
Prerequisites
- Docker and Docker Compose (v2+)
- Git
- A code editor (VS Code / Cursor recommended)
Clone the Repository
git clone <repo-url> unpispas.nx
cd unpispas.nx
Docker Environment Overview
The development stack is defined in docker/docker-compose.yml. Two networks isolate development from production-like services:
graph LR
subgraph dev-network
NXDEV["nx-dev<br/>(Node + Angular + PHP)"]
DBTEST["db-test<br/>(MariaDB for tests)"]
end
subgraph app-network
TRAEFIK["traefik<br/>(reverse proxy)"]
FRONT["frontend<br/>(Nginx)"]
BACK["backend<br/>(Nginx + PHP-FPM)"]
DB["db<br/>(MariaDB)"]
PMA["phpMyAdmin"]
DOCS["documentation<br/>(Nginx)"]
end
NXDEV --> DBTEST
TRAEFIK --> FRONT & BACK & PMA & DOCS
BACK --> DB
Key Containers
| Container | Image | Purpose | Ports |
|---|---|---|---|
upp-nxdev | Custom (Dockerfile.nxdev) | Development environment — Node.js, npm, Nx, PHP, Composer. Workspace mounted at /app. | 4200 (dev server), 9229 (debugger), 4211 (dep-graph) |
db-test | mariadb:10.6.11 | MariaDB for PHPUnit tests only | — |
upp-front | nginx:1.27.2 | Serves built Angular apps from dist/apps/ | 80 (via Traefik) |
php-back | Custom (Dockerfile.php81) | PHP-FPM for the REST API | — |
upp-back | nginx:1.27.2 | Nginx reverse proxy to php-fpm | 80 (via Traefik) |
mariadb | mariadb:10.6.11 | Production-like database | — |
phpmyadmin | phpmyadmin/phpmyadmin | Database admin UI | 80 (via Traefik) |
traefik | traefik:v2.10 | HTTPS termination with Let's Encrypt | 80, 443 |
upp-docs | nginx:1.27.2 | Serves codedoc, coverage, swagger | 80 (via Traefik) |
Starting the Development Environment
cd docker
docker compose up -d nx-dev db-test
This starts only the development containers. The workspace is bind-mounted from the host into /app inside upp-nxdev, so file changes on the host are immediately visible inside the container.
To start the full production-like stack (with Traefik, backend, frontend, database):
cd docker
docker compose up -d
Running Commands Inside the Container
All commands must run inside nx-dev. Never run nx, npm, npx, or composer directly on the host.
Attach an interactive shell
cd docker
docker compose exec nx-dev bash
# Now inside the container at /app:
cd /app
One-off commands from the host
cd docker
docker compose exec nx-dev bash -c "cd /app && <command>"
Common Development Tasks
Install dependencies
docker compose exec nx-dev bash -c "cd /app && npm install"
Serve an app (dev server)
docker compose exec nx-dev bash -c "cd /app && npx nx serve unpispas-pos"
The dev server listens on port 4200, which is mapped to the host. Open http://localhost:4200 in your browser.
Build an app
# Build a single app
docker compose exec nx-dev bash -c "cd /app && npx nx build unpispas-pos"
# Build all projects
docker compose exec nx-dev bash -c "cd /app && npx nx run-many --target=build --all"
Build output goes to dist/apps/unpispas-pos/.
Run tests
# Test a single library
docker compose exec nx-dev bash -c "cd /app && npx nx test upp-data"
# Test all projects
docker compose exec nx-dev bash -c "cd /app && npx nx run-many --target=test --all"
# Test with coverage
docker compose exec nx-dev bash -c "cd /app && npx nx run-many --target=test --coverage --all"
Run PHP tests
docker compose exec nx-dev bash -c "cd /app/server && composer test"
PHP tests use the db-test MariaDB instance (credentials: unpispas_test / unpispas_test).
Lint
docker compose exec nx-dev bash -c "cd /app && npx nx run-many --target=lint --all"
View the dependency graph
docker compose exec nx-dev bash -c "cd /app && npx nx graph --host=0.0.0.0 --port=4211"
Then open http://localhost:4211 in your browser.
Remote debugging (Jest)
Port 9229 is exposed for the Node.js inspector. To debug a test:
docker compose exec nx-dev bash -c "cd /app && node --inspect-brk=0.0.0.0:9229 ./node_modules/.bin/jest libs/upp-base --runInBand --no-cache"
Attach your IDE debugger to localhost:9229.
Publishing Coverage to Documentation
After running tests with coverage:
docker compose exec nx-dev bash -c "cd /app && npx nx run-many --target=test --coverage --all"
docker compose exec nx-dev bash -c "cd /app && npm run coverage:to-docs"
This populates docs/coverage/angular/ which is served by the upp-docs container.
Environment Variables
The docker-compose.yml uses several environment variables (typically from a .env file in docker/):
| Variable | Purpose |
|---|---|
MARIADB_ROOT_PASSWORD | Root password for MariaDB |
MARIADB_USER / MARIADB_PASSWORD / MARIADB_DATABASE | App database credentials |
APP_DOMAIN | Domain for the frontend (Traefik routing) |
API_DOMAIN | Domain for the backend API |
ADM_DOMAIN | Domain for phpMyAdmin |
DOC_DOMAIN | Domain for documentation |
EMAIL | Email for Let's Encrypt certificates |
PLATFORM | Platform specification (e.g., for phpMyAdmin) |
Important Rules
- Never run builds or tests on the host — always use
nx-dev. - Do not install packages on the host —
npm installruns inside the container. - File edits on the host are fine — the bind mount syncs them into
/app. - The host environment must remain untouched — no global installs, no config changes.