# Local development

Reach every local service at its own *.localhost hostname, without publishing a port for each one.

Run one Ceryx on your machine for all your projects. Instead of remembering which service runs on `localhost:3000` and which on `localhost:4000`, open `http://web.app.localhost` and `http://api.app.localhost`.

> [!NOTE] Secure context over HTTP
> Browsers treat `*.localhost` as a potentially trustworthy origin, so many [features that require a secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts) work during local development. HTTP is still unencrypted.

## 1. Run Ceryx on your machine

Save this as `compose.yml` in a directory of its own, such as `~/ceryx`:

```yaml
name: ceryx

services:
  ceryx:
    image: ghcr.io/withlogicco/ceryx:v1.0.0
    restart: unless-stopped
    ports:
      - 80:80
      # The API, for your machine only
      - 127.0.0.1:8080:8080
    environment:
      # Let's Encrypt can't issue certificates for .localhost names
      CERYX_DISABLE_LETS_ENCRYPT: "true"
    volumes:
      - ceryx:/var/lib/ceryx

networks:
  default:
    name: ceryx

volumes:
  ceryx:
```

Then start it:

```bash
cd ~/ceryx
docker compose up -d
```

## 2. Join your projects to the network

In each project's Compose file, add the services you want to reach to the `ceryx` network. They don't need published ports:

```yaml
services:
  web:
    build: .
    networks:
      - ceryx
  api:
    build: ./api
    networks:
      - ceryx

networks:
  ceryx:
    external: true
```

## 3. Add routes

The API is available on your machine at `localhost:8080`:

```bash
curl -X POST localhost:8080/api/routes \
  -H 'Content-Type: application/json' \
  -d '{"source": "web.app.localhost", "target": "http://web:3000"}'

curl -X POST localhost:8080/api/routes \
  -H 'Content-Type: application/json' \
  -d '{"source": "api.app.localhost", "target": "http://api:4000"}'
```

Routes are stored in the `ceryx` volume, so you only add them once.

## 4. Open your services

Open [http://web.app.localhost](http://web.app.localhost). Hostnames ending in `.localhost` point to your own machine in browsers and `curl`, so you don't need to edit DNS or `/etc/hosts`. If another tool can't resolve `.localhost` names, add them to `/etc/hosts`.
