Step 3: Modifying a Docker Image

Objective: Modify a Dockerfile to extend it or add additional

functionality, which allows us to build a custom image.

We are now running a Docker container from the image that we built. Let’s modify the image!

  • The base image is out of date. The current release of Alpine Linux release 3.9.

    • Exposing the port allows Docker to add the rule to the firewall.

    • The proxy_pass setting in the Nginx site will not work if the firewall is set for conditional FORWARD rules unless we define it in the image.

  • The original author included some plugins, but we can add some additional ones.

  • The default 404 page is not user-friendly, as some of you have found out.

4.3.1 Update Dockerfile

  1. Edit Dockerfile.

    • Change the version from alpine:3.8 to alpine:3.9.

    • Add sphinx-notfound-page to the end of the list on line 8.

    Dockerfile Contents
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     FROM alpine:3.9
    
     MAINTAINER Loïc Pauletto <loic.pauletto@gmail.com>
     MAINTAINER Quentin de Longraye <quentin@dldl.fr>
    
     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 sphinx-notfound-page
    
     RUN wget http://downloads.sourceforge.net/project/plantuml/plantuml.jar -P /opt/ \
         && echo -e '#!/bin/sh -e\njava -jar /opt/plantuml.jar "$@"' > /usr/local/bin/plantuml \
         && chmod +x /usr/local/bin/plantuml
    
     COPY ./server.py /opt/sphinx-server/
     COPY ./.sphinx-server.yml /opt/sphinx-server/
    
     WORKDIR /web
    
     EXPOSE 8000 35729
    
     CMD ["python", "/opt/sphinx-server/server.py"]
    
  2. We will now build the image with our modifications.

    1. Let’s tag it as version 0.1

      docker build -t sphinx-server:0.1 .
      docker images
      
      Expected Output
      . . .
      Removing intermediate container 0f722b985f00
       ---> 62256b6c7b1d
      Successfully built 62256b6c7b1d
      Successfully tagged sphinx-server:0.1
      root@vps298933:~/sphinx-server#
      
    2. Our Dockerfile might contain an error, which causes the build process to stop.

    3. If so, correct the error, remove any image tagged with <none>, and then rebuild.

  3. Remove the running container, restart using our custom image, then verify the site works.

    docker stop sphinx-server && docker rm sphinx-server
    docker run -itd -v "$(pwd)":/web -u $(id -u):$(id -g) -p 20852:8000 --name sphinx-server sphinx-server:0.1
    
  4. Verify that our container is running the new image.

    • Open up a shell to the container so we can look at the version of Alpine.

      docker exec -it sphinx-server /bin/sh
      cat /etc/*-release
      exit
      
    Output
    root@vps298933:~/sphinx-server# docker exec -it sphinx-server /bin/sh
    /web # cat /etc/*-release
    3.9.2
    NAME="Alpine Linux"
    ID=alpine
    VERSION_ID=3.9.2
    PRETTY_NAME="Alpine Linux v3.9"
    HOME_URL="https://alpinelinux.org/"
    BUG_REPORT_URL="https://bugs.alpinelinux.org/"
    /web # exit
    root@vps298933:~/sphinx-server#
    

4.3.2 Enabling the Extension

The extensions are listed in the conf.py file in Sphinx.

  1. Edit conf.py

  2. Verify the configuration instructions from sphinx-notfound-page GitHub page

  3. Add 'notfound.extension', to the extensions section

    extensions = [
        'sphinx.ext.autodoc',
        'notfound.extension',
    ]
    
  4. We can verify that the extension is working by visiting page 404.html on our docs site.

    • The document indicates that this 404.html page should show for any 404 error. We need to modify our Nginx conf file.

  5. The plugin defaults to a language setting and version. It assumes that a user has those settings enabled. We are not using those settings, but we can try to fake out the system.

    ../../_images/sphinx-404-page-broke.png

    ‘Not found page’ with broken styling and linking

    ../../_images/sphinx-404-page-working.png

    ‘Not found page’ after the settings hack

    Note

    This method is a hack. Don’t rely it on it too much.

    1. sphinx-notfound-page GitHub page provides some configurations.

    2. Edit conf.py and add the configurations after the extensions block.

    3. Put your domain name in the notfound_default_version configuration setting.

      extensions = [
          'sphinx.ext.autodoc',
          'notfound.extension',
      ]
      
      notfound_default_language = ''
      notfound_default_version = 'docs.domain.com'
      
    4. Now, the styling and linking should work well enough for the user to click on the home page link, which is the goal.

  6. We still have the problem that the default 404 page displays the a blank page with text 404: Not Found.

    Unfortunately, we will not solve the problem of redirecting any 404 error to page 404.html during this lab.

4.3.3 Optional Tasks

Create a docker-compose.yml file

docker run

We have been using this docker run command to start the Sphinx container. It is not complicated, but it is not as convenient as using docker-compose.

docker run -itd -v "$(pwd)":/web -u $(id -u):$(id -g) -p 20852:8000 --name sphinx-server sphinx-server:0.1

docker compose

Here is the equivalent docker-compose.yml file. Notice that it includes the option for restart: always.

Note

Commands $(id -u) and $(id -g) returns the user ID and group of the logged in user.

  1. Verify your ID and group using this command: echo $(id -u):$(id -g)

  2. Substitute your user ID and group number in docker-compose.yml

docker-compose.yml
version: "3.3"

services:
  sphinx:
    image: sphinx-server:0.1
    volumes:
      - ./:/web
    user: 0:0
    restart: always
    ports:
      - 20852:8000

Starting the container using docker-compose up -d will start a new container called sphinxserver_sphinx_1.

root@vps298933:~# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                           NAMES
f15473c63505        sphinx-server:0.1     "python /opt/sphinx-…"   36 minutes ago      Up 35 minutes       20852/tcp, 35729/tcp, 0.0.0.0:20852->8000/tcp   sphinxserver_sphinx_1
76cbf38e5975        nextcloud             "/entrypoint.sh apac…"   7 days ago          Up 43 hours         0.0.0.0:20850->80/tcp                           nextclouddocker_app_1
2906aaa944f5        mariadb               "docker-entrypoint.s…"   7 days ago          Up 43 hours         3306/tcp                                        nextclouddocker_db_1
8f5b05b6c627        redis                 "docker-entrypoint.s…"   7 days ago          Up 43 hours         6379/tcp                                        nextclouddocker_redis_1
c60b6e70e4a9        wordpress:latest      "docker-entrypoint.s…"   7 days ago          Up 43 hours         0.0.0.0:20851->80/tcp                           wordpressdocker_wordpress_1
386e4587b991        mariadb               "docker-entrypoint.s…"   7 days ago          Up 43 hours         3306/tcp                                        wordpressdocker_db_1
913ff74dd94c        redis                 "docker-entrypoint.s…"   7 days ago          Up 43 hours         6379/tcp                                        wordpressdocker_redis_1
root@vps298933:~#

Add Additional Plugins

Sphinx has plugins that can build diagrams. Check them out! You can add a page for diagrams in the next part.

  1. Add these lines to Dockerfile

    # Add the requirements to install the diagram extensions, then install using pip
    RUN apk add --no-cache build-base python-dev py-pip jpeg-dev zlib-dev \
    && pip install sphinxcontrib-actdiag sphinxcontrib-blockdiag sphinxcontrib-nwdiag sphinxcontrib-seqdiag
    
  2. Build a new image

    docker build -t sphinx-server:0.2 .
    
  3. Start the container using image version 0.2

  4. Enable the extensions in conf.py

    'sphinxcontrib.actdiag'
    'sphinxcontrib.blockdiag'
    'sphinxcontrib.nwdiag'
    'sphinxcontrib.seqdiag'
    
  5. Run make html in the container to verify the extensions enabled correctly

  • You can run that command using docker exec.

  • Look at the previous step for the args

Diagram Example

Activity Diagram


Block Diagram


Network-related Diagram


Sequence Diagram


Video Walkthrough

Watch on asciinema.org if the video will not load.