Lab settings
This page explains each setting on a lab's Preferences tab and when it takes effect. Open a lab and go to Preferences. Your changes are saved when you select Save Preferences and applied on the next deploy — or immediately if you use Apply & Redeploy now.
You need to be the owner, or have the Manager role on a shared lab, to see this tab. Challenge labs do not have it.
Everything on this page
The sections you see depend on the lab — a lab without a browser editor has no editor password, a lab that cannot be public has no error page.
| Section | Setting | Takes effect |
|---|---|---|
| Lab icon | Customize icon — pick a glyph, upload an image, or reset to the lab's default. Shown on your Launchpad and in your instances list. | Immediately |
| Access | The sudo password and the lab's launch password | Next deploy |
| Networking | WG Networks, Reallocate IP, Domain for VS Code Web | Next deploy |
| Public Exposure | Expose to Web (port 80), Choose Domains, HTTP Proxies, domains for the lab's own app ports | Next deploy — see Publishing ports |
| SSH Keys | Deploy with keys | Next deploy |
| Lifecycle | Always-on | As soon as you save |
| Expose TCP Ports | Up to 3 raw TCP ports | Next deploy — see Publishing ports |
| Startup Script | The script, and Run now | Next deploy, or immediately with Run now |
| Custom Error Page | Its own Save Error Page button | Immediately |
| Rate limit | Its own Save button | Next deploy |
| Agent Prompt | Its own Save Agent Prompt button | Immediately |
Save Preferences stores the form and the startup script. Apply & Redeploy now stores both and redeploys straight away. Run now saves the script before running it. The error page, rate limit and agent prompt each save with their own button.
Startup script
This is the most useful setting on this page. The script runs as root on every deploy, so it is how you make your setup survive a rebuild.
#!/bin/bash
apt-get update
apt-get install -y nginx postgresql-client jq
# your home directory persists, so restore from it
if [ -f /home/$USER/site.conf ]; then
cp /home/$USER/site.conf /etc/nginx/sites-available/default
fi
systemctl enable --now nginx
Run now executes it immediately and streams the output, so you can test without redeploying. The lab must be running.
The script is a file in your home directory — its path is shown next to the heading. Each extra copy has its own script, so copies that share one home can still start different things.
It runs as root at the end of every deploy. Test it with Run now before you rely on it, and make it idempotent — safe to run again and again.
Passwords
| Password | Used for | If you leave it blank |
|---|---|---|
| sudo | sudo inside the lab | A default built from your username, shown as the field's placeholder. It is the same on every deploy and appears in your connection info. |
| The launch password — labeled by the lab, for example Code-server password | The browser VS Code, or the lab's own app or desktop | A new random password on every deploy |
If you set one, it is applied on the next deploy and stays the same. The eye button shows the value; the circular-arrow button fills in a strong random one.
The blank default is predictable. If anyone else can reach your lab, set a private one.
Passwords can be up to 128 characters. They cannot contain = or control
characters.
SSH keys
By default every enabled key on your account is installed into a deployed lab. Manage the keys themselves in Account Settings → SSH.
To limit the keys for one lab, pick specific keys in that lab's settings.
Adding a key to your account changes nothing in labs that are already running. Redeploy the lab to install it.
Always-on
Keeps the lab exempt from idle expiry. If it stops unexpectedly, the platform brings it back within about ten minutes, as you, with your saved settings.
Requires: the lab's template to allow it, and a paid plan or 5,000 Zeal. If you are not eligible, the switch is shown but locked.
How it behaves:
| Situation | What happens |
|---|---|
| You switch it on and save | It applies straight away — no redeploy needed |
| The lab stops — it crashed, was removed, or you selected Stop | It is deployed again within about ten minutes, as you, with your saved settings. The Activity tab shows Auto-started · always-on. |
| The lab would expire or be stopped for idleness | It is left running |
| You drop below 5,000 Zeal or your plan is downgraded | It is no longer restarted — the lab stays down after its next stop |
| An administrator holds the lab down | The switch shows An admin has paused auto-start for this instance and the lab stays down until they release it |
The restart is an ordinary deploy, so your running-labs limit still applies. If you are at your limit when it tries, the lab stays down.
Turn Always-on off and save before you select Stop. Otherwise it comes back.
Always-on does not resume a lab you paused — restarting it would destroy the state you paused to keep.
Custom error page
The page visitors see on your domains while the lab is down. Maximum 64 KB; leave it empty for the platform default.
This one applies immediately — no redeploy is needed. It is available once the lab is publicly reachable.
The error page appears when a visitor reaches your domain but the lab does not answer — for example, while it is starting up, or when the app inside it has stopped. If you leave it empty, visitors see the page the lab's template supplies, or the platform's default page if the template has none. Write it as plain HTML.
Rate limit
Shown only when the lab's template lets you change it. It caps how many web requests each visitor's IP address can make to this lab's domains:
| Field | Meaning |
|---|---|
| Requests | How many requests one address may make per window, up to the maximum shown |
| Window | 1s, 3s, 10s or 1m |
Leave Requests blank or 0 to go back to the platform default. Applied on the next redeploy.
Agent prompt
Instructions an AI assistant receives when it works with this lab through MCP — project conventions, where things live, what not to touch. Maximum 64 KB.
Shown only when your platform has AI assistant connections turned on. Leave it empty to use the prompt the lab's template supplies. Each copy has its own.
Reserved address
Request a specific private address so the lab keeps the same one across redeploys. Useful when you have scripts or firewall rules pointing at it.
The setting is Reallocate IP under Networking. It lists the lab's current address and the addresses reserved on your account that no device is using.
Applying changes
| Change | Takes effect |
|---|---|
| Custom error page, agent prompt, lab icon, always-on | Immediately |
| Startup script | Next deploy, or Run now |
| Passwords, SSH keys, address, rate limit | Next deploy |
| Routing and domains | Use Apply & Redeploy — see Publishing ports |
Do it with an AI assistant
You can also do this by asking an AI assistant connected to your account — see Connect an AI assistant to set one up.
| Ask | What the assistant does |
|---|---|
| “Add a line to my lab's startup script that installs jq, then run it” | Reads the current script with lab_startup_script, writes it back with the new line, and redeploys with deploy_lab |
| “Set the sudo password on my essentials lab” | set_lab_password, then deploy_lab |
| “Only let my work-laptop key into this lab” | Finds the key with list_ssh_keys, saves the selection with configure_lab_runtime, then deploy_lab |
| “Keep my lab always on” | configure_lab_runtime, then deploy_lab |
Every change here is stored straight away but reaches the lab only when it is deployed again, so ask the assistant to redeploy afterwards. The startup script is replaced as a whole, not appended to — the assistant should read it before changing it.