[Part 1] Creating a Docker container that delivers Markdown in HTML with Apache / Pandoc

Introduction

I created a Docker container that incorporates Apache and Pandoc, so I will share my experience.

You can use Pandoc to convert Markdown to HTML or PDF. You can dynamically convert Markdown to HTML by embedding it in Apache. Putting the website created in this way in a Docker container makes it easier to build and distribute. For example, you can expand the range of use by registering with the container service of Amazon AWS.

The Docker file and other sources are on github, and the created Docker image is published on Docker Hub (see the end).

Pandoc

To convert Markdown to HTML using a Pandoc converter on your local PC (eg using Windows WSL):

$ ls
 test.md
$ cat test.md
 # test.md
 Hello **Wonderful** World.
$ pandoc test.md > test.html
$ ls
 test.md
 test.html
$ cat test.html
 <h1 id="test.md">test.md</h1>
 <p>Hello <strong>Wonderful</strong> World.</p>
$

Apache

If you enable Pandoc to be executed when the Markdown file extension md is referenced in Apache, automatic conversion to HTML can be realized. It's easy to use Apache's external filter mechanism. If you set the following in Apache, the specified filter will be executed when the Markdown file is referenced. Here it is named pandoc-filter.

[local.conf]

LoadModule ext_filter_module modules/mod_ext_filter.so

ExtFilterDefine pandoc-filter \
        mode=output intype=text/markdown outtype=text/html \
        cmd="/usr/local/apache2/pandoc-filter"

<Directory /usr/local/apache2/htdocs>
        SetOutputFilter pandoc-filter
        AddType text/markdown .md
</Directory>

I will explain.

--Load ext_filter_module to make external filters available with LoadModule. --Specify the MIME type and command path that the filter targets with ExtFilterDefine. --The setting in Directory is to have the filter executed when a file with the extension md is referenced in the specified directory.

Apache filter

I have created an Apache filter that calls Pandoc. A Bash shell script that calls Pandoc on the Markdown source passed on standard input and outputs the converted HTML to standard output.

[pandoc-filter]

 #!/bin/bash
 BASENAME=$(basename -s .md $DOCUMENT_URI)
 /usr/bin/pandoc -f gfm -t html5 -c "/pandoc-gfm.css" \
	-T "Converted" -M title=${BASENAME}

Supplement.

--The path of the referenced Markdown file is passed in the DOCUMENT_URI environment variable. For example, "/test.md". Take the title to pass to Pandoc from here. -- -f is the conversion source format, -t is the conversion destination format, -c is the stylesheet location, Specify the HTML title to be output with -T and-M title =. --Pandoc reads from standard input and outputs to standard output if nothing is specified.

Docker creation

Create a Docker container that incorporates the above Apache config file and filter script.

$ ls
 Dockerfile
 usr-local-apache2/
$ ls usr-local-apache2
 local.conf
 pandoc-filter
$ cat Dockerfile
 FROM httpd:2.4
 RUN apt-get update && apt-get install -y pandoc
 COPY ./usr-local-apache2 /usr/local/apache2/
 RUN echo 'Include local.conf' >> /usr/local/apache2/conf/httpd.conf
$ docker build -t pandoc:test .

I will explain in order.

--When creating a Docker container, create a Dockerfile that describes the build procedure. --Specify the original Docker image with FROM. Get the image httpd with Linux and Apache from the official Docker hub. --Install Pandoc with RUN. --Copy the Apache configuration file and filter prepared earlier with COPY to the container. The copy destination is under / usr / local / apachce. --Added the specification to include the configuration file with the RUN command that follows to the end of the main Apache configuration file. --Execute the Docker build command.

Docker container execution

Once you have a Docker container, try running it on the created host.

$ docker run --detach -publish 8080:80 \
	--mount type=bind,src=/var/docker/pandoc/htdocs,dst=/usr/local/apache2/htdocs,ro \
	pandoc:test

I will explain in order.

----detach is a specification to run the container in the background (as a daemon). --Connect the port of the host machine and the port used in the container so that it can be accessed from the outside with --publish. ---- mount binds / usr / local / apache2 / htdocs in the document directory inside the container to the directory on the host side. Otherwise you will have to add files to the container each time.

test

First from within the host machine running the container:

$ curl localhost:8080/test.md

Then access it with a browser from outside the host machine.

http://example.com:8080/test.md

usage environment

Reference link

The source of Dockerfile, Apache configuration file, and Apache filter is published on github. You can create a container by git clone and docker build.

You can also get the created image from Docker Hub.

Related page of Yokohama Kobunsha

-Markdown conversion Docker -Markdown Dynamic Conversion -Markdown commentary

Written 2020/09/21

Recommended Posts

[Part 1] Creating a Docker container that delivers Markdown in HTML with Apache / Pandoc
[Part 2] Creating a Docker container that delivers Markdown as HTML in Apache / Pandoc-remote version
[Part 1] Creating a Docker container that delivers Markdown in HTML with Apache / Pandoc
[Part 2] Creating a Docker container that delivers Markdown as HTML in Apache / Pandoc-remote version
Creating a lightweight Java environment that runs on Docker
Starting with installing Docker on EC2 and running Yellowfin in a container
Creating a java web application development environment with docker for mac part1
Creating a matrix class in Java Part 1
How to start a Docker container with a volume mounted in a batch file
A story that got stuck with an error during migration in docker PHP laravel
[Note] Build a Python3 environment with Docker in EC2
Creating a lightweight Java environment that runs on Docker
Run PHP-FPM with OPcache enabled in a Read Only container
[Docker] Delete only the volume associated with a specific container
Build a container that automatically formats Docker x Laravel code
I can no longer connect to a VM with a Docker container that can be connected via SSH
Let's create a Docker container that can connect to CentOS 8 with the minimum configuration by SSH