Everything you can do with your hosting account, in the order you are likely to
need it. Written for customers; if you run the server itself, read the
Administrator Guide instead.
The panel lives at https://panel.vlamnet.nl.
Your administrator creates your account and gives you an email address and a
password. Go to the panel, enter both, and you are in. If two-factor
authentication is switched on for your account, you are asked for a six-digit
code as well — see Account and security.
Sessions are stored in a secure cookie. Changing your password signs you out of
every browser, including this one, on purpose.
If you get the sign-in page wrong ten times within five minutes, the panel stops
accepting attempts from your address for a while. Wait, then try again.
Everything you run here is a service. A website is a service. A PostgreSQL
database is a service. A WordPress install is two services — the application
and its database — shown together as one deployment.
Each service gets:
Services in your account can talk to each other over a private network. No other
customer's services can reach yours, and yours cannot reach theirs.
The first screen after sign-in lists everything you run.
| Element | What it does |
|---|---|
| Search | Filters by name or domain |
| Filter by type | Websites, databases, applications, your own containers |
| Status dot | Running, stopped, deploying, or failed |
| Card | Click it to open the service's detail page |
A card marked "Reachable only by your other services" has no public address —
that is normal for a database. A multi-container deployment (WordPress, Ghost,
n8n…) appears as one card, and its components are listed as a strip on the
detail page so you can jump between them.
If you have reached your service limit, a banner says so. Ask your
administrator to raise it, or delete something you no longer need.
Every service, whatever kind, has the same page:
| Tab | Shown for | Purpose |
|---|---|---|
| Overview | everything | Status, address, memory, CPU, disk, uptime, connection details |
| Deploys | services you deploy code to | Upload, deploy, history, rollback |
| Domains | web-facing services | Shared subdomain and custom domains |
| Environment | everything | Configuration variables |
| Storage | everything | Paths that survive a redeploy |
| Logs | everything | Live container output |
| Settings | everything | Name, runtime, resources, auto-deploy, delete |
Tabs you do not see do not apply. A database has no Deploys tab because there
is nothing to deploy — it runs a published image as it ships.
At the top of the page: Start, Stop and Restart.
Add a service → Your own code → Website, or go straight to /sites/new.
The name is for you. From it the panel derives a slug — lowercase letters,
digits and dashes — which becomes your free web address:
<slug>.sites.vlamnet.nl
You may also type a custom domain here to attach it straight away. You can
always add one later.
Upload an archive. A .zip, .tar, .tar.gz or .tgz of your site. The
panel checks the file's real type from its contents rather than trusting the
extension, and refuses archives that are suspiciously large, contain too many
files, or try to write outside their own directory.
Connect a Git repository. An https:// URL — SSH is not accepted. For a
private repository, paste an access token; it is encrypted before it is stored
and never shown back to you. Optionally set a branch (default main).
Tick Deploy automatically on new commits to have the panel watch the branch.
You can also use a webhook instead, which is instant — see
Automatic deploys.
| Runtime | Use it when | What serves your files |
|---|---|---|
| Automatic | You are not sure | Builds your Dockerfile if the repository has one, otherwise serves the files as static HTML |
| Static HTML | Plain HTML/CSS/JS, or the output of a site generator | nginx, from your publish directory |
| PHP | WordPress-style PHP, Laravel, a classic site | php:8.4-apache, from /var/www/html |
| Node.js | An Express/Nest/Next server | node:24-alpine, running your start command from /app |
| Dockerfile | You want full control | Your own image |
Related fields:
Dockerfile are looked up. means the root; a Vite build usually wants dist, Next's staticout, Hugo public.npm ci && npm run build. Runs in a throwawaynpm start. Your app should listen on thePORT variable.index.html for anyRuntime choices take effect on your next deploy, not immediately.
If your application writes files it must keep — uploads, a SQLite database —
name those paths now. Deciding afterwards means your first deploy has already
written somewhere that is about to be thrown away. See
Persistent storage.
The site is created and, for a Git site, a first deploy starts immediately. For
an upload site, go to Deploys and upload your archive.
A deploy returns immediately and keeps running if you close the tab. A failed
deploy leaves the previous version serving — your site does not go down
because a build broke.
The release directory is mounted read-only. Anything your application writes
outside a path you declared under Storage is gone at the next deploy.
On the Deploys tab:
Every deploy writes a transcript you can watch live, line by line. Click View
log on any entry in History to reopen it, including for a deploy that
already failed. Secret environment values are redacted from the transcript.
Statuses: queued → running → success or failed. A failed deploy shows the
reason on the entry itself.
Previous versions lists the releases still on disk (five by default). Click
Restore on one and the container is recreated against it. Nothing is rebuilt
and nothing is downloaded, so this is fast — it is the right first move when a
deploy has broken production.
Your persistent storage is not rolled back. Only the code is.
Two ways, on the Settings tab of a Git-backed site:
Webhook (preferred). Copy the webhook URL from the Deploys or Settings tab
into GitHub (Settings → Webhooks) or GitLab (Settings → Webhooks). Every push
to your branch triggers a deploy at once. The URL contains a secret — treat it
like a password.
Polling. Tick Deploy automatically when the branch changes. The panel asks
your repository for its current commit on a schedule (five minutes by default)
and deploys when it has moved. Use this when your Git host cannot reach the
panel. Check now polls immediately instead of waiting. If the last check
failed — a bad token, a deleted branch — the reason is shown here.
Every web-facing service gets <slug>.sites.vlamnet.nl the moment it is
created, with a valid certificate. Nothing to configure.
The panel resolves the name first and refuses it if it does not point here. That
is deliberate: it stops anyone routing a domain they do not control, and it
avoids burning the certificate authority's retry budget on a hostname that
cannot pass validation yet. If you have just changed DNS and the check fails,
wait and use Retry.
Once accepted, a Let's Encrypt certificate is requested automatically and HTTPS
starts working within a minute or two. The domain row shows the certificate
status, and Retry SSL re-attempts a failed issuance.
Notes:
www.example.com and example.com are two hostnames. Add both if you wantEnvironment on any service. Variables are available to your build and to the
running container.
DATABASE_URL — letters,PATH, HOME, LD_PRELOAD and similar) becauseChanges apply when the container is next created. Save a variable and then
deploy — or, if there is nothing to deploy, restart the service.
The panel shows a second list, As seen by the running container, read from
Docker itself rather than from the page. When it disagrees with what you saved,
that is your answer to "why isn't my new variable there?" — it is saved but not
live yet.
For catalogue services, connection details (host, port, user, generated
password) appear here and on the Overview tab. That is how an application finds
the database it was deployed with.
A container's filesystem is disposable. The only things that survive a redeploy
are the paths you declare on the Storage tab.
/app/uploads, /var/www/html/wp-content/uploads.Mounts attach when a container is created. A saved mount is not live until
the container is replaced. The panel compares what you saved with what Docker
actually has mounted and offers Apply now, which recreates the container on
the release it is already serving — no rebuild, no code change.
If your image declares a volume for a path you have not mounted, Docker creates
an anonymous one and discards it on the next deploy. The panel detects that and
warns you. It is the most common cause of "my data keeps disappearing".
Logs streams your container's output live. Use it to see why an application
will not start, what a request did, or what a database is complaining about.
The view keeps a scrollback buffer, follows new output as it arrives, and lets
you pause. For a multi-container deployment, switch component at the top of the
page to read the other one's logs.
Deploy transcripts are separate and live on the Deploys tab.
Your account has a pool: a number of services, an amount of memory, an amount of
CPU, and an amount of disk. You divide the pool between your services yourself.
Settings → Resources on any service sets its memory and CPU. The card shows
what is left in your pool and warns before you commit more than you have.
1000 means one core. 500 is half a core.The catalogue page (Add a service) shows your allowance at the top, so you
can see what you have room for before choosing anything.
If you need more, ask your administrator.
Add a service lists applications and databases that deploy without you
writing anything. What you see depends on what your administrator has granted
your account — an empty or short list is a permissions question, not a fault.
Shipped entries include:
| Category | Entries |
|---|---|
| Databases | PostgreSQL, MariaDB, MySQL (via Ghost), MongoDB, Redis |
| CMS | WordPress, Drupal, Ghost, Directus, Strapi |
| Apps | n8n, Uptime Kuma |
The image is pinned at creation. If the catalogue is later updated to a newer
release, your existing instance keeps running what it was created with — nobody
gets a surprise major-version upgrade of their database.
WordPress creates two services: a MariaDB and the application. Each gets its own
row, its own logs, its own storage and its own slice of your allowance. The
database is started first and the application waits for it to report healthy.
A database has no public address, no certificate and no proxy entry. It is
reachable only from your own services, by the hostname shown on its Overview
tab — which is its slug. Connection details are on that page and in the
Environment tab.
Connecting your own application to it means putting that hostname, the port and
the generated password into the application's environment variables.
There is no backup of your database unless you arrange one. Ask your
administrator what is in place.
Switching an existing database to a newer major version is blocked. Postgres 17
refuses to start on a Postgres 16 data directory, and a crash-looping container
is worse than a clear refusal. The path is: deploy the new version alongside,
dump from the old, restore into the new, then delete the old.
If your administrator has enabled it, Add a service → Your own code offers
two more routes.
Paste a Dockerfile; the panel builds it and runs the image. There is no
repository behind it, so everything the build needs must be in the file itself.
You can edit and rebuild later from Settings → Dockerfile.
This also requires builds to be enabled on the server. The page says so if they
are not.
Paste a Docker Compose file and each service in it becomes one service here,
deployed together on your own private network. Up to ten services, up to 64 KB.
The panel validates the file against an allowlist and tells you exactly which
key it would not accept and why. Accepted per service:
image environment volumes depends_on command
entrypoint healthcheck restart working_dir user
Refused by name, with a reason:
privileged, cap_add, cap_drop, network_mode, networks, pid, ipc,
uts, userns_mode, devices, security_opt, sysctls, extra_hosts,
build, ports, any volume with a host path, and any resource declaration
(deploy.resources, mem_limit, cpus).
Those are not arbitrary. Each would either reach the host or make the isolation
between accounts a suggestion. Resources are refused because what a service may
use is an allocation out of your pool made in the panel, not a claim the file
makes about itself.
After validation you get a preview of what will be created, and you choose which
service (if any) gets a web address and on which port.
Your account (top-right menu).
Change it with your current password and a new one of at least twelve
characters. You are signed out everywhere afterwards, including the browser you
did it in. That is the point: if someone else had a session, it stops working.
Strongly recommended.
After that, sign-in asks for a code. A recovery code works in place of one.
Almost always a clock problem. Check that your phone's time is set
automatically, then try the next code.
Settings → Delete, and type the service's name to confirm.
This removes the container, the routing, the certificate entry, the database
record, and the files — including your persistent storage. It cannot be
undone. Take a copy of anything you want to keep first.
Deleting one component of a multi-service deployment deletes that component. The
warning on the page tells you when you are about to remove the whole thing.
Freed memory, CPU and service slots return to your pool immediately.
My site shows the nginx welcome page.
The publish directory is wrong, or your build did not produce the files where
the panel looked. Check Publish directory under Settings and the deploy
transcript for what was actually published.
My deploy failed.
Open the transcript on the Deploys tab — the reason is in it. Common ones: a
build command that exits non-zero, a missing dependency, a Dockerfile that
does not build, a Git token that has expired. The previous version is still
serving while you fix it.
The site is up but returns 502.
Your application is not listening where the panel expects. Node apps must listen
on the port in PORT, on 0.0.0.0 rather than 127.0.0.1. Check Logs for a
crash on startup.
My environment variable is not there.
Saved variables apply when the container is next created. Deploy or restart, and
compare the two lists on the Environment tab.
My uploads disappear on every deploy.
The directory is not a declared mount. Add it under Storage, then use Apply
now so the mount attaches.
My custom domain is refused.
DNS does not point here yet, or points somewhere else. Check with
dig +short example.com and compare with the address shown on the Domains tab.
Wait for the old TTL to expire, then Retry.
HTTPS is not working on a domain that was accepted.
Certificate issuance is asynchronous. Give it a minute, then Retry SSL. If it
keeps failing, DNS may have changed since the domain was added.
I cannot sign in.
Ten failures in five minutes locks the endpoint briefly. If it is a 2FA code,
check your device clock. If your account has been suspended, the panel says so —
contact your administrator.
I am out of memory / services.
Free some by deleting or by lowering another service's allocation, or ask for a
larger pool.
| Term | Meaning |
|---|---|
| Service | One container you run: a website, a database, an application |
| Slug | The short name in URLs and hostnames, derived from the name |
| Release | One immutable published version of your files |
| Deploy | Producing a release and recreating the container against it |
| Rollback | Recreating the container against an earlier release |
| Runtime | What serves your site: static, PHP, Node or your own Dockerfile |
| Publish directory | The folder inside your project that gets served |
| Root directory | The subfolder of a monorepo your project lives in |
| Mount / volume | A path inside the container whose contents survive a deploy |
| Allocation | Memory and CPU committed to one service out of your pool |
| Catalogue | Ready-made services you can deploy without writing anything |
| Shared domain | The free <slug>.sites.vlamnet.nl address |