Welcome the new Virtualmin Podman Plugin

Hello,

I’m happy to announce that after months of intensive development and testing, I’m finally ready to introduce a developer preview of the new Virtualmin Podman plugin. It’s now available for testing for all Virtualmin Pro users.

To install it on EL systems:

curl -u 'SERIAL:KEY' https://download.virtualmin.dev/webmin-virtualmin-podman-latest.rpm -o /tmp/webmin-virtualmin-podman-latest.rpm
sudo dnf install /tmp/webmin-virtualmin-podman-latest.rpm

and for Debian and its derivatives:

curl -u 'SERIAL:KEY' https://download.virtualmin.dev/webmin-virtualmin-podman-latest.deb -o /tmp/webmin-virtualmin-podman-latest.deb
sudo apt-get install /tmp/webmin-virtualmin-podman-latest.deb

After the installation is complete, the plugin should be enabled globally on the “System Settings ⇾ Features and Plugins” page. Once this is done, it should also be enabled individually for each domain using the “Edit Virtual Server” page.

I tried to make it as simple as possible, but the module config has an intimidating number of options and can enable advanced features that are disabled by default. It’s designed to be simple out of the box but powerful for advanced users.

Note that we are open to constructive suggestions, and changes can be made before the final release.


Screenshots











README.md

Virtualmin Podman Plugin

Virtualmin Podman plugin for deploying and managing Podman containers and pods
per virtual server, with integrated networking, proxying, runtime controls,
logs, and browser terminal access.

Overview

This module adds Podman management to Virtualmin domains and to the global
Virtualmin explorer. It supports both container and pod workflows, runtime-
aware rootless and rootful execution, reverse proxy integration, image
discovery, reusable defaults, and browser-based troubleshooting tools.

Current features

Containers

  • Domain-scoped management view for each virtual server
  • Global cross-domain container explorer
  • Install, edit, save/reinstall, start, stop, restart, delete, and bulk
    lifecycle actions
  • Configurable list columns for ports, paths, volumes, envs, status, logs,
    console access, and optional runtime usage stats
  • Quick links to logs and terminal console from list and details views
  • Runtime metadata and inspect summaries for troubleshooting

Pods

  • Per-domain and global pod tabs with configurable columns
  • Create, clone, view, start, stop, delete, and bulk lifecycle actions
  • Pod details view with member container summaries
  • Pod-level logs view plus member-container logs and console links
  • Support for creating containers directly inside an existing pod in the
    matching runtime context

Runtime modes

  • Image user (rootless) [default]: Podman runs rootless as the virtual
    server owner, and containers keep the image’s own user model
  • Domain user (rootful): Podman runs rootful, and containers run as
    the virtual server UID/GID

Runtime mode policy can be exposed as a selector, shown as a fixed note, or
kept hidden while still applying the configured default. Separate Podman
runtime contexts are respected for container discovery, pod discovery, and
network selection.

Networking and proxying

  • Multi-port host-to-container mappings with TCP or UDP
  • Pod-level port publishing for shared pod frontends
  • Automatic host-port allocation from a configurable base
  • Optional reverse proxy path mapping for containers and pods
  • Proxy target port selection
  • Proxy host-header forwarding policy support
  • Pod network modes:
    • Default network
    • Specific Podman network
    • Host
    • None
  • Inline create and delete of Podman networks in the selected runtime context
  • Advanced pod network options:
    • network aliases
    • static IPv4, IPv6, and MAC where supported
    • DNS servers, search domains, and resolver options
    • extra host entries
    • no-hosts and no-resolv controls

Storage, environment, and security

  • Multi-volume host path mappings with rw and ro
  • Pod bind mounts with SELinux relabel and ownership-shift controls
  • Domain-home path controls for non-admin contexts
  • Environment variables as KEY=VALUE
  • Extra Linux capability controls
  • Runtime hardening flags such as no-new-privileges and read-only root
    filesystem
  • Host access controls for privileged mode, host namespaces, and sensitive or
    outside-home mounts

