Skip to content

MkDocs com Docker e Live Reload automático

Documentação do setup de um servidor MkDocs rodando em Docker com atualização automática ao editar documentos via FileBrowser, sem necessidade de reiniciar o container ou acessar via SSH.


Visão geral

A solução utiliza uma imagem Docker customizada baseada no squidfunk/mkdocs-material, com um script de entrypoint que faz polling a cada 5 segundos nos arquivos .md e .yml. Quando uma mudança é detectada, o processo do MkDocs é reiniciado automaticamente.


Estrutura de diretórios

/home/ubuntu/
├── mkdocs/                        # Conteúdo da documentação
│   ├── docs/
│   │   ├── Automação/
│   │   ├── Fiocruz/
│   │   ├── Inteligência Artificial/
│   │   ├── Linux Desktop/
│   │   ├── Teste/
│   │   ├── assets/
│   │   │   ├── styles/
│   │   │   │   └── custom.css
│   │   │   └── javascripts/
│   │   │       └── custom.js
│   │   └── index.md
│   └── mkdocs.yml
│
└── mkdocs-build/                  # Arquivos para build da imagem
    ├── Dockerfile
    └── entrypoint.sh

Pré-requisitos

  • Docker instalado no servidor
  • FileBrowser ou acesso ao sistema de arquivos para editar os documentos
  • Porta 8005 disponível no servidor

Passo 1 — Criar a estrutura de diretórios

mkdir -p /home/ubuntu/mkdocs/docs/assets/styles
mkdir -p /home/ubuntu/mkdocs/docs/assets/javascripts
mkdir -p /home/ubuntu/mkdocs-build

Passo 2 — Criar o arquivo mkdocs.yml

Crie o arquivo /home/ubuntu/mkdocs/mkdocs.yml com o seguinte conteúdo:

site_name: Docs@RuiOgawa
theme:
  name: material
  features:
    - navigation.top
    - navigation.path
    - navigation.indexes
    - navigation.instant
    - content.code.copy
    - content.tabs.link
    - search.suggest
    - search.highlight
  palette:
    - scheme: default
      primary: indigo
      accent: indigo
      toggle:
        icon: material/weather-night
        name: Switch to dark mode
    - scheme: slate
      primary: indigo
      accent: indigo
      toggle:
        icon: material/weather-sunny
        name: Switch to light mode
plugins:
  - awesome-pages

extra_css:
  - assets/styles/custom.css
extra_javascript:
  - assets/javascripts/custom.js

Passo 3 — Criar o Dockerfile

Crie o arquivo /home/ubuntu/mkdocs-build/Dockerfile:

FROM squidfunk/mkdocs-material:latest

RUN pip install --no-cache-dir \
    mkdocs-awesome-pages-plugin \
    watchdog

WORKDIR /docs
EXPOSE 8000

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]

O que cada instrução faz

  • FROM squidfunk/mkdocs-material:latest — usa a imagem oficial do MkDocs Material como base
  • pip install — instala o plugin awesome-pages (navegação automática) e watchdog (monitoramento de arquivos)
  • WORKDIR /docs — define o diretório de trabalho como /docs, onde o volume será montado
  • COPY entrypoint.sh — copia o script de controle para dentro da imagem
  • ENTRYPOINT — usa o tini como init process e executa o entrypoint customizado

Passo 4 — Criar o entrypoint.sh

Crie o arquivo /home/ubuntu/mkdocs-build/entrypoint.sh:

#!/bin/sh

DOCS_DIR="/docs"

get_hash() {
    find "$DOCS_DIR" -type f \( -name "*.md" -o -name "*.yml" \) -print0 | \
    sort -z | \
    xargs -0 md5sum 2>/dev/null | md5sum
}

mkdocs serve --dev-addr=0.0.0.0:8000 &
MKDOCS_PID=$!
echo "MkDocs iniciado com PID $MKDOCS_PID"

