Core ConceptsArchitecture

Architecture

Lizard groups services into projects and projects into workspaces. Managed addons belong to a project.

workspace
└── project
    ├── service (app)          ← built from GitHub or an upload
    ├── service (worker)       ← background job, no HTTP port
    └── addons
        ├── postgres
        ├── redis
        └── s3

Workspace

A workspace is the account or organization level. You belong to at least one, and billing, members, and projects live under it. List the ones you can access:

lizard workspace list
lizard whoami        # shows your active workspace

Many commands accept -w, --workspace <ws> to disambiguate when the same project name exists in more than one workspace.

Project

A project groups related services and addons inside a workspace. Your working directory gets linked to a project, and that link (stored in ~/.lizard/config.json) is how the CLI knows what you’re targeting.

lizard init --name my-project   # create or select a project, link the cwd
lizard link --project my-project  # link to an existing project
lizard status                   # show the current directory's link
lizard unlink                   # remove the link
lizard project list             # all projects in the workspace

Tip: Use the repo or directory name for the project, and app-style names (api, worker, web) for services.

Service

A service is a single deployable unit. Its source is one of:

  • github: a connected GitHub repo. Pushes to the tracked branch auto-redeploy.
  • upload: a tarball uploaded with lizard up.

Each running service runs as its own isolated pod with a default-deny network policy, a generated <name>-<suffix>.onlizard.com domain (older services keep <words>.<region>.onlizard.com), and automatic TLS. This is container as a service: you supply the container and Lizard runs it. The blog explains which tasks remain yours. Inspect and manage services with:

lizard ps                       # list services with status + URL
lizard service show             # full config as JSON
lizard service set <svc> --set <field>=<value>
lizard service rename <new-name> --service <svc>
lizard service delete --service <svc>

Service configuration fields are flat and map 1:1 to the wire schema (e.g. repoUrl, branch, buildCommand, startCommand, containerPort, rootDirectory). There is no build.* / deploy.* nesting. See lizard service for the full list.

App vs. worker services

By default a service is an HTTP app that listens on a port (default 3000) and is served at its domain. A service that doesn’t listen on a port, such as a queue consumer, reconciler, or polling loop, should run in worker mode by setting containerPort=0. Workers skip port injection, the reachability health check, and load-balancer registration.

Managed addons

Addons are Managed Postgres, Managed Redis, and Managed Object Storage (S3-compatible) that you provision per project:

lizard add postgres redis s3

Each addon exposes a fixed set of environment variables that your services consume by reference (${{<addon-name>.KEY}}). See Managed Addons.

Cross-resource references

To read a service or addon value from another resource’s environment, use:

${{<name>.<KEY>}}

References resolve at deploy time against the target’s merged environment. They match the target’s current name: if you rename a service or addon, update every reference that uses the old name. A reference to a missing target or key resolves to an empty string (it does not fail the deploy); only circular references throw.

# Wire a service to the project's Postgres
lizard secrets set DATABASE_URL='${{postgres.DATABASE_URL}}' --service api

Check that the reference resolved. The build log prints a warning for every reference that resolved to an empty value, and secrets list shows what is stored:

lizard logs --build --service api
lizard secrets list --service api --show

Platform-injected variables

Lizard sets these variables on every service; you cannot override them:

VariableDescription
PORTPort your app should listen on (omitted in worker mode)
LIZARD_SERVICE_NAMEThe service’s name
LIZARD_PROJECT_IDThe project ID
LIZARD_PUBLIC_DOMAINThe service’s public domain (set once a domain is assigned)
LIZARD_PRIVATE_DOMAINThe service’s private hostname, <host>.lizard.internal, reachable from the same project

See Variables & Secrets for how these interact with your own variables and the full precedence order.

Updated