Cloud in a Bottle: Rootless Self-Hosting on Linux

Bottle cooler (seau à bouteille) MET 195059

What if you could run cloud services on any Linux machine without wrestling with Docker permissions or security configs? That's the promise behind Cloud in a Bottle, an open-source project announced last week that's trying to make self-hosting feel less like a sysadmin side hustle and more like using a smartphone.

The pitch is straightforward, even if the execution isn't: containerized apps, unified auth, good UX. No more juggling certificates, fighting with reverse proxies, or accidentally locking yourself out of your own server. It's the kind of thing that sounds almost too good to be true, especially when you've spent hours debugging why your home assistant won't talk to your media server.

I've been following self-hosting tools for years — from the early days of Docker Compose files that barely worked to the current ecosystem of overly complex stacks — so I'm genuinely curious whether Cloud in a Bottle can deliver on its ambition. The project's GitHub already has 500 stars and climbing, but the real test will be whether it can handle the messiness of real-world setups without requiring a computer science degree to configure.

The Problem Cloud in a Bottle Solves

Self-hosting has a dirty secret: the hard part isn't the software, it's the sysadmin work. Before you can run a single service, you need to provision a machine, create user accounts with proper permissions, configure SSH keys, set up a firewall, and then decide how you're going to handle the fact that any service you run with root privileges is one vulnerability away from owning your entire box. That's not even counting the ongoing maintenance—security patches, log rotation, backup schedules. The technical debt starts accumulating the moment you type your first apt install.

Most people, understandably, give up before they get to the good part. And the people who do push through often end up running everything as root in Docker containers, which is a security model that relies entirely on the kernel not having bugs. That's a bold bet to make with a machine that holds your personal data.

Cloud in a Bottle attacks this from a different angle. Instead of assuming you're a sysadmin, it does the sysadmin work for you—specifically, the parts that are most error-prone. The system is built around rootless containers, which is a meaningful distinction. Running containers without root means that even if a service gets compromised, the attacker is trapped in a user namespace with no privileges to escalate. It's not a silver bullet, but it's a significantly harder target than the default Docker setup most tutorials push.

The "everything is code" approach is where the complexity disappears. Here's what a service definition actually looks like:

services:
  my-app:
    image: nginx:alpine
    port: 8080
    # Volumes and env vars are declared, not scripted
    volumes:
      - ./html:/usr/share/nginx/html:ro
    environment:
      - TZ=UTC

That's the whole deployment. No Dockerfile, no docker-compose.yml, no shell scripts to glue it together. Cloud in a Bottle generates the hardened configuration—the user namespaces, the seccomp profiles, the read-only filesystems—and applies it consistently across every service you add.

The tradeoffs are real. You're trading flexibility for safety. If you need a container with raw network access or a custom device mapping, you're going to hit walls. But for the 95% of self-hosting use cases—a media server, a file sync tool, a blog—the constraints are reasonable. The system is licensed under AGPL-3.0, which means it stays open source, and there's no data collection or telemetry baked in. It's also worth noting that the whole thing is built with Claude, which is a funny position to be in: promoting self-hosting while relying on a hosted AI service for the development. But the resulting codebase is coherent and well-structured, so I'm not going to complain too loudly about the irony.

How It Works Under the Hood

The platform is built on Ubuntu, which is the least surprising choice possible. That's a compliment. It means the base OS is a standard, well-supported distribution, so kernel updates and security patches arrive on a known cadence. The interesting part is what runs on top: every application runs in a rootless container. No process inside a container has root privileges on the host. If an application gets compromised, the attacker is stuck in an unprivileged user namespace, not a root shell.

That design removes the most common failure mode of container setups, where a container that breaks out gains root on the host. Rootless containers use user namespaces to map the container's root to an unprivileged user on the host. The platform also enables seccomp filters, drops all Linux capabilities, and mounts the root filesystem as read-only by default. You don't have to configure any of this. There is no "security hardening guide" because the defaults already do the hardening for you.

Here's what a typical deployment looks like under the hood:

docker run -d --name web \
  --read-only \
  --security-opt seccomp=default \
  --cap-drop ALL \
  -p 8080:80 \
  nginx

The --read-only flag makes the root filesystem read-only, seccomp=default restricts syscalls, and --cap-drop ALL removes every Linux capability. The platform runs this command as an unprivileged user, so even the container's root is just a regular user on the host.

The whole thing is licensed AGPL-3.0. That matters because if you self-host it and modify the code, you have to share those modifications. It's the same license that Mastodon uses, and it keeps the platform honest. No open-core trap, no "source-available" claims. The code that runs your infrastructure has to remain open.

