This is the practical follow-up to our announcement about selling Docker app hosting through PNLCS. If you're setting up a self-hosted app hosting or one-click Docker container hosting product for customers — on Panelica, through PNLCS, or just running the app catalogue yourself — here's what to know before you put an app in front of a paying customer.
Every app in the catalogue shows a minimum memory figure on its card. That number is the floor for the app's main container — it is not a guarantee that the whole app fits in that much RAM.
Around twenty apps in the catalogue start more than one container: a database, a cache, a background worker, a machine-learning helper, whatever the upstream project needs. All of those extra containers land in the same account, draw on the same cgroup allowance, and count against the same plan.
The honest example is Immich. Its own installation docs ask for a minimum of 6 GB and recommend 8 GB (see docs.immich.app/install/requirements) — and that number exists because Immich's compose stack is Postgres + Redis + a machine-learning container + the main server, all running together. We had Immich's memory floor set too low at one point: the card said 2 GB, which is what the main server container alone needs. The stack deployed, then died — the ML container got starved of memory, uploads failed, and the customer was left holding an app that "needs 2 GB" according to the panel that sold it to them. The floor is now 6 GB, and it's the whole-stack number, not the front container's number.
The lesson for anyone building a catalogue or a plan matrix on top of this: check what upstream actually asks for, not just what the main image needs to boot, before you set — or trust — a memory floor.
Every container an account deploys runs unprivileged, inside that account's own cgroup slice — no shared root namespace with other tenants, no privileged mode. This isn't a setting you have to remember to turn on; it's enforced at the API, and it's enforced even for a billing platform's operator key.
Concretely: a request to deploy a privileged container, add Linux capabilities, or bind-mount a host path outside the account's own home directory is rejected before it reaches the Docker daemon — whether it comes from the panel UI, a customer through PNLCS, or an operator key with the highest role the system has. An integration bug or a compromised billing server asking for "-v /:/mnt" gets a 403, not a container that can see the host filesystem.
If you're building your own product on top of the app catalogue or the container API, don't rely on your own integration to enforce this — it's already enforced on the server side regardless of what your code sends.
The plain OS images in the catalogue — Ubuntu, AlmaLinux, Debian, Alpine — ship with no SSH server. That's deliberate: they start with the process asleep and nothing listening, which is the smaller attack surface. The way in is the panel's own web terminal for that specific container (a WebSocket session opened per-container, scoped to that account), not a port you open to the outside world. If you're used to reaching for SSH to poke around inside a base-image container, use the container terminal in the panel instead — `docker exec` from inside that session is the documented way to get a shell and install packages.
Before you list an app as a product — whether that's "App Hosting" pointing a domain at it, or just adding it to a hosting plan's catalogue:
- Read the upstream requirements — don't trust a default memory number without checking what the project itself documents. Immich taught us this one the hard way.
- Check the container count — does it deploy alone, or does it bring a database/cache/worker with it? That changes both the memory floor and what "restart the app" actually means operationally.
- Decide if it needs a domain — some apps are meant to sit behind a vhost with SSL (most web apps); others are meant to be a bare container a customer reaches over a published port or manages entirely from inside. Match the product shape (hosting-with-apps, App Hosting, or a bare container plan) to what the app actually is.
If you sell hosting and want the storefront/billing side of this (plans, checkout, provisioning) rather than just the container engine, see our announcement on PNLCS's new Docker app hosting product path — source, live demo, docs.
Questions or found an app whose memory floor looks wrong? Reply here.