Reference

Troubleshooting

What to check when the panel doesn't open, a domain doesn't go live, a build fails or an app can't find its data.

The panel doesn't open after installing

  • Ports 80 and 443 must be open in your provider's firewall, not only on the server. Many providers block them by default.

  • Check the services:

    systemctl status layer-panel layer-agent caddy
    journalctl -u caddy -n 50
    
  • On your own domain, its DNS must point at the server before the certificate can be issued. Until then, the installer's sslip.io address works.

A domain waits for DNS

The panel checks public DNS, not the server's own resolver.

  • The A record must point at this server's public IP.
  • If Cloudflare's proxy is on (the orange cloud), set the record to DNS only, or press Keep the proxy and follow the steps on Domains.
  • An AAAA (IPv6) record pointing somewhere else also stops it. Remove it, or point it at this server.
  • DNS changes can take a few minutes to spread. The page checks again on its own.

The certificate isn't issued

Let's Encrypt reaches your server over plain HTTP, on port 80, for the first certificate.

  • Port 80 must be open in your provider's firewall.
  • Behind Cloudflare, turn Always Use HTTPS off, and set SSL/TLS to Full (strict).
journalctl -u caddy | grep <domain>

A build runs out of memory

  • On servers with less than 4 GB of RAM, the installer adds swap, so builds slow down instead of failing.
  • A build can use twice its app's memory limit. Raise the limit in the project's Settings → Resources.
  • Keep Settings → Builds at 1 on small servers, so builds don't compete.

A build stops for lack of disk

Builds empty large package caches when the disk is under 25% free, and stop under 15%. Free some space, then redeploy:

df -h /
du -sh /srv/apps/* | sort -h

The app shows no data, or can't save files

Each deploy builds into a fresh folder, and that folder can't be written while the app runs. The one folder that survives deploys is DATA_DIR, /srv/apps/<app>/data.

  • If the app opens ./data relative to its working folder, it reads an empty copy inside the build folder. Make it read process.env.DATA_DIR first:

    const dataDir = process.env.DATA_DIR || path.join(process.cwd(), "data");
    
  • If it reads its own variable, like SQLITE_PATH, point it inside /srv/apps/<app>/data on the Environment page.

  • Other folders the app must write go in Settings → Run → Writable folders.

The app keeps restarting

layer logs <app> -n 100
  • It must listen on PORT, on 127.0.0.1. The server sets PORT and HOST for it.
  • The health check path must answer before traffic switches to a new build. Set it in Settings → Run.
  • The memory limit: an app that goes over restarts. Raise it in Settings → Resources.

A crash-looping app raises an alert after 3 restarts in a minute.

You're locked out of the panel

  • Limited the panel to an address you no longer have: on the server, run layer access reset.
  • Lost your phone: sign in with one of your recovery codes, then set up two-factor sign-in again.
  • Too many failed sign-ins: that address and account are locked for 15 minutes.

MongoDB doesn't start

The install says why, from MongoDB's own log, and stops it so it doesn't retry forever. After fixing the cause, press Start on the server's Databases page.

systemctl status mongod
journalctl -u mongod -n 50

A generated file was edited by hand

Units, Caddy sites and env files are written by the agent. If one was changed or deleted, put it back:

layer repair

Still stuck

The agent's log and the activity log say what happened, in order:

journalctl -u layer-agent -n 100
tail -n 50 /var/log/layer/audit.jsonl