Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

From Podman Desktop to containers in production

August 13, 2024
Evan Shortiss
Related topics:
CI/CDContainersNode.js
Related products:
Podman Desktop

Share:

    This article will take you through the process of getting started with Podman Desktop, creating a Node.js application (you can use your preferred programming language instead, if you like) and building it into a container using Podman Desktop, and configuring a continuous integration (CI) pipeline to build and push your container images to Quay.io using GitHub Actions workflows. In essence this is an introduction to the inner and outer loops of cloud-native development.

    To get started, install Podman Desktop. This step is pretty straightforward, owing to the fact that Podman Desktop has a downloads page that supports typical installation flows for Linux, macOS, and Windows and has setup guides for each platform. Once installed, it will look something like this (Figure 1).

    A view of the Podman Desktop user interface post-installation.
    The Podman Desktop UI post-installation.
    Figure 1: The Podman Desktop UI post-installation.

    You’ll be prompted to install the Podman binary during the installation if it’s not already present on your system. The Podman binary will also be available in your terminal, allowing you to manage containers using a CLI as well as with the Podman Desktop application.

    Create a Node.js application

    A simple application will suffice for this article, so I’ve taken the liberty of creating a minimalist Node.js application that tracks the top story on Hacker News over time, and logs it to the console whenever it changes. The complete source code for this application is available in this repository on GitHub. You can validate it locally by following the instructions in the repository’s README.

    Build and run a container image

    You can use Podman Desktop to build and run a container image of the Node.js application locally. Start by forking the repository to your own GitHub account, then clone it to your local development environment using the Git CLI or GitHub desktop application.

    Define a Containerfile (or Dockerfile)

    A Containerfile (or Dockerfile) is required to build your application into a deployable container image. The Containerfile for this application contains (see what I did there?) five relatively simple instructions. The inline comments explain what each instruction is doing:

    # Use the Red Hat Universal Base image for Node.js v20
    FROM registry.access.redhat.com/ubi8/nodejs-20-minimal
    
    # Copy package.json and package-lock.json into the container
    COPY package*.json .
    
    # Install production dependencies
    RUN npm ci --omit dev
    
    # Copy application code into the container
    COPY index.mjs index.mjs
    
    # Define the command that is run when the container starts
    CMD ["node", "index.mjs"]

    These instructions are all you need to get a working container image that can be used to deploy your Node.js application as a container. The sample application linked above already includes this Containerfile, but if you're using your own application you'll need to add this file to the root of your repository.

    It’s worth noting that a Containerfile can become a little more complicated if you’re using TypeScript or JavaScript bundlers, and might need Linux permission adjustments if you plan to deploy on Red Hat OpenShift—don’t worry, you can read more about building Node.js containers in this article.

    Use Podman Desktop to build the container image

    To build the container image, go to the Images screen of Podman Desktop and click the Build button. Select the Containerfile in the repository that you cloned, and enter an image name, e.g., hackernews-tracker. You can also choose a Platform to build against, or create a multi-architecture build by selecting both aarch64 and x86_64—during local development it’s most convenient and fastest to build for the architecture that matches your development machine’s architecture. Click Build, and after a few moments you’ll have a container image (Figure 2).

    In Podman Desktop go to Images > Build.
    Using Podman Desktop to build a container image.
    Figure 2: Using Podman Desktop to build a container image.

    Run the container image

    With a container image in hand, you can now deploy a running container based on that image using Podman Desktop. Visit the Images section of Podman Desktop. Your new container image will be listed, along with the base image it was built from. See Figure 3.

    In Podman Desktop go to Images to view your container image.
    The Podman Desktop Images List
    Figure 3: The Podman Desktop Images List.

    Click the Play icon on the row that corresponds to your new container image, enter a Container Name when prompted, then click the Start Container button. The container will start near instantaneously and should log the current top story on Hacker News. Leave it running and check the logs throughout the day to observe changes to the top story (Figure 4).

    In Podman Desktop, click the Play icon in the same row as your container, enter a container name, then click Start Container and watch it run.
    A running container, shown in the Podman Desktop UI.
    Figure 4: A running container, shown in the Podman Desktop UI.

    Push your image to a container registry

    With the help of Podman Desktop, we've been able to validate that our container image is working properly—this is part of the development process's inner loop. We want to be able to quickly build, test and run our containers during the local development of our application.

    Once you're satisfied that the application is ready to be deployed, you’ll usually need to push the image to a cloud or self-hosted image registry such as Quay (quay.io), GitHub Container Registry (ghcr.io), or DockerHub (docker.io).

    You can push the image using Podman Desktop, but generally speaking it’s best to set up a CI (continuous integration) pipeline to build your images when you push changes to your production branch in Git. You can use this pipeline to run tests, code quality checks, vulnerability scans, and create a unique container image for every commit to your production branch. 

    Another benefit is that your CI pipeline can efficiently build images for x86-64 infrastructure if your development machine is ARM-based. 

    I’ll be using GitHub Actions workflows as a CI provider and Quay.io as my container registry in this section, but the instructions are generally applicable.

    Select a container registry and obtain authentication credentials

    You need to create an image repository, and obtain credentials that your GitHub Actions workflow (or other CI tool) can use to push container images to your image repository on Quay.io.

    Register and sign into Quay.io, then use the plus icon in the top right hand corner of the page to create a new container image repository named hackernews-tracker. For the sake of simplicity, set the visibility as Public, and select Empty repository as the initialization option (Figure 5).

    In Quay.io, click the plus sign in the top right corner to create a new container image registry named "hackernews-tracker", set the visibility to Public, then select Empty repository.
    Creating an empty repository on Quay.io
    Figure 5: Creating an empty repository on Quay.io.

    Next, click your profile picture and select the Account Settings page. Use the Create Robot Account button on the Robot Accounts page to create a new account. Provide write permissions to the hackernews-tracker repository (Figure 6).

    In Quay.io, navigate to your profile picture > Account settings page > Robot Accounts page > Create Robot Account > provide write permissions to the "hacknernews-tracker" repository.
    Setting write permissions to a single repository for a Robot Account on Quay.io
    Figure 6: Setting write permissions to a single repository for a Robot Account on Quay.io.

    Click the new account in the Robot Accounts list to view the username and password associated with the robot account.

    Configure GitHub actions

    This section can be summarized as “add variables to the Git repository so it can push images to Quay.io”. Even if it looks like there’s a lot of content, there really isn’t much to it!

    Head over to your fork of the sample application in GitHub and visit the repository Settings screen. Select Actions under the Secrets and variables section, and add two secrets using the New repository secret button:

    1. QUAY_USER: Your Quay.io robot account username.
    2. QUAY_PASS: Your Quay.io robot account password.

    You’ll also need to add a plaintext variable. Switch from the Secrets to the Variables tab and the New repository variable button. Add a variable named QUAY_ORG and set the value to your Quay.io username, or the name of the organization you want to push the container image to. See Figure 7.

    In Quay.io, switch from the Secrets to the Variables tab and the New repository variable button, then add the variable QUAY_ORG and set the value to your Quay.io username.
    Setting secrets and variables for GitHub Actions.
    Figure 7: Setting secret and variables for Github Actions.

    Next, take a look at the build.yaml file in the .github/workflows directory inside the repository. It defines a build job with three steps:

    1. Log in to Quay.io using redhat-actions/podman-login, and the QUAY_USER and QUAY_PASS.
    2. Build and tag the image using Buildah (Podman uses Buildah behind the scenes). The QUAY_ORG variable is used here, to construct the image URL. 
    3. Push the image tags to your container image repository using redhat-actions/push-to-registry.

    Everything’s in place to build and push the image, so let’s make it happen.

    Push the image to the container registry

    To trigger the GitHub Actions workflow (CI pipeline) you can either make a change to the application code and push it to the main branch, or select Actions from the root of GitHub repository then select the Build Node.js Container, and use the Run Workflow button.

    Once the workflow is complete, two new tags will be visible in your repository on Quay.io. One representing the specific commit that the build was generated from, and another representing the latest version of the image. The latest tag will change over time, but the tags for a specific commit will remain unchanged, allowing you to rollback to older versions of the application at any time by referencing the correct tag. See Figure 8. Amazing!

    Two new tabs that are now visible in your repository on Quay.io.
    Two tags that were pushed to Quay.io by the GitHub Actions workflow.
    Figure 8: Two tags that were pushed to Quay.io by the GitHub Actions workflow.

    Deploy the container 

    Congratulations, you can now use Podman (or another container engine) to run your application in a production environment such as a machine running Red Hat Enterprise Linux (or other Linux distribution) or on an Red Hat OpenShift cluster. 

    If you’d like to deploy your application on OpenShift, you can try it for free using the OpenShift Developer Sandbox. You can use the built-in web-terminal to use the oc new-app command to deploy your container image, followed by the oc logs command to see the latest top story:

    oc new-app quay.io/evanshortiss/hackernews-tracker
    oc logs -l 'deployment=hackernews-tracker' -f

    If you're self-hosting you can use the following command to start your application, and restart it if it stops for any reason other than explicitly issuing a podman stop command: 

    podman run -d --restart unless-stopped quay.io/evanshortiss/hackernews-tracker

    Conclusion

    By using Podman Desktop, you were able to build and validate a containerized application in a local development setting. You then learned how to create a CI flow to test, build, and push your container images to an image registry for production deployment. If you plan to run your container images as Pods in a Kubernetes or OpenShift cluster, be sure to try out the Kind and OpenShift Developer Sandbox extensions for Podman Desktop to streamline your development workflow. 

    Related Posts

    • Optimize Node.js images with the UBI 8 Node.js minimal image

    • What is Podman Desktop? A developer's introduction

    • Working with Kubernetes in Podman Desktop

    • Podman Desktop 1.0: Local container development made easy

    Recent Posts

    • How Kafka improves agentic AI

    • How to use service mesh to improve AI model security

    • How to run AI models in cloud development environments

    • How Trilio secures OpenShift virtual machines and containers

    • How to implement observability with Node.js and Llama Stack

    What’s up next?

    This learning path demonstrates how you can go from an initial application to a container to a fully running pod on Kubernetes using Podman Desktop and the no-cost Developer Sandbox for Red Hat OpenShift.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    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

    Red Hat legal and privacy links

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

    Report a website issue