-
Notifications
You must be signed in to change notification settings - Fork 57
Docker Deployment
This page covers all Docker-based deployment options for Markdown Viewer.
- Quick Start
- Docker Run
- Docker Compose
- Building the Image Locally
- Nginx Configuration
- Transparency & Security
- Environment & Customization
- Automated Image Publishing
- Reverse Proxy Setup
docker run -d \
--name markdown-viewer \
-p 8080:80 \
--restart unless-stopped \
ghcr.io/thisis-developer/markdown-viewer:latestOpen http://localhost:8080.
docker run -p 8080:80 ghcr.io/thisis-developer/markdown-viewer:latestdocker run -p 3000:80 ghcr.io/thisis-developer/markdown-viewer:latestdocker run -d \
--name markdown-viewer \
-p 8080:80 \
--restart unless-stopped \
ghcr.io/thisis-developer/markdown-viewer:latestdocker pull ghcr.io/thisis-developer/markdown-viewer:<tag>
docker run -p 8080:80 ghcr.io/thisis-developer/markdown-viewer:<tag>Available tags: latest, main, and commit SHA tags (e.g., abc1234).
The repository includes a ready-to-use docker-compose.yml.
docker compose up -ddocker compose downdocker compose up -d --buildservices:
markdown-viewer:
image: ghcr.io/thisis-developer/markdown-viewer:latest
container_name: markdown-viewer
ports:
- "8080:80"
restart: unless-stoppedTo change the host port, update the left value in "8080:80" to your desired port.
# From the repository root
git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git
cd Markdown-Viewer
docker build -t markdown-viewer:local .
docker run -p 8080:80 markdown-viewer:localThe Dockerfile is based on nginx:alpine and:
-
Copies all web app files (
index.html,script.js,styles.css,assets/) into/usr/share/nginx/html. -
Configures Nginx for SPA routing (all paths serve
index.html). - Sets cache headers for static assets (1-year max-age).
-
Adds security headers:
X-Frame-Options: SAMEORIGINX-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-origin
The embedded Nginx config (/etc/nginx/conf.d/default.conf) includes:
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
# SPA fallback routing
location / {
try_files $uri $uri/ /index.html;
}
# Static asset caching (1 year)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
}The Docker image is intentionally minimal:
- Static assets only: HTML, CSS, JavaScript, and images served by Nginx.
- No background services: No analytics, telemetry, or server-side processing.
- External dependencies: The app references CDN-hosted libraries unless you bundle them locally.
-
Security headers: Nginx applies
X-Frame-Options,X-Content-Type-Options, andReferrer-Policy.
Because the app is purely static, there are no runtime environment variables to configure. All customization is done at build time by modifying the source files.
To serve the app at a sub-path (e.g., /markdown-viewer/), adjust the Nginx location directive in the Dockerfile and rebuild the image.
The GitHub Actions workflow .github/workflows/docker-publish.yml automatically builds and publishes Docker images to GHCR on every push:
| Event | Action |
|---|---|
Push to main
|
Build and push latest tag |
| Pull request | Build only (no push) |
| Any push | Build and push with commit SHA tag |
Images are published to:
ghcr.io/thisis-developer/markdown-viewer
You can pull the image without authentication (public repository):
docker pull ghcr.io/thisis-developer/markdown-viewer:latestTo run Markdown Viewer behind a reverse proxy (Nginx, Caddy, Traefik, Apache), proxy requests to the container's port 80.
server {
listen 443 ssl;
server_name markdown.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}markdown.example.com {
reverse_proxy localhost:8080
}services:
markdown-viewer:
image: ghcr.io/thisis-developer/markdown-viewer:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.markdown.rule=Host(`markdown.example.com`)"
- "traefik.http.routers.markdown.entrypoints=websecure"
- "traefik.http.routers.markdown.tls.certresolver=letsencrypt"