Welcome the new Virtualmin Podman Plugin

Hi Ilia,

Following up on the multi-container question — I run a few stacks that are Docker Compose projects with several interdependent services (e.g. Jitsi: prosody + jicofo + jvb + web sharing a network, and an app stack: postgres/pgvector + ollama + a custom ingestion service + a webui, also networked together).

Joe mentioned single containers without a recipe still work fine (just set port/volume/env manually). Does that same approach extend to a group of containers that need to share a network and start in a specific order, or is the plugin currently scoped to one container (or one pod) at a time, with no way to express “these 4 containers belong together and talk to each other”?

If it’s the latter, is compose-like multi-service support on the roadmap, or is that intentionally out of scope for this plugin?

Thanks!
Bernard

Yeah, that’s right! The “Install New Container” page still exists. Don’t get me wrong, we won’t have a recipe for every container out there. Still, I’m inclined to make the experience sweet for users. And, to be fair, you literally begged me to make it simple and one-click. So I’m fully dedicated to doing exactly that. :smiling_face:

1 Like

I’d rather provide it for free, make the customer happy, and have them put in a good word for us than try to squeeze a penny out of every little thing.

Yes, you can create a pod and add multiple containers to it. They share the same network, communicate over 127.0.0.1, and can be managed together.

Yet, we don’t support Docker Compose files or Compose-style startup order. At least not yet, as for now, recipes handle those more complex setups. Compose support may come later, but I haven’t planned that yet.

Tell me, what would you expect from Compose support though? Just simply importing a docker-compose.yml, or managing the whole stack afterward as well? And how important would this be for your workflow?

Thanks for confirming pods handle the networking part. That’s already useful. :folded_hands:

For my use case, what I’d actually want is: import an existing docker-compose.yml (so I don’t have to manually re-enter ports/volumes/env for stacks I already have running), and then manage the resulting containers/pod through the plugin afterward; start/stop/update/logs, the same way you’d manage anything else installed via the plugin. I don’t need Compose-specific features like build contexts or profiles, just the ability to bring in what’s already defined in a compose file as a starting point.

Startup order matters for me mainly for one stack (a DB that other services depend on) — not a hard requirement if pods let me just add them in the right order manually.

How important is it?
Right now it’s the main thing stopping me from moving my multi-container stacks (Jitsi, an app+DB stack) to the plugin. Everything single-container already works great for me with recipes/manual setup.

I think the startup order would best be controlled by the order in the config file instead of some complex logic workflow. Maybe add some simple delay mechanism to make sure they are fully initialized before starting the next one.

Maybe some sort of config value that controls if a multi container bundle is started in parallel or one after another. So on a staggered launch the system waits for some kind of step completion to be returned and on a parallel launch it just starts them all at once.

That should cover 99% of use cases and any more advanced use cases are up to the user to configure themselves.

Thanks!

Could you share your docker-compose.yml file for Jitsi?

Also:

  • Is a one-time import enough, with the plugin managing everything afterward?
  • Should it preserve existing volumes and data, or is recreating them under plugin-managed storage acceptable?

Heads-up!

First-class support for service-only recipes is now available, allowing local services without a public web endpoint. Reverse-proxy backends also now bind securely to 127.0.0.1, while explicitly public ports remain accessible.


Virtualmin Pro users are encouraged to try the new module and share feedback or feature requests. Development is nearly complete, with Virtualmin 8.2.0 just around the corner.

Here’s my Jitsi compose (domain anonymized to example.com, this is otherwise the standard jitsi/docker-jitsi-meet setup — nothing custom):slight_smile:

