Step 2: Building a Docker Image

Objective: Build a Docker image that is a replica of the image on

Docker Hub.

We now have dldl/sphinx-server running using default configurations. Let’s rebuild the image using the instructions in Dockerfile. After a successful build, we can then change the build process to create a custom image.

4.2.1 The Docker Build Process


The overview of the Dockerfile Elements are in lab 5 and in the references section.

The Dockerfile contains the specific instructions to build the image. You can view the Dockerfile for this project on the dldl/sphinx-server GitHub page. The file is in our project directory because we cloned the project. You can view the contents using on the local VPS using nano Dockerfile.

Dockerfile Contents
FROM alpine:3.8

MAINTAINER Loïc Pauletto <>
MAINTAINER Quentin de Longraye <>

RUN apk add --no-cache --virtual --update py-pip make wget ca-certificates ttf-dejavu openjdk8-jre graphviz \
    && pip install --upgrade pip \
    && pip install livereload sphinx sphinx_rtd_theme sphinxcontrib-plantuml sphinx_autobuild

RUN wget -P /opt/ \
    && echo -e '#!/bin/sh -e\njava -jar /opt/plantuml.jar "$@"' > /usr/local/bin/plantuml \
    && chmod +x /usr/local/bin/plantuml

COPY ./ /opt/sphinx-server/
COPY ./.sphinx-server.yml /opt/sphinx-server/


EXPOSE 8000 35729

