My service deploys but never becomes healthy
The build succeeds and a new pod starts, but the deploy is marked failed or the new version never receives traffic.
What this means
The platform’s health check — a TCP probe on your app’s port — never passes, so traffic never shifts to the new pod. Lizard waits about 30 seconds, then marks the deploy failed. A service that already ran keeps serving its previous version, unless it has an attached volume: then its old pod stops first, and the service is down until a deploy passes. A first deploy shows as crashed.
Why this can happen
- Your app isn’t listening on the expected port. Lizard injects a
PORTenvironment variable (default container port3000) and checks that your app is reachable there. If your app is hardcoded to a different port, or never binds one, the health check never passes. A Python app is the usual case:gunicornanduvicornbind127.0.0.1unless you tell them otherwise, and the probe comes from outside the process. Python app hosting has the--bind 0.0.0.0:$PORTline each framework needs. - The service port doesn’t match the image. When
lizard upcreates a service from a Dockerfile with noEXPOSEline, it sets port3000, even if the base image listens elsewhere, such asnginxon 80. APORTvariable does not change that port. Runlizard port <n>and redeploy, or add anEXPOSEline. See which port Lizard routes to. - The service is accidentally in worker mode. Setting
containerPort=0puts a service into worker mode, which skips the health check and load-balancer registration entirely. A service that’s supposed to serve HTTP but got flipped tocontainerPort=0will deploy “successfully” and just never serve anything — worker mode hides the underlying startup problem instead of surfacing it.
Possible solutions
Check the current port
lizard port --service apiIf this prints worker mode, the service has containerPort=0. Set it back to a real port if this service is meant to serve HTTP:
lizard port 3000 --service api
lizard redeploy --service apiConfirm your app is listening where Lizard expects
Read the runtime logs for startup errors and the address the app reports it listens on. Compare it with the service port, which Lizard passes to the app as PORT:
lizard logs --service api
lizard port --service apiSee also
- Background Workers — when
containerPort=0is (and isn’t) the right call. - Deployments → lifecycle — where the health check sits in a deploy.
Updated