services:
  web:
    image: jitsi/web:${JITSI_IMAGE_VERSION:-stable-11031}
    ports:
      - '${HTTP_PORT}:80'
      - '${HTTPS_PORT}:443'
    volumes:
      - ${CONFIG}/web:/config:Z
      - /etc/letsencrypt/live/jitsi.example.com/fullchain.pem:/config/keys/cert.crt
      - /etc/letsencrypt/live/jitsi.example.com/privkey.pem:/config/keys/cert.key
    depends_on:
      - jvb
    networks:
      meet.jitsi:

  prosody:
    image: jitsi/prosody:${JITSI_IMAGE_VERSION:-stable-11031}
    expose:
      - '${XMPP_PORT:-5222}'
      - '${PROSODY_S2S_PORT:-5269}'
      - '5347'
      - '${PROSODY_HTTP_PORT:-5280}'
    volumes:
      - ${CONFIG}/prosody/config:/etc/prosody:Z
      - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z
    networks:
      meet.jitsi:
        aliases:
          - ${XMPP_SERVER:-xmpp.meet.jitsi}

  jicofo:
    image: jitsi/jicofo:${JITSI_IMAGE_VERSION:-stable-11031}
    ports:
      - '127.0.0.1:${JICOFO_REST_PORT:-8888}:8888'
    volumes:
      - ${CONFIG}/jicofo:/config:Z
    depends_on:
      - prosody
    networks:
      meet.jitsi:

  jvb:
    image: jitsi/jvb:${JITSI_IMAGE_VERSION:-stable-11031}
    ports:
      - '${JVB_PORT:-10000}:${JVB_PORT:-10000}/udp'
      - '127.0.0.1:${JVB_COLIBRI_PORT:-8080}:8080'
    volumes:
      - ${CONFIG}/jvb:/config:Z
    depends_on:
      - prosody
    networks:
      meet.jitsi:

networks:
  meet.jitsi:

(Trimmed the long environment: lists for readability — they’re just the standard Jitsi env passthrough, nothing custom. Happy to share those too if useful.)

${CONFIG} points to a local path, and the actual secret values (auth passwords, etc.) live in a separate .env, not shown here — the compose only references variable names.

This illustrates the case well: 4 services, a shared network (meet.jitsi), and depends_on for startup order (jicofo/jvb wait on prosody, web waits on jvb).

To answer your questions:

  • One-time import is enough for me — I don’t need the plugin to keep syncing with the compose file afterward, just to save the manual re-entry on day one.
  • Preserving existing volumes/data matters a lot for stateful services (I also run a Postgres/pgvector DB elsewhere) — recreating under plugin-managed storage would mean a painful migration or starting fresh, neither ideal for something in production. For stateless services (like web here) recreating would be fine.

Thanks for looking into this!

1 Like

Thanks!

This is supported now in the latest Virtualmin Podman 1.5-development version.

From the main Container Apps Manager page, use Add New → Import Compose file (right now requires at least one virtual server to have Podman feature enabled), select the virtual server, and upload the Compose file and its .env.

It’s intentionally kept as an advanced option and is currently available only from the main manager page. The import is one-time, with existing data being preserved, and the module manages the containers afterward. Matching running containers can also be adopted.

For the /etc/letsencrypt mounts in your example, a master admin must enable Allow mounts outside home and Allow sensitive host mounts during import.

I have run tests on these two test files:

phpbb.env (245 Bytes)
phpbb-compose.yaml (1.5 KB)

Go ahead and test it out, then tell me if it’s working the way it should for you.

And, ignore some theme/layout imperfections, they will be fixed in further updates.

1 Like

I hope this is the right place:

This is after I installed a Discourse container, decided I needed to start over fresh, so I deleted the three containers from the containers tab, and now I’m stuck. I checked the box, but there’s no way to go ahead and override.

For now, it’ll be easier for me to delete and recreate this virtual server.

I will also mention that I have a thread in Help about how Discourse forces the email admin@[domain] and I can’t find a place to change that, but even if I create that email, it doesn’t send email. And also, when you paste links/images/et cetera, Discourse can’t resolve anything outside the container so can’t generate a preview.

So far I’m having AI help me figure out how to configure things, but I would hope these things would work out of the box — like how you can specify user/pass when you set up WordPress via Virtualmin. :slight_smile:

That said, the other containers I’ve played with so far are working well, and I LOVE LOVE LOVE you for this <3 <3 <3 This is already very awesome :slight_smile:

1 Like

Thank you very much for giving it a try and for such kind and positive words! It means a lot to me!

As for the issues you mentioned, I’m taking a closer look at it today and will get back to you with more details.

1 Like

With Gemini assistance, I have developed a solution that appears to be working on my server, which is Ubuntu:

I posted it there so as not to spam up here, but I can post it here if desired. Basically a script that interactively allows you to create an authenticted admin user, fix gateway/host issues so when you paste links you get previews. More info over there.

