Deploy
These guides assume you already have set-up the documentation folder with content in it, see Getting Started if you don't. Pick whichever path matches your environment. Docker is the fastest, usually under a minute from a blank folder to a running site.
Option A: Docker Compose
Prebuilt images are published to GHCR on every tagged release.
services:
bark:
image: ghcr.io/melosso/bark:latest
container_name: bark
ports:
- "8080:8080"
volumes:
- ./docs:/app/docsMount your own docs/ folder (your .md files plus an optional config.json), then run:
docker compose up -dBrowse to http://localhost:8080.
Option B: Windows / IIS
- Download the latest
*-Windows_x64.zipfrom Releases. - Extract it to your site folder (for example
C:\inetpub\bark). - In IIS, create a site (or app) pointing at that folder, with the No Managed Code .NET CLR version. Bark hosts itself via the ASP.NET Core Module, it doesn't need the CLR to load anything.
- The zip already includes a
web.configwired for in-process hosting. No manual edits needed. - Install the .NET 10 Hosting Bundle on the server. This gives IIS the ASP.NET Core Module.
- Start the site and browse to it.
Option C: Linux release zip
A self-contained Linux x64 build (*-Linux_x64.zip) ships alongside every release. This is a convenient option if you prefer running the binary directly without Docker.
- Download the latest
*-Linux_x64.zipfrom Releases. - Extract it to your server (for example
/srv/bark):
mkdir -p /srv/bark && unzip Bark-*-Linux_x64.zip -d /srv/bark- Prepare your
docs/directory with your Markdown content and optionalconfig.json:
mkdir -p /srv/bark/docs
# Place your .md files in /srv/bark/docs- Run the binary:
cd /srv/bark && ./BarkNote
The binary expects a docs/ folder relative to the current working directory. If your content lives elsewhere, set Docs:RootPath in appsettings.json or pass it as an environment variable. See Environment Variables for the full list.
- Browse to
http://localhost:8080.
For a production setup, you can configure Bark as a systemd service (see Running as a service below).
Option D: Build from source
If you're contributing to Bark itself, or don't want to pull a container image:
cd Bark
dotnet publish src/Bark -c Release -o ./publishYour docs/ folder is copied into the publish output automatically:
cd publish
dotnet Bark.dllYou need the .NET 10 SDK installed to publish. The published output still needs the .NET runtime on the target machine unless you add --self-contained true -r <rid>.
If you're actively developing Bark's own source rather than running it, dotnet watch --project src/Bark from a clone gives you C#-side hot reload too.
Option E: Static export (GitHub Pages, etc.)
You can skip the server entirely and export plain HTML, CSS, and JS for any static host: GitHub Pages, Netlify, or a plain web server. This path requires cloning the repository and compiling Bark yourself.
dotnet publish src/Bark -c Release -o ./publish
cd publish && ./Bark --export ./output --base-url https://you.github.io --base-path /your-repoWhen you run the binary, it accepts these CLI flags:
| Flag | Purpose |
|---|---|
--export <dir> |
Writes every page, plus 404.html, robots.txt, llms.txt, sitemap.xml, and wwwroot to the given directory. |
--base-url <origin> |
The real public origin used for absolute URLs in robots.txt and llms.txt. |
--base-path </prefix> |
Required when the site lives under a subpath, such as a GitHub project page (you.github.io/your-repo/). This flag overrides Docs:BasePath at runtime. See Site Config. |
Note
Run the binary from inside the publish folder (cd publish first). The docs/ lookup is relative to the current directory, not the executable's location. The --export flag also disables hot reload, so there is no /api/build-version polling. Search still renders but fails gracefully without a backend.
A working GitHub Actions example lives in .github/workflows/bark-deployment.yml. It still needs Settings → Pages → Source → GitHub Actions set once per repo before the first deploy succeeds.
Production-ready
Bark is configured for production stability out of the box. The following optimizations are pre-configured and active by default:
- Automatic Compression: All web traffic uses Brotli or Gzip compression (including secure HTTPS traffic) to significantly reduce page load times and save bandwidth.
- Built-in DoS Protection: Safety limits are pre-configured to protect the server from resource exhaustion. This includes strict limits on request body sizes, header sizes, maximum simultaneous connections, and keep-alive timeouts.
- Production Logging: Logs are routed directly to the console. You can easily adjust how detailed these logs are for different environment if necessary.
- Smart Caching (ETags): Every page includes a unique fingerprint (SHA-256 ETag). If a user's browser already has the current version of a page then the server responds with "304 Not Modified" status, saving resources.
What does this mean for you?
Performance and security optimizations are enabled automatically. You only need to configure your external infrastructure, such as your domain, firewall, and SSL certificates.
Reverse Proxy Setup
Bark is designed to sit behind a dedicated web server or load balancer that handles SSL/TLS certificates and external traffic encryption.
If you are using Docker, Bark listens internally on port 8080. Below is a minimal Nginx configuration to safely route external traffic to your Bark container:
server {
listen 443 ssl;
server_name docs.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Building from source and running dotnet Bark.dll directly uses whatever port ASPNETCORE_URLS or your launch profile configures instead of 8080. Adjust proxy_pass to match.
If you're behind a reverse proxy, configure Forwarded Headers Middleware so Bark sees the real client scheme/host. robots.txt and sitemap.xml both build absolute URLs from the incoming request, so getting this right matters for SEO correctness, not just logging.
Running as a service (source builds)
Docker and the IIS zip already manage their own process lifecycle. If you published from source and want it to survive a reboot, a basic systemd unit:
[Unit]
Description=Bark documentation server
After=network.target
[Service]
WorkingDirectory=/srv/bark/publish
ExecStart=/usr/bin/dotnet /srv/bark/publish/Bark.dll
Restart=always
RestartSec=5
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.targetHot reload (the FileSystemWatcher on docs/) keeps working in this setup. You don't need to restart the service to publish a content change, only to ship a code change.
Deploying to Production
We have ensured that Bark is secure for production environments when running without a reverse proxy. However, you should evaluate whether this setup meets your specific requirements.
For production container deployments, it is recommended to set Docs__EnableHotReload to false. Since documentation is typically either baked directly into your image or provided as a read-only volume at startup, the filesystem watcher will not have any functional purpose.
Sizing expectations
Bark holds the entire rendered page set and the search index in memory. For a documentation site in the hundreds-of-pages range, that's a non-issue on essentially any environment.
But, if you're hosting tens of thousands of pages, you've outgrown the assumptions this tool was built around.