DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Java CI/CD: From Local Build to Jenkins Continuous Integration
  • Mitigating DevOps Repository Risks
  • Basic Guide for Debian Packaging (NodeJS)
  • Careers in DevOps For Non-Technical People

Trending

  • AI-Driven Root Cause Analysis in SRE: Enhancing Incident Resolution
  • A Simple, Convenience Package for the Azure Cosmos DB Go SDK
  • Detection and Mitigation of Lateral Movement in Cloud Networks
  • Docker Base Images Demystified: A Practical Guide
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. DevOps and CI/CD
  4. Using the Ubuntu Docker Image

Using the Ubuntu Docker Image

In this post, we'll show you how to make the most of the base Ubuntu images while building your own Docker images and more!

By 
Matthew Casperson user avatar
Matthew Casperson
·
Dec. 14, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
6.9K Views

Join the DZone community and get the full member experience.

Join For Free

The official Ubuntu Docker image is the most downloaded image from Docker Hub. With over one billion downloads, Ubuntu has proven itself to be a popular and reliable base image on which to build your own custom Docker images.

In this post, I show you how to make the most of the base Ubuntu images while building your own Docker images.

An Example Dockerfile

This is an example Dockerfile that includes the tweaks discussed in this post. I go through each of the settings to explain what value they add:

Dockerfile
 
FROM ubuntu:22.04
RUN echo 'APT::Install-Suggests "0";' >> /etc/apt/apt.conf.d/00-docker
RUN echo 'APT::Install-Recommends "0";' >> /etc/apt/apt.conf.d/00-docker
RUN DEBIAN_FRONTEND=noninteractive \
  apt-get update \
  && apt-get install -y python3 \
  && rm -rf /var/lib/apt/lists/*
RUN useradd -ms /bin/bash apprunner
USER apprunner


Build the image with the command:

Shell
 
docker build . -t myubuntu


Now that you've seen how to build a custom image from the Ubuntu base image, let's go through each of the settings to understand why they were added.

Selecting a Base Image

Docker images are provided for all versions of Ubuntu, including Long Term Support (LTS) releases such as 20.04 and 22.04, and normal releases like 19.04, 19.10, 21.04, and 21.10.

LTS releases are supported for 5 years, and the associated Docker images are also maintained by Canonical during this period, as described on the Ubuntu release cycle page:

These images are also kept up to date, with the publication of rolled up security updated images on a regular cadence, and you should automate your use of the latest images to ensure consistent security coverage for your users.

When creating Docker images hosting production software, it makes sense to base your images on the latest LTS release. This allows DevOps teams to rebuild their custom images on top of the latest LTS base image, which automatically includes all updates but is also unlikely to include the kind of breaking changes that can be introduced between major operating system versions.

I used the Ubuntu 22.04 LTS Docker image as the base for this image:

Shell
 
FROM ubuntu:22.04


Not Installing Suggested or Recommended Dependencies

Some packages have a list of suggested or recommended dependencies that aren't required but are installed by default. These additional dependencies can add to the size of the final Docker image unnecessarily, as Ubuntu notes in their blog post about reducing Docker image sizes.

To disable the installation of these optional dependencies for all invocations of apt-get, the configuration file at /etc/apt/apt.conf.d/00-docker is created with the following settings:

Shell
 
RUN echo 'APT::Install-Suggests "0";' >> /etc/apt/apt.conf.d/00-docker
RUN echo 'APT::Install-Recommends "0";' >> /etc/apt/apt.conf.d/00-docker


Installing Additional Packages

Most custom images based on Ubuntu require you to install additional packages. For example, to run custom applications written in Python, PHP, Java, Node.js, or DotNET, your custom image must have the packages associated with those languages installed.

On a typical workstation or server, packages are installed with a simple command like:

Shell
 
apt-get install python3


The process of installing new software in a Docker image is non-interactive, which means you don't have an opportunity to respond to prompts. This means you must add the -y argument to automatically answer "yes" to the prompt asking to continue with the package installation:

Shell
 
RUN apt-get install -y python3


Preventing Prompt Errors During Package Installation

The installation of some packages attempts to open additional prompts to further customize installation options. In a non-interactive environment, such as during the construction of a Docker image, attempts to open these dialogs result in errors like:

Shell
 
unable to initialize frontend: Dialog


These errors can be ignored as they don't prevent the packages from being installed. But the errors can be prevented by setting the DEBIAN_FRONTEND environment variable to noninteractive:

Shell
 
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3


The Docker website provides official guidance on the use of the DEBIAN_FRONTEND environment variable. They consider it a cosmetic change and recommend against permanently setting the environment variable. The command above sets the environment variable for the duration of the single apt-get command, meaning any subsequent calls to apt-get will not have the DEBIAN_FRONTEND defined.

Cleaning Up Package Lists

Before any packages can be installed, you need to update the package list by calling:

Shell
 
RUN apt-get update


However, the package list is of little value after the required packages have been installed. It's best practice to remove any unnecessary files from a Docker image to ensure the resulting image is as small as it can be. To clean up the package list after the required packages have been installed, the files under /var/lib/apt/lists/ are deleted.

Here you update the package list, install the required packages, and clean up the package list as part of a single command, broken up over multiple lines with a backslash at the end of each line:

Shell
 
RUN DEBIAN_FRONTEND=noninteractive \
  apt-get update \
  && apt-get install -y python3 \
  && rm -rf /var/lib/apt/lists/*


Run as a Non-Root User

By default, the root user is run in a Docker container. The root user typically has far more privileges than are required when running a custom application, so creating a new user without root privileges provides better security.

The useradd command provides a non-interactive way to create new users.

This isn't to be confused with the adduser command, which is a higher-level wrapper over useradd.

After all configuration files have been edited and packages have been installed, you create a new user called apprunner:

Shell
 
RUN useradd -ms /bin/bash apprunner


This user is then set as the default user for any further operations:

Shell
 
USER apprunner


Conclusion

It's possible to use the base Ubuntu Docker images with little customization beyond installing any required additional packages. But with a few tweaks to limit optional packages from being installed, cleaning up package lists after the packages are installed, and creating new users with limited permissions to run custom applications, you can create smaller and more secure images for your custom applications.

Learn how to use other popular container images:

  • Using the NGINX Docker image
  • Using the Alpine Docker image

Resources

  • Ubuntu Docker image
  • Dockerfile reference

Happy deployments!

IT Docker (software) operating system ubuntu DevOps Java (programming language) Python (language)

Published at DZone with permission of Matthew Casperson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Java CI/CD: From Local Build to Jenkins Continuous Integration
  • Mitigating DevOps Repository Risks
  • Basic Guide for Debian Packaging (NodeJS)
  • Careers in DevOps For Non-Technical People

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!