Skip to content

HTTP Routing with Backend ​

Goal ​

After this guide, you can verify these 3 points:

  1. exec://... handler does both "start process + forward traffic", suitable for single-container backend bootstrap.
  2. http://... handler only forwards traffic and does not start processes, suitable for existing independent services.
  3. You understand default protection, minimal application.public_path exposure, and why backend data should go to /lzcapp/var.

Prerequisites ​

  1. You completed Hello World in 5 Minutes.
  2. lzc-cli box default points to your target microservice.
  3. curl is available on your machine (optional verification).

Steps ​

1. Create a backend template project ​

bash
lzc-cli project create hello-api -t todolist-golang

At app id prompt, press Enter for default id or provide your own. Then enter project dir:

bash
cd hello-api

2. Deploy first and verify default exec handler ​

bash
lzc-cli project deploy
lzc-cli project info

By default, project commands prefer lzc-build.dev.yml and print the active Build config. Use --release if you want to operate on lzc-build.yml.

Before continuing, ensure lzc-cli project info includes Project app is running.
If still starting, wait a few seconds and rerun lzc-cli project info.

Open Target URL in browser and complete login. In browser Console, run:

javascript
fetch('/api/health').then((r) => r.json()).then(console.log);
fetch('/api/todos').then((r) => r.json()).then(console.log);

Expected:

  1. /api/health returns {"status":"ok"}.
  2. /api/todos returns an items list (usually empty initially).

Notes:

  1. Default route is /=exec://3000,/app/run.sh.
  2. This runs /app/run.sh and forwards traffic to 127.0.0.1:3000.
  3. That is the core behavior of exec handler: start + forward.

3. Add a third-party service to demonstrate http handler ​

Edit lzc-manifest.yml. Keep default exec route and add /inspect/ route with whoami service:

yml
application:
  image: embed:app-runtime
  routes:
    - /inspect/=http://whoami:80/
    - /=exec://3000,/app/run.sh

services:
  whoami:
    image: registry.lazycat.cloud/traefik/whoami

Notes:

  1. whoami is a real third-party service used as a clear http forwarding target.
  2. /inspect/ goes to http://whoami:80/ and does not trigger /app/run.sh.
  3. Keep "/=exec://..." unchanged so original Todo behavior remains.
  4. Put /inspect/ before "/=" to avoid broader rule matching first.

4. Deploy and verify http handler ​

bash
lzc-cli project deploy
lzc-cli project info

In logged-in browser Console:

javascript
fetch('/inspect/').then((r) => r.text()).then(console.log);

Expected: output includes whoami request info (Hostname, RemoteAddr, Headers, etc.).

5. (Optional) Configure application.public_path and test with curl ​

By default, HTTPS paths are protected by login state. Direct unauthenticated curl is expected to be blocked.

If you want to expose health check path, add in lzc-manifest.yml:

yml
application:
  public_path:
    - /api/health

Redeploy and verify:

bash
lzc-cli project deploy
lzc-cli project info
curl "<Target URL>/api/health"

Only expose minimal paths in public_path.

6. Check Todolist data directory (/lzcapp/var) ​

First add 1-2 todo items in app UI so data files are created.

Enter app container:

bash
lzc-cli project exec -s app /bin/sh

Then run inside container:

bash
ls -la /lzcapp/var

For Todolist-like backend data, files should be in /lzcapp/var (for example /lzcapp/var/todos.json).

Important: only content under /lzcapp/var/ persists across app restarts.

Verification ​

Pass conditions:

  1. project info shows Current version deployed: yes.
  2. /api/health returns status: "ok".
  3. /inspect/ returns whoami request info.
  4. Using project exec, you can verify Todolist persistent path under /lzcapp/var.

Troubleshooting ​

1. /inspect/ returns 404 or 502 ​

Check in order:

  1. Route is exactly /inspect/=http://whoami:80/.
  2. This route is before "/=".
  3. services.whoami.image is registry.lazycat.cloud/traefik/whoami.
  4. Run lzc-cli project log -s whoami -f.

2. curl <Target URL>/api/health is blocked or redirected to login ​

Reason: default protection is enabled.

Fix:

  1. Verify via logged-in browser with fetch('/api/health').
  2. Or add application.public_path and redeploy.

3. Not sure where Todolist data should be stored ​

Use /lzcapp/var; only this path persists across restarts.

4. No visible change after deploy ​

bash
lzc-cli project deploy
lzc-cli project info

Ensure Current version deployed: yes.

Next ​

Continue with: How LPK Works