Skip to content

mountain-pass/go-markdown-server

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Go Markdown Server

A low memory, <10MB Go web server that serves markdown files converted to HTML.

Features

  • πŸ”„ Automatic Markdown to HTML conversion using the gomarkdown library
  • 🎨 Clean, responsive HTML template with modern CSS styling
  • πŸ“ File-based routing - serve .md files from the content/ directory
  • πŸ”— Clean URLs - access files with or without the .md extension
  • πŸ“¦ Static file serving for CSS, images, and other assets
  • 🐳 Ultra-minimal Docker containers using scratch base image (no OS!)
  • πŸ›‘οΈ Auto-generated sample content when content directory is empty

Project Structure

go-markdown-server/
β”œβ”€β”€ main.go              # Main server application
β”œβ”€β”€ go.mod              # Go module dependencies
β”œβ”€β”€ go.sum              # Dependency checksums (generated)
β”œβ”€β”€ Dockerfile          # Docker build configuration (scratch-based)
β”œβ”€β”€ LICENSE             # MIT License
β”œβ”€β”€ README.md           # This file
β”œβ”€β”€ content/            # Directory for markdown files
β”‚   └── index.md        # Sample homepage content
└── static/             # Directory for static assets
    └── style.css       # CSS styling for HTML output

Prerequisites

  • Go 1.21 or later
  • Docker (optional, for containerized deployment)

Installation & Setup

  1. Install Go dependencies:

    go mod tidy
  2. Run the server locally:

    go run main.go
  3. Access the server: Open your browser to http://localhost:8080

Configuration

The server can be configured using environment variables:

  • PORT: Server port (default: 8080)
  • CONTENT_DIR: Directory containing markdown files (default: ./content)
  • HTTP_SECURITY_HEADERS: Enable/disable HTTP security headers (default: enable, set to disable to turn off)

Example:

PORT=3000 CONTENT_DIR=/path/to/markdown/files HTTP_SECURITY_HEADERS=disable go run main.go

Security Features

HTTP Security Headers

The server includes comprehensive HTTP security headers by default to protect against common web vulnerabilities:

  • X-Content-Type-Options: Prevents MIME type sniffing attacks
  • X-XSS-Protection: Enables XSS filtering in browsers
  • Referrer-Policy: Controls referrer information sharing
  • X-Permitted-Cross-Domain-Policies: Blocks Flash/PDF cross-domain requests
  • Content-Security-Policy: Comprehensive CSP that allows iframe embedding while maintaining security

Note: Security headers can be disabled by setting HTTP_SECURITY_HEADERS=disable if needed for compatibility with legacy systems.

Container Security

The Docker deployment includes advanced security hardening:

  • Minimal privileges: All Linux capabilities dropped except what's necessary
  • Non-root execution: Runs as user 1001:1001 inside the container
  • No privilege escalation: no-new-privileges security option enabled
  • Path traversal protection: Server validates all file paths to prevent directory traversal attacks

Input Validation

  • Path sanitization: All URL paths are validated and sanitized
  • File extension restrictions: Only serves .md and .css files from the content directory
  • Directory containment: Server ensures all file access stays within the designated content directory

Docker Deployment

Ultra-Minimal Container (Recommended)

This Dockerfile uses a scratch base image, creating an extremely small container with just the Go binary and essential files - no operating system!

Benefits:

  • Tiny size: ~10-15MB total (vs ~50MB+ with Alpine)
  • Enhanced security: No shell, package manager, or OS vulnerabilities
  • Fast startup: Minimal overhead
  • Production-ready: Statically linked binary with all dependencies included

Using Docker Compose (Recommended)

Build and run with Docker Compose:

docker-compose up --build

Build and run in background:

docker-compose up --build -d

Run development version:

docker-compose --profile dev up --build

Build the image without running:

docker-compose build

Stop services:

docker-compose down

Publishing the Image

Build and tag for publishing:

docker-compose build
docker tag mountainpass/go-markdown-server:latest mountainpass/go-markdown-server:v1.0.0

Push to registry:

docker push mountainpass/go-markdown-server:latest
docker push mountainpass/go-markdown-server:v1.0.0

Multi-Platform Publishing

For publishing images that work on both Mac (ARM64) and Linux (AMD64) architectures, use the dedicated multiplatform compose file:

Prerequisites:

# Login to Docker Hub (or your preferred registry)
docker login

Build and publish multi-platform images:

# Build and push directly to registry (recommended)
docker-compose -f docker-compose.multiplatform.yml build --push

# Or build first, then push separately
docker-compose -f docker-compose.multiplatform.yml build
docker-compose -f docker-compose.multiplatform.yml push

Supported architectures:

  • linux/amd64 - Standard Linux x86_64 systems
  • linux/arm64 - Mac M1/M2 (Apple Silicon) and ARM-based Linux systems

Note: Multi-platform builds create manifest lists that automatically serve the correct architecture when pulled. The images are stored in the registry but won't appear in your local docker image ls output unless specifically loaded.

Pull and run from registry:

docker pull mountainpass/go-markdown-server:latest
docker run -p 8080:8080 mountainpass/go-markdown-server:latest

Manual Docker Build (Alternative)

Build the Docker image:

docker build -t mountainpass/go-markdown-server .

Run the container:

docker run -p 8080:8080 mountainpass/go-markdown-server

Run with custom content directory:

docker run -p 8080:8080 -v ./content:/content mountainpass/go-markdown-server

Environment variables in Docker:

docker run -p 3000:3000 -e PORT=3000 -e CONTENT_DIR=/content mountainpass/go-markdown-server

Usage

  1. Add markdown files to the content/ directory

  2. Access files via clean URLs:

    • http://localhost:8080/ β†’ serves content/index.md
    • http://localhost:8080/about β†’ serves content/about.md
    • http://localhost:8080/docs/setup β†’ serves content/docs/setup.md
  3. Static assets can be placed in the static/ directory and accessed via /static/ URL path

  4. Auto-generated content: If the content directory is empty, a sample index.md is automatically created

Markdown Features Supported

  • Headers (H1-H6)
  • Lists (ordered and unordered)
  • Code blocks with syntax highlighting
  • Links and images
  • Tables
  • Blockquotes
  • Horizontal rules
  • Bold and italic text
  • Automatic heading IDs for anchor links

Development

To modify the server:

  1. Edit main.go for server logic changes
  2. Edit static/style.css for styling changes
  3. Add sample content to content/ directory

The server automatically extracts page titles from the first H1 header (# Title) in each markdown file.

Container Security & Performance

The scratch-based Docker image provides:

  • No attack surface: No shell, package manager, or OS components
  • Minimal size: Only contains the statically-linked Go binary and essential files
  • Fast deployment: Smaller images mean faster pulls and starts
  • Production security: No unnecessary system packages or vulnerabilities

Note: The scratch approach works because Go can compile to a statically-linked binary that includes all dependencies. This is ideal for microservices and containerized deployments.

License

This project is open source and available under the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 72.7%
  • CSS 23.7%
  • Dockerfile 3.6%