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

Introducing the Atomic command

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

Share:

    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

    • Meet the Red Hat Node.js team at PowerUP 2025

    • How to use pipelines for AI/ML automation at the edge

    • What's new in network observability 1.8

    • LLM Compressor: Optimize LLMs for low-latency deployments

    • How to set up NVIDIA NIM on Red Hat OpenShift AI

    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