For an internal presentation “Text-based tools, not just for nerds” (presentation is mostly in Dutch) I wanted to demo MkDocs with the material theme.
The creator of the mkdocs-material theme already created the Docker image as an alternative way to try the theme.
For the demo I wanted to run it with a minimal configuration. No errors, no extra’s and for that I created a bash script.
Quick Setup or TL;DR version
- Download/copy and create the script ‘setup.sh’
- Make it executable:
chmod +x setup.sh
- Run the setup script:
./setup.sh
- Run the just created start script:
./start
- Open a browser and go to: ‘localhost:8001’
Create new content:
- Add a new ‘.md’ file and add it to the ‘nav’ section in ‘mkdocs.yml’
It will automagically show up in the browser in the left sidebar.
A running Docker environment is a requirement.
setup.sh
#!/usr/bin/env bash
# Create docs directory
if [ ! -e docs ]; then
mkdir docs
fi
# Create images directory
if [ ! -e docs/images ]; then
mkdir docs/images
fi
# Create site directory
if [ ! -e site ]; then
mkdir site
fi
# Create the first document
if [ ! -e docs/index.md ]; then
printf "# Hello material world!\n" >> docs/index.md
fi
# Create mkdocs.yml
if [ ! -e mkdocs.yml ]; then
printf "site_name: '[site name here]'\nsite_url: http://localhost\nsite_dir: '/site'\n\nnav:\n - Home: index.md\n\ntheme:\n name: 'material'\n" >> mkdocs.yml
fi
# start file
printf \
"#!/usr/bin/env bash\n
EXPOSED_PORT=8001
echo 'Connect your browser to 127.0.0.1:'\${EXPOSED_PORT}\n
docker run --rm --name mkdocs-material -it -p \${EXPOSED_PORT}:8000 -v \${PWD}:/docs -v \${PWD}/site:/site squidfunk/mkdocs-material" > start
chmod +x ./start
# build-file
printf "#!/usr/bin/env bash\n\ndocker exec -it mkdocs-material mkdocs build" > build
chmod +x ./build
What the script does
The script creates the following:
- ‘docs’ and ‘site’ directories, required
- ‘index.md’, the first content
- ‘mkdocs.yml’, minimal configuration file
- ‘start’, bash script that runs the container if the image is present otherwise it first downloads the Docker image (standard Docker behaviour)
- ‘build’, bash script that builds the site and copies it to the ‘site’ directory
Additionally the ‘start’ and ‘build’ scripts are made executable.
Start script
You can configure the Docker exposed port in the ‘start’ script. For my demo I used Reveal.js which runs by default on port 8000. By default the container uses port 8001, you can change it by changing the value of the ‘EXPOSED_PORT’ variable.
#!/usr/bin/env bash
EXPOSED_PORT=8001
echo 'Connect your browser to 127.0.0.1:'${EXPOSED_PORT}
docker run --rm --name mkdocs-material -it -p ${EXPOSED_PORT}:8000 -v ${PWD}:/docs -v ${PWD}/site:/site squidfunk/mkdocs-material
!!! warning “warning” Do not change the name of the container, the build script uses the name to find the running container.
Build script
The build script only works when the Docker container ‘mkdocs-material’ is running. The easiest way is to run it in a different terminal.
#!/usr/bin/env bash
docker exec -it mkdocs-material mkdocs build
MkDocs requirements
MkDocs expects:
- ‘docs’ directory with a file named ‘index.md’.
- ‘mkdocs.yml’ in the root of the ‘mkdocs’ directory
Required for the build step:
- ‘site’ directory at the same level as the “docs” directory.
.
docs
└── index.md
site
└── [for the build output]
mkdocs.yml
These minimal requirements are handled by the ‘setup.sh’ script.
Full configuration
The setup above is the bare minimum. No customized logo, a site_url that directs to the local machine, no markdown extensions etc. etc.
Examples of a full setup with the file structure and anonimized configuration files can be found below:
file structure
.
docs
└── index.md
└── [your .md content]
└── images
└── [your logo].png
└── [your logo]-192.png
└── [your logo]-512.png
site
└── [build output]
manifest.webmanifest
mkdocs.yml
mkdocs.yml
site_name: "[your site name]"
site_description: "[your site description]"
site_author: "[your name]"
copyright: "Copyright © 2019 [your name]"
site_url: http://[your site location]
# Location where the output HTML and other files are created,
# the path is local in the Docker container but redirected to the 'site' directory.
site_dir: "/site"
nav:
- Home: index.md
theme:
name: "material"
language: "en"
logo: "images/[your logo]"
feature:
tabs: false
palette:
primary: "indigo"
accent: "indigo"
font: true
# https://developers.google.com/web/fundamentals/web-app-manifest/
extra:
manifest: "manifest.webmanifest"
social:
- type: "github"
link: "https://github.com/[your GitHub account]"
- type: "twitter"
link: "https://twitter.com/[your Twitter handle]"
- type: "linkedin"
link: "https://www.linkedin.com/in/[your LinkedIn shortname]/"
# Extensions
markdown_extensions:
- admonition
- codehilite:
guess_lang: true
- toc:
permalink: true
- nl2br
- sane_lists
- footnotes
- pymdownx.betterem:
smart_enable: all
- pymdownx.details
- pymdownx.emoji:
emoji_generator: !!python/name:pymdownx.emoji.to_svg
- pymdownx.escapeall
- pymdownx.keys
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
manifest.webmanifest
{
"short_name": "[short name]",
"name": "[name]",
"icons": [
{
"src": "/images/[your logo]-192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/images/[your logo]-512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/",
"background_color": "#3367D6",
"display": "browser",
"scope": "/",
"theme_color": "#3367D6"
}
Kudos go to the MkDocs community and SquidFunk for the Material theme.