Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / Dokumentacja systemu SUSE LINUX Enterprise Server / Docker Open Source Engine Guide / Creating Docker Images of Applications
Applies to SUSE Linux Enterprise Server 15

5 Creating Docker Images of Applications

Docker Open Source Engine is a technology that can help minimize resources used to run or build 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 Open Source Engine to automate 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 an application inside a Docker container has 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 Open Source Engine to build applications has the following advantages:

  • You can prepare a complete building image.

  • Your build always runs in the same environment.

  • 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 examples and tips on creating Docker images for applications. Prior to reading further, make sure that you have activated your SLES base Docker image as described in Section 4.1, “Downloading Base SLES Images”.

5.1 Running an Application with Specific Package Versions

You may face the 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 can 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 registry.suse.com/suse/sles12sp4
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"]

Build the image by running the following command in the directory that the Dockerfile resides in:

> 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 the application package to the image. The source RPM must be placed in the build context.

  4. Unpacks the application.

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

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

> docker run -it --name application_instance tux_application:latest

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

5.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 registry.suse.com/suse/sles12sp4
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.

You can now build the image. After a successful build, you can run a container based on your image.

5.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 Open Source Engine 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
Note: Discarding Changes to the Directory to Be Shared

After you declare a mount point by using the VOLUME instruction, all 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. For example, to 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 sles12sp4:latest /bin/bash
Note
Note

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

Now 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 registry.suse.com/suse/sles12sp4
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 configuration to the image. The data directory will be owned by the admin user and will be used as a mount point to store Web pages.

5.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, the Docker container can be run in the background.

An example Dockerfile for an application exposing a port looks as follows:

Example 5.1: Building an Apache2 Web Server Docker Container (Dockerfile)
FROM registry.suse.com/suse/sle15 1
MAINTAINER tux 2

ADD etc/ /etc/zypp/ 3
RUN zypper refs && zypper refresh 4
RUN zypper --non-interactive in apache2 5

RUN echo "The Web server is running" > /srv/www/htdocs/test.html 6
# COPY data/* /srv/www/htdocs/ 7

EXPOSE 80 8

ENTRYPOINT ["/usr/sbin/httpd"]
CMD ["-D", "FOREGROUND"]

1

Base image, taken from Section 4.1, “Downloading Base SLES Images”.

2

Maintainer of the image (optional).

3

The repositories and service files. These are copied to /etc/zypp/repos.d and /etc/zypp/services.d to make these files available on the host in the Docker container too.

4

Command to refresh repositories and services.

5

Command to install Apache2.

6

Test line for debugging purposes, can be removed if everything works as expected.

7

The copy instruction to copy own data to the server's directory. The leading hash character (#) marks this line as a comment, so it is not executed.

8

The exposed port for the Apache Web server.

Note
Note: Check for Running Apache2 Instances on the Host

Make sure there are no Apache2 server instances running on the host. Otherwise, the Docker container will not serve any data. Remove or stop any Apache2 servers on your host.

To use the container, proceed as follows:

Procedure 5.1: Testing the Apache2 Web Server
  1. Prepare the host system for the build process:

    1. Make sure the host system is subscribed to the Server Applications Module of SUSE Linux Enterprise Server. To see installed modules or install additional modules, open YaST and select Add System Extensions or Modules.

    2. Make sure the SUSE Linux Enterprise images from the SUSE registry are installed, as described in Section 4.1, “Downloading Base SLES Images”.

    3. Save the Dockerfile from Example 5.1, “Building an Apache2 Web Server Docker Container (Dockerfile)” into the docker directory.

    4. Within the Docker container, you need access to software repositories and services that are registered on the host. To make them available, copy repositories and service files from the host to the docker/etc directory:

      > cd docker
      > mkdir etc
      > sudo cp -a /etc/zypp/{repos.d,services.d} etc/

      Instead of copying all repository and service files, you can also copy only the subset that is required by the Docker container.

    5. Add Web site data (such as HTML files) into the docker/data directory. The contents of this directory are copied to the Docker image and are thus published by the Web server.

  2. Build the container. Set a tag for your image with the -t option (here tux/apache2, but you can use any name you want):

    > sudo docker build -t tux/apache2 .

    Docker Open Source Engine will now execute the instructions provided in Dockerfile: It will take the base image, copy content, refresh repositories and install the Apache2, etc.

  3. Create a Docker container instance from the Docker image created in the previous step:

    > docker run --detach --interactive --tty tux/apache2

    Docker Open Source Engine returns the container ID, for example:

    7bd674eb196d330d50f8a3cfc2bc61a243a4a535390767250b11a7886134ab93
  4. Point a browser at http://localhost:80/test.html. You should see the message The Web server is running.

  5. To see an overview of running containers, use:

    > docker ps --latest
    CONTAINER ID        IMAGE               COMMAND                  [...]
    7bd674eb196d        tux/apache2         "/usr/sbin/httpd -..."   [...]

    To stop and delete the Docker container, use the following command:

    > docker rm --force 7bd674eb196d

The above procedure describes building an image containing the Apache2 Web server. You can use the resulting container to serve your data with the Apache2 Web server by following these steps:

Procedure 5.2: Creating a Docker Container with your Own Data
  1. In Dockerfile:

  2. Rebuild the image as described in Step 2 of Procedure 5.1.

  3. Run the image in detached mode:

    > docker run --detach --interactive --tty tux/apache2

    Docker Open Source Engine responds with the container ID, for example:

    e43fff4ae9832ecdb7677c058a73039d7610c32145a1d9b6ad0a4ed52b5c4dc7

To view the published data, point a browser at http://localhost:80/test.html.

To avoid copying Web site data into the Docker container, share a directory of the host with the container. For information, see https://docs.docker.com/storage/volumes/.