Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

How to simplify your multi-repo workflow with Podman

May 28, 2025
Caleb Evans
Related topics:
ContainersDeveloper productivityDeveloper toolsDevOpsIDEs
Related products:
Podman Desktop

    I've recently discovered the wonders of development (dev) containers in my workflow. I work on a project with many different components, using various languages, and in some cases, different versions of those languages. These variations from component to component caused me to spend at least an hour or two every week fixing environment-related issues, not to mention the lengthy process of setting up my local environment when I first joined the project.

    I will discuss the methods I used to build a fully containerized dev environment that is consistent, quick to rebuild, and speeds up development. Not only did this solve my problem, it is available for the entire team to use and is incredibly easy for new developers to start using.

    Prerequisites

    To build this environment, you'll need:

    • Podman
    • An integrated development environment (IDE) with support for dev containers. We'll use VS Code for this tutorial.

    Before we dive into the tutorial, there are a few configuration steps in the IDE and Podman:

    1. Enable the compose extension in Podman.
    2. Install the dev containers extension.
    3. Configure the dev containers extension. In the extension settings, set the following values:
      • "Copy Git Config": Enabled 
      • "Docker Compose Path": podman compose
      • "Docker Path": podman
      • "Docker Socket Path": unix:///run/user/1000/podman/podman.sock
        • Note: This value is usually correct. However, you can run the following command to confirm your path: $ podman info --format "{{.Host.RemoteSocket.Path}}"

    Demo repository

    This tutorial uses an accompanying demo repository to explain the concepts. The repo follows this hypothetical setup:

    • Two Quarkus microservices that communicate with each other using Kafka.
    • One Python API that provides external access to the microservices.

    To support these services, we also need:

    • PostgreSQL database
    • Kafka broker
    • ZooKeeper (required by Kafka)

    You can apply the same setup to any combination of technologies or languages. The key takeaway is that these components rely on each other and often need extra infrastructure—like databases and messaging systems—to run properly.

    Creating the dev environment

    The configuration for dev containers is often handled on a per-repository basis. For instance, when you open a repo in VS Code, you might be prompted to create a new dev container config for that repo. While there’s nothing inherently wrong with that approach, it may not be ideal when working with multiple repos. This tutorial shows you how to create a single development repository that everyone on your team can use for an easily repeatable local dev environment. 

    This process consists of six steps:

    1. Start a new repository.
    2. Write your Containerfile(s).
    3. Clone your repos.
    4. Write a Compose file.
    5. Write the dev container configs.
    6. Define environment variables.

    Step 1: Start a new repository

    To begin, create a new repository in your Git platform of choice. This repository will be the gateway to developing the set of components you choose, so name it accordingly. Personally, I use a <name of product>-development format. 

    Next clone the repo and open in your IDE. Then create the following directories:

    • ./Containerfiles: Stores any Containerfiles you may need.
    • ./.devcontainer: Stores all dev container configuration files.

    Step 2: Write your Containerfile(s)

    You can use default dev container images if you’d like, but most users will need to add extra packages or tools. There are many dev container images available from various sources, including Microsoft dev container base images and dev container templates.

    For this tutorial, I’ll use:

    • mcr.microsoft.com/devcontainers/python:3.11 for the API.
    • mcr.microsoft.com/devcontainers/java:17 for the Quarkus microservices.

    In the ./Containerfiles directory, create your Containerfiles. You can name them however you like (e.g., Containerfile.python311 and Containerfile.java17). 

    Here’s an example:

    FROM mcr.microsoft.com/devcontainers/python:3.11
    
    # Set env vars you want for ALL python environments
    ENV HOME="/root"
    ENV PATH="/opt/venv/bin:$PATH"
    
    # Copy in anything you may need.
    # In this example we have a ./Containerfiles/scripts dir to hold any scripts needed after the containers are created.
    COPY --chmod=0755 Containerfiles/scripts /tmp/scripts
    
    # Install any specific packages you may need. 
    # Here we will install a few helpful tools and establish a Python virtual environment.
    RUN apt update -y \
        && apt -y install --no-install-recommends \
            kafkacat \
            curl \
            maven \
            postgresql-client
    
    RUN mkdir -p /opt/venv && \
        python3 -m venv /opt/venv && \
        /opt/venv/bin/pip install --upgrade pip && \
        /opt/venv/bin/pip install pre-commit
        
    CMD ["sleep", "infinity"]

    Step 3: Clone your repos

    This step might sound simple, but it can be tricky if you’re building something for a team. What I mean by "clone your repos" is make sure users clone their forks into a specific directory. You can enforce this with a script. 

    For example, the script could:

    1. Check if ./repos exists.
      • If it does, ask the user if they want to delete it.
      • Or else, create the directory.
    2. Ask for the user's Git username.
    3. Use the username and a pre-defined YAML list of repos (./repos.yaml in the demo) to clone all of their forks to the ./repos directory.

    I would recommend writing your own script to fit your needs. Modifying the one I provide in the demo repo may be a good start. Whatever solution you choose, be sure to add your chosen directory to the repo’s .gitignore.

    Step 4: Write a Compose file

    The Compose file ties everything together. You have a lot of freedom here to define your environment exactly how you need it. You’ll need to define all your components in this file, including supporting infrastructure.

    First, add the components you plan to develop. For example, use the Containerfiles written earlier to build the image. Notice the volumes—one mounts the user's local SSH config (for Git authentication), and the other mounts the directory holding the repos we cloned earlier:

    services:
      microservice-1:
        container_name: microservice-1
        image: "demo-dev-java:17"
        volumes:
          - ~/.ssh:/root/.ssh:cached,z
          - ../repos:/root/repos:cached,z
        networks:
          - demo-network

    Add any supporting infrastructure. For example, here is the Kafka broker service used in the demo:

    kafka:
        hostname: kafka
        image: docker.io/wurstmeister/kafka:latest
        ports:
          - "9092:9092"
        environment:
          - KAFKA_BROKER_ID=1
          - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
          - ALLOW_PLAINTEXT_LISTENER=yes
          - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT
          - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092
          - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092
          - KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT
          - KAFKA_CREATE_TOPICS=demo-topic-one:1:1,demo-topic-two:1:1
        volumes:
          - type: tmpfs
            target: /kafka
        depends_on:
          - zookeeper
        networks:
          - demo-network

    Finally, add the shared network as follows:

    networks:
      demo-network:
        driver: bridge

    Add or configure anything else you may need in your environment. Save this file wherever you prefer. I keep it at ./compose.yaml.

    Step 5: Write the dev container configs

    These configuration files define how your IDE will run within each dev container. The following code snippet is an example devcontainer.json you can tweak to your needs. This example demonstrates a few possibilities, but there are many configuration options to choose from.

    {
      "name": "microservice-1",
      "dockerComposeFile": [
        "../compose.yaml"
      ],
      "service": "microservice-1",
      "workspaceFolder": "/root/repos/microservice-1",
      "updateRemoteUserUID": true,
      "remoteUser": "root",
      "onCreateCommand": "/bin/bash /tmp/scripts/on-create.sh",
      "customizations": {
        "vscode": {
          "settings": {
            "chat.commandCenter.enabled": false,
            "editor.renderWhitespace": "all"
          },
          "extensions": [
            "redhat.java",
            "redhat.vscode-quarkus",
            "redhat.vscode-yaml",
            "redhat.vscode-xml"
          ]
        }
      }
    }

    Organize your .devcontainer folder so each component has its own directory as follows:

    .devcontainer
    ├── api
    │   └── devcontainer.json
    ├── microservice-1
    │   └── devcontainer.json
    ├── microservice-2
    │   └── devcontainer.json

    Here is an explanation of the example config:

    • name: Name of the dev container.
    • dockerComposeFile: References your Compose file.
    • service: The name of the service defined in the Compose file.
    • workspaceFolder: The folder in the container opened by your IDE (here it points to the ./repos directory).
    • updateRemoteUserUID: Matches the UID/GID of the container user to your local user (prevents permissions issues).
    • remoteUser: Which user to run as in the container.
    • onCreateCommand: Command to run after the container is created.
    • customizations: Defines IDE settings and extensions.

    Step 6: Define environment variables

    If you need environment variables, you can either add them directly in the Compose file or define them in a file and reference that in the Compose file. It’s often helpful to have a single common.env file for variables used across components and individual *.env files for variables specific to each component as follows:

    .devcontainer
    ├── api
    │   └── devcontainer.json
    │   └── var.env
    ├── microservice-1
    │   └── devcontainer.json
    │   └── var.env
    ├── microservice-2
    │   └── devcontainer.json
    │   └── var.env
    └── common.env

    The following is in the Compose file:

    services:
      microservice-1:
        container_name: microservice-1
        image: "demo-dev-java:17"
        env_file:
          - ./common.env
          - ./microservice-1/var.env
        volumes:
          - ~/.ssh:/root/.ssh:cached,z
          - ../repos:/root/repos:cached,z
        networks:
          - demo-network

    Set up the dev environment

    To set up the environment:

    1. Build the images using the Containerfiles you created, making sure to match the Compose file’s image name: podman build -f ./Containerfiles/Containerfile.java17 -t demo-dev-java:17 .

    Note:

    To streamline this process, you could build the images in CI and publish them to an image registry or add these commands to a Makefile.

    1. Make sure your repos are cloned.

    Open the environment in a container

    Next open the environment in a container:

    1. Open the new *-development (or whatever you named it) repo in VS Code, if you haven't already.
    2. Open the command palette by entering: CTRL + SHIFT + P.
    3. Search for and select: Dev Containers: Reopen in Container.
    4. Select the name of the component you want to start developing.

    After you select the component, the window will appear blank and show a status bar in the bottom-right corner. You can decide if you want to watch the startup logs. It may take a few minutes, depending on what kind of scripts you have set up to run on start up. The first time you do this, it may take additional time because you also need to create all of the containers.

    Switch to a different component

    To switch to an alternate component:

    1. Open the command palette by entering: CTRL + SHIFT + P.
    2. Search for and select: Dev Containers: Switch Container.
    3. Select the name of the component you want to switch to.

    Rebuild the containers

    When you break something, just rebuild the environment as follows:

    1. Open the command palette by entering: CTRL + SHIFT + P.
    2. Search for and select: Dev Containers: Rebuild Container.

    This will destroy the environment and rebuild it. You will not lose progress on any work as it is stored locally and mounted to the containers.

    Next steps

    This tutorial only scratches the surface of what’s possible. Check out the official documentation for more ideas.

    • Compose specification
    • Dev containers specification

    Related Posts

    • Four creative ways to create an OpenShift/Kubernetes dev environment

    • Build and run Buildah inside a Podman container

    • Monitoring container vitality and availability with Podman

    • Introducing IDE support for Apache Camel K Modeline

    Recent Posts

    • Protect data offloaded to GPU-accelerated environments with OpenShift sandboxed containers

    • Case study: Measuring energy efficiency on the x64 platform

    • How to prevent AI inference stack silent failures

    • Preventing GPU waste: A guide to JIT checkpointing with Kubeflow Trainer on OpenShift AI

    • How to manage TLS certificates used by OpenShift GitOps operator

    What’s up next?

    This learning path demonstrates the full lifecycle of how you can go from an initial application, to a container, to a fully running Pod on Kubernetes in 30 minutes using Podman Desktop and the Developer Sandbox.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.