As system administrators, we usually work with container images and use them to deploy our applications. In this article, we’ll delve into the steps involved in upgrading the Alpine image with bash.
Without further ado, let’s get into the nitty-gritty details of it.
2. What Is Alpine?
Generally, Alpine is an open-source, small, simple, and secure Linux distribution system. Predominantly, the Alpine Images are well-known for their smaller size and faster boot-in times.
For example, the size of the official Ubuntu Linux image is 3.6G, but the Alpine Linux image comes with an impressive size of 135MB. Furthermore, the containerized version of the Alpine Docker Image comes at just 5MB in size.
2.1. Accessing the Alpine Docker Image
For the sake of demonstration, let’s pull an OpenJDK Alpine image from the DockerHub repository using the docker pull command:
$ docker pull openjdk:8-jdk-alpine 8-jdk-alpine: Pulling from library/openjdk ... ... output truncated ... ... Status: Downloaded newer image for openjdk:8-jdk-alpine
Also, we can retrieve the image information on the host machine using the docker images command:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE openjdk 8-jdk-alpine a3562aa0b991 3 years ago 105MB
Next, let’s spin an openjdk-alpine container using the image and try to access the bash through the tty (-t) and interactive (-i) sessions. As mentioned earlier, Alpine images are very light images that strip off all non-essential parts of the OS.
Hence, the base command line interpreter is available under /bin/sh, but the enhanced version of shell will not be there in Alpine images. The error indicates that the bash binary file is not accessible on the default path:
$ docker run -it a3562aa0b991 /bin/bash docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown. ERRO error waiting for container: context canceled
However, the command line shell is accessible on /bin/sh:
$ docker run -it a3562aa0b991 /bin/sh / #
3. Install bash the Alpine
Now, let’s try to install bash in the Alpine image and access the container through it. This can be accomplished in two ways: through the CLI or Dockerfile. We’ll showcase both options in the below sections.
3.1. Image Build Through CLI
Here, we’ll log in to the container with a basic command line interpreter (/bin/sh). Next, using the Alpine Package Keeper (apk), we can install bash into the container core utilities.
After successful installation, we can get the installed path of the bash with the help of which command:
$ docker run -i -t openjdk:8-jdk-alpine /bin/sh / # which bash / # / # apk add --no-cache bash ... ... output truncated ... ... (5/5) Installing bash (4.4.19-r1) Executing bash-4.4.19-r1.post-install / # which bash /bin/bash
This installation forms a new layer on top of the existing openjdk-alpine container. The below snippets showcase the list of running and stopped containers on the host machine:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES daf51dcba91c a3562aa0b991 "/bin/sh" 29 seconds ago Exited (0) 7 seconds ago happy_curie
Let’s use the docker commit command to turn this stopped container into an image:
$ docker commit daf51dcba91c openjdk:8-jdk-alpine-with-bash-cli-mode sha256:be9564ccef2fa48c214d99eb06c044b606c67b0cb4ac1a1b713ae39018d640ce $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE openjdk 8-jdk-alpine-with-bash-cli-mode be9564ccef2f 6 seconds ago 110MB openjdk 8-jdk-alpine a3562aa0b991 3 years ago 105MB
Let’s quickly spin a container with our custom-built Alpine image (openjdk:8-jdk-alpine-with-bash-cli-mode). Now, we can see that it directly takes us to the bash prompt:
$ docker run --rm -i -t openjdk:8-jdk-alpine-with-bash-cli-mode /bin/bash bash-4.4# bash-4.4# which bash /bin/bash
3.2. Image Build Through Dockerfile
Alternatively, we can use Dockerfile to build the Alpine image with bash in a single step. Create a Dockerfile that contains a checklist of things that needs to build the image.
In our case, we are going to incorporate the bash inside the miniature Alpine image:
$ cat Dockerfile #Dockerfile to create a JDK Alpine Image with bash FROM openjdk:8-jdk-alpine MAINTAINER baeldung.com # Update Alpine Linux Package Manager and Install the bash RUN apk update && apk add bash # Run the bash terminal on container startup CMD /bin/bash
Let’s construct an image using the created Dockerfile on the same path. Each line in the Dockerfile creates an image layer. Finally, the openjdk:8-jdk-alpine-with-bash is successfully created:
$ docker build -t openjdk:8-jdk-alpine-with-bash . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM openjdk:8-jdk-alpine ---> a3562aa0b991 ... ... output truncated ... ... (5/5) Installing bash (4.4.19-r1) Executing bash-4.4.19-r1.post-install ... ... output truncated ... ... Successfully built 92440c815f97 Successfully tagged openjdk:8-jdk-alpine-with-bash
Using this image, let’s spin the container with bash as the command-line shell:
$ docker run --rm -i -t openjdk:8-jdk-alpine-with-bash /bin/bash bash-4.4# bash-4.4# which bash /bin/bash
In summary, we’ve examined the Alpine images and their benefits. Then, we also described how to install and use bash on the Alpine Docker image.