Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

docs(mdbook-htmx): Docker Compose Local Development

Aperta
#40 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@aRustyDev ci sta già lavorando.

Dal 5/1/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

documentation

Docker Compose Local Development

Run mdbook-htmx locally with Docker Compose for development and testing.

Implementation

The Docker Compose configuration lives in the mdbook-htmx repository:

mdbook-htmx/docker/
├── compose.yml         # Base configuration
├── compose.auth.yml    # +OAuth2 proxy (Phase 3)
├── compose.search.yml  # +Meilisearch (Phase 4)
├── compose.prod.yml    # +Caching, metrics (Phase 5)
├── nginx.conf          # NGINX with HTMX routing
├── Dockerfile.build    # Multi-stage build image
└── .env.example        # Environment template

See ADR-0016 for phase-by-phase additions.

Overview

This setup includes:

  • NGINX: Serving documentation with HTMX fragment routing
  • Meilisearch: Full-text search (optional, Phase 4+)
  • OAuth2 Proxy: Authentication (optional, Phase 3+)
  • Live reload: Watch for changes

Basic Setup

docker-compose.yml
version: "3.8"

services:
  docs:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./book:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost/healthz"]
      interval: 10s
      timeout: 5s
      retries: 3

  # Live rebuild (optional)
  builder:
    image: rust:latest
    volumes:
      - .:/docs
      - cargo-cache:/usr/local/cargo/registry
    working_dir: /docs
    command: >
      bash -c "
        cargo install mdbook mdbook-htmx &&
        mdbook watch --open
      "
    profiles:
      - dev

volumes:
  cargo-cache:
nginx.conf
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    sendfile on;
    keepalive_timeout 65;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    server {
        listen 80;
        root /usr/share/nginx/html;
        index index.html;

        # HTMX requests
        location / {
            try_files $uri $uri/ /index.html;

            # CORS for local development
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
            add_header Access-Control-Allow-Headers "Content-Type, HX-Request";
        }

        # Health check
        location /healthz {
            return 200 "OK\n";
            add_header Content-Type text/plain;
        }
    }
}

With Meilisearch

docker-compose.yml
version: "3.8"

services:
  docs:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./book:/usr/share/nginx/html:ro
      - ./nginx-with-search.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      meilisearch:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost/healthz"]
      interval: 10s
      timeout: 5s
      retries: 3

  meilisearch:
    image: getmeili/meilisearch:v1.6
    ports:
      - "7700:7700"
    environment:
      MEILI_ENV: development
      MEILI_MASTER_KEY: devkey123
      MEILI_NO_ANALYTICS: "true"
    volumes:
      - meili-data:/meili_data
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:7700/health"]
      interval: 10s
      timeout: 5s
      retries: 3

  # Index documentation on startup
  indexer:
    image: python:3.11-slim
    volumes:
      - ./book:/docs:ro
      - ./scripts:/scripts:ro
    environment:
      MEILI_HOST: http://meilisearch:7700
      MEILI_MASTER_KEY: devkey123
    command: >
      bash -c "
        pip install meilisearch &&
        python /scripts/index.py
      "
    depends_on:
      meilisearch:
        condition: service_healthy
    profiles:
      - index

volumes:
  meili-data:
nginx-with-search.conf
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    upstream meilisearch {
        server meilisearch:7700;
    }

    server {
        listen 80;
        root /usr/share/nginx/html;
        index index.html;

        # Static files
        location / {
            try_files $uri $uri/ /index.html;
        }

        # Proxy search to Meilisearch
        location /search {
            proxy_pass http://meilisearch/indexes/docs/search;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Authorization "Bearer devkey123";

            # CORS
            add_header Access-Control-Allow-Origin * always;
            add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
            add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;

            if ($request_method = OPTIONS) {
                return 204;
            }
        }

        location /healthz {
            return 200 "OK\n";
        }
    }
}
scripts/index.py
#!/usr/bin/env python3
"""Index documentation to Meilisearch."""
import json
import os
import hashlib
from pathlib import Path
import meilisearch
import time

MEILI_HOST = os.environ.get('MEILI_HOST', 'http://localhost:7700')
MEILI_KEY = os.environ.get('MEILI_MASTER_KEY', 'devkey123')
DOCS_PATH = os.environ.get('DOCS_PATH', '/docs')