LAST_HASH=$(get_hash)

while true; do
    sleep 5
    CURRENT_HASH=$(get_hash)

    if [ "$CURRENT_HASH" != "$LAST_HASH" ]; then
        echo "Mudança detectada! Reiniciando MkDocs..."
        kill $MKDOCS_PID 2>/dev/null
        wait $MKDOCS_PID 2>/dev/null
        sleep 1
        mkdocs serve --dev-addr=0.0.0.0:8000 &
        MKDOCS_PID=$!
        LAST_HASH=$(get_hash)
        echo "MkDocs reiniciado com PID $MKDOCS_PID"
    fi
done

Como o script funciona

  1. Define /docs como diretório monitorado
  2. A função get_hash percorre todos os arquivos .md e .yml recursivamente, gera um MD5 de cada um e combina tudo num hash único — usando -print0 e xargs -0 para lidar corretamente com nomes de arquivos com espaços e caracteres especiais
  3. Inicia o mkdocs serve em background e guarda o PID
  4. Entra em loop infinito verificando a cada 5 segundos se o hash mudou
  5. Se mudou: mata o processo anterior, aguarda encerramento, reinicia o MkDocs e atualiza o hash

Por que polling e não inotify?
O inotify (mecanismo padrão do Linux para watch de arquivos) não propaga eventos corretamente para dentro de containers Docker em bind mounts. O polling via md5sum é a solução mais compatível e confiável nesse cenário.


Passo 5 — Build da imagem

cd /home/ubuntu/mkdocs-build
docker build -t mkdocs-rui:latest .

A imagem será criada localmente com o nome mkdocs-rui:latest.


Passo 6 — Criar o docker-compose.yml

Crie o arquivo /home/ubuntu/mkdocs/docker-compose.yml:

version: '3.8'
services:
  mkdocs:
    image: mkdocs-rui:latest
    pull_policy: never
    container_name: mkdocs_documentation
    ports:
      - "8005:8000"
    volumes:
      - /home/ubuntu/mkdocs:/docs
    restart: unless-stopped

pull_policy: never é necessário porque a imagem mkdocs-rui é local e não está em nenhum registry público. Sem essa diretiva, o Docker tentará baixá-la e falhará.


Passo 7 — Subir o container

cd /home/ubuntu/mkdocs
docker compose up -d

Para recriar o container após um novo build da imagem:

docker compose up -d --force-recreate mkdocs

Verificando o funcionamento

Verificar se o container está rodando

docker ps | grep mkdocs

Acompanhar os logs em tempo real

docker logs -f mkdocs_documentation

Saída esperada ao iniciar:

MkDocs iniciado com PID 8
INFO    -  Building documentation...
INFO    -  Documentation built in 0.58 seconds
INFO    -  [23:06:23] Serving on http://0.0.0.0:8000/

Saída esperada ao editar um arquivo:

Mudança detectada! Reiniciando MkDocs...
MkDocs reiniciado com PID 94
INFO    -  Building documentation...
INFO    -  Documentation built in 0.60 seconds
INFO    -  [23:07:18] Serving on http://0.0.0.0:8000/

Acessar a documentação

http://<ip-do-servidor>:8005

Fluxo de atualização

Editar .md no FileBrowser
        ↓
  Salvar o arquivo
        ↓
  Script detecta mudança (em até 5 segundos)
        ↓
  MkDocs reinicia automaticamente
        ↓
  Documentação atualizada no browser

Rebuild da imagem (quando necessário)

Se precisar atualizar o Dockerfile ou o entrypoint.sh:

# 1. Editar os arquivos em /home/ubuntu/mkdocs-build/

# 2. Rebuildar a imagem
cd /home/ubuntu/mkdocs-build
docker build -t mkdocs-rui:latest .

# 3. Recriar o container
cd /home/ubuntu/mkdocs
docker compose up -d --force-recreate mkdocs

Referências