Product overview
One server between the network and your application.
Webship is a self-hosted Rust edge and static web server. One runtime terminates modern protocols, applies edge policy, serves files, and proxies application requests.
Modern transport
Accept HTTP/1.1, HTTP/2, and HTTP/3, with TLS 1.3 and an optional WebTransport endpoint.
Static and proxied delivery
Serve static files with validators and precompressed sidecars, or proxy application traffic through bounded upstream pools.
Secure defaults
Begin with the WAF, DDoS controls, bot challenge, response security headers, API Shield, and dot-file protection enabled.
Observable operations
Use authenticated statistics, Prometheus metrics, request IDs, graceful reloads, and the optional MCP control plane.
Quick start
From release binary to healthy listener.
Start on loopback, validate everything before binding, and verify the built-in health response before adding public traffic.
Prepare files
Place the release binary, its TOML configuration, the static root, and any configured TLS certificate and key files on the host.
Validate and inspect
Run both configuration commands. Fix the first error and inspect the redacted effective result before startup.
Start privately
Start Webship with the selected TOML file. Add a complete certificate pair or automatic TLS when the site is ready for secure public traffic.
Verify the runtime
Call GET /health locally. Then test static paths, TLS, proxy routes, security rules, and authenticated monitoring.
listen = "127.0.0.1:4433"
workers = 4
root = "./public"/usr/local/bin/webship --check-config --config /etc/webship/production.toml
/usr/local/bin/webship --print-effective-config --config /etc/webship/production.toml/usr/local/bin/webship --config /etc/webship/production.toml
curl --http3-only --insecure https://127.0.0.1:4433/healthQuick Start Guide for AI Agents
Connect an AI agent to Webship in five lines.
Connect Claude Code, OpenAI, DeepSeek, or any compatible MCP client through a private SSH tunnel. The agent receives an authenticated operations surface without sharing the public listener or exposing control credentials to internet traffic.
{
"mcpServers": {
"webship": { "url": "https://localhost:19443/mcp",
"headers": { "Authorization": "Bearer <token>" } }
} }Static delivery
Serve a directory with protocol-aware defaults.
Set a root globally or per site. TLS sites default to HTTP/3 only; cleartext sites default to HTTP/1.1 and H2C. Override HTTP/1.1, HTTP/2, and HTTP/3 independently for each site.
[[sites]]
domain = "app.example.com"
root = "/srv/app"
listen = "0.0.0.0:443"
[sites.protocols]
h1 = true
h2 = true
h3 = trueThe built-in router supports GET and HEAD, byte ranges, conditional requests, validators, and .br, .zst, and .gz sidecars. Dot-file paths are refused by default; .well-known remains available.
Application traffic
Route requests to one or more upstreams.
Enable reverse proxying, match a host and path, then define a final unconditional policy. Webship supports bounded pools, health checks, load balancing, circuit breakers, safe bodyless retries, WebSockets, and caching.
[reverse_proxy]
enabled = true
[[reverse_proxy.routes]]
domain = "app.example.com"
path_prefix = "/api"
strip_path_prefix = true
upstreams = ["127.0.0.1:8080", "127.0.0.1:8081"]
[[reverse_proxy.policies]]
name = "default"
hosts = []
path_prefixes = ["/"]
methods = []
max_body_bytes = 1048576
total_timeout_ms = 30000TLS and HTTP/3
Use manual certificates or let Webship manage them.
Webship accepts TLS 1.3. HTTP/3 runs over the matching UDP listener; enable HTTP/1.1 or HTTP/2 explicitly when a TLS site also needs TCP compatibility.
listen = "0.0.0.0:443"
[automatic_tls]
enabled = true
directory_url = "https://acme-v02.api.letsencrypt.org/directory"
cache_dir = "/var/lib/webship/acme"
contacts = ["mailto:ops@example.com"]
accept_terms_of_service = true
[[sites]]
domain = "app.example.com"
root = "/srv/app"Edge policy
Keep the secure baseline intact.
Webship enables its main protection layers by default. Tune limits for your workload and validate after every rule or header-policy change.
[ddos]
enabled = true
mode = "normal"
requests_per_minute = 600
burst = 100
block_seconds = 300
[security.response_headers]
enabled = true
nosniff = true
frame_deny = true
referrer_no_referrer = true
hsts = "max-age=31536000; includeSubDomains"
content_security_policy = "default-src 'self'; frame-ancestors 'none'"Use normal mode for regular traffic, under_attack for stricter active-attack handling, and lockdown when only probes and explicitly permitted paths should remain available.
Private diagnostics
Inspect the edge without exposing the control plane.
Statistics and Prometheus metrics run on a separate authenticated listener. Instrumentation must be enabled whenever either endpoint is active.
[observability]
instrumentation = true
stats = true
metrics = true
listen = "127.0.0.1:9090"
token = "replace-with-at-least-32-random-printable-ascii-characters"Safe operations
Reload deliberately. Keep rollback close.
Configuration reload
Send SIGHUP after editing a file-backed configuration. Webship validates the replacement before installing it and retains the running configuration when validation fails.
Upgrade and rollback
Install the new binary beside the previous version, validate the production configuration with it, then verify health, TLS, proxying, and metrics. Keep the previous binary until every gate passes.
kill -HUP "$(pidof webship)"
/usr/local/bin/webship update --config /etc/webship/production.toml
sudo systemctl daemon-reload
sudo systemctl enable --now webship
sudo systemctl status webshipProfile-guided optimization
Collect target-native profiles without confusing training and production.
Every Webship 1.1 target has a separate instrumented CLI for collecting target-native LLVM profile data under your representative traffic. Use the exact version and target triple, exercise the routes and protocols that matter, and stop the process gracefully so it can flush every .profraw file.
Select the exact target
Download the PGO training CLI whose release version and Rust target triple exactly match the runtime you intend to optimize. Verify its published SHA-256 first.
Capture representative traffic
Set LLVM_PROFILE_FILE to a writable directory, start the training CLI with a validated copy of the real configuration, replay representative direct and reverse-proxy traffic, then stop Webship gracefully.
Merge raw profiles
Use llvm-profdata from the compiler generation recorded for the release. Merge every emitted .profraw file into one sparse webship.profdata file.
Rebuild and gate
Apply the merged profile only to the exact source, compiler, crypto provider, feature set, and target that generated it. Run correctness and performance gates before promotion.
mkdir -p ./profiles
export LLVM_PROFILE_FILE="$PWD/profiles/webship-%p-%m.profraw"
./webship-pgo-training-1.1.0-<target> --config ./webship.tomlNew-Item -ItemType Directory -Force ./profiles
$env:LLVM_PROFILE_FILE = "$PWD/profiles/webship-%p-%m.profraw"
.\webship-pgo-training-1.1.0-<target>.exe --config .\webship.tomlllvm-profdata merge -sparse ./profiles/*.profraw -o ./webship.profdataCommand-line reference
Small surface, explicit startup.
webship [OPTIONS] | webship update [OPTIONS]
-c, --config PATH- Select the TOML file. If it does not exist, Webship creates it with a private localhost TLS identity.
--check-config- Validate the complete configuration and exit without starting listeners.
--print-effective-config- Print the merged effective configuration with secrets removed.
update- Verify the signed community manifest, select this exact platform target, and install a newer version when one exists.
--help / --version- Print command help or the installed Webship version.
Common failure modes
Start with configuration, then move outward.
- Run --check-config and correct the first reported error; unknown TOML fields are rejected.
- Confirm the configured TCP and UDP ports are available and allowed by the firewall.
- Confirm the certificate and key exist, are readable by the service account, and form a matching pair.
- For automatic TLS, confirm every configured domain resolves to the Webship host.
- Call /health on the local application listener before testing through DNS or an external load path.
- Enable authenticated observability temporarily when runtime evidence is required.