Troubleshooting

Diagnose failed deploys, unreachable preview URLs, memory/timeout issues, and private image pull failures.

When a preview environment misbehaves, the fastest path to a diagnosis is usually the Action logs and an SSH session into the instance. This page walks through the most common failure classes and how to resolve them.

Start fresh

When a deploy ends up in a bad state, the cleanest fix is to recreate the environment from scratch:

  1. Remove the pullpreview label from the pull request.
  2. Wait for the destroy workflow to finish tearing down the instance.
  3. Re-add the label to trigger a fresh deploy.

This guarantees you start from a clean instance with no leftover containers, volumes, or networking state. See Configuration if you need to change the label name or other inputs.

Build runs out of memory or times out

Two distinct limits can cut a deploy short:

  • Memory. If your build or running containers are heavy, the instance can run out of RAM. Increase the instance_type input to provision a larger machine. See the available sizes for each provider in Providers.
  • Time. If your stack is slow to boot, the GitHub Actions job can hit its time limit before the environment is ready. Increase timeout-minutes on the workflow job so the Action has enough time to finish provisioning and starting your services.

Adjust both in your workflow file as needed, then trigger a new deploy.

SSH in to inspect

The Action prints the exact SSH command in the job summary, and the SSH user is also exposed via the username action output. The user depends on your provider:

  • AWS Lightsail: ec2-user
  • Hetzner: root

Port 22 is always open, so you can connect directly to the instance IP and inspect Docker state:

Terminal window
ssh ec2-user@<ip> # use root@<ip> on Hetzner
docker ps -a
docker logs <container>

Use docker ps -a to confirm which containers started (and which exited), then docker logs <container> to read the output of any container that failed or restarted. The Action logs also include heartbeat, SSH, and Docker Compose output that can point you to the failing step.

Preview URL is not reachable

If the deploy succeeds but the preview URL does not load, work through these checks:

  • Service health checks. Verify the health checks on your Compose services. PullPreview waits for services to report healthy, and an incorrect health check can mask a service that never actually came up.
  • Ports. Confirm the port you expect to serve traffic on is published in your Compose file and matches default_port. The default_port value controls the port used to build the clickable preview URL posted to the PR.
  • TLS proxy mapping. If you use proxy_tls, verify the target mapping. The format is service:port, where port is the internal container port the proxy forwards to. When proxy_tls is set, the preview URL is forced to https on port 443 regardless of default_port. See HTTPS and custom domains for the full TLS setup.

Private images fail to pull

If containers fail to start because an image cannot be pulled from a private registry:

  • Set the registries input so the Action authenticates before pulling.
  • Ensure the credential or token you provide has pull rights for that specific registry.

See Private registries for the exact input format and per-registry examples.

Still stuck?

If the failure persists after a fresh deploy and the checks above, review the full Action logs end to end and the docker logs output from the relevant container. Understanding the deploy lifecycle often makes it clear which stage is failing.