Resource limits and health checks

  • rootful runtime only for explicit container resource controls
  • Memory, swap, reservation, CPU, PID, cpuset, shared memory, blkio/device
    throttling, and ulimits where supported
  • Optional cgroup-parent mode to inherit limits from the user slice
  • Pod CPU, memory, and shared-memory defaults and limits
  • Container health command, interval, timeout, retries, start period, and
    failure policy
  • Container restart policy and pull behavior
  • Pod restart policy, exit policy, stop timeout, infra container, user
    namespace mode, and shared namespace controls

Image discovery and defaults

  • Registry search UI with keyboard navigation
  • Metadata fetch for selected images
  • Architecture compatibility checks
  • Defaults resolution from:
    • local podman image inspect
    • remote skopeo inspect --config
    • bundled presets.json
    • optional custom presets JSON from module configuration
  • Preset and metadata hints for ports, mounts, envs, health checks, and proxy
    behavior

Logs, console access, and list views

  • Container log viewer
  • Pod log viewer
  • In-container interactive terminal shell
  • Integrated with Webmin xterm backend
  • Domain and container context shown in terminal header
  • Global and per-domain list views for both containers and pods

Access control and UI defaults

  • Owner and reseller access controls
  • Separate pod access policy for master administrators, all users, or disabled
  • Configurable default list columns for containers and pods
  • Configurable visible panels for container and pod create workflows
  • Module-level defaults for runtime mode, restart behavior, networking,
    security, mounts, extra Podman flags, and other create-time behavior

Module configuration

Config is organized into:

  • General settings
    • Podman command path
    • owner and reseller access
    • pod access policy
    • default runtime mode
    • runtime mode selector display
    • proxy host-header policy
    • default log lines
  • User interface settings
    • default container list columns
    • default pod list columns
    • visible container panels
    • visible pod panels
  • Registry and discovery
    • default registry pool
    • search result limit
    • presets source mode:
      • use bundled presets only
      • merge bundled presets with custom presets JSON
  • Container defaults
    • restart policy
    • base auto-port
    • user-slice cgroup-parent behavior
    • default extra run flags
    • default capabilities
    • default hardening options
    • default host access options
  • Pod defaults
    • infra container and user namespace mode
    • shared namespaces and network mode
    • restart, exit, and stop-timeout policy
    • user-slice limits, CPU, memory, and shared memory defaults
    • mount SELinux and ownership-shift defaults
    • default extra create flags

Presets

presets.json supports curated defaults for known images, including:

  • recommended volume targets
  • recommended env variables
  • recommended port and proxy hints
  • optional notes shown in the UI

Custom presets entered in module configuration are saved in:
/etc/webmin/virtualmin-podman/presets.json

When custom mode is enabled, bundled and custom presets are merged and custom
rules take precedence over bundled rules for matching entries.

If the custom file is empty or invalid, bundled presets are used.

Requirements

  • Virtualmin Pro with this plugin installed and enabled
  • Podman installed on the host and reachable by the configured command path
  • skopeo recommended for remote image metadata lookups
  • Webmin xterm module for browser console access
  • Reverse proxy feature enabled on domains that need proxied container or pod
    paths

Notes

  • rootless behavior depends on host capabilities and user-session or systemd
    setup
  • Runtime capability and cgroup behavior can differ between rootful and
    rootless modes
  • Some static network addressing and resource controls are only available in
    supported runtime or network combinations
  • Downloaded image listings, pods, and Podman network choices are runtime-
    context aware
  • Enabling CPU and memory list columns adds an extra runtime stats query
5 Likes

I propose to change the name “Virtualmin” to “VirtualGOAT”. This is an absolute win.

By the way, I got this warning in my Ubuntu Pro 24.04 test environment:

Setting up podman (4.9.3+ds1-1ubuntu0.2+esm2) ...
WARN[0000] Error validating CNI config file /etc/cni/net.d/87-podman-bridge.conflist: 
[failed to find plugin "bridge" in path [/usr/local/libexec/cni /usr/libexec/cni 
/usr/local/lib/cni /usr/lib/cni /opt/cni/bin] failed to find plugin "portmap" 
in path [/usr/local/libexec/cni /usr/libexec/cni /usr/local/lib/cni /usr/lib/cni /opt/cni/bin] 
failed to find plugin "firewall" in path [/usr/local/libexec/cni /usr/libexec/cni 
/usr/local/lib/cni /usr/lib/cni /opt/cni/bin] 
failed to find plugin "tuning" in path [/usr/local/libexec/cni /usr/libexec/cni 
/usr/local/lib/cni /usr/lib/cni /opt/cni/bin]]