CMD ["python", "/opt/sphinx-server/"]

  1. First, we build the image without modifications to verify that the build process succeeds.

    We’ll use docker build to execute the build. Here is a look at the command and the arguments:

    docker build -t sphinx-server:default.
    docker build

    The build command

    -t sphinx-server:default

    Specifies an image name.

    • sphinx-server:default is a name:tag pair.

    • name defines the name of the project.

    • tag defines a specific build, such as a product or test version.

    • We will call ours default because it is the default image without any modifications.


    Instructs the build process to look in the current directory for the Dockerfile


    You might get a free(): invalid pointer error. If so, just ignore it.

    1. You will notice that there is a step for each command in the Dockerfile.

    root@vps298933:~# cd ~/sphinx-server/
    root@vps298933:~/sphinx-server# docker build -t sphinx-server:default .
    Sending build context to Docker daemon  10.17MB
    Step 1/10 : FROM alpine:3.8
    3.8: Pulling from library/alpine
    c87736221ed0: Pull complete
    Digest: sha256:a4d41fa0d6bb5b1194189bab4234b1f2abfabb4728bda295f5c53d89766aa046
    Status: Downloaded newer image for alpine:3.8
     ---> dac705114996
    Step 2/10 : MAINTAINER Loïc Pauletto <>
     ---> Running in b83c967dcc2a
    Removing intermediate container b83c967dcc2a
     ---> 1e949c0ec023
    Step 3/10 : MAINTAINER Quentin de Longraye <>
     ---> Running in e40abe3adb98
    Removing intermediate container e40abe3adb98
     ---> f8b9af6599dc
    Step 4/10 : RUN apk add --no-cache --virtual --update py-pip make wget ca-certificates ttf-dejavu openjdk8-jre graphviz     && pip install --upgrade pip     && pip install livereload sphinx sphinx_rtd_theme sphinxcontrib-plantuml sphinx_autobuild
     ---> Running in b9a7bc68df0c
    (1/69) Installing libbz2 (1.0.6-r6)
    (2/69) Installing expat (2.2.5-r0)
    . . .
    (67/69) Installing pango (1.40.14-r1)
    (68/69) Installing graphviz (2.40.1-r1)
    (69/69) Installing --update (0)
    Executing busybox-1.28.4-r3.trigger
    Executing ca-certificates-20171114-r3.trigger
    Executing fontconfig-2.12.6-r1.trigger
    Executing mkfontscale-1.1.3-r0.trigger
    Executing mkfontdir-1.0.7-r1.trigger
    Executing java-common-0.1-r0.trigger
    Executing glib-2.56.1-r0.trigger
    Executing graphviz-2.40.1-r1.trigger
    OK: 171 MiB in 82 packages
    Collecting pip
      Downloading (1.4MB)
    Installing collected packages: pip
      Found existing installation: pip 10.0.1
        Uninstalling pip-10.0.1:
          Successfully uninstalled pip-10.0.1
    Successfully installed pip-19.0.3
    DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
    Collecting livereload
    Collecting sphinx
      Downloading (3.1MB)
    Collecting sphinx_rtd_theme
      Downloading (6.4MB)
      . . .
    Collecting certifi>=2017.4.17 (from requests>=2.0.0->sphinx)
      Downloading (158kB)
    Collecting urllib3<1.25,>=1.21.1 (from requests>=2.0.0->sphinx)
      Downloading (118kB)
    Installing collected packages: futures, six, singledispatch, backports-abc, tornado, livereload, snowballstemmer, alabaster, MarkupSafe, Jinja2, imagesize, pytz, babel, Pygments, pyparsing, packaging, docutils, chardet, idna, certifi, urllib3, requests, typing, sphinxcontrib-websupport, sphinx, sphinx-rtd-theme, sphinxcontrib-plantuml, pathtools, argh, PyYAML, watchdog, port-for, sphinx-autobuild
      Running install for tornado: started
        Running install for tornado: finished with status 'done'
      Running install for MarkupSafe: started
        Running install for MarkupSafe: finished with status 'done'
      Running install for sphinxcontrib-plantuml: started
        Running install for sphinxcontrib-plantuml: finished with status 'done'
      Running install for pathtools: started
        Running install for pathtools: finished with status 'done'
      Running install for PyYAML: started
        Running install for PyYAML: finished with status 'done'
      Running install for watchdog: started
        Running install for watchdog: finished with status 'done'
      Running install for port-for: started
        Running install for port-for: finished with status 'done'
    Successfully installed Jinja2-2.10 MarkupSafe-1.1.1 PyYAML-5.1 Pygments-2.3.1 alabaster-0.7.12 argh-0.26.2 babel-2.6.0 backports-abc-0.5 certifi-2019.3.9 chardet-3.0.4 docutils-0.14 futures-3.2.0 idna-2.8 imagesize-1.1.0 livereload-2.6.0 packaging-19.0 pathtools-0.1.2 port-for-0.3.1 pyparsing-2.3.1 pytz-2018.9 requests-2.21.0 singledispatch- six-1.12.0 snowballstemmer-1.2.1 sphinx-1.8.5 sphinx-autobuild-0.7.1 sphinx-rtd-theme-0.4.3 sphinxcontrib-plantuml-0.14 sphinxcontrib-websupport-1.1.0 tornado-5.1.1 typing-3.6.6 urllib3-1.24.1 watchdog-0.9.0
    Removing intermediate container b9a7bc68df0c
     ---> 5846bd12f3ff
    Step 5/10 : RUN wget -P /opt/     && echo -e '#!/bin/sh -e\njava -jar /opt/plantuml.jar "$@"' > /usr/local/bin/plantuml     && chmod +x /usr/local/bin/plantuml
     ---> Running in ee081501ff4e
    --2019-04-06 04:54:00--
    Connecting to||:80... connected.
    HTTP request sent, awaiting response... 302 Found
    Location: [following]
    --2019-04-06 04:54:01--
    Connecting to||:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 7483276 (7.1M) [application/java-archive]
    Saving to: '/opt/plantuml.jar'
         0K .......... .......... .......... .......... ..........  0% 1.43M 5s
        . . .
      7200K .......... .......... .......... .......... .......... 99%  146M 0s
      7250K .......... .......... .......... .......... .......... 99%  207K 0s
      7300K .......                                               100% 73.9M=0.9s
    2019-04-06 04:54:02 (7.87 MB/s) - '/opt/plantuml.jar' saved [7483276/7483276]
    Removing intermediate container ee081501ff4e
     ---> b20a44ba46ab
    Step 6/10 : COPY ./ /opt/sphinx-server/
     ---> bbbc4c08b4b9
    Step 7/10 : COPY ./.sphinx-server.yml /opt/sphinx-server/
     ---> 6f4bb329bdea
    Step 8/10 : WORKDIR /web
     ---> Running in 2619731752f3
    Removing intermediate container 2619731752f3
     ---> 888b1a5d26de
    Step 9/10 : EXPOSE 8000 35729
     ---> Running in f782b9bbc9d8
    Removing intermediate container f782b9bbc9d8
     ---> b2adabbf8f6d
    Step 10/10 : CMD ["python", "/opt/sphinx-server/"]
     ---> Running in 9f8ec02b53e1
    Removing intermediate container 9f8ec02b53e1
     ---> 4d46973def97
    Successfully built 4d46973def97
    Successfully tagged sphinx-server:
  2. We should verify that image build successfully.

  1. Use command docker images to view the list of images on the VPS

  2. You should see an image called sphinx-server with tag default

  3. The sphinx-server image was built from a base image called alpine:3.8 in step 1

    • Step 1/10 : FROM alpine:3.8

