A complete development environment and build system for creating professional technical documentation with Typst, featuring automated diagram compilation, dual PDF/HTML output with dark mode support, and comprehensive Python API documentation generation.
💡 Quick Start: After installing requirements, run
.devcontainer/setup-user-conf.shto test all logins and validate your setup before opening the devcontainer!
You need one of the following:
-
Podman
-
Podman Desktop GUI application, or
-
Podman CLI command-line only
-
Ensure podman machine is initialized and running (macOS/Windows):
podman machine init podman machine start
-
On Linux, podman runs natively without a machine
-
-
Docker Desktop (alternative)
- Download Docker Desktop
- Ensure Docker Desktop is running before opening the devcontainer
- VS Code with Dev Containers extension
- Install VS Code: https://code.visualstudio.com/
- Install extension: Dev Containers
Before opening the devcontainer, your host machine (or remote server) must have:
The devcontainer image is pulled from GitHub Container Registry and requires authentication.
Create GitHub Personal Access Token:
- Go to GitHub Settings → Developer settings → Tokens (classic)
- Click "Generate new token (classic)"
- Name:
GHCR Dev Container Access - Select scope:
read:packages✅ (required) - Generate and copy the token immediately
Login to GHCR:
# Docker
echo "YOUR_TOKEN" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
# Podman
echo "YOUR_TOKEN" | podman login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdinVerify:
# Docker
docker pull ghcr.io/morepet/containers/dev/typst:1.3-dev
# Podman
podman pull ghcr.io/morepet/containers/dev/typst:1.3-devgit config --global user.name "Your Name"
git config --global user.email "your.email@example.com"For SSH/remote scenarios (if git not configured on remote server):
export GIT_USER_NAME="Your Name"
export GIT_USER_EMAIL="your.email@example.com"The setup expects: ~/.ssh/id_ed25519_github.pub
If you don't have this key:
# Generate new key
ssh-keygen -t ed25519 -C "your.email@example.com" -f ~/.ssh/id_ed25519_github
# Add to GitHub as "Signing key"
cat ~/.ssh/id_ed25519_github.pub
# Add at: https://github.com/settings/keysIf you have a different key name:
# Create symlink
ln -s ~/.ssh/your_key.pub ~/.ssh/id_ed25519_github.pubFor commit signature verification:
mkdir -p ~/.config/git
echo "your.email@example.com $(cat ~/.ssh/id_ed25519_github.pub)" > ~/.config/git/allowed-signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed-signersFor seamless GitHub integration:
# Install (see https://cli.github.com/)
# Then authenticate
gh auth login
# Verify
gh auth statusBefore attempting to open the devcontainer, run this script to test all logins and prerequisites:
.devcontainer/setup-user-conf.shThis script validates:
- ✅ GHCR authentication (Docker/Podman login to ghcr.io)
- ✅ Git configuration (user.name and user.email)
- ✅ SSH key setup (id_ed25519_github.pub)
- ✅ Allowed-signers file
- ✅ GitHub CLI authentication
The script will:
- Show exactly what's configured ✅ and what's missing ❌
- Provide step-by-step instructions to fix any issues
- Tell you if you're ready to open the devcontainer
Note: Docker and Podman commands are interchangeable in this guide.
Docker Desktop users:
- Launch Docker Desktop application
- Wait for it to fully start (Docker icon in system tray)
Podman users (macOS/Windows):
# Initialize podman machine (first time only)
podman machine init
# Start podman machine
podman machine start
# Verify it's running
podman machine listPodman on Linux:
No setup needed - podman runs natively without a machine.
.devcontainer/setup-user-conf.shThis validates:
- GHCR authentication (Docker/Podman → ghcr.io)
- GitHub CLI authentication
- Git configuration
- SSH keys and allowed-signers
You'll get a full report showing:
- ✅ What's correctly configured
- ❌ What's missing (with instructions to fix)
⚠️ Optional items that can be configured later
Only proceed to step 3 if the script shows all required items are configured!
Important: Complete Host Machine Prerequisites first!
- Clone this repository
- Open the folder in VS Code
- When prompted, click "Reopen in Container"
- Or use Command Palette: "Dev Containers: Reopen in Container"
- Container will pull and initialize (first time: 2-3 minutes)
- Watch initialization output for:
- ✅ Container image pulled successfully
- ✅ Git configuration valid
- ✅ SSH key copied
- ✅ GitHub CLI authenticated
If container fails to pull: You're not authenticated to ghcr.io (see prerequisites step 1)
Once inside the devcontainer:
# Build the default project (docs/)
make
# Or build the example project
make exampleOpen your browser to http://localhost:8000 to see:
- PDF version:
build/technical-documentation.pdf - HTML version:
build/technical-documentation.html
That's it! The build system handles everything automatically.
If you prefer to use Podman directly instead of VS Code's built-in devcontainer support, you have three options. All options assume you've completed the Host Machine Prerequisites (especially GHCR authentication).
Use Podman command-line directly for maximum control and minimal dependencies.
Start the container:
# Linux (with SELinux context)
podman run -it --rm \
-v "${PWD}:/workspace:Z" \
-w /workspace \
ghcr.io/morepet/containers/dev/typst:1.3-dev \
/bin/bash
# macOS/Windows (no SELinux)
podman run -it --rm \
-v "${PWD}:/workspace" \
-w /workspace \
ghcr.io/morepet/containers/dev/typst:1.3-dev \
/bin/bashImportant: SELinux Context (Linux only)
The :Z flag is required on Linux systems with SELinux to allow the container to access the mounted volume. Without it, you'll get permission denied errors.
:Z- Private unshared label (recommended for single container access):z- Shared label (use if multiple containers need access)
Inside the container, run initialization scripts in order:
# 1. Post-create (one-time setup)
/workspace/.devcontainer/post-create.sh
# 2. Post-attach (session setup)
/workspace/.devcontainer/post-attach.sh
# 3. Build documentation
makeScript execution order matters:
post-create.sh- Sets up git, GitHub CLI, pre-commit hooks, Node.jspost-attach.sh- Configures git and verifies GitHub CLI for current session
Pros:
- No additional tools required beyond Podman
- Full control over container lifecycle
- Easy to customize and script
Cons:
- Manual script execution required
- Need to remember the correct command and flags
- No automatic devcontainer.json integration
Use podman compose for a more declarative approach with persistent configuration.
Install docker compose:
# Using pip
pip install docker-compose
# Or using system package manager (Fedora/RHEL)
sudo dnf install docker-compose
# Or using system package manager (Debian/Ubuntu)
sudo apt install docker-composeStart the container:
# Start in detached mode
podman compose up -d
# Attach to the running container
podman compose exec dev /bin/bashInside the container, run initialization scripts:
# Run setup scripts in order
/workspace/.devcontainer/post-create.sh
/workspace/.devcontainer/post-attach.sh
# Build documentation
makeStop the container:
podman compose downConfiguration file: The repository includes podman-compose.yml with proper settings:
- Volume mount with cached consistency
- Working directory set to
/workspace - Interactive terminal support
- Matches devcontainer.json configuration
Pros:
- Declarative configuration in
podman-compose.yml - Easy to start/stop with simple commands
- Persistent container state (optional)
- Familiar Docker Compose syntax
Cons:
- Requires installing podman-compose
- Still need to manually run initialization scripts
- Limited devcontainer.json feature support
Use the official Dev Container CLI for full devcontainer.json compatibility with Podman.
Install Dev Container CLI:
npm install -g @devcontainers/cliStart the devcontainer with Podman:
# Build and start the devcontainer
devcontainer up --workspace-folder . --docker-path podman
# Execute commands inside
devcontainer exec --workspace-folder . make
# Open a shell
devcontainer exec --workspace-folder . /bin/bashFull integration:
The Dev Container CLI automatically:
- ✅ Reads and applies
.devcontainer/devcontainer.jsonsettings - ✅ Runs
initializeCommandon the host - ✅ Executes
postCreateCommandandpostAttachCommandin container - ✅ Mounts volumes correctly
- ✅ Installs VS Code extensions (when used with VS Code)
- Dual Output Format: Generate both PDF and HTML from the same Typst source
- Bootstrap HTML: Modern, responsive HTML with Bootstrap 5.3 styling
- Dark Mode: Automatic dark mode support with manual toggle and system preference detection
- Live Development Server: Auto-reloading development server (live-server with Python fallback)
- Cache-Busting: Automatic CSS cache invalidation for reliable updates
- Fletcher Diagrams: Architecture, data flow, and state machine diagrams
- Theme-Aware: Diagrams automatically switch colors for light/dark modes
- Automatic Compilation: Diagrams compile automatically as part of the build process
- SVG Embedding: Diagrams embedded as SVG in HTML for crisp rendering
- API Documentation: Generate API reference from Python source using griffe
- Google-Style Docstrings: Full support for structured docstring parsing
- Test Integration: Automatically include test coverage and results
- Self-Contained: All documentation generated within the build system
- VS Code Devcontainer: Pre-configured development environment with all tools
- SSH Agent Integration: Git commit/tag signing works seamlessly in container
- Pre-commit Hooks: Automatic linting and formatting (Ruff, shellcheck, pymarkdown, yamllint)
- Protected Configs: Linting configuration files protected from accidental modification
The build automatically handles:
- Generating color palettes from
lib/colors.json - Compiling all diagrams in
diagrams/folder - Building PDF output
- Building HTML with Bootstrap styling
- Starting development server on http://localhost:8000
make # Build technical-documentation (default)
make example # Build the example project
make test # Build and validate all projects
make clean # Remove all build artifacts
make rebuild # Clean and rebuild everythingworkspace/
├── docs/ # Default project
│ ├── main.typ # Main document
│ └── diagrams/ # Diagram source files
│
├── build/ # Build outputs (default project)
│ ├── diagrams/ # Compiled diagram SVGs
│ ├── technical-documentation.pdf
│ └── technical-documentation.html
│
├── example/ # Example project
│ ├── docs/
│ │ ├── main.typ
│ │ └── diagrams/
│ └── build/ # Example build outputs
│ ├── diagrams/
│ ├── technical-documentation.pdf
│ └── technical-documentation.html
│
├── lib/ # Shared library
│ ├── technical-documentation-package.typ # Typst functions
│ ├── colors.json # Color palette
│ ├── styles-bootstrap.css # HTML styling
│ └── generated/ # Auto-generated files
│
├── scripts/ # Build scripts
│ ├── build-html-bootstrap.py # HTML processing
│ └── generate-colors.py # Color palette generator
│
└── Makefile # Build system