(edits: word wrap in output box)

Well, this is welcome and amazing.

I haven’t played with podman (or docker) because I used to be cPanel, and now have been Virtualmin - but of course I’ll be playing with this now that we have this tool.

Is there a good site for trying to get projects intended for docker working with podman? Some initial googling tells me that one of the ones I’m interested in - Discourse - may not be so easy. I’m not afraid to google for answers, but if people know of good resources, I’d love to be pointed to them. Not Discourse specifically, just docker/podman in general (and the oddities in getting docker stuff working in podman).

Can’t wait to play around with this!

1 Like

So, there’s a lot to unpack here.

Docker doesn’t work with Podman. They do the same thing. Podman replaces Docker. Podman has the same command line arguments as Docker, but it is a better/safer implementation that works better with the Linux architecture. You can copy/paste a docker command, replace docker with podman and it will almost certainly Just Work™. Podman can also use Docker hub, or any other Docker container registry.

Discourse is a bit of a special case, though, in that they have their own management tools/scripts in addition to some containers. It’s more complicated than the usual web app, and you might be best served by using their tools as documented…you probably want a dedicated VM. Discourse is demanding, and their tools live in /var/discourse, and you need root to manage it. Everything about their Docker deployment is built with the assumption you’ve got a dedicated machine, or at least have root. Those scripts/tools just happen to use the docker command and runtime. I’d be surprised if there aren’t people using podman, instead, though. Maybe I’ll convert this forum to running with podman if I get some free time, just to prove the point.

But, I think the point to make about Discourse is that the reason installing/using Discourse in the Virtualmin podman plugin might be challenging is not that we’re using Podman by default and Discourse uses Docker in their installation and tools. It’s that the Virtualmin Podman plugin is not designed for deploying something that has a bunch of ancillary tools that are not containers that orchestrate the Discourse container(s). You should think of the Discourse installation as a management environment for Discourse containers plus the containers, rather than a container you can just install with docker run <discourse-container> or whatever (which is what the Virtualmin Podman plugin is intended for, at this point).

There are very few oddities. Podman is simpler to use, as it doesn’t have a daemon and the other trashy bits of Docker. It’s just a better architecture.

But, also, as far as I know, Ilia built the module to also work with docker, if you absolutely must use docker (but you almost certainly don’t need docker).

3 Likes

I mean, just check the Discourse Docker basic installation docs: discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub

That’s not a simple docker container.

You can safely ignore it, as CNI is deprecated and should be suppressed with Netavark now being the default backend.

1 Like

just out of interest, is this installed as a webmin module? I didnt think virtuamin had a plugin system

A Virtualmin plugin is simply a Webmin module

so its a webmin module :smiley:

It’s a Virtualmin Plugin. It requires Virtualmin and provides a virtual_feature.pl. You can’t use it with Webmin by itself.

It literally says it is webmin module on the link you sent me, however I understand it needs virtualmin

Yeah it uses webmin module system to create the virtuamin plugin. Virtualmin is built on webmin.

If this plugin is what I thinking then it is absolute win for hosting admins who have headaches with old web page migration from ancient hosting servers going to retire. Talking about PHP5 and PHP7 based pages who must remain contained for some time while new sites are developed without polluting whole server with security holes. Where I can sign up for testing?

Sorry for the late reply!

You can buy a Virtualmin Pro license at Shop – Virtualmin and then follow the instructions from the original post to install it.

Thank you!

I’m wrapping up the documentation for the new Virtualmin Podman plugin, fixing a few small issues, and getting it ready for a stable release to all Virtualmin Pro users.

If anyone have tried it, I’d love to hear your feedback.

The documentation for this new Virtualmin Podman plugin is now available here:

3 Likes