def main():
    # Wait for Meilisearch
    client = meilisearch.Client(MEILI_HOST, MEILI_KEY)
    for _ in range(30):
        try:
            client.health()
            break
        except:
            time.sleep(1)
    else:
        raise Exception("Meilisearch not ready")

    # Load search index
    search_index = Path(DOCS_PATH) / 'search-index.json'
    if not search_index.exists():
        print("No search-index.json found, skipping indexing")
        return

    with open(search_index) as f:
        data = json.load(f)

    # Transform documents
    documents = []
    for page in data.get('pages', []):
        documents.append({
            'id': hashlib.md5(page['path'].encode()).hexdigest(),
            'path': page['path'],
            'title': page['title'],
            'content': page.get('content', ''),
            'headings': page.get('headings', []),
        })

    # Create/update index
    index = client.index('docs')
    index.update_settings({
        'searchableAttributes': ['title', 'headings', 'content'],
        'displayedAttributes': ['path', 'title', 'headings'],
    })

    task = index.add_documents(documents)
    client.wait_for_task(task.task_uid)
    print(f"Indexed {len(documents)} documents")

if __name__ == '__main__':
    main()

With Live Reload

docker-compose.yml
version: "3.8"

services:
  docs:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./book:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

  # Watch and rebuild
  watcher:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/docs
      - cargo-cache:/usr/local/cargo/registry
    working_dir: /docs
    command: mdbook watch
    environment:
      RUST_LOG: info

  # Browser sync (optional)
  browsersync:
    image: ustwo/browser-sync
    ports:
      - "3000:3000"
      - "3001:3001"
    command: start --proxy "docs:80" --files "book/**/*"
    depends_on:
      - docs

volumes:
  cargo-cache:
Dockerfile.dev
FROM rust:latest

# Install mdbook and plugins
RUN cargo install mdbook mdbook-htmx

# Install watchexec for better file watching
RUN cargo install watchexec-cli

WORKDIR /docs

With Authentication (OAuth2 Proxy)

docker-compose.yml
version: "3.8"

services:
  docs:
    image: nginx:alpine
    volumes:
      - ./book:/usr/share/nginx/html:ro
      - ./nginx-auth.conf:/etc/nginx/nginx.conf:ro

  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1
    ports:
      - "4180:4180"
    environment:
      OAUTH2_PROXY_PROVIDER: github
      OAUTH2_PROXY_CLIENT_ID: ${GITHUB_CLIENT_ID}
      OAUTH2_PROXY_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET}
      OAUTH2_PROXY_COOKIE_SECRET: ${COOKIE_SECRET}
      OAUTH2_PROXY_EMAIL_DOMAINS: "*"
      OAUTH2_PROXY_UPSTREAMS: http://docs:80
      OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180
      OAUTH2_PROXY_REDIRECT_URL: http://localhost:4180/oauth2/callback
.env
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
COOKIE_SECRET=$(openssl rand -base64 32 | head -c 32)

Make Commands

Makefile
.PHONY: build serve dev clean index

# Build documentation
build:
	mdbook build

# Start docs server
serve:
	docker-compose up -d docs
	@echo "Docs available at http://localhost:8080"

# Development mode with live reload
dev:
	docker-compose up docs watcher browsersync

# Start with search
search:
	docker-compose up -d docs meilisearch
	docker-compose run --rm indexer

# Rebuild search index
index:
	docker-compose run --rm indexer

# Stop all services
stop:
	docker-compose down

# Clean up
clean:
	docker-compose down -v
	rm -rf book/

# View logs
logs:
	docker-compose logs -f

# Shell into docs container
shell:
	docker-compose exec docs sh

Environment Variables

.env.example
# Meilisearch
MEILI_MASTER_KEY=devkey123

# OAuth (for authenticated docs)
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
COOKIE_SECRET=

# Build options
MDBOOK_BUILD=release

Usage

# Start basic docs server
docker-compose up -d

# Build and serve with search
make search

# Development with live reload
make dev

# View logs
docker-compose logs -f docs

# Stop all
docker-compose down

Port Reference

Service Port Description
docs (nginx) 8080 Documentation server
meilisearch 7700 Search API
browsersync 3000 Live reload proxy
browsersync 3001 BrowserSync UI
oauth2-proxy 4180 Auth proxy

Troubleshooting

Container won't start
# Check logs
docker-compose logs docs

# Verify volumes
docker-compose config

# Rebuild
docker-compose build --no-cache
Search not working
# Check Meilisearch health
curl http://localhost:7700/health

# Check index
curl http://localhost:7700/indexes/docs -H "Authorization: Bearer devkey123"

# Re-index
docker-compose run --rm indexer
Permission issues
# Fix permissions on macOS/Linux
chmod -R 755 book/

Next Steps

Lingua principale
Rust
Stelle
0
Fork
1
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di aRustyDev/mdbook-htmx

Tutte le issue di aRustyDev/mdbook-htmx

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.