root@vps298933:~/sphinx-server# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
sphinx-server        default             4d46973def97        22 minutes ago      265MB
wallabag             local               0de0a1565dd9        8 days ago          454MB
wordpress            latest              0a1f8ac5c829        9 days ago          421MB
redis                latest              a55fbf438dfd        10 days ago         95MB
dldl/sphinx-server   latest              94ad212bd087        13 days ago         275MB
nextcloud            latest              ace08abb9937        3 weeks ago         598MB
mariadb              latest              e93652b8b80d        3 weeks ago         368MB
alpine               3.8                 dac705114996        4 weeks ago         4.41MB
alpine               3.9                 5cb3aa00f899        4 weeks ago         5.53MB
alpine               latest              5cb3aa00f899        4 weeks ago         5.53MB
mysql                5.7                 ee7cbd482336        4 weeks ago         372MB
hello-world          latest              fce289e99eb9        3 months ago        1.84kB

4.2.2 Rebuild Sphinx using the local image

We should verify that our new image functions correctly before we modify the Dockerfile to build a custom image.


Removing the base image and container becomes seamless because we have already configured the Sphinx project! We can replace the containers without losing any data.

  1. Before we can test our new image, we should stop and remove the previous container.

    • Here is a one-line command to run:

    docker stop sphinx-server && docker rm sphinx-server
  2. Replace the last argument of docker run with the image that we just built and then start the container

    • Replace dldl/sphinx-server with sphinx-server:default

    docker run -itd -v "$(pwd)":/web -u $(id -u):$(id -g) -p 20852:8000 --name sphinx-server sphinx-server:default
    docker ps
    curl --head localhost:20852
      root@vps298933:~/sphinx-server# docker stop sphinx-server && docker rm sphinx-server
      root@vps298933:~/sphinx-server# docker run -itd -v "$(pwd)":/web -u $(id -u):$(id -g) -p 20852:8000 --name sphinx-server sphinx-server:default
      root@vps298933:~/sphinx-server# docker ps
      CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                         NAMES
      e254082e348f        sphinx-server:default   "python /opt/sphinx-…"   9 seconds ago       Up 8 seconds        35729/tcp,>8000/tcp            sphinx-server
      76cbf38e5975        nextcloud               "/ apac…"   6 days ago          Up 18 hours>80/tcp                         nextclouddocker_app_1
      2906aaa944f5        mariadb                 "docker-entrypoint.s…"   6 days ago          Up 18 hours         3306/tcp                                      nextclouddocker_db_1
      8f5b05b6c627        redis                   "docker-entrypoint.s…"   6 days ago          Up 18 hours         6379/tcp                                      nextclouddocker_redis_1
      c60b6e70e4a9        wordpress:latest        "docker-entrypoint.s…"   6 days ago          Up 18 hours>80/tcp                         wordpressdocker_wordpress_1
      386e4587b991        mariadb                 "docker-entrypoint.s…"   6 days ago          Up 18 hours         3306/tcp                                      wordpressdocker_db_1
      913ff74dd94c        redis                   "docker-entrypoint.s…"   6 days ago          Up 18 hours         6379/tcp                                      wordpressdocker_redis_1
      root@vps298933:~/sphinx-server# curl --head localhost:20852
      HTTP/1.1 200 OK
      Content-Length: 5134
      Accept-Ranges: bytes
      Server: TornadoServer/5.1.1
      Last-Modified: Sat, 06 Apr 2019 05:42:16 GMT
      Etag: "20777b5402b45aaffaf026c88b89eafa"
      Date: Sat, 06 Apr 2019 05:42:48 GMT
      Content-Type: text/html
  3. Verify that you can access the page through the URL