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.
    • 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

Introducing the Atomic command

April 21, 2015
Daniel Walsh
Related topics:
Containers
Related products:
Red Hat Enterprise Linux

    RH_Icon_Container_with_App_Flat

    Introducing the Atomic command

    '/usr/bin/atomic'

    The atomic command defines the entrypoint for Project Atomic hosts.  On an
    Atomic Host, there are at least two distinct software delivery vehicles; Docker (often used in combination with the traditional RPM/yum/dnf), and rpm-ostree to provide atomic upgrades of the host system.

    The goal of the atomic command is to provide a high level, coherent entrypoint to the system, and fill in gaps in Linux container implementations.

    For Docker, atomic can make it easier to interact with special kinds of containers, such as super-privileged debugging tools and the like.

    The atomic host subcommand wraps rpm-ostree, click to read more ...

    The atomic command is also available on non Atomic Platforms.  You can run it on a standard RHEL, Fedora and Centos OS.  We would like to see it get used on other platforms in the future.

    Container Image as a software delivery mechanism

    The most exciting things about Docker:

    Docker images are a new way of delivering software applications to a host operating system.

    But, in a lot of ways Docker falls short as a software delivery mechanism.

    The atomic command is our effort to close the gaps.

    Red Hat has been using RPM to ship software for over 18 years now.  We can look at some of its features to see the short comings.

    One of the big features of RPM that Docker image is missing is the mechanism to launch the application at boot time.  When I install the httpd package using yum/rpm it includes the systemd unit file used to launch it at boot time.

    We would like to be able to ship one object that a user could easily install.  Currently when you want to install software using Docker images there are two different objects,  You do a Docker pull to install the image, then you build a systemd unit file to run the container, or you execute a complex Docker or Kubernetes command to have the software run as a Docker service.  Bottom line is the developer needs to not only create the Docker image, but he also needs to publish recommended installation procedures. The installation procedures would be easy to misconfigure and we could end up with a support headache.

    Software Installation

    We need a way for a container to 'install' itself in the system to be automatically restarted.

    I introduced the concept of something I called a Super Privileged Container back in November.

    https://developers.redhat.com/blog/2014/11/06/introducing-a-super-privileged-container-concept/

    The idea here is to allow a container the ability to see and potentially to manipulate the container hosts. One large use of this would be to allow a container to install itself.

    Problem Statement

    I am developing a new Apache PHP based application, that I would like to allow my customers to install.  I want to use a systemd unit file.  And I would like to allow my customers to install multiple copies of my application that they could customize to run for different accounts.

    The current method for users would be to write up a complicated installation procedure where each user could cut and paste a systemd unit file, and copy it into /etc/sytemd/system/APP.service.  They could download content and setup volume mounts for log directories, data directories and config directories. Perhaps even setup some default data.

    The LABEL Patch

    We worked with upstream Docker community for over a year to get the LABEL patch, into Docker, which finally got merged into Docker-1.6 package.  This patch allows a software developer to add additional JSON Fields (LABEL) into the Docker Image.  For example I could add a LABEL field to my Docker file like the following.

    LABEL INSTALL="docker run --rm --privileged -v /:/host -e HOST=/host -e LOGDIR=${LOGDIR} -e CONFDIR=${CONFDIR} -e DATADIR=${DATADIR} --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE /bin/install.sh"

    Note that this docker run command is actually a Super Privileged Container command, in that it is privileged and the host OS is mounted at /host within the container.

    If an application developer added an LABEL INSTALL line like that in a container image named apache_php, users could examine the docker image for the install line and execute the command.  One problem is the command has NAME and IMAGE embedded in it rather then the container name and the image name.

    Better yet the user could let the atomic command do install the application for him.

    atomic install apache_php

    The atomic command will:

    • The atomic command pulls the apache_php image from a registry if it is not currently installed.
    • The atomic command reads the LABEL INSTALL line from the container image json file.
    • The atomic command replaces any IMAGE values that it sees with the image name installed.  This means the -e IMAGE=IMAGE IMAGE will get substituted with -e IMAGE=apache_php apache_php.
    • The atomic command also allows you to specify a name for your container, and defaults to the image name if the container name is not specified.  In this case since the user did not specify the container name, atomic command will replace NAME with apache_php.  (--name apache_php -e NAME=apache_php).
    • The atomic command generates three directory names and sets passes them in as environment variables 'LOGDIR=/var/log/NAME, DATADIR=/var/lib/NAME and CONFDIR=/etc/NAME', where NAME is substituted with the container name (apache_php).  These directories can be used by the container installation procedure to create initial content and eventually could be volume mounted from the host.

    If a user wanted to install multiple copies he could just execute

    atomic install -n customer1 apache_php
    atomic install -n customer2 apache_php

    And two containers would be installed and ready to run.

    Notice the LABEL INSTALL line in my example executes the /bin/install.sh script that we packaged into the container.  This allows the developer to imbed his installation script into the container image.  Since we are running the container as a SPC we are volume mounting / at /host within the container.

    We would like /host to become the standard location for mounting / into a container.  We set the environment variable $HOST within the container to point at /host.  This allows the application developer to write scripts that install content ralative to $HOST/PATH. For example the install.sh might be creating a systemd unit file on the host in /etc/systemd/system/APP.service.  If the install.sh creates the file in ${HOST}/etc/sytemd/system/APP.service, the script would work in an SPC container where -e HOST=/host or if he ran it directly on his test machine outside a container and $HOST would not be set.

    The install.sh could also use the $CONFDIR, $LOGDIR and $DATADIR to setup additional content for the container.

    Here is my example

    /bin/install.sh

    #!/bin/sh
    # Make Data Dirs
    mkdir -p ${HOST}/${CONFDIR} ${HOST}/${LOGDIR}/httpd ${HOST}/${DATADIR}
    
    # Copy Config
    cp -pR /etc/httpd ${HOST}/${CONFDIR}
    
    # Create Container
    chroot ${HOST} /usr/bin/docker create -v /var/log/${NAME}/httpd:/var/log/httpd:Z -v /var/lib/${NAME}:/var/lib/httpd:Z --name ${NAME} ${IMAGE}
    
    # Install systemd unit file for running container
    sed -e "s/NAME/${NAME}/g" etc/systemd/system/httpd_template.service > ${HOST}/etc/systemd/system/httpd_${NAME}.service
    
    # Enabled systemd unit file
    chroot ${HOST} /usr/bin/systemctl enable /etc/systemd/system/httpd_${NAME}.service

    Notice how the install script is creating directories on the host for the container.  Also it modifies the systemd httpd template file below into a systemd unit file and enables the service.

    /etc/systemd/system/httpd_template.service

    [Unit]
    Description=The Apache HTTP Server for NAME
    After=Docker.service
    
    [Service]
    ExecStart=/usr/bin/docker start NAME
    ExecStop=/usr/bin/docker stop NAME
    ExecReload=/usr/bin/docker exec -t NAME /usr/sbin/httpd $OPTIONS -k graceful
    
    [Install]
    WantedBy=multi-user.target

    When the installation is done the service is ready to run.  And will run on reboot.

    Software Removal

    The atomic command can also be used to uninstall software.  It will use the LABEL UNINSTALL option if available.

    In our example we will use a LABEL like:

    LABEL UNINSTALL="docker run --rm --privileged -v /:/host -e HOST=/host -e IMAGE=IMAGE -e NAME=NAME IMAGE /bin/uninstall.sh

    Then the user can execute the following uninstall command:

    atomic uninstall apache_php

    The atomic command will execute the /bin/uninstall.sh script

    /bin/uninstall.sh

    #!/bin/sh
    chroot ${HOST} /usr/bin/systemctl disable /etc/systemd/system/httpd_${NAME}.service
    rm -f ${HOST}/etc/systemd/system/httpd_${NAME}.service

    Notice the script disables the service and then remove the unit file.

    Finally the atomic uninstall will attempt to docker rm a container name if the name is specified or default to the image name.

    If the container name is the same as the image name atomic uninstall with also docker rmi the container image.

    How do I run the application?

    Problem Statement

    • My application is nicely rolled into a container images.
    • My application run mostly confined but needs additional privileges?
      -- How do I tell the user to run it?</b></p>

    Lets look at an example

    The FreeIPA team has been experimenting with running the IPA daemons as separate containers.  One daemon they currently use is ntpd.  The nptd container needs to run with --cap_add SYS_TIME, in order to adjust the system hosts time.  The ntpd container developer has to tell users to run the container with the following command.

    Docker run -d -n ntpd --cap_add SYS_TIME ntpd

    The atomic command supports another label LABEL RUN, which the application developer can use to define how his application can be run.

    FROM rhel7
    RUN yum -y install ntpd; yum -y clean all
    LABEL RUN=&amp;quot;docker run -d -n NAME --cap_add SYS_TIME IMAGE&amp;quot;
    CMD /usr/bin/ntpd

    Now if the user examined the Docker image, he would know exactly how to run the container. He could inspect the installed image and then cut and paste the image line.   We automate this process by adding the atomic run command.  A user only needs to execute the following command:

    atomic run ntpd

    This will do a Docker pull of the ntpd container package onto your host and then execute the label RUN command, if it exists.  If the command does not exist the command will default to a

    Docker create -ti -n ntpd ntpd

    • This gives us the ability to define how a specific container expects to be run. Specifically this includes the privilege level required, as well as special mounts and host access, etc.

    Other features of the atomic command.

    One of the key features of rpm is to list information about a package.

    # rpm -qi Docker
    Name        : Docker
    Version     : 1.5.0
    Release     : 25.git5ebfacd.fc23
    Architecture: x86_64
    Install Date: Thu 26 Mar 2015 03:05:47 PM EDT
    Group       : Unspecified
    Size        : 21735169
    License     : ASL 2.0
    Signature   : (none)
    Source RPM  : Docker-1.5.0-25.git5ebfacd.fc23.src.rpm
    Build Date  : Thu 26 Mar 2015 01:01:50 AM EDT
    Build Host  : buildhw-05.phx2.fedoraproject.org
    Relocations : (not relocatable)
    Packager    : Fedora Project
    Vendor      : Fedora Project
    URL         : http://www.Docker.com
    Summary     : Automates deployment of containerized applications
    Description :
    Docker is an open-source engine that automates the deployment of any application as a lightweight, portable, self-sufficient container that will run virtually anywhere.
    
    Docker containers can encapsulate any payload, and will run consistently on and between virtually any server. The same container that a developer builds and tests on a laptop will run at scale, in production*, on VMs, bare-metal servers, OpenStack clusters, public instances, or combinations of the above.

    We want to be able to include data similar to this in the container image.  We again take advantage of the LABEL patch, and add data like the following to the Dockerfile.

    LABEL Name=apache_php
    LABEL Version=1.0
    LABEL Vendor="Red Hat" License=GPLv3
    LABLE Description="
    The Apache PHP Application is a example of using atomic command to install a service onto a machine."

    atomic info apache_php
    Name         : apache_php
    Version      : 1.0
    Vendor       : Red Hat
    License      : GPLv3
    INSTALL      : docker run --rm --privileged -v /:/host -e HOST=/host -e LOGDIR= -e CONFDIR= -e DATADIR= -e IMAGE=IMAGE -e NAME=NAME IMAGE /bin/install.sh
    UNINSTALL    : docker run --rm --privileged -v /:/host -e HOST=/host -e IMAGE=IMAGE -e NAME=NAME IMAGE /bin/uninstall.sh
    Last updated: February 22, 2024

    Recent Posts

    • Confidential virtual machine storage attack scenarios

    • Introducing virtualization platform autopilot

    • Integrate zero trust workload identity manager with Red Hat OpenShift GitOps

    • Best Practice Configuration and Tuning for Linux and Windows VMs

    • Red Hat UBI 8 builders have been promoted to the Paketo Buildpacks organization

    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