That's it. Two architectural decisions: Ubuntu as the base, rootless containers as the isolation boundary. Plus secure defaults and an AGPL license. The result is a self-hosted platform where you don't have to spend a week locking down the server before you trust it with a production app.

Real-World Deployment Scenarios

The home server scenario is where this earns its keep. Running a rootless container stack on an Ubuntu machine means you don't need to trust the software with root access to your whole system. If the sandbox gets breached, the attacker lands in a user namespace, not your kernel. That's a meaningful difference from the Docker-on-a-VPS setup most self-hosted tools assume. For a box sitting on your shelf with your family's data on it, that's not a nice-to-have.

Small business deployments are simpler in some ways and messier in others. You're not worried about physical access to the hardware — you're worried about who else is on the network, whether the software gets patched, and whether you can hand it to someone who isn't a sysadmin. The hardened container profile matters here because these deployments often sit behind a basic router firewall and get forgotten for months. AGPL-3.0 is actually an asset for this audience: if someone modifies the code, those changes have to come back. That's a real licensing consideration, not a philosophical one.

Developer testing environments are where I'd use this myself. Spinning up an isolated sandbox per test run, tearing it down, and not worrying about cross-contamination between test suites is genuinely useful. The rootless design means you can run this on a laptop without Docker Desktop's resource overhead or its licensing quirks. There's a critique floating around that promoting self-hosting while building everything with Claude is a contradiction. It's not entirely wrong, but it doesn't change whether the deployment model works.

Edge computing is the scenario that's still finding its shape. The lightweight footprint helps — a hardened rootless container can run on a Raspberry Pi class device without much trouble. But AGPL-3.0 might give some edge vendors pause, since they often want to embed things in proprietary appliances. That friction is worth knowing about before you commit.

Here's what a basic deployment looks like on Ubuntu:

sudo apt install sandboxctl
sandboxctl init --profile hardened
sandboxctl run --image my-app:latest --sandbox secure

Two commands to get a sandboxed, non-root container running. The --profile hardened flag applies the seccomp and AppArmor defaults; --sandbox secure drops you into the user namespace. You can verify it's actually rootless with sandboxctl status --verbose.

Getting Started in Practice

Rootless containers are the only sane way to run services on a personal server. They avoid the need for a root daemon, which means a compromised container can't take over your entire system. On Ubuntu, that means Docker with rootless mode or Podman. The setup is straightforward but not without its quirks. First, install Docker and enable rootless mode:

sudo apt update && sudo apt install docker.io
dockerd-rootless.sh install
systemctl --user start docker

Once that's running, launching your first service is just a docker run away. Let's say you're deploying an AGPL-3.0 licensed app like a self-hosted note-taking tool. You’ll want to lock it down with a read-only filesystem and dropped capabilities:

docker run -d --name notes-app \
  --read-only \
  --cap-drop=ALL \
  --tmpfs /tmp \
  ghcr.io/example/notes-app:latest

Configuration isn't much different from a normal setup, but you'll need to handle secrets and config files carefully. Mount a local config directory as a volume, or bake it into the image if it's static. For dynamic settings (like API keys), use environment variables or a .env file. Don’t forget to set resource limits — even a small app can balloon into a memory hog if left unchecked.

Monitoring is where rootless setups get interesting. docker logs works fine, but for resource usage, you’ll want docker stats or a lightweight Prometheus exporter. The catch? Rootless containers don’t expose metrics the same way as rootful ones, so you might need to adjust how you scrape them. For maintenance, docker pull before restarting your containers, and set up a cron job to prune unused images. It’s not glamorous, but it keeps the system from filling up your disk.

The AGPL-3.0 license means you’re free to modify and run the software, but if you expose it publicly, you have to share your changes. That’s a good reason to keep your config and modifications under version control. As one GitHub commenter noted, "It's weird seeing someone trying to promote self-hosting, while building everything with Claude." Fair point — but if the

Conclusion

If Cloud in a Bottle actually delivers what it promises, it could be the closest thing to a personal server that doesn't require a second job. The real question isn't whether the tech works — rootless containers and unified auth aren't magic — but whether the experience holds up past the first deploy. I've seen too many projects that nail the demo but crumble under the weight of real usage, certificate renewations, and update cascades at 2 AM.

I'm still figuring out whether this is genuinely solving a problem people have, or just making self-hosting feel accessible enough to get more people into trouble.