
Applies to SUSE Linux Enterprise Server 12 SP3

6 Dockerizing Applications

Docker is a technology that can help you to minimize resources used to run or build your applications. There are several types of applications that are suitable to run inside a Docker container like daemons, Web pages or applications that expose ports for communication. You can use Docker for automation of building and deployment processes by adding the build process into a docker image, then building the image and then running containers based on that image.

Running your application inside a docker container provides you with the following advantages:

  • You can minimize the runtime environment of the application as you can add to the docker image of the application just the required processes and applications.

  • The image with your application is portable across machines also with different Linux host systems.

  • You can share the image of your application by using a repository.

  • You can use different versions of required packages in the container than the host system uses without having problems with dependencies.

  • You can run several instances of the same application that are completely independent from each other.

Using Docker for building of applications provides the following features:

  • You can prepare a complete building image.

  • Your build always runs in the same environment.

  • Your developers can test their code in the same environment as used in production.

  • You can set up an automated building process.

The following section provides you with examples and tips on how to dockerize your applications. Prior to reading further, make sure that you have activated your SLES base docker image as described in Section 5.1, “Obtaining Base SLES Images”.

6.1 Running an Application with Specific Package Versions

You may face a problem that your application uses a specific version of a package that is different from the package installed on the system that should run your application. You can modify your application to work with another version or you may create a Docker image with that particular package version. The following example of a Dockerfile shows an image based on a current version of SLES but with an older version of the example package

                FROM suse/sles12sp3:latest
                MAINTAINER Tux

                RUN zypper ref && zypper in -f example-1.0.0-0
                COPY application.rpm /tmp/

                RUN zypper --non-interactive in /tmp/application.rpm

                ENTRYPOINT ["/etc/bin/application"]

                CMD ["-i"]

Now you can build the image by running in the same directory as the Dockerfile resides:

                docker build --tag tux_application:latest .

The Dockerfile example shown above performs the following operations during the docker build:

  1. Updates the SLES repositories.

  2. Installs the desired version of the example package.

  3. Copies your application package to the image. The source RPM must be placed in the build context.

  4. Unpacks your application.

  5. The last two steps run your application after a container is started.

After a successful build of the tux_application image, you can start a container based on your new image:

                docker run -it --name application_instance tux_application:latest

You have created a container that runs a single instance of your application. Bear in mind that after closing the application, the Docker container exits as well.

6.2 Running Applications with Specific Configuration

You may need to run an application that is delivered in a standard package accessible through SLES repositories but you may need to use a different configuration or use specific environment variables. In case you would like to run several instances of the application with non-standard configuration, you can create your own image that will pass the custom configuration to the application.

An example with the example application follows:

                FROM suse/sles12sp3:latest

                RUN zypper ref && zypper --non-interactive in example

                ENV BACKUP=/backup

                RUN mkdir -p $BACKUP
                COPY configuration_example /etc/example/

                ENTRYPOINT ["/etc/bin/example"]

The above example Dockerfile results in the following operations:

  1. Refreshing of repositories and installation of the example.

  2. Sets a BACKUP environment variable (the variable persists to containers started from the image). You can always overwrite the value of the variable with a new one while running the container by specifying a new value.

  3. Creates the directory /backup.

  4. Copies the configuration_example to the image.

  5. Runs the example application.

Now you can build the image and after a successful build, you can run a container based on your image.

6.3 Sharing Data between an Application and the Host System

You may run an application that needs to share data between the application's container and the host file system. Docker enables you to do data sharing by using volumes. You can declare a mount point directly in the Dockerfile. But you cannot specify a directory on the host system in the Dockerfile as the directory may not be accessible at the build time. You can find the mounted directory in the /var/lib/docker/volumes/ directory on the host system.

Note: Discarding Changes to the Directory to Be Shared

After you declare a mount point by using the VOLUME instruction, all your changes performed (by using the RUN instruction) to the directory will be discarded. After the declaration, the volume is part of a temporary container that is then removed after a successful build. In case you need to e.g. change permissions, perform the change before you declare the directory as a mount point in the Dockerfile.

You can specify a particular mount point on the host system when running a container by using the -v option:

                docker run -it --name testing -v /home/tux/data:/data sles12sp3:latest /bin/bash

Using the -v option overwrites the VOLUME instruction if you specify the same mount point in the container.

Now let's create an example image with a Web server that will read Web content from the host's file system. The Dockerfile could look as follows:

FROM suse/sles12sp3:latest

                RUN zypper ref && zypper --non-interactive in apache2

                COPY apache2 /etc/sysconfig/

                RUN chown -R admin /data

                EXPOSE 80

                VOLUME /data

                ENTRYPOINT ["apache2ctl"]

The example above installs the Apache Web server to the image and copies all your configuration to the image. The data directory will be owned by the admin user and will be used as a mount point to store your web pages.

6.4 Applications Running in the Background

Your application may need to run in the background as a daemon or as an application exposing ports for communication. In that case a typical Docker container may be run in background. Do not run your application in the container in the background as it may cause exiting of the container. Run the container in the background instead. An example Dockerfile for an application exposing a port looks as follows:

                FROM suse/sles12sp3:latest

                RUN zypper ref && zypper --non-interactive in postfix
                RUN mkdir -p /var/spool/mail

                COPY main.cf /etc/postfix/main.cf

                EXPOSE 25 587

                VOLUME ["/var/spool/mail"]
                ENTRYPOINT ["/usr/sbin/postfix"]

Now you can build your image. Docker performs the following operations according to the instructions in the Dockerfile:

  1. Docker refreshes repositories and installs the postfix mail server as it is not installed by default in the SLES docker image.

  2. The /var/spool/mailboxes directory is created in the file system of the image. The directory will store all mailboxes if you configure the mail server to store data in this directory.

  3. Here you copy a configuration file to the particular directory. Make sure that the main.cf is located in the same directory as the Dockerfile. Bear in mind that the configuration will be the same for all instance run in the future. In case you need a different configuration for each container, you will need to edit it after running the container.

  4. Each started container will expose the ports: 25 and 587. In case you will run several instances of this image on the same machine, you should define a specific host name for each container.

  5. The VOLUME instruction creates a mount point at the /var/spool/mail directory in the container.

  6. The last instructions runs the postfix mail server in the started container.

After a successful build, you can run a container based on the image:

                docker run -d --name mail_server -v /var/spool/mail:/var/spool/mail postfix:latest /bin/bash

The -d option runs the container in a detached mode and further communication by using the CLI will not be possible. To reattach the container run:

                docker attach <container identification>
Print this page