If this is not desired, please remove and/or let me know to. I hope it’s helpful.

Obviously run at your own risk, but I have tested, and the script has a dry run mode.

1 Like

I really cannot tell you how much this rocks. I’m always trying to learn more and more, but since I was so long in the cPanel world, I couldn’t play with this stuff. And until now, when I’d tried to play with docker on my own, I struggled - couldn’t get things working.

With this, I already have several containers working thanks to the plugin, and I’m feeling confident that as I mess around with this stuff, I’ll be able to offer enough stability to be able to perhaps offer hosting for small businesses who may benefit from some of these things, meaning I can stand apart from those cPanel n00bs. hehe

But also just on a personal level, I’ve wanted to have discourse. And other containers. So this truly is delightful, and I apologize for ‘spamming’ you with more praise, but really, this is HUGE for me. And surely others who are right in my tech niche - I’m comfortable with a lot of Linux admin (not everything), but just haven’t messed much with containers yet. :slight_smile:

As for the issues you mentioned, I’m taking a closer look at it today and will get back to you with more details.

I hope the script might be helpful. But either way, thank you! :slight_smile:

2 Likes

Thank you again! :smiling_face_with_tear:

And, by the way, I already fixed that earlier Discourse deployment issue on the latest development build, where a user would get stuck partway through the admin registration process. More details here:

Can I run this podman and the plugin if I already use docker and docker compose and Portainer via proxy paths on the same machine?

Yes, Virtualmin Podman can safely coexist with Docker, Docker Compose, and a Docker-managed Portainer installation. The engines use separate APIs, storage, containers, images, volumes, and networks.

Our plugin explicitly invokes Podman, not Docker. But just don’t install podman-docker.

This is exciting news! Podman has been gaining a lot of traction as a container platform, so it’s great to see Virtualmin adding native support. Thanks for all the work that has clearly gone into developing and testing the plugin. Looking forward to trying it out and seeing how it integrates with existing Virtualmin workflows. Best of luck with the developer preview and feedback phase.

So after installation, I can’t update the SMTP settings as far as I can tell. And the settings set up do not work. But I’ll need to update them anyway if I use a third-party SMTP service.

I’m a newbie to containers, but as far as I can tell, there’s not any yaml file that might have that, or any other config file I can find. And Discourse protects that setting in the admin settings, so I have to configure it in the settings file.

BUT, I was able to uninstall that container and then install it again on the same subdomain, so that’s definitely progress! :slight_smile:

Yeah, you’d have to configure quite a few options manually before it goes online. The important bit was to make sure you can log in to Discourse as an admin with a preconfigured username and password. The rest, I don’t think, is something we should handle on the Virtualmin Podman side, and is something a user should do, I think. What do you think?

Yeah, that is meant to be fixed too.

2 Likes

EDIT: I just saw the environment variables. I’ve looked at the plugin pages a ton and just realized I could click on them. Please ignore the below for now! Sorry to be blind!

edit2: I don’t have DISCOURSE_SMTP_USER_NAME, DISCOURSE_SMTP_PASSWORD, DISCOURSE_SMTP_PORT, DISCOURSE_SMTP_ENABLE_START_TLS

But I don’t have them here either: https://i.imgur.com/cNkt8nW.png

Maybe this is all a Discourse problem. I’m just trying to figure out where to configure them, so I don’t yet even know for sure.

From my googling, I expected to be able to set those in app.yml, but can’t find that, hence message below. I’m confused, and I know it, I’m sorry! But I promise in return for the help, I’ll be writing up what I’ve learned in a post to hopefully help anyone else getting started :slight_smile:

I agree, and my message was not intended to ask that Virtualmin change that setting, but rather: I cannot find where to change that setting. I’ve googled and also using gemini to try and find the settings, but have been unsucessful.

If that is a failure on my part, I apologize, but I was looking for app.yml which is where I understand those setings to be - and I cannot find that file. As far as I can tell, it should be located in the path somewhere, perhaps at the container directory itself?

Is it there and I’m missing it?

Gemini seems to think the environmental variables are coming from somewhere else but can’t figure out where to update them.

edit: I found some: https://i.imgur.com/mC5W9Vi.png - not a complete screenshot because contains private info, but I found those - but they don’t contain all I need, as noted above.