Local Setup Guide
This guide walks through setting up NENE2 locally from a fresh clone to a running API.
Prerequisites
- Docker Desktop (or Docker Engine + Compose plugin)
- Git
No host PHP, Node.js, or MySQL installation required. All runtime dependencies run inside Docker.
1. Clone and Configure
bash
git clone https://github.com/hideyukiMORI/NENE2.git
cd NENE2
cp .env.example .envOpen .env and adjust any values if needed. The defaults work for local development without changes.
Key environment variables:
| Variable | Default | Purpose |
|---|---|---|
APP_ENV | local | Runtime environment |
NENE2_MACHINE_API_KEY | (empty) | Leave empty to disable machine-client auth in local dev |
DB_ADAPTER | mysql | sqlite or mysql |
DB_HOST | mysql | Matches the Docker Compose service name |
2. Build and Install
bash
docker compose build
docker compose run --rm app composer install3. Run Backend Checks
bash
docker compose run --rm app composer checkThis runs PHPUnit, PHPStan, PHP-CS-Fixer, OpenAPI validation, and MCP catalog validation in sequence. All should pass on a clean clone.
4. Start the Web Server
bash
docker compose up -d appVerify it is running:
bash
curl -i http://localhost:8080/healthExpected response:
json
{"status":"ok","service":"NENE2"}Other useful local endpoints:
| URL | Description |
|---|---|
http://localhost:8080/ | Framework info |
http://localhost:8080/health | Health check |
http://localhost:8080/examples/ping | Ping example |
http://localhost:8080/examples/notes/{id} | Note by ID (requires DB) |
http://localhost:8080/openapi.php | Raw OpenAPI JSON |
http://localhost:8080/docs/ | Swagger UI |
5. Stop the Server
bash
docker compose downOptional: MySQL Database Setup
The default test suite uses SQLite in-memory. If you want to verify the MySQL adapter or run write-operation smoke tests against a real service database:
bash
docker compose up -d mysql
docker compose run --rm app composer migrations:migrate
docker compose run --rm app composer test:database:mysqlSee docs/development/docker.md for the SQLite vs MySQL comparison.
Optional: Machine-Client Authentication
The /machine/health endpoint requires an API key. To test it locally:
- Set
NENE2_MACHINE_API_KEY=local-dev-keyin.env. - Restart the app service:
docker compose up -d app - Call the protected endpoint:
bash
curl -i -H 'X-NENE2-API-Key: local-dev-key' http://localhost:8080/machine/healthSee docs/development/machine-client-smoke.md for the full machine-client smoke workflow.
Optional: Frontend Setup
bash
npm install --prefix frontend
npm run dev --prefix frontendThe frontend dev server proxies API calls to the app container. See docs/development/frontend-integration.md.
Optional: Local MCP Server
bash
docker compose run --rm -e NENE2_LOCAL_API_BASE_URL=http://app app php tools/local-mcp-server.phpSee docs/integrations/local-mcp-server.md for MCP client configuration.
Optional: Verify Request ID in Logs
Every request generates an X-Request-Id that is echoed in the response header and attached to every Monolog log record as extra.request_id. To verify this is working:
- Start the app:
docker compose up -d app - Send a request:bash
curl -i http://localhost:8080/health # Look for X-Request-Id in the response headers - Watch the structured log output:bash
docker compose logs app # Each JSON log line includes "extra":{"request_id":"<id>"}
You can also supply your own ID:
bash
curl -i -H 'X-Request-Id: my-trace-id' http://localhost:8080/health
# The same id appears in the response header and in docker compose logsTroubleshooting
composer check fails on a clean clone Run docker compose run --rm app composer install first. The vendor/ directory is not committed.
Port 8080 already in use Stop whatever is using it, or change the port mapping in compose.yaml:
yaml
ports:
- "8081:80" # use 8081 insteadMySQL connection refused during migrations The mysql container takes a few seconds to become ready after docker compose up -d mysql. Wait a moment and retry.
DB_HOST default is 127.0.0.1 but I get connection refused Inside Docker containers, use the service name mysql as the host. The default .env.example and compose.yaml already set this correctly — check that your .env has DB_HOST=mysql.