New Website: Phase I (#357)

* Initial commit; starting new design

Dropdown menu

* Begin docs layout of new design

* Get themes under control; button hover splash

* Some basic responsiveness

* Finish responsive layout; several bug fixes

* Avoid flash during color scheme change

* Begin building top of homepage

* docs: Start building quick-assist feature

* Work on homepage a little more

* Keep working on homepage

* More homepage progress

* Some sponsor SVGs

* Add sponsor features

* Implement basic Sponsor Experience box

* Reorganize some styles

* WIP sponsors page

* Start features page WIP

* Minor improvements

* Fix headings; work on features page

* WIP features page

* Continue work on marketing pages

* Continue work on features page

* More features WIP

* Continue features page...

* More work on features page

* Keeping going  :)

* Continue home and features pages

* More homepage/features content, screenshots, tweaks

* Minor fixes to features page

* Minor tweaks

* Work on testimonials

* Work on homepage more

* More homepage work

* Continue work on homepage

* Add some sponsor logos

* Some citation screenshots

* Add citations

* Start making homepage responsive

* Re-add cache busting

Fix docs

* Use markdown syntax highlighting on frontpage

* Rework AJQuery to $_ to not interfere with jQuery

* Rewrite quick assist with AlpineJS, use markdown for contents

* More work on marketing pages

* Rebase and fix code displays

* Syntax highlight on-demand example, fix rollover

* Adjust on-demand demo

* Work on responsiveness

* Keep working on responsiveness

* Mainly finish making design responsive

* Thiccer favicon

* More work on marketing pages

* Keep on going

* Fix link

* Move new site into src folder

* Add open graph image

* Add recorded demo for homepage

* Tweak caption

* Fix Poppins font for now

* Minor tweaks

* Trim demo ending

* Remove unfinished pages

Also update Framer logo

---------

Co-authored-by: Francis Lavoie <lavofr@gmail.com>
This commit is contained in:
Matt Holt 2023-12-11 10:07:34 -07:00 committed by GitHub
parent 5bb6d92c63
commit 07c51663ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
191 changed files with 13008 additions and 4970 deletions

View file

@ -2,14 +2,14 @@
<html>
<head>
<title>Create Account - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/create.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/create.js{{template "cacheBust"}}"></script>
</head>
<body>
<form action="/api/create-account" class="card">
<section class="head">
<a href="/"><img src="/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
<a href="/"><img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
</section>
<section>
<h1>Create Account</h1>

View file

@ -2,14 +2,14 @@
<html>
<head>
<title>Dashboard - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<link rel="stylesheet" href="/resources/css/account/dashboard.css{{template "cacheBust"}}">
<script src="/resources/js/account/dashboard.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/dashboard.js{{template "cacheBust"}}"></script>
</head>
<body>
<div class="container">
{{include "/includes/account/nav.html"}}
{{include "/old/includes/account/nav.html"}}
<main class="dashboard">
<section>
<h1 class="pad">Your packages<a href="/account/register-package" class="gray button float-right">Register package</a></h1>

View file

@ -2,14 +2,14 @@
<html>
<head>
<title>Log In - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/login.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/login.js{{template "cacheBust"}}"></script>
</head>
<body>
<form action="/api/login" class="card">
<section class="head">
<a href="/"><img src="/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
<a href="/"><img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
</section>
<section>
<h1>Log In</h1>

View file

@ -2,9 +2,9 @@
<html>
<head>
<title>Logout - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/logout.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/logout.js{{template "cacheBust"}}"></script>
</head>
<body>
Logging out...

View file

@ -2,13 +2,13 @@
<html>
<head>
<title>Register Package - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/register-package.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/register-package.js{{template "cacheBust"}}"></script>
</head>
<body>
<div class="container">
{{include "/includes/account/nav.html"}}
{{include "/old/includes/account/nav.html"}}
<main>
<section>
<form action="/api/claim-package">

View file

@ -2,14 +2,14 @@
<html>
<head>
<title>Reset Password - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/reset-password.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/reset-password.js{{template "cacheBust"}}"></script>
</head>
<body>
<form action="/api/reset-password" class="card" id="reset-password-step1">
<section class="head">
<a href="/"><img src="/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
<a href="/"><img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
</section>
<section>
<h1>Reset Password</h1>
@ -22,7 +22,7 @@
</form>
<form action="/api/reset-password" class="card" id="reset-password-step2">
<section class="head">
<a href="/"><img src="/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
<a href="/"><img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
</section>
<section>
<h1>Reset Password</h1>

View file

@ -2,14 +2,14 @@
<html>
<head>
<title>Confirm Account - Caddy</title>
{{import "/includes/account/head.html"}}
{{import "/old/includes/account/head.html"}}
{{template "account-head"}}
<script src="/resources/js/account/verify.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/account/verify.js{{template "cacheBust"}}"></script>
</head>
<body>
<form action="/api/verify-account" class="card">
<section class="head">
<a href="/"><img src="/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
<a href="/"><img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" class="logo"></a>
</section>
<section>
<h1>Confirm Account</h1>

View file

@ -1,48 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Caddy for Business</title>
{{import "/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/resources/css/business.css">
<meta property="og:title" content="Caddy 2 for Business">
<meta name="twitter:title" value="Caddy 2 for Business">
</head>
<body>
<div class="wrapper">
<header>
<div id="logo-container">
<a href="/"><img src="/resources/images/caddy-logo.svg" id="logo" alt="Caddy"></a>
<div id="zerossl-project">a <a href="https://zerossl.com"><img src="/resources/images/zerossl-logo.svg" id="zerossl-logo"></a> project</div>
</div>
{{include "/includes/header-nav.html"}}
</header>
<h1>Ready for business</h1>
<section>
<div class="panels">
<div>
<h2>Need help with something?</h2>
<p>
Most users should participate in our <a href="https://caddy.community">community forum</a> to help others and ask questions.
</p>
<p>
The only price for this help is to put some effort into your question and say thank you. 😃
</p>
</div>
<div>
<h2>Support and development for businesses</h2>
<p>
We highly recommend that companies using Caddy get a support plan and contract any related development work with our exclusive partner <a href="https://www.ardanlabs.com/">Ardan Labs</a>. Contact us to get started:
</p>
<a href="m&#97;&#105;lto&#58;&#98;%&#55;5s%69&#37;6Eess&#64;ca&#37;64dys&#101;&#37;72&#118;er&#46;c%6F&#109;" class="button red">Email <b>business&#64;&#99;addy&#115;&#101;rver&#46;&#99;om</b></a>
</div>
</div>
</section>
</div>
{{include "/includes/footer.html"}}
</body>
</html>

View file

@ -8,15 +8,15 @@
<html>
<head>
<title>{{$title}} &mdash; Caddy Documentation</title>
{{import "/includes/docs/head.html"}}
{{import "/old/includes/docs/head.html"}}
{{template "docs-head"}}
<meta property="og:title" content="{{$title}} - Caddy Documentation">
<meta name="twitter:title" value="{{$title}} - Caddy Documentation">
</head>
<body>
{{include "/includes/docs/header.html"}}
{{include "/old/includes/docs/header.html"}}
<main>
{{include "/includes/docs/nav.html"}}
{{include "/old/includes/docs/nav.html"}}
<div class="article-container">
<div class="paper" id="paper1"></div>
<div class="paper" id="paper2"></div>
@ -26,6 +26,6 @@
</div>
<div class="sidebar"></div>
</main>
{{include "/includes/footer.html"}}
{{include "/old/includes/footer.html"}}
</body>
</html>

View file

@ -2,17 +2,17 @@
<html>
<head>
<title>JSON Config Structure - Caddy Documentation</title>
{{import "/includes/docs/head.html"}}
{{import "/old/includes/docs/head.html"}}
{{template "docs-head"}}
<link rel="stylesheet" href="/resources/css/docs-json.css{{template "cacheBust"}}">
<script src="/resources/js/marked-0.8.0.min.js"></script>
<script src="/resources/js/docs-api.js{{template "cacheBust"}}"></script>
<script src="/resources/js/json-docs.js{{template "cacheBust"}}"></script>
<link rel="stylesheet" href="/old/resources/css/docs-json.css{{template "cacheBust"}}">
<script src="/old/resources/js/marked-0.8.0.min.js"></script>
<script src="/old/resources/js/docs-api.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/json-docs.js{{template "cacheBust"}}"></script>
</head>
<body>
{{include "/includes/docs/header.html"}}
{{include "/old/includes/docs/header.html"}}
<main>
{{include "/includes/docs/nav.html"}}
{{include "/old/includes/docs/nav.html"}}
<div class="article-container">
<div class="paper" id="paper1"></div>
<div class="paper" id="paper2"></div>
@ -21,16 +21,16 @@
<div class="breadcrumbs">
<!--Populated by JS-->
</div>
{{include "/includes/docs/renderbox.html"}}
{{include "/includes/docs/details.html"}}
{{include "/old/includes/docs/renderbox.html"}}
{{include "/old/includes/docs/details.html"}}
</article>
</div>
</div>
<div class="sidebar"></div>
</main>
{{include "/includes/docs/hovercard.html"}}
{{include "/old/includes/docs/hovercard.html"}}
{{include "/includes/footer.html"}}
{{include "/old/includes/footer.html"}}
</body>
</html>

View file

@ -153,7 +153,7 @@ You should see:
<aside class="tip">
You can use the [`jq` command <img src="/resources/images/external-link.svg" class="external-link">](https://stedolan.github.io/jq/) to prettify JSON output: **`curl ... | jq`**
You can use the [`jq` command <img src="/old/resources/images/external-link.svg" class="external-link">](https://stedolan.github.io/jq/) to prettify JSON output: **`curl ... | jq`**
</aside>

View file

@ -4,7 +4,7 @@ title: "API"
# API
Caddy is configured through an administration endpoint which can be accessed via HTTP using a [REST <img src="/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/Representational_state_transfer) API. You can [configure this endpoint](/docs/json/admin/) in your Caddy config.
Caddy is configured through an administration endpoint which can be accessed via HTTP using a [REST <img src="/old/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/Representational_state_transfer) API. You can [configure this endpoint](/docs/json/admin/) in your Caddy config.
**Default address: `localhost:2019`**
@ -254,7 +254,7 @@ This section is for all `/config/` endpoints. It is experimental and subject to
</aside>
Caddy's config API provides [ACID guarantees <img src="/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/ACID) for individual requests, but changes that involve more than a single request are subject to collisions or data loss if not properly synchronized.
Caddy's config API provides [ACID guarantees <img src="/old/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/ACID) for individual requests, but changes that involve more than a single request are subject to collisions or data loss if not properly synchronized.
For example, two clients may `GET /config/foo` at the same time, make an edit within that scope (config path), then call `POST|PUT|PATCH|DELETE /config/foo/...` at the same time to apply their changes, resulting in a collision: either one will overwrite the other, or the second might leave the config in an unintended state since it was applied to a different version of the config than it was prepared against. This is because the changes are not aware of each other.

View file

@ -39,7 +39,7 @@ Here's a 28-second video showing how it works:
- Caddy serves IP addresses and local/internal hostnames over HTTPS using self-signed certificates that are automatically trusted locally (if permitted).
- Examples: `localhost`, `127.0.0.1`
- Caddy serves public DNS names over HTTPS using certificates from a public ACME CA such as [Let's Encrypt <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org) or [ZeroSSL <img src="/resources/images/external-link.svg" class="external-link">](https://zerossl.com).
- Caddy serves public DNS names over HTTPS using certificates from a public ACME CA such as [Let's Encrypt <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org) or [ZeroSSL <img src="/old/resources/images/external-link.svg" class="external-link">](https://zerossl.com).
- Examples: `example.com`, `sub.example.com`, `*.example.com`
Caddy keeps all managed certificates renewed and redirects HTTP (default port `80`) to HTTPS (default port `443`) automatically.
@ -89,7 +89,7 @@ Any of the following will prevent automatic HTTPS from being activated, either i
**Special cases:**
- Domains ending in `.ts.net` will not be managed by Caddy. Instead, Caddy will automatically attempt to get these certificates at handshake-time from the locally-running [Tailscale <img src="/resources/images/external-link.svg" class="external-link">](https://tailscale.com) instance. This requires that [HTTPS is enabled in your Tailscale account <img src="/resources/images/external-link.svg" class="external-link">](https://tailscale.com/kb/1153/enabling-https/) and the Caddy process must either be running as root, or you must configure `tailscaled` to give your Caddy user [permission to fetch certificates](https://github.com/caddyserver/caddy/pull/4541#issuecomment-1021568348).
- Domains ending in `.ts.net` will not be managed by Caddy. Instead, Caddy will automatically attempt to get these certificates at handshake-time from the locally-running [Tailscale <img src="/old/resources/images/external-link.svg" class="external-link">](https://tailscale.com) instance. This requires that [HTTPS is enabled in your Tailscale account <img src="/old/resources/images/external-link.svg" class="external-link">](https://tailscale.com/kb/1153/enabling-https/) and the Caddy process must either be running as root, or you must configure `tailscaled` to give your Caddy user [permission to fetch certificates](https://github.com/caddyserver/caddy/pull/4541#issuecomment-1021568348).
## Effects
@ -126,7 +126,7 @@ Caddy uses HTTPS automatically for all sites with a host (domain, IP, or hostnam
To serve non-public sites over HTTPS, Caddy generates its own certificate authority (CA) and uses it to sign certificates. The trust chain consists of a root and intermediate certificate. Leaf certificates are signed by the intermediate. They are stored in [Caddy's data directory](/docs/conventions#data-directory) at `pki/authorities/local`.
Caddy's local CA is powered by [Smallstep libraries <img src="/resources/images/external-link.svg" class="external-link">](https://smallstep.com/certificates/).
Caddy's local CA is powered by [Smallstep libraries <img src="/old/resources/images/external-link.svg" class="external-link">](https://smallstep.com/certificates/).
Local HTTPS does not use ACME nor does it perform any DNS validation. It works only on the local machine and is trusted only where the CA's root certificate is installed.
@ -158,7 +158,7 @@ Unlike the root certificate, intermediate certificates have a much shorter lifet
To test or experiment with your Caddy configuration, make sure you [change the ACME endpoint](/docs/modules/tls.issuance.acme#ca) to a staging or development URL, otherwise you are likely to hit rate limits which can block your access to HTTPS for up to a week, depending on which rate limit you hit.
One of Caddy's default CAs is [Let's Encrypt <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/), which has a [staging endpoint <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) that is not subject to the same [rate limits <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/rate-limits/):
One of Caddy's default CAs is [Let's Encrypt <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/), which has a [staging endpoint <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) that is not subject to the same [rate limits <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/rate-limits/):
```
https://acme-staging-v02.api.letsencrypt.org/directory
@ -166,7 +166,7 @@ https://acme-staging-v02.api.letsencrypt.org/directory
## ACME challenges
Obtaining a publicly-trusted TLS certificate requires validation from a publicly-trusted, third-party authority. These days, this validation process is automated with the [ACME protocol <img src="/resources/images/external-link.svg" class="external-link">](https://tools.ietf.org/html/rfc8555), and can be performed one of three ways ("challenge types"), described below.
Obtaining a publicly-trusted TLS certificate requires validation from a publicly-trusted, third-party authority. These days, this validation process is automated with the [ACME protocol <img src="/old/resources/images/external-link.svg" class="external-link">](https://tools.ietf.org/html/rfc8555), and can be performed one of three ways ("challenge types"), described below.
The first two challenge types are enabled by default. If multiple challenges are enabled, Caddy chooses one at random to avoid accidental dependence on a particular challenge. Over time, it learns which challenge type is most successful and will begin to prefer it first, but will fall back to other available challenge types if necessary.
@ -245,7 +245,7 @@ Here's what happens if there's an error obtaining or renewing a certificate:
- Maximum of 1 day between attempts
- For up to 30 days
During retries with Let's Encrypt, Caddy switches to their [staging environment <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) to avoid rate limit concerns. This isn't a perfect strategy, but in general it's helpful.
During retries with Let's Encrypt, Caddy switches to their [staging environment <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) to avoid rate limit concerns. This isn't a perfect strategy, but in general it's helpful.
ACME challenges take at least a few seconds, and internal rate limiting helps mitigate accidental abuse. Caddy uses internal rate limiting in addition to what you or the CA configure so that you can hand Caddy a platter with a million domain names and it will gradually -- but as fast as it can -- obtain certificates for all of them. Caddy's internal rate limit is currently 10 attempts per ACME account per 10 seconds.
@ -255,7 +255,7 @@ To avoid leaking resources, Caddy aborts in-flight tasks (including ACME transac
Caddy is the first (and so far only) server to support fully-redundant, automatic failover to other CAs in the event it cannot successfully get a certificate.
By default, Caddy enables two ACME-compatible CAs: [**Let's Encrypt** <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org) and [**ZeroSSL** <img src="/resources/images/external-link.svg" class="external-link">](https://zerossl.com). If Caddy cannot get a certificate from Let's Encrypt, it will try with ZeroSSL; if both fail, it will backoff and retry again later. In your config, you can customize which issuers Caddy uses to obtain certificates, either universally or for specific names.
By default, Caddy enables two ACME-compatible CAs: [**Let's Encrypt** <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org) and [**ZeroSSL** <img src="/old/resources/images/external-link.svg" class="external-link">](https://zerossl.com). If Caddy cannot get a certificate from Let's Encrypt, it will try with ZeroSSL; if both fail, it will backoff and retry again later. In your config, you can customize which issuers Caddy uses to obtain certificates, either universally or for specific names.
## Storage
@ -277,4 +277,4 @@ If using the Caddyfile, Caddy takes site names literally with regards to the cer
Wildcard certificates represent a wide degree of authority and should only be used when you have so many subdomains that managing individual certificates for them would strain the PKI or cause you to hit CA-enforced rate limits.
**Note:** [Let's Encrypt requires <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/challenge-types/) the [DNS challenge](#dns-challenge) to obtain wildcard certificates.
**Note:** [Let's Encrypt requires <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/challenge-types/) the [DNS challenge](#dns-challenge) to obtain wildcard certificates.

View file

@ -147,7 +147,7 @@ The **format** subdirective lets you customize how logs get encoded (formatted).
<aside class="tip">
**A note about Common Log Format (CLF):** CLF clashes with modern structured logs. To transform your access logs into the deprecated Common Log Format, please use the [`transform-encoder` plugin <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder).
**A note about Common Log Format (CLF):** CLF clashes with modern structured logs. To transform your access logs into the deprecated Common Log Format, please use the [`transform-encoder` plugin <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder).
</aside>
@ -440,7 +440,7 @@ log {
}
```
<span id="multiple-outputs" /> To write the access logs for a particular subdomain to two different files, with different formats (one with [`transform-encoder` plugin <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder) and the other with [`json`](#json)).
<span id="multiple-outputs" /> To write the access logs for a particular subdomain to two different files, with different formats (one with [`transform-encoder` plugin <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder) and the other with [`json`](#json)).
This works by overriding the logger name as `foo` in the site block, then including the access logs produced by that logger in the two loggers in global options with `include http.log.access.foo`:

View file

@ -748,7 +748,7 @@ reverse_proxy 10.0.0.1:443 {
[Strip a path prefix](/docs/caddyfile/directives/handle_path) before proxying; but be aware of the [subfolder problem <img src="/resources/images/external-link.svg" class="external-link">](https://caddy.community/t/the-subfolder-problem-or-why-cant-i-reverse-proxy-my-app-into-a-subfolder/8575):
[Strip a path prefix](/docs/caddyfile/directives/handle_path) before proxying; but be aware of the [subfolder problem <img src="/old/resources/images/external-link.svg" class="external-link">](https://caddy.community/t/the-subfolder-problem-or-why-cant-i-reverse-proxy-my-app-into-a-subfolder/8575):
```caddy-d
handle_path /prefix/* {

View file

@ -94,17 +94,17 @@ Keep in mind that Let's Encrypt may send you emails about your certificate neari
- `secp384r1`
- `secp521r1`
- **alpn** <span id="alpn"/> is the list of values to advertise in the [ALPN extension <img src="/resources/images/external-link.svg" class="external-link">](https://developer.mozilla.org/en-US/docs/Glossary/ALPN) of the TLS handshake.
- **alpn** <span id="alpn"/> is the list of values to advertise in the [ALPN extension <img src="/old/resources/images/external-link.svg" class="external-link">](https://developer.mozilla.org/en-US/docs/Glossary/ALPN) of the TLS handshake.
- **load** <span id="load"/> specifies a list of folders from which to load PEM files that are certificate+key bundles.
- **ca** <span id="ca"/> changes the ACME CA endpoint. This is most often used to set [Let's Encrypt's staging endpoint <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) when testing, or an internal ACME server. (To change this value for the whole Caddyfile, use the `acme_ca` [global option](/docs/caddyfile/options) instead.)
- **ca** <span id="ca"/> changes the ACME CA endpoint. This is most often used to set [Let's Encrypt's staging endpoint <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) when testing, or an internal ACME server. (To change this value for the whole Caddyfile, use the `acme_ca` [global option](/docs/caddyfile/options) instead.)
- **ca_root** <span id="ca_root"/> specifies a PEM file that contains a trusted root certificate for the ACME CA endpoint, if not in the system trust store.
- **key_type** <span id="key_type"/> is the type of key to use when generating CSRs. Only set this if you have a specific requirement.
- **dns** <span id="dns"/> enables the [DNS challenge](/docs/automatic-https#dns-challenge) using the specified provider plugin, which must be plugged in from one of the [`caddy-dns` <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) repositories. Each provider plugin may have their own syntax following their name; refer to their docs for details. Maintaining support for each DNS provider is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
- **dns** <span id="dns"/> enables the [DNS challenge](/docs/automatic-https#dns-challenge) using the specified provider plugin, which must be plugged in from one of the [`caddy-dns` <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) repositories. Each provider plugin may have their own syntax following their name; refer to their docs for details. Maintaining support for each DNS provider is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
- **propagation_timeout** <span id="propagation_timeout"/> is a [duration value](/docs/conventions#durations) that sets the maximum time to wait for the DNS TXT records to appear when using the DNS challenge. Set to `-1` to disable propagation checks. Default 2 minutes.
@ -114,13 +114,13 @@ Keep in mind that Let's Encrypt may send you emails about your certificate neari
- **dns_challenge_override_domain** <span id="dns_challenge_override_domain"/> overrides the domain to use for the DNS challenge. This is to delegate the challenge to a different domain.
You may want to use this if your primary domain's DNS provider does not have a [DNS plugin <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) available. You can instead add a `CNAME` record with subdomain `_acme-challenge` to your primary domain, pointing to a secondary domain for which you _do_ have a plugin.
You may want to use this if your primary domain's DNS provider does not have a [DNS plugin <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) available. You can instead add a `CNAME` record with subdomain `_acme-challenge` to your primary domain, pointing to a secondary domain for which you _do_ have a plugin.
When ACME issuers try to solve the DNS challenge for your primary domain, they will then follow the `CNAME` to your secondary domain to find the `TXT` record.
- **resolvers** <span id="resolvers"/> customizes the DNS resolvers used when performing the DNS challenge; these take precedence over system resolvers or any default ones. If set here, the resolvers will propagate to all configured certificate issuers.
This is typically a list of IP addresses. For example, to use [Google Public DNS <img src="/resources/images/external-link.svg" class="external-link">](https://developers.google.com/speed/public-dns):
This is typically a list of IP addresses. For example, to use [Google Public DNS <img src="/old/resources/images/external-link.svg" class="external-link">](https://developers.google.com/speed/public-dns):
```caddy-d
resolvers 8.8.8.8 8.8.4.4
@ -230,13 +230,13 @@ Obtains certificates using the ACME protocol. Note that `acme` is a default issu
- **dns_challenge_override_domain** <span id="dns_challenge_override_domain"/> overrides the domain to use for the DNS challenge. This is to delegate the challenge to a different domain.
You may want to use this if your primary domain's DNS provider does not have a [DNS plugin <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) available. You can instead add a `CNAME` record with subdomain `_acme-challenge` to your primary domain, pointing to a secondary domain for which you _do_ have a plugin.
You may want to use this if your primary domain's DNS provider does not have a [DNS plugin <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddy-dns) available. You can instead add a `CNAME` record with subdomain `_acme-challenge` to your primary domain, pointing to a secondary domain for which you _do_ have a plugin.
When ACME issuers try to solve the DNS challenge for your primary domain, they will then follow the `CNAME` to your secondary domain to find the `TXT` record.
- **resolvers** <span id="resolvers"/> customizes the DNS resolvers used when performing the DNS challenge; these take precedence over system resolvers or any default ones. If set here, the resolvers will propagate to all configured certificate issuers.
This is typically a list of IP addresses. For example, to use [Google Public DNS <img src="/resources/images/external-link.svg" class="external-link">](https://developers.google.com/speed/public-dns):
This is typically a list of IP addresses. For example, to use [Google Public DNS <img src="/old/resources/images/external-link.svg" class="external-link">](https://developers.google.com/speed/public-dns):
```caddy-d
resolvers 8.8.8.8 8.8.4.4
@ -298,7 +298,7 @@ These manager modules come standard with the `tls` directive:
#### tailscale
Get certificates from a locally-running [Tailscale <img src="/resources/images/external-link.svg" class="external-link">](https://tailscale.com) instance. [HTTPS must be enabled in your Tailscale account](https://tailscale.com/kb/1153/enabling-https/) (or your open source [Headscale server <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/juanfont/headscale)); and the Caddy process must either be running as root, or you must configure `tailscaled` to give your Caddy user [permission to fetch certificates](https://github.com/caddyserver/caddy/pull/4541#issuecomment-1021568348).
Get certificates from a locally-running [Tailscale <img src="/old/resources/images/external-link.svg" class="external-link">](https://tailscale.com) instance. [HTTPS must be enabled in your Tailscale account](https://tailscale.com/kb/1153/enabling-https/) (or your open source [Headscale server <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/juanfont/headscale)); and the Caddy process must either be running as root, or you must configure `tailscaled` to give your Caddy user [permission to fetch certificates](https://github.com/caddyserver/caddy/pull/4541#issuecomment-1021568348).
_**NOTE: This is usually unnecessary!** Caddy automatically uses Tailscale for all `*.ts.net` domains without any extra configuration._

View file

@ -323,7 +323,7 @@ Skips the attempts to install the local CA's root into the system trust store, a
##### `acme_ca`
Specifies the URL to the ACME CA's directory. It is strongly recommended to set this to Let's Encrypt's [staging endpoint <img src="/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) for testing or development. Default: ZeroSSL and Let's Encrypt's production endpoints.
Specifies the URL to the ACME CA's directory. It is strongly recommended to set this to Let's Encrypt's [staging endpoint <img src="/old/resources/images/external-link.svg" class="external-link">](https://letsencrypt.org/docs/staging-environment/) for testing or development. Default: ZeroSSL and Let's Encrypt's production endpoints.
Note that a globally-configured ACME CA may not apply to all sites; see the [hostname requirements](/docs/automatic-https#hostname-requirements) for using the default ACME issuer(s).
@ -642,7 +642,7 @@ Events typically include a metadata payload. The best way to learn about events
Binds an event handler to the named event. Specify the name of the event handler module, followed by its configuration.
For example, to run a command after a certificate is obtained ([third-party plugin <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/mholt/caddy-events-exec) required), with a part of the event payload being passed to the script using a placeholder:
For example, to run a command after a certificate is obtained ([third-party plugin <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/mholt/caddy-events-exec) required), with a part of the event payload being passed to the script using a placeholder:
```caddy
{
@ -656,7 +656,7 @@ For example, to run a command after a certificate is obtained ([third-party plug
These standard events are emitted by Caddy:
- [`tls` events <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/certmagic#events)
- [`tls` events <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/certmagic#events)
- [`reverse_proxy` events](/docs/caddyfile/directives/reverse_proxy#events)
Plugins may also emit events, so check their documentation for details.

View file

@ -65,7 +65,7 @@ unix//path/to/socket|0200
<aside class="tip">
Caddy network addresses are not URLs. URLs couple the lower and higher layers of the [OSI model <img src="/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/OSI_model#Layer_architecture), but Caddy often uses network addresses independently of a specific application, so combining them would be problematic. In Caddy, network addresses refer precisely to resources that can be dialed or bound at L3-L5, but URLs combine L3-L7, which is too many. A network address requires a host+port and path to be mutually exclusive, but URLs do not. Network addresses sometimes support port ranges, but URLs do not.
Caddy network addresses are not URLs. URLs couple the lower and higher layers of the [OSI model <img src="/old/resources/images/external-link.svg" class="external-link">](https://en.wikipedia.org/wiki/OSI_model#Layer_architecture), but Caddy often uses network addresses independently of a specific application, so combining them would be problematic. In Caddy, network addresses refer precisely to resources that can be dialed or bound at L3-L5, but URLs combine L3-L7, which is too many. A network address requires a host+port and path to be mutually exclusive, but URLs do not. Network addresses sometimes support port ranges, but URLs do not.
</aside>
@ -78,7 +78,7 @@ Caddy's configuration supports the use of _placeholders_ (variables). Using plac
<aside class="tip">
Placeholders are a similar idea to variables in other software. For example, [nginx has variables <img src="/resources/images/external-link.svg" class="external-link">](https://nginx.org/en/docs/varindex.html) like `$uri` and `$document_root`.
Placeholders are a similar idea to variables in other software. For example, [nginx has variables <img src="/old/resources/images/external-link.svg" class="external-link">](https://nginx.org/en/docs/varindex.html) like `$uri` and `$document_root`.
</aside>
@ -98,7 +98,7 @@ Placeholder | Description
`{system.arch}` | The system's architecture
`{system.wd}` | The current working directory
`{time.now}` | The current time as a Go Time struct
`{time.now.http}` | The current time in the format used in [HTTP headers <img src="/resources/images/external-link.svg" class="external-link">](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified)
`{time.now.http}` | The current time in the format used in [HTTP headers <img src="/old/resources/images/external-link.svg" class="external-link">](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified)
`{time.now.unix}` | The current time as a unix timestamp in seconds
`{time.now.unix_ms}` | The current time as a unix timestamp in milliseconds
`{time.now.common_log}` | The current time in Common Log Format

View file

@ -9,8 +9,8 @@ Caddy is easy to extend because of its modular architecture. Most kinds of Caddy
**Prerequisites:**
- Basic understanding of [Caddy's architecture](/docs/architecture)
- Go language proficiency
- [`go` <img src="/resources/images/external-link.svg" class="external-link">](https://golang.org/doc/install)
- [`xcaddy` <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/xcaddy)
- [`go` <img src="/old/resources/images/external-link.svg" class="external-link">](https://golang.org/doc/install)
- [`xcaddy` <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/xcaddy)
## Quick Start

View file

@ -92,7 +92,7 @@ You can see how the structured log is much more useful and contains much more in
Because the logs are structured and strongly-typed, they can be encoded into any format. So if you don't want to work with JSON, logs can be encoded into any other representation. Caddy supports others through [log encoder modules](/docs/json/logging/logs/encoder/), and even more can be added.
**Most importantly** in the distinction between structured logs and legacy formats, with a performance penalty a structured log [can be transformed into the legacy Common Log Format <img src="/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder), but not the other way around. It is non-trivial (or at least inefficient) to go from CLF to structured formats, and impossible considering the lack of information.
**Most importantly** in the distinction between structured logs and legacy formats, with a performance penalty a structured log [can be transformed into the legacy Common Log Format <img src="/old/resources/images/external-link.svg" class="external-link">](https://github.com/caddyserver/transform-encoder), but not the other way around. It is non-trivial (or at least inefficient) to go from CLF to structured formats, and impossible considering the lack of information.
In essence, efficient, structured logging generally promotes these philosophies:

View file

@ -2,17 +2,17 @@
<html>
<head>
<title>Modules - Caddy Documentation</title>
{{import "/includes/docs/head.html"}}
{{import "/old/includes/docs/head.html"}}
{{template "docs-head"}}
<link rel="stylesheet" href="/resources/css/docs-json.css{{template "cacheBust"}}">
<script src="/resources/js/marked-0.8.0.min.js"></script>
<script src="/resources/js/docs-api.js{{template "cacheBust"}}"></script>
<script src="/resources/js/module-docs.js{{template "cacheBust"}}"></script>
<link rel="stylesheet" href="/old/resources/css/docs-json.css{{template "cacheBust"}}">
<script src="/old/resources/js/marked-0.8.0.min.js"></script>
<script src="/old/resources/js/docs-api.js{{template "cacheBust"}}"></script>
<script src="/old/resources/js/module-docs.js{{template "cacheBust"}}"></script>
</head>
<body>
{{include "/includes/docs/header.html"}}
{{include "/old/includes/docs/header.html"}}
<main>
{{include "/includes/docs/nav.html"}}
{{include "/old/includes/docs/nav.html"}}
<div class="article-container">
<div class="paper" id="paper1"></div>
<div class="paper" id="paper2"></div>
@ -42,8 +42,8 @@
<div id="module-template" class="module-repo-container">
<div class="module-repo-selector"></div>
<article>
{{include "/includes/docs/renderbox.html"}}
{{include "/includes/docs/details.html"}}
{{include "/old/includes/docs/renderbox.html"}}
{{include "/old/includes/docs/details.html"}}
</article>
</div>
</div>
@ -51,7 +51,7 @@
</div>
<div class="sidebar"></div>
</main>
{{include "/includes/docs/hovercard.html"}}
{{include "/includes/footer.html"}}
{{include "/old/includes/docs/hovercard.html"}}
{{include "/old/includes/footer.html"}}
</body>
</html>

View file

@ -2,21 +2,21 @@
<html>
<head>
<title>Download Caddy</title>
{{import "/includes/head.html"}}
{{import "/old/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/resources/css/download.css{{template "cacheBust"}}">
<script src="/resources/js/jquery-3.4.1.min.js"></script>
<script src="/resources/js/sweetalert.min.js"></script>
<script src="/resources/js/download.js{{template "cacheBust"}}"></script>
<link rel="stylesheet" href="/old/resources/css/download.css{{template "cacheBust"}}">
<script src="/old/resources/js/jquery-3.4.1.min.js"></script>
<script src="/old/resources/js/sweetalert.min.js"></script>
<script src="/old/resources/js/download.js{{template "cacheBust"}}"></script>
</head>
<body>
<div class="wrapper">
<header>
<div id="logo-container">
<a href="/"><img src="/resources/images/caddy-logo.svg" id="logo" alt="Caddy"></a>
<div id="zerossl-project">a <a href="https://zerossl.com"><img src="/resources/images/zerossl-logo.svg" id="zerossl-logo"></a> project</div>
<a href="/"><img src="/old/resources/images/caddy-logo.svg" id="logo" alt="Caddy"></a>
<div id="zerossl-project">a <a href="https://zerossl.com"><img src="/old/resources/images/zerossl-logo.svg" id="zerossl-logo"></a> project</div>
</div>
{{include "/includes/header-nav.html"}}
{{include "/old/includes/header-nav.html"}}
</header>
<div class="notice">
@ -89,6 +89,6 @@
</div>
</div>
{{include "/includes/footer.html"}}
{{include "/old/includes/footer.html"}}
</body>
</html>

1726
src/features.html Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
{{define "account-head"}}
{{import "/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/resources/css/account/common.css{{template "cacheBust"}}">
<script src="/resources/js/jquery-3.4.1.min.js"></script>
<script src="/resources/js/sweetalert.min.js"></script>
<script src="/resources/js/account/common.js{{template "cacheBust"}}"></script>
{{end}}

View file

@ -1,13 +0,0 @@
{{define "docs-head"}}
{{import "/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/resources/css/docs.css{{template "cacheBust"}}">
<link rel="stylesheet" href="/resources/css/chroma.css{{template "cacheBust"}}">
{{$directives := list }}
{{range $i, $file := (listFiles "/docs/markdown/caddyfile/directives")}}
{{$directives = append $directives ($file | trimSuffix ".md")}}
{{end}}
<script type="text/javascript">window.CaddyfileDirectives = {{$directives | toJson}};</script>
<script src="/resources/js/jquery-3.4.1.min.js"></script>
<script src="/resources/js/docs.js{{template "cacheBust"}}"></script>
{{end}}

View file

@ -1,12 +0,0 @@
<header>
<div id="logo-container">
<div id="logo-docs-container">
<a href="/"><img src="/resources/images/caddy-logo.svg" id="logo" alt="Caddy"></a>
<div id="logo-docs">Documentation</div>
</div>
<div id="zerossl-project">
a <a href="https://zerossl.com"><img src="/resources/images/zerossl-logo.svg" id="zerossl-logo"></a> project
</div>
</div>
{{include "/includes/header-nav.html"}}
</header>

View file

@ -0,0 +1,24 @@
<div class="ex-custom-ca">
```caddy
{
pki {
ca corporate {
name "Our Corporation Authority"
}
}
}
internal.example.com {
# ACME endpoint: /acme/corporate/directory
acme_server {
ca corporate
}
}
```
</div>
<script>
window.$_('.ex-custom-ca code').classList.add('light');
</script>

View file

@ -0,0 +1,63 @@
<script>
ready(() => {
let startElement, endElement;
startElement = findWithContent('.ex-fs pre.chroma code span.line', 'file_server /downloads/* {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-compress rollover-blue');
startElement = findWithContent('.ex-fs pre.chroma code span', 'encode');
endElement = findNextText(startElement, 'gzip');
wrapRangeWithSpan(startElement, endElement, 'rollover-compress rollover-blue');
startElement = findWithContent('.ex-fs pre.chroma code span.line', 'file_server /database/* {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-vfs rollover-green');
startElement = findWithContent('.ex-fs pre.chroma code span.line', 'file_server /embedded/* {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-vfs rollover-green');
startElement = findWithContent('.ex-fs pre.chroma code span', '# (Range/Etag/etc. all work without extra config)');
wrapRangeWithSpan(startElement, startElement, 'rollover-range rollover-yellow');
startElement = findWithContent('.ex-fs pre.chroma code span', 'file_server');
endElement = findNextText(startElement, 'browse');
wrapRangeWithSpan(startElement, endElement, 'rollover-browse rollover-purple');
window.$_('.ex-fs code').classList.add('light');
});
</script>
<div class="ex-fs">
```caddy
example.com
root * /var/www
# Serve precompressed files if present
file_server /downloads/* {
precompressed gzip zstd br
}
# Compress everything else that would benefit
encode zstd gzip
# Static site using database as file system
file_server /database/* {
fs sqlite data.sql
}
# Static site embedded within the Caddy binary
file_server /embedded/* {
fs embedded
}
# (Range/Etag/etc. all work without extra config)
# Serve static site with directory listings
file_server browse
```
</div>

View file

@ -0,0 +1,22 @@
<div class="ex-json-automate-certs">
```json
{
"apps": {
"tls": {
"certificates": {
"automate": [
"example.com",
"sub.example.com",
"example.net"
]
}
}
}
}
```
</div>
<script>
window.$_('.ex-json-automate-certs code').classList.add('light');
</script>

View file

@ -0,0 +1,21 @@
<div class="ex-local-https">
```caddy
localhost {
respond "Hello from HTTPS!"
}
192.168.1.10 {
respond "Also HTTPS!"
}
http://localhost {
respond "Plain HTTP"
}
```
</div>
<script>
window.$_('.ex-local-https code').classList.add('light');
</script>

View file

@ -0,0 +1,36 @@
<script>
ready(() => {
let startElement, endElement;
startElement = findWithContent('.ex-on-demand pre.chroma code span.line', 'on_demand_tls {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-abuse rollover-purple');
startElement = findWithContent('.ex-on-demand pre.chroma code span.line', 'tls');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-ondemand rollover-green');
window.$_('.ex-on-demand code').classList.add('light');
});
</script>
<div class="ex-on-demand">
```caddy
{
on_demand_tls {
ask http://localhost:9123/check
}
}
https:// {
tls {
on_demand
}
# reverse_proxy, etc...
}
# other sites...
```
</div>

View file

@ -0,0 +1,53 @@
<script>
ready(() => {
let startElement, endElement;
startElement = findWithContent('.ex-proxy pre.chroma code span', 'php_fastcgi');
endElement = findNextText(startElement, '9000');
wrapRangeWithSpan(startElement, endElement, 'rollover-php rollover-green');
startElement = findWithContent('.ex-proxy pre.chroma code span.line', 'reverse_proxy /api/* {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-dynamic-backends rollover-purple');
startElement = findWithContent('.ex-proxy pre.chroma code span.line', 'reverse_proxy /service/* {');
endElement = findNextText(startElement, '}');
wrapRangeWithSpan(startElement, endElement, 'rollover-ha rollover-blue');
window.$_('.ex-proxy code').classList.add('dark');
});
</script>
<div class="ex-proxy">
```caddy
example.com
# Serve PHP sites
handle /blog/* {
root * /var/www/wordpress
php_fastcgi localhost:9000
file_server
}
# Proxy an autoscaling API with dynamic backends
reverse_proxy /api/* {
dynamic srv _api._tcp.example.com
}
# Proxy a compute-heavy distributed service
# with load balancing and health checks
reverse_proxy /service/* {
to 10.0.1.1:80 10.0.1.2:80 10.0.1.3:80
lb_policy least_conn
lb_try_duration 10s
fail_duration 5s
}
# Proxy everything else to an HTTPS upstream
reverse_proxy https://service.example.com {
header_up Host {upstream_hostport}
}
```
</div>

View file

@ -0,0 +1,23 @@
<div class="ex-website-caddyfile">
```caddy
caddyserver.com
root * src
file_server
templates # markdown & syntax highlighting!
encode zstd gzip
redir /docs/json /docs/json/
rewrite /docs/json/* /docs/json/index.html
rewrite /docs/* /docs/index.html
reverse_proxy /api/* localhost:9002
```
</div>
<script>
window.$_('.ex-website-caddyfile code').classList.add('light');
</script>

View file

@ -1,24 +1,49 @@
<div class="wrapper">
<footer>
<div>
<img src="/resources/images/caddy-logo.svg" alt="Caddy" id="footer-logo">
An <a href="https://github.com/caddyserver/caddy">open source</a> Go community project
<footer>
<div class="wrapper">
<div class="logo-area">
<img src="/resources/images/logo-dark.svg" class="logo" alt="Caddy web server">
<p>
A free <a href="https://github.com/caddyserver/caddy">open source</a> project
that relies on <a href="/sponsor">sponsors</a>.
</p>
<p>
<a href="https://usefathom.com/ref/AUKNWU">Privacy-respecting analytics</a> by Fathom
</p>
<br>
in partnership with <a href="https://www.ardanlabs.com/">Ardan Labs</a>
<br>
<small><a href="https://usefathom.com/ref/AUKNWU">Privacy-respecting analytics by Fathom</a></small>
<p>
&copy; {{now | date "2006"}} ZeroSSL. All rights reserved.
</p>
</div>
<div class="copyright">
&copy; {{now | date "2006"}} ZeroSSL. All rights reserved.
<br>
Caddy&reg; is a registered trademark of ZeroSSL GmbH.
<div class="link-col">
<div class="col-header">Project</div>
<a href="/features">Features</a>
<a href="/download">Download</a>
<a href="/docs">Documentation</a>
</div>
</footer>
</div>
<!-- Fathom - beautiful, simple website analytics -->
<script src="https://cdn.usefathom.com/script.js" site="GVMGKAKP" honor-dnt="true" defer></script>
<!-- / Fathom -->
<!-- Algolia DocSearch -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@docsearch/js@3"></script>
<div class="link-col">
<div class="col-header">Business services</div>
<a href="/support">Support</a>
<a href="/sponsor">Sponsorships</a>
</div>
<div class="link-col">
<div class="col-header">Community</div>
<a href="https://caddy.community">Forum</a>
<a href="https://github.com/caddyserver">GitHub</a>
<a href="https://twitter.com/caddyserver">Twitter / X</a>
<a href="https://scholar.google.com/scholar?q=caddy+web+server">Research</a>
</div>
</div>
<div class="wrapper nostalgia">
<p>Caddy supports an open Web that promotes privacy, preserves data ownership, fosters innovation, freely allows varieties of client software, and safeguards human sanctity.</p>
<div class="nostalgia-badges">
<img src="/resources/images/nostalgia/get.gif" title="Honoring early Web clients">
<img src="/resources/images/nostalgia/microsoft-ie.gif" title="Honoring early Web clients">
<img src="/resources/images/nostalgia/now_anim.gif" title="Honoring early Web clients">
<div class="w3c">
<img src="/resources/images/nostalgia/valid_html5_yellow.png" title="This site uses HTML 5">
<img src="/resources/images/nostalgia/valid_css3_blue.png" title="This site uses CSS 3">
</div>
<div title="Don't forget to sign our guestbook!">{{ maybe "hitCounter" .OriginalReq.URL.Path }}</div>
</div>
</div>
</footer>

View file

@ -9,33 +9,36 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin />
<link rel="icon" href="/resources/images/favicon.png{{template "cacheBust"}}">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:400,700|Maven+Pro:400,700,900|Montserrat:400,700|PT+Mono&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gantari:wght@400..800&family=Figtree:wght@300..900&&family=JetBrains+Mono:wght@400..600&family=Inter:wght@400..600&family=Poppins:wght@400;500;600;700;800&family=Albert+Sans:wght@400..600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/resources/css/common.css{{template "cacheBust"}}">
<link rel="stylesheet" href="/resources/css/chroma.css{{template "cacheBust"}}">
<script src="/resources/js/lib.js{{template "cacheBust"}}"></script>
<script src="/resources/js/common.js{{template "cacheBust"}}"></script>
<!-- General metatags -->
<meta name="author" content="Caddy Web Server">
<meta name="description" content="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta name="theme-color" content="#5ea9a2">
<meta name="theme-color" content="#1b3143">
<!-- Open Graph tags -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://caddyserver.com/">
<meta property="og:url" content="https://{{.Req.Host}}/">
<meta property="og:description" content="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta property="og:image" content="https://caddyserver.com/resources/images/caddy-open-graph.jpg">
<meta property="og:image" content="https://{{.Req.Host}}/resources/images/open-graph-square.png">
<!-- Twitter card tags additive with the og: tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:domain" value="caddyserver.com">
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" value="{{.Req.Host}}">
<meta name="twitter:site" value="@caddyserver">
<meta name="twitter:description" value="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta name="twitter:image" content="https://caddyserver.com/resources/images/caddy-open-graph.jpg">
<meta name="twitter:url" value="https://caddyserver.com/">
<!-- Algolia DocSearch -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
<meta name="twitter:image" content="https://{{.Req.Host}}/resources/images/open-graph-square.png{{template "cacheBust"}}">
<meta name="twitter:url" value="https://{{.Req.Host}}{{.OriginalReq.URL}}">
<!-- Global site tag (gtag.js) - Google Analytics (ZeroSSL) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-2DLB04LK4P"></script>
@ -45,8 +48,4 @@
gtag('js', new Date());
gtag('config', 'G-2DLB04LK4P');
</script>
<!-- Alpine.js to augment markdown docs -->
<script src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
{{end}}

208
src/includes/header.html Normal file
View file

@ -0,0 +1,208 @@
<header class="{{index .Args 0}}">
<div class="topbar">
<div class="wrapper">
<a href="https://zerossl.com">
A ZeroSSL Project
</a>
<a href="https://store.caddyserver.com">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-building-store" width="24" height="24"
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 21l18 0" />
<path d="M3 7v1a3 3 0 0 0 6 0v-1m0 1a3 3 0 0 0 6 0v-1m0 1a3 3 0 0 0 6 0v-1h-18l2 -4h14l2 4" />
<path d="M5 21l0 -10.15" />
<path d="M19 21l0 -10.15" />
<path d="M9 21v-4a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v4" />
</svg>
Store
</a>
<a href="https://github.com/caddyserver/caddy">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"></path>
</svg>
GitHub
</a>
<a href="javascript:nextTheme();">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brightness-half" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 9a3 3 0 0 0 0 6v-6z"></path>
<path d="M6 6h3.5l2.5 -2.5l2.5 2.5h3.5v3.5l2.5 2.5l-2.5 2.5v3.5h-3.5l-2.5 2.5l-2.5 -2.5h-3.5v-3.5l-2.5 -2.5l2.5 -2.5z"></path>
</svg>
<span>Theme: <span id="current-theme">System</span></span>
</a>
</div>
</div>
<div class="navbar wrapper">
<a href="/" class="logo-link">
<img src="/resources/images/logo-light.svg" class="logo" id="logo-light" alt="Caddy web server">
<img src="/resources/images/logo-dark.svg" class="logo" id="logo-dark" alt="Caddy web server">
</a>
<nav role="navigation">
<ul>
<li class="dropdown-trigger">
<a href="/docs/">Documentation</a>
<!--
<div class="dropdown">
<div class="row flatlinks">
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-server-bolt" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z"></path>
<path d="M15 20h-9a3 3 0 0 1 -3 -3v-2a3 3 0 0 1 3 -3h12"></path>
<path d="M7 8v.01"></path>
<path d="M7 16v.01"></path>
<path d="M20 15l-2 3h3l-2 3"></path>
</svg>
Install
</b>
Various ways to install Caddy on your computer or server
</a>
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-text" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
<path d="M9 9l1 0"></path>
<path d="M9 13l6 0"></path>
<path d="M9 17l6 0"></path>
</svg>
Caddyfile
</b>
A simplified, human-friendly configuration format
</a>
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-code" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M14 3v4a1 1 0 0 0 1 1h4"></path>
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path>
<path d="M10 13l-1 2l1 2"></path>
<path d="M14 13l1 2l-1 2"></path>
</svg>
JSON
</b>
Powerful and programmable native config format
</a>
</div>
<div class="row">
<div class="linkbox">
<div class="col">
<div class="links-header">Tutorials</div>
<a href="javascript:">Caddy basics</a>
<a href="javascript:">Static files</a>
<a href="javascript:">Reverse proxy</a>
<a href="javascript:">Troubleshooting</a>
</div>
<div class="col">
<div class="links-header">Reference</div>
<a href="javascript:">Command line</a>
<a href="javascript:">Caddyfile</a>
<a href="javascript:">API</a>
<a href="javascript:">JSON Config</a>
<a href="javascript:">Auto HTTPS</a>
</div>
<!-- <div class="col">
<div class="links-header">Caddyfile</div>
<a href="javascript:">Directives</a>
<a href="javascript:">Request matchers</a>
<a href="javascript:">Global options</a>
</div> -- >
<div class="col">
<div class="links-header">Develop</div>
<a href="javascript:">Architecture</a>
<a href="javascript:">Contribute</a>
<a href="javascript:">Write a module</a>
</div>
<div class="col">
<div class="links-header">Articles</div>
<a href="javascript:">Logging</a>
<a href="javascript:">Monitoring</a>
<a href="javascript:">Security</a>
<a href="javascript:">Custom domains</a>
<a href="javascript:">All articles...</a>
</div>
</div>
<!-- Make a new linkbox div for a separate section. -- >
</div>
<div class="row featured">
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-atom-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
<path d="M12 21l0 .01"></path>
<path d="M3 9l0 .01"></path>
<path d="M21 9l0 .01"></path>
<path d="M8 20.1a9 9 0 0 1 -5 -7.1"></path>
<path d="M16 20.1a9 9 0 0 0 5 -7.1"></path>
<path d="M6.2 5a9 9 0 0 1 11.4 0"></path>
</svg>
Examples
</b>
Learn from examples contributed by the community
</a>
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-message-circle-question" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M15.02 19.52c-2.341 .736 -5 .606 -7.32 -.52l-4.7 1l1.3 -3.9c-2.324 -3.437 -1.426 -7.872 2.1 -10.374c3.526 -2.501 8.59 -2.296 11.845 .48c1.649 1.407 2.575 3.253 2.742 5.152"></path>
<path d="M19 22v.01"></path>
<path d="M19 19a2.003 2.003 0 0 0 .914 -3.782a1.98 1.98 0 0 0 -2.414 .483"></path>
</svg>
<!-- <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-help-hexagon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M19.875 6.27c.7 .398 1.13 1.143 1.125 1.948v7.284c0 .809 -.443 1.555 -1.158 1.948l-6.75 4.27a2.269 2.269 0 0 1 -2.184 0l-6.75 -4.27a2.225 2.225 0 0 1 -1.158 -1.948v-7.285c0 -.809 .443 -1.554 1.158 -1.947l6.75 -3.98a2.33 2.33 0 0 1 2.25 0l6.75 3.98h-.033z"></path>
<path d="M12 16v.01"></path>
<path d="M12 13a2 2 0 0 0 .914 -3.782a1.98 1.98 0 0 0 -2.414 .483"></path>
</svg> -- >
FAQ
</b>
Get fast answers to common questions
</a>
<a href="/docs/install">
<b>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-hexagons" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M4 18v-5l4 -2l4 2v5l-4 2z"></path>
<path d="M8 11v-5l4 -2l4 2v5"></path>
<path d="M12 13l4 -2l4 2v5l-4 2l-4 -2"></path>
</svg>
Modules
</b>
The official list of registered Caddy plugins
</a>
</div>
<div class="row">
<div class="plainbox">
<a href="javascript:">Documentation index</a>
<a href="javascript:">Community wiki</a>
<a href="javascript:">Contribute to docs</a>
</div>
</div>
</div>
-->
</li>
<li>
<a href="/features">Features</a>
</li>
<li>
<a href="/account">Account</a>
</li>
<li>
<a href="/support">Support</a>
</li>
</ul>
</nav>
<div class="actions">
<a href="/download" class="button primary">Download</a>
<a href="/sponsor" class="button purple">Sponsor</a>
</div>
</div>
</header>

View file

@ -0,0 +1,136 @@
<!--
All the markdown content is hidden by default, and loaded by ID.
The HTML ID should start with qa-content- followed by the state ID.
Make sure to leave empty lines after the opening of the div and before the end,
otherwise the markdown parsing will not work.
-->
<div id="qa-content-install_dpkg">
<pre><code class="cmd"><span class="bash">sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https</span>
<span class="bash">curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg</span>
<span class="bash">curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list</span>
<span class="bash">sudo apt update</span>
<span class="bash">sudo apt install caddy</span></code></pre>
</div>
<div id="qa-content-install_rpm">
<pre><code class="cmd"><span class="bash">dnf install 'dnf-command(copr)'</span>
<span class="bash">dnf copr enable @caddy/caddy</span>
<span class="bash">dnf install caddy</span></code></pre>
</div>
<div id="qa-content-install_arch">
<pre><code class="cmd"><span class="bash">pacman -Syu caddy</span></code></pre>
</div>
<div id="qa-content-install_mac">
<pre><code class="cmd bash">brew install caddy</code></pre>
</div>
<div id="qa-content-install_windows">
<p>Chocolatey:</p> <pre><code class="cmd">choco install caddy</code></pre>
<p>Scoop:</p> <pre><code class="cmd">scoop install caddy</code></pre>
</div>
<div id="qa-content-install_nix">
- Package name: [`caddy`](https://search.nixos.org/packages?channel=unstable&show=caddy&query=caddy)
- NixOS module: [`services.caddy`](https://search.nixos.org/options?channel=unstable&show=services.caddy.enable&query=services.caddy)
</div>
<div id="qa-content-install_android">
In Termux: <pre><code class="cmd">pkg install caddy</code></pre>
</div>
<div id="qa-content-install_other">
<h4>Webi</h2>
<p>Linux and macOS:</p>
<pre><code class="cmd bash">curl -sS https://webi.sh/caddy | sh</code></pre>
<p>Windows:</p>
<pre><code class="cmd">curl.exe https://webi.ms/caddy | powershell</code></pre>
<h4>Ansible</h4>
<pre><code class="cmd bash">ansible-galaxy install nvjacobo.caddy</code></pre>
</div>
<div id="qa-content-install_docker">
<pre><code class="cmd bash">docker pull caddy</code></pre>
</div>
<div id="qa-content-install_build">
Make sure to have `git` and the latest version of [Go](https://go.dev) installed.
<pre><code class="cmd"><span class="bash">git clone "https://github.com/caddyserver/caddy.git"</span>
<span class="bash">cd caddy/cmd/caddy/</span>
<span class="bash">go build</span></code></pre>
</div>
<div id="qa-content-install_with_plugins">
[`xcaddy`](https://github.com/caddyserver/xcaddy) is a command line tool that helps you build Caddy with plugins. A basic build looks like:
<pre><code class="cmd bash">xcaddy build</code></pre>
To build with plugins, use `--with`:
<pre><code class="cmd bash">xcaddy build \
--with github.com/caddyserver/nginx-adapter
--with github.com/caddyserver/ntlm-transport@v0.1.1</code></pre>
</div>
<div id="qa-content-install_binary">
1. Obtain a Caddy binary:
- [from releases on GitHub](https://github.com/caddyserver/caddy/releases) (expand "Assets")
- Refer to [Verifying Asset Signatures](/docs/signature-verification) for how to verify the asset signature
- [from our download page](/download)
- [by building from source](/docs/build) (either with `go` or `xcaddy`)
2. [Install Caddy as a system service.](/docs/running#manual-installation) This is strongly recommended, especially for production servers.
Place the binary in one of your `$PATH` (or `%PATH%` on Windows) directories so you can run `caddy` without typing the full path of the executable file. (Run `echo $PATH` to see the list of directories that qualify.)
You can upgrade static binaries by replacing them with newer versions and restarting Caddy. The [`caddy upgrade` command](/docs/command-line#caddy-upgrade) can make this easy.
</div>
<div id="qa-content-cfg_ondemand_smallscale">
On-demand TLS is designed for situations when you either don't control the domain names, or you have too many certificates to load all at once when the server starts. For every other use case, standard TLS automation is likely better suited.
</div>
<div id="qa-content-cfg_ondemand_caddyfile">
In order to prevent abuse, you must first configure an `ask` endpoint so Caddy can check whether it should get a certificate. Add this to your global options at the top:
```caddy
{
on_demand_tls {
ask http://localhost:5555/check
}
}
```
Change that endpoint to be something you've set up that will respond with HTTP 200 if the domain given in the `domain=` query parameter is allowed to have a certificate.
Then create a site block that serves all sites/hosts on the TLS port:
```caddy
https:// {
tls {
on_demand
}
}
```
This is the minimum config to enable Caddy to accept and service TLS connections for arbitrary hosts. This config doesn't invoke any handlers. Usually you'll also [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy) to your backend application.
</div>

View file

@ -0,0 +1,103 @@
{{ include "/includes/quick-assist/structure.html" }}
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('quick_assist', () => ({
current: 'start',
crumbs: [],
structure: quickAssistStructure,
getQuestion() {
const data = this.structure[this.current];
return data ? (data.title ?? data.prompt) : "";
},
getContent() {
const content = document.getElementById(`qa-content-${this.current}`);
return content ? content.innerHTML : "";
},
getOptions() {
const data = this.structure[this.current];
return data ? (data.options ?? []) : [];
},
hasNext() {
return this.getOptions().some(opt => opt.next);
},
crumbTitle(crumb) {
if (crumb.title) {
return crumb.title;
}
const data = this.structure[crumb.id];
return data ? (data.title ?? data.prompt) : "";
},
goto(next, title = null) {
if (!next) return true;
// Do nothing if last crumb is the same as the next state
const count = this.crumbs.length;
if (count && this.crumbs[count - 1].id === next) return true;
// Change the page
this.current = next;
// Read backwards through the crumbs and if we find it pop everything after it
for (let i = count - 1; i >= 0; i--) {
if (this.crumbs[i].id === next) {
this.crumbs.splice(i + 1);
return false;
}
}
// Insert the crumb
this.crumbs.push({ id: next, title: title });
return false;
},
reset() {
this.current = 'start';
this.crumbs = [];
}
}));
});
</script>
<div x-data="quick_assist" class="box box-filled box-capped quick-assist">
<div class="box-cap quick-assist-history">
<a title="Click quick for slick trick (not AI)" @click="reset()">Quick Assist</a>
<template x-for="crumb in crumbs">
<a x-text="crumbTitle(crumb)" @click="goto(crumb.id)" />
</template>
</div>
<div>
<h3 class="quick-assist-question" x-text="getQuestion()"></h3>
<div class="quick-assist-content" x-html="getContent()"></div>
<div class="quick-assist-options">
<template x-for="opt in getOptions()">
<div>
<a
x-show="opt.href ?? false"
:href="opt.href"
x-text="opt.text ?? ''"
class="button reset"
/>
<a
x-show="!opt.href"
@click.prevent="goto(opt.next, opt.crumb ?? opt.text)"
x-text="opt.text ?? ''"
class="button reset"
/>
</div>
</template>
<a
x-show="!hasNext()"
@click="reset()"
class="button reset"
>
Reset
</a>
</div>
</div>
</div>
<!-- All the markdown content is hidden by default and loaded by ID -->
<div style="display: none;">
{{ markdown (include "/includes/quick-assist/content.md") }}
</div>

View file

@ -0,0 +1,275 @@
<script>
const quickAssistStructure = {
start: {
prompt: "What are you looking for?",
options: [
{
text: "How to install Caddy",
next: "install"
},
{
text: "Help configuring Caddy",
next: "configure"
},
{
text: "A solution to a problem",
next: "solution"
},
{
text: "An example for my use case",
next: "example"
}
]
},
install: {
prompt: "How do you want to install Caddy?",
options: [
{
text: "OS package manager",
next: "install_pkgmgr"
},
{
text: "Docker",
next: "install_docker"
},
{
text: "Build from source",
next: "install_build"
},
{
text: "Build with plugins",
next: "install_with_plugins"
},
{
text: "Pre-built binary",
next: "install_binary"
}
]
},
install_pkgmgr: {
prompt: "Which OS are you using?",
options: [
{
text: "Linux (Debian, Ubuntu, Raspbian)",
next: "install_dpkg"
},
{
text: "Linux (Fedora, RedHat, CentOS)",
next: "install_rpm"
},
{
text: "Linux (Arch, Manjaro, Parabola)",
next: "install_arch"
},
{
text: "macOS",
next: "install_mac"
},
{
text: "Windows",
next: "install_windows"
},
{
text: "Nix/NixOS",
next: "install_nix"
},
{
text: "Android",
next: "install_android"
},
{
text: "Other",
next: "install_other"
}
]
},
install_dpkg: {
title: "Install Caddy on Debian-based systems",
options: [
{
text: "Learn more",
href: "/docs/install#debian-ubuntu-raspbian"
}
]
},
install_rpm: {
title: "Install Caddy via RPM",
options: [
{
text: "Learn more",
href: "/docs/install#fedora-redhat-centos"
}
]
},
install_arch: {
title: "Install Caddy on Arch/Manjaro/Parabola Linux",
options: [
{
text: "Learn more",
href: "/docs/install#arch-linux-manjaro-parabola"
}
]
},
install_mac: {
title: "Install Caddy on macOS",
options: [
{
text: "Learn more",
href: "/docs/install#homebrew"
}
]
},
install_windows: {
title: "Install Caddy on Windows",
options: [
{
text: "Learn more",
href: "/docs/install#windows"
}
]
},
install_nix: {
title: "Install Caddy on Nix/Nixpkgs/NixOS",
options: [
{
text: "Learn more",
href: "/docs/install#nixnixpkgsnixos"
}
]
},
install_android: {
title: "Install Caddy on Android",
content: ``,
options: [
{
text: "Learn more",
href: "/docs/install#termux"
}
]
},
install_other: {
title: "Miscellaneous install methods",
options: [
{
text: "Learn more",
href: "/docs/install#fedora-redhat-centos"
}
]
},
install_docker: {
title: "Official Docker image",
options: [
{
text: "Learn more",
href: "/docs/install#docker"
}
]
},
install_build: {
title: "Build Caddy from source",
options: [
{
text: "Learn more",
href: "/docs/build"
}
]
},
install_with_plugins: {
title: "Build Caddy with plugins",
options: [
{
text: "Learn more",
href: "/docs/build#xcaddy"
}
]
},
install_binary: {
title: "Install Caddy binary manually",
options: [
{
text: "Learn more",
href: "/docs/build#xcaddy"
}
]
},
configure: {
prompt: "What are you trying to configure?",
options: [
{
text: "On-demand TLS",
next: "cfg_ondemand"
},
{
text: "Authentication",
next: "cfg_authentication"
},
{
text: "Load balancing",
next: "cfg_loadbalancing"
}
]
},
cfg_ondemand: {
prompt: "Do you control the (DNS records of) the domain names you're serving?",
options: [
{
text: "Yes",
crumb: "I control the domains",
next: "cfg_ondemand_havecontrol"
},
{
text: "No",
crumb: "DNS out of my control",
next: "cfg_ondemand_ok"
}
]
},
cfg_ondemand_havecontrol: {
prompt: "Do you have hundreds or thousands of your own domain names to serve?",
options: [
{
text: "Yes",
crumb: "Lots of domains",
next: "cfg_ondemand_ok"
},
{
text: "No",
crumb: "Small scale",
next: "cfg_ondemand_smallscale"
}
]
},
cfg_ondemand_smallscale: {
title: "You likely don't need on-demand TLS.",
options: [
{
text: "Learn more",
href: "/docs/automatic-https#on-demand-tls"
}
]
},
cfg_ondemand_ok: {
prompt: "Are you using the Caddyfile or JSON to configure Caddy?",
options: [
{
text: "Caddyfile",
next: "cfg_ondemand_caddyfile"
},
{
text: "JSON",
next: "cfg_ondemand_json"
}
]
},
cfg_ondemand_caddyfile: {
title: "Setting up On-Demand TLS",
options: [
{
text: "Learn more",
href: "/docs/automatic-https#on-demand-tls"
}
]
},
};
</script>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
{{define "account-head"}}
{{import "/old/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/old/resources/css/account/common.css{{template "cacheBust"}}">
<script src="/old/resources/js/jquery-3.4.1.min.js"></script>
<script src="/old/resources/js/sweetalert.min.js"></script>
<script src="/old/resources/js/account/common.js{{template "cacheBust"}}"></script>
{{end}}

View file

@ -1,6 +1,6 @@
<nav>
<div class="logo-container">
<img src="/resources/images/caddy-lock.png" alt="Caddy Portal" title="Caddy Portal" class="logo">
<img src="/old/resources/images/caddy-lock.png" alt="Caddy Portal" title="Caddy Portal" class="logo">
<br>
<b>Portal</b>
<br>

View file

@ -0,0 +1,13 @@
{{define "docs-head"}}
{{import "/old/includes/head.html"}}
{{template "head"}}
<link rel="stylesheet" href="/old/resources/css/docs.css{{template "cacheBust"}}">
<link rel="stylesheet" href="/old/resources/css/chroma.css{{template "cacheBust"}}">
{{$directives := list }}
{{range $i, $file := (listFiles "/docs/markdown/caddyfile/directives")}}
{{$directives = append $directives ($file | trimSuffix ".md")}}
{{end}}
<script type="text/javascript">window.CaddyfileDirectives = {{$directives | toJson}};</script>
<script src="/old/resources/js/jquery-3.4.1.min.js"></script>
<script src="/old/resources/js/docs.js{{template "cacheBust"}}"></script>
{{end}}

View file

@ -0,0 +1,12 @@
<header>
<div id="logo-container">
<div id="logo-docs-container">
<a href="/"><img src="/old/resources/images/caddy-logo.svg" id="logo" alt="Caddy"></a>
<div id="logo-docs">Documentation</div>
</div>
<div id="zerossl-project">
a <a href="https://zerossl.com"><img src="/old/resources/images/zerossl-logo.svg" id="zerossl-logo"></a> project
</div>
</div>
{{include "/old/includes/header-nav.html"}}
</header>

View file

@ -1,7 +1,7 @@
<nav class="sidebar">
<ul>
<li><a href="/docs/">Welcome</a></li>
<li><a href="https://caddy.community/c/wiki/13">Wiki <img src="/resources/images/external-link.svg"></a></li>
<li><a href="https://caddy.community/c/wiki/13">Wiki <img src="/old/resources/images/external-link.svg"></a></li>
<li class="heading">Get Caddy</li>
<li><a href="/docs/install">Install</a></li>
@ -59,6 +59,6 @@
</li>
<li><a href="/docs/extending-caddy/namespaces">Module Namespaces</a></li>
<br>
<li><a href="/caddy-v1-docs-archive.tar.gz">v1 Docs <img src="/resources/images/external-link.svg"></a></li>
<li><a href="/caddy-v1-docs-archive.tar.gz">v1 Docs <img src="/old/resources/images/external-link.svg"></a></li>
</ul>
</nav>

View file

@ -0,0 +1,24 @@
<div class="wrapper">
<footer>
<div>
<img src="/old/resources/images/caddy-logo.svg" alt="Caddy" id="footer-logo">
An <a href="https://github.com/caddyserver/caddy">open source</a> Go community project
<br>
in partnership with <a href="https://www.ardanlabs.com/">Ardan Labs</a>
<br>
<small><a href="https://usefathom.com/ref/AUKNWU">Privacy-respecting analytics by Fathom</a></small>
</div>
<div class="copyright">
&copy; {{now | date "2006"}} Stack Holdings. All rights reserved.
<br>
Caddy&reg; is a registered trademark of Stack Holdings GmbH.
</div>
</footer>
</div>
<!-- Fathom - beautiful, simple website analytics -->
<script src="https://cdn.usefathom.com/script.js" site="GVMGKAKP" honor-dnt="true" defer></script>
<!-- / Fathom -->
<!-- Algolia DocSearch -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@docsearch/js@3"></script>

View file

@ -0,0 +1,58 @@
{{define "cacheBust" -}}
{{- if fileExists "/.commit-hash" -}}
{{- $commitHash := (include "/.commit-hash") -}}
{{- trim (printf "?v=%v" $commitHash) -}}
{{- end -}}
{{- end}}
{{define "head"}}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin />
<link rel="icon" href="/old/resources/images/favicon.png{{template "cacheBust"}}">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:400,700|Maven+Pro:400,700,900|Montserrat:400,700|PT+Mono&display=swap">
<link rel="stylesheet" href="/old/resources/css/common.css{{template "cacheBust"}}">
<script src="/old/resources/js/common.js{{template "cacheBust"}}"></script>
<!-- General metatags -->
<meta name="author" content="Caddy Web Server">
<meta name="description" content="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta name="theme-color" content="#5ea9a2">
<!-- Open Graph tags -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://caddyserver.com/">
<meta property="og:description" content="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta property="og:image" content="https://caddyserver.com/resources/images/caddy-open-graph.jpg">
<!-- Twitter card tags additive with the og: tags -->
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" value="caddyserver.com">
<meta name="twitter:description" value="Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go">
<meta name="twitter:image" content="https://caddyserver.com/resources/images/caddy-open-graph.jpg">
<meta name="twitter:url" value="https://caddyserver.com/">
<!-- Algolia DocSearch -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
<!-- Global site tag (gtag.js) - Google Analytics (Stack Holdings) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-2DLB04LK4P"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-2DLB04LK4P');
</script>
<!-- Alpine.js to augment markdown docs -->
<script src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<!-- TODO: These don't work -- color values need to be tweaked if they do work -- I think because background-color is set on the body. -->
<meta name="theme-color" content="#123245" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#123245" media="(prefers-color-scheme: dark)">
{{end}}

View file

@ -1,11 +1,11 @@
<!--TODO: add class="current" to the current link-->
<nav>
<div id="search"></div>
<a href="/v2">v2 <span class="new">new</span></a>
<a href="/download">Download</a>
<a href="/docs/">Documentation</a>
<a href="https://caddy.community">Forum</a>
<a href="https://github.com/caddyserver/caddy">GitHub</a>
<a href="/account/">Account</a>
<a href="/business" class="red button">For business</a>
<a href="/support"><b>Support</b></a>
<a href="/sponsor" class="red button">Sponsor</a>
</nav>

View file

@ -0,0 +1,161 @@
/*
Derived from https://gist.github.com/nicolashery/5765395
Adjusted to be high-contrast
*/
/*
Solarized Light (High Contrast)
Derived from http://ethanschoonover.com/solarized
*/
.chroma {
background: linear-gradient(0deg, #f8fbfd 0%, #edf5fd 100%);
color: #254048;
}
.chroma .c { color: #93a1a1 } /* Comment */
.chroma .err { color: #586e75 } /* Error */
.chroma .g { color: #586e75 } /* Generic */
.chroma .k { color: #577b00 } /* Keyword */
.chroma .l { color: #586e75 } /* Literal */
.chroma .n { color: #586e75 } /* Name */
.chroma .o { color: #577b00 } /* Operator */
.chroma .x { color: #d03d00 } /* Other */
.chroma .p { color: #586e75 } /* Punctuation */
.chroma .cm { color: #93a1a1 } /* Comment.Multiline */
.chroma .cp { color: #577b00 } /* Comment.Preproc */
.chroma .c1 { color: #93a1a1 } /* Comment.Single */
.chroma .cs { color: #577b00 } /* Comment.Special */
.chroma .gd { color: #dc322f; background-color: #efdede } /* Generic.Deleted */
.chroma .ge { color: #586e75; font-style: italic } /* Generic.Emph */
.chroma .gr { color: #dc322f } /* Generic.Error */
.chroma .gh { color: #d03d00 } /* Generic.Heading */
.chroma .gi { color: #577b00; background-color: #ddecdc } /* Generic.Inserted */
.chroma .go { color: #586e75 } /* Generic.Output */
.chroma .gp { color: #586e75 } /* Generic.Prompt */
.chroma .gs { color: #586e75; font-weight: bold } /* Generic.Strong */
.chroma .gu { color: #d03d00 } /* Generic.Subheading */
.chroma .gt { color: #586e75 } /* Generic.Traceback */
.chroma .kc { color: #d03d00 } /* Keyword.Constant */
.chroma .kd { color: #0673bf } /* Keyword.Declaration */
.chroma .kn { color: #577b00 } /* Keyword.Namespace */
.chroma .kp { color: #577b00 } /* Keyword.Pseudo */
.chroma .kr { color: #0673bf } /* Keyword.Reserved */
.chroma .kt { color: #dc322f } /* Keyword.Type */
.chroma .ld { color: #586e75 } /* Literal.Date */
.chroma .m { color: #008076 } /* Literal.Number */
.chroma .s { color: #008076 } /* Literal.String */
.chroma .na { color: #586e75 } /* Name.Attribute */
.chroma .nb { color: #B58900 } /* Name.Builtin */
.chroma .nc { color: #0673bf } /* Name.Class */
.chroma .no { color: #d03d00 } /* Name.Constant */
.chroma .nd { color: #0673bf } /* Name.Decorator */
.chroma .ni { color: #d03d00 } /* Name.Entity */
.chroma .ne { color: #d03d00 } /* Name.Exception */
.chroma .nf { color: #0673bf } /* Name.Function */
.chroma .nl { color: #586e75 } /* Name.Label */
.chroma .nn { color: #586e75 } /* Name.Namespace */
.chroma .nx { color: #586e75 } /* Name.Other */
.chroma .py { color: #586e75 } /* Name.Property */
.chroma .nt { color: #0673bf } /* Name.Tag */
.chroma .nv { color: #0673bf } /* Name.Variable */
.chroma .ow { color: #577b00 } /* Operator.Word */
.chroma .w { color: #586e75 } /* Text.Whitespace */
.chroma .mf { color: #008076 } /* Literal.Number.Float */
.chroma .mh { color: #008076 } /* Literal.Number.Hex */
.chroma .mi { color: #008076 } /* Literal.Number.Integer */
.chroma .mo { color: #008076 } /* Literal.Number.Oct */
.chroma .sb { color: #93a1a1 } /* Literal.String.Backtick */
.chroma .sc { color: #008076 } /* Literal.String.Char */
.chroma .sd { color: #586e75 } /* Literal.String.Doc */
.chroma .s2 { color: #008076 } /* Literal.String.Double */
.chroma .se { color: #d03d00 } /* Literal.String.Escape */
.chroma .sh { color: #586e75 } /* Literal.String.Heredoc */
.chroma .si { color: #008076 } /* Literal.String.Interpol */
.chroma .sx { color: #008076 } /* Literal.String.Other */
.chroma .sr { color: #dc322f } /* Literal.String.Regex */
.chroma .s1 { color: #008076 } /* Literal.String.Single */
.chroma .ss { color: #008076 } /* Literal.String.Symbol */
.chroma .bp { color: #0673bf } /* Name.Builtin.Pseudo */
.chroma .vc { color: #0673bf } /* Name.Variable.Class */
.chroma .vg { color: #0673bf } /* Name.Variable.Global */
.chroma .vi { color: #0673bf } /* Name.Variable.Instance */
.chroma .il { color: #008076 } /* Literal.Number.Integer.Long */
@media (prefers-color-scheme: dark) {
/*
Solarized Dark (High Contrast)
Derived from http://ethanschoonover.com/solarized
*/
.chroma {
background: linear-gradient(0deg, #18384d 0%, #122537 100%);
color: #93a1a1;
}
.chroma .c { color: #586e75 } /* Comment */
.chroma .err { color: #93a1a1 } /* Error */
.chroma .g { color: #93a1a1 } /* Generic */
.chroma .k { color: #76a507 } /* Keyword */
.chroma .l { color: #93a1a1 } /* Literal */
.chroma .n { color: #93a1a1 } /* Name */
.chroma .o { color: #76a507 } /* Operator */
.chroma .x { color: #ec662e } /* Other */
.chroma .p { color: #93a1a1 } /* Punctuation */
.chroma .cm { color: #586e75 } /* Comment.Multiline */
.chroma .cp { color: #76a507 } /* Comment.Preproc */
.chroma .c1 { color: #586e75 } /* Comment.Single */
.chroma .cs { color: #76a507 } /* Comment.Special */
.chroma .gd { color: #dc322f; background-color: #efdede } /* Generic.Deleted */
.chroma .ge { color: #93a1a1; font-style: italic } /* Generic.Emph */
.chroma .gr { color: #dc322f } /* Generic.Error */
.chroma .gh { color: #ec662e } /* Generic.Heading */
.chroma .gi { color: #76a507 } /* Generic.Inserted */
.chroma .go { color: #93a1a1 } /* Generic.Output */
.chroma .gp { color: #93a1a1 } /* Generic.Prompt */
.chroma .gs { color: #93a1a1; font-weight: bold } /* Generic.Strong */
.chroma .gu { color: #ec662e } /* Generic.Subheading */
.chroma .gt { color: #93a1a1 } /* Generic.Traceback */
.chroma .kc { color: #ec662e } /* Keyword.Constant */
.chroma .kd { color: #0090f5 } /* Keyword.Declaration */
.chroma .kn { color: #76a507 } /* Keyword.Namespace */
.chroma .kp { color: #76a507 } /* Keyword.Pseudo */
.chroma .kr { color: #0090f5 } /* Keyword.Reserved */
.chroma .kt { color: #dc322f } /* Keyword.Type */
.chroma .ld { color: #93a1a1 } /* Literal.Date */
.chroma .m { color: #09a598 } /* Literal.Number */
.chroma .s { color: #09a598 } /* Literal.String */
.chroma .na { color: #93a1a1 } /* Name.Attribute */
.chroma .nb { color: #B58900 } /* Name.Builtin */
.chroma .nc { color: #0090f5 } /* Name.Class */
.chroma .no { color: #ec662e } /* Name.Constant */
.chroma .nd { color: #0090f5 } /* Name.Decorator */
.chroma .ni { color: #ec662e } /* Name.Entity */
.chroma .ne { color: #ec662e } /* Name.Exception */
.chroma .nf { color: #0090f5 } /* Name.Function */
.chroma .nl { color: #93a1a1 } /* Name.Label */
.chroma .nn { color: #93a1a1 } /* Name.Namespace */
.chroma .nx { color: #93a1a1 } /* Name.Other */
.chroma .py { color: #93a1a1 } /* Name.Property */
.chroma .nt { color: #0090f5 } /* Name.Tag */
.chroma .nv { color: #0090f5 } /* Name.Variable */
.chroma .ow { color: #76a507 } /* Operator.Word */
.chroma .w { color: #93a1a1 } /* Text.Whitespace */
.chroma .mf { color: #09a598 } /* Literal.Number.Float */
.chroma .mh { color: #09a598 } /* Literal.Number.Hex */
.chroma .mi { color: #09a598 } /* Literal.Number.Integer */
.chroma .mo { color: #09a598 } /* Literal.Number.Oct */
.chroma .sb { color: #586e75 } /* Literal.String.Backtick */
.chroma .sc { color: #09a598 } /* Literal.String.Char */
.chroma .sd { color: #93a1a1 } /* Literal.String.Doc */
.chroma .s2 { color: #09a598 } /* Literal.String.Double */
.chroma .se { color: #ec662e } /* Literal.String.Escape */
.chroma .sh { color: #93a1a1 } /* Literal.String.Heredoc */
.chroma .si { color: #09a598 } /* Literal.String.Interpol */
.chroma .sx { color: #09a598 } /* Literal.String.Other */
.chroma .sr { color: #dc322f } /* Literal.String.Regex */
.chroma .s1 { color: #09a598 } /* Literal.String.Single */
.chroma .ss { color: #09a598 } /* Literal.String.Symbol */
.chroma .bp { color: #0090f5 } /* Name.Builtin.Pseudo */
.chroma .vc { color: #0090f5 } /* Name.Variable.Class */
.chroma .vg { color: #0090f5 } /* Name.Variable.Global */
.chroma .vi { color: #0090f5 } /* Name.Variable.Instance */
.chroma .il { color: #09a598 } /* Literal.Number.Integer.Long */
}

View file

@ -0,0 +1,283 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Inter, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
tab-size: 4;
-moz-tab-size: 4;
}
.wrapper {
max-width: 1400px;
margin-left: auto;
margin-right: auto;
padding-left: 40px;
padding-right: 40px;
}
.text-center {
text-align: center;
}
.text-right {
text-align: right;
}
.float-right {
float: right;
}
a {
color: #0694f1;
text-decoration: none;
}
a:hover {
color: #ff3f2c;
}
header {
display: flex;
justify-content: space-between;
padding: 25px 0;
}
#logo-container {
display: flex;
flex-direction: column;
align-items: flex-end;
}
#logo {
height: 50px;
}
#zerossl-project {
font-size: 12px;
margin-top: -5px;
}
#zerossl-logo {
height: 1.5em;
vertical-align: middle;
}
header nav {
text-align: right;
line-height: 40px;
}
header nav > a {
display: inline-block;
padding-left: 12px;
padding-right: 12px;
text-decoration: none;
color: inherit;
}
header nav > a:hover {
color: #ff3f2c;
}
header nav > a.current {
font-weight: bold;
}
/* Algolia DocSearch */
#search {
display: inline-block;
vertical-align: middle;
}
.DocSearch-Container {
color: initial;
}
.DocSearch-Footer {
margin-top: 0;
}
/* End Algolia DocSearch */
header nav .new {
background-color: #ffe300;
font-size: 75%;
vertical-align: top;
padding: 4px 8px;
border-radius: 1em;
}
header nav .button {
margin: 0 0 0 10px;
padding-top: 2px;
padding-bottom: 2px;
}
button,
.button {
border-radius: 2em;
padding: 10px 20px;
margin: 15px 0;
height: auto;
transition: all .2s;
text-decoration: none;
display: inline-block;
border: 0;
cursor: pointer;
}
button:hover,
.button:hover {
transform: scale(1.05);
}
button:active,
.button:active {
transform: translateY(2px);
}
button.red,
.button.red {
background-color: #d9552b;
color: white;
}
button.red:hover,
.button.red:hover {
background-color: #fd511a;
}
button.blue,
.button.blue {
background-color: #0082d0;
color: white;
}
button.blue:hover,
.button.blue:hover {
background-color: #00aaff;
}
button.gray,
.button.gray {
background-color: #4c6a79;
color: white;
}
button.gray:hover,
.button.gray:hover {
background-color: #4f8098;
}
button.big,
.button.big {
font-size: 125%;
text-transform: uppercase;
font-weight: bold;
padding: 20px 50px;
margin-right: 20px;
}
button.disabled,
.button.disabled,
button:disabled,
.button:disabled {
background-color: #aaa !important;
color: white !important;
transform: none !important;
cursor: not-allowed;
}
p button,
p .button {
font-size: 18px;
padding: 12px 30px;
}
article a:hover {
text-decoration: underline;
}
pre,
code,
kbd {
font-family: 'PT Mono', 'Source Code Pro', monospace;
padding: 3px 6px;
font-size: 95%;
line-height: 1.5em;
}
kbd {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.1);
font-size: 80%;
font-weight: bold;
}
footer {
display: flex;
justify-content: space-between;
margin-top: 100px;
padding-bottom: 100px;
line-height: 125%;
}
footer > div {
width: 50%;
}
#footer-logo {
float: left;
max-width: 150px;
margin-right: 35px;
vertical-align: middle;
margin-top: -4px;
}
.copyright {
text-align: right;
font-size: 14px;
color: #999;
}
@media (max-width: 900px) {
header {
flex-direction: column;
gap: 1em;
}
#logo-container {
align-items: center;
}
header nav {
text-align: center;
}
footer {
flex-direction: column;
margin-top: 0;
padding: 20px 0;
}
footer > div {
width: initial;
text-align: center;
margin: 10px 0;
}
#footer-logo {
float: none;
display: block;
margin: 0 auto 25px;
}
.copyright {
text-align: center;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,334 @@
body {
font-family: 'Inter', sans-serif;
}
.hero {
background-image: url('/resources/images/bg-teal.jpg');
background-repeat: no-repeat;
background-size: cover;
padding-bottom: 100px;
background-position: center;
}
h1 {
text-transform: uppercase;
font-size: 70px;
font-family: Montserrat, sans-serif;
text-align: center;
margin: 70px 0 20px;
}
h2 {
font-size: 28px;
font-weight: normal;
text-align: center;
max-width: 60rem;
margin: 0 auto 50px;
line-height: 1.5em;
}
h3 {
font-family: Montserrat, sans-serif;
font-weight: 400;
font-size: 55px;
}
p {
font-size: 20px;
max-width: 600px;
margin-top: 20px;
line-height: 1.5em;
}
.download-container {
text-align: center;
margin-top: 50px;
}
.download-container .button.big {
margin-bottom: 15px;
}
section {
padding: 100px 0;
}
section.alternate:nth-child(even) {
background-color: #f5f8f9;
}
section.alternate:nth-child(odd) .side-by-side {
flex-direction: row-reverse;
}
.side-by-side {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.side-by-side > * {
width: 48%;
}
.side-by-side img {
max-height: 400px;
}
.code-caption {
font-size: 24px;
font-weight: bold;
margin: 75px auto 20px;
}
code {
font-family: 'PT Mono', monospace;
}
code.block {
display: block;
background: #2f2f2f;
color: #eee;
font-size: 20px;
padding-top: 30px;
padding-bottom: 30px;
line-height: 1.25em;
white-space: pre-wrap;
}
.actions {
padding-top: 100px;
}
code.caddyfile {
background-color: #dbebf3;
color: black;
}
.cf-key {
color: #d22500;
font-weight: bold;
}
.cf-comment {
color: #7291a0;
}
.cf-dir {
color: #006c96;
font-weight: bold;
}
.cf-arg {
color: #008000;
}
.cf-subdir {
color: #835234;
}
code.rest {
background-color: #f0f5f4; /*#073d59;*/
color: #253a28;
}
.footnote {
font-size: 18px;
text-align: center;
}
@media (max-width: 1100px) {
.side-by-side,
section.alternate:nth-child(odd) .side-by-side {
flex-direction: column;
}
section.alternate:nth-child(odd) .side-by-side > img {
flex-direction: column-reverse;
margin-bottom: 50px;
}
.side-by-side-content {
margin-bottom: 50px;
}
.side-by-side > * {
width: initial;
}
p {
max-width: 900px;
}
}
@media (max-width: 900px) {
h1 {
font-size: 50px;
word-wrap: break-word;
}
h2 {
font-size: 24px;
}
}
/* TODO: */
/* TAKEN FROM features.css */
.features-start {
background: linear-gradient(0deg, #13a8f5 0%, #18b125 100%);
color: white;
padding: 35px 0;
}
.main-features {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding-top: 2rem;
}
.main-feature {
text-align: center;
padding: 0 2rem;
margin: 3rem 0;
width: 25%;
}
.main-feature img {
height: 130px;
margin-bottom: 15px;
}
.main-feature .title {
font-size: 24px;
font-weight: bold;
margin-bottom: 15px;
}
.main-feature p {
text-align: left;
font-size: 16px;
margin: 0;
}
.feature-points {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
font-size: 28px;
}
.feature-point {
width: 33.333%;
min-width: 300px;
padding: 1rem 3rem;
}
#features-title {
width: 80%;
max-width: 700px;
display: block;
margin: 50px auto 0;
position: relative;
top: 40px;
}
.features-area h3 {
border-bottom: 3px solid #2BABED;
}
.features-area h4 {
text-align: center;
padding-top: 80px;
padding-bottom: 40px;
font-family: Montserrat, sans-serif;
font-size: 40px;
}
.features-area h5 {
font-size: 18px;
text-transform: uppercase;
letter-spacing: 1px;
}
.section-heading {
font-style: italic;
font-size: 20px;
line-height: 2rem;
color: #000;
max-width: 550px;
text-align: center;
margin: 2rem auto 0;
}
.features {
display: flex;
flex-wrap: wrap;
}
.feature {
width: 33.333%;
padding: 25px;
}
.feature p {
margin-top: 5px;
color: #333;
font-size: 18px;
}
@media (max-width: 900px) {
.main-feature {
width: 50%;
margin: 3rem 0;
padding: 0 1rem;
}
.feature {
width: 50%;
}
}
@media (max-width: 700px) {
.pitch {
width: 100%;
border-right: none;
}
.feature-highlight {
padding: 1rem;
}
}
@media (max-width: 500px) {
.main-feature {
width: 100%;
}
.feature {
width: 100%;
}
}

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 939 B

After

Width:  |  Height:  |  Size: 939 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

View file

@ -0,0 +1,81 @@
document.addEventListener('DOMContentLoaded', function() {
// Algolia search
docsearch({
appId: "BH4D9OD16A",
apiKey: '14275a785f6ebd31d162f9d2d8fc0125',
indexName: 'caddyserver',
container: '#search',
});
});
const caddyImportPath = 'github.com/caddyserver/caddy/v2';
function isStandard(packagePath) {
return packagePath.startsWith(caddyImportPath);
}
function truncate(str, maxLen) {
if (!str) return "";
str = str.trim();
let firstPeriod = str.match(/\.(\s|$)/); // first dot not in the middle of a word, or at end of string
let terminate = firstPeriod ? firstPeriod.index+1 : str.length;
str = str.substring(0, terminate);
if (str.length <= maxLen) {
return str;
}
return str+"...";
}
function moduleDocsPreview(mod, maxLen) {
if (!mod || !mod.docs) return "";
let short = truncate(mod.docs, maxLen);
if (short.indexOf(mod.name) === 0) {
short = short.substr(mod.name.length).trim();
}
return short;
}
function detectPlatform() {
// assume 32-bit linux, then change OS and architecture if justified
var os = "linux", arch = "amd64";
// change os
if (/Macintosh/i.test(navigator.userAgent)) {
os = "darwin";
} else if (/Windows/i.test(navigator.userAgent)) {
os = "windows";
} else if (/FreeBSD/i.test(navigator.userAgent)) {
os = "freebsd";
} else if (/OpenBSD/i.test(navigator.userAgent)) {
os = "openbsd";
}
// change architecture
if (os == "darwin" || /amd64|x64|x86_64|Win64|WOW64|i686|64-bit/i.test(navigator.userAgent)) {
arch = "amd64";
} else if (/arm64/.test(navigator.userAgent)) {
arch = "arm64";
} else if (/ ARM| armv/.test(navigator.userAgent)) {
arch = "arm";
}
// change arm version
if (arch == "arm") {
var arm = "7"; // assume version 7 by default
if (/armv6/.test(navigator.userAgent)) {
arm = "6";
} else if (/armv5/.test(navigator.userAgent)) {
arm = "5";
}
arch += arm;
}
return [os, arch];
}
// Detect the platform OS, but with an allow-list of values
// and if the value is not allowed, return the default.
function defaultOS(allowed, def) {
var [os] = detectPlatform();
return allowed.includes(os) ? os : def;
}

View file

@ -0,0 +1,87 @@
$(function() {
function hasPrefix(str, prefix) {
if (!prefix) return true;
if (!str) return false;
return str.indexOf(prefix) === 0;
}
// highlight current page in left nav
var $currentPageLink = $('main nav a[href="'+window.location.pathname+'"]');
if (hasPrefix(window.location.pathname, "/docs/json/")) {
// as a special case, highlight the JSON structure link anywhere within it
$currentPageLink = $('main nav a[href="/docs/json/"]');
}
if (hasPrefix(window.location.pathname, "/docs/modules/")) {
// as another special case, highlight the modules link anywhere within it
$currentPageLink = $('main nav a[href="/docs/modules/"]');
}
$currentPageLink.addClass('current');
// add anchor links, inspired by https://github.com/bryanbraun/anchorjs
$('article > h1[id], article > h2[id], article > h3[id], article > h4[id], article > h5[id], article > h6[id]').each(function() {
var $anchor = $('<a href="#'+this.id+'" class="anchor-link" title="Direct link">🔗</a>');
$(this).append($anchor);
});
// the server-side markdown renderer annoyingly renders
// colored code blocks differently from plain ones, in that
// colorized ones do not have the additional <code> inside
// the <pre>; this line finds those and adds a .chroma class
// to the outer pre element, and our CSS file has a style to
// ensure the inner code block does not produce extra padding
$('article > pre:not(.chroma) > code:not(.cmd)').parent().addClass('chroma');
// Add links to Caddyfile directive tokens in code blocks.
// See include/docs-head.html for the whitelist bootstrapping logic
$('pre.chroma .k')
.filter((k, item) =>
window.CaddyfileDirectives.includes(item.innerText)
|| item.innerText === '<directives...>'
)
.map(function(k, item) {
let text = item.innerText;
let url = text === '<directives...>'
? '/docs/caddyfile/directives'
: '/docs/caddyfile/directives/' + text;
text = text.replace(/</g,'&lt;').replace(/>/g,'&gt;');
$(item).html('<a href="' + url + '" style="color: inherit;" title="Directive">' + text + '</a>');
});
// Add links to [<matcher>] or named matcher tokens in code blocks.
// The matcher text includes <> characters which are parsed as HTML,
// so we must use text() to change the link text.
$('pre.chroma .nd')
.map(function(k, item) {
let text = item.innerText.replace(/</g,'&lt;').replace(/>/g,'&gt;');
$(item).html('<a href="/docs/caddyfile/matchers#syntax" style="color: inherit;" title="Matcher token">' + text + '</a>');
});
});
// addLinkaddLinksToSubdirectivessToAnchors finds all the ID anchors
// in the article, and turns any directive or subdirective span into
// links that have an ID on the page. This is opt-in for each page,
// because it's not necessary to run everywhere.
function addLinksToSubdirectives() {
let anchors = $('article *[id]').map((i, el) => el.id).toArray();
$('pre.chroma .k')
.filter((k, item) => anchors.includes(item.innerText))
.map(function(k, item) {
let text = item.innerText.replace(/</g,'&lt;').replace(/>/g,'&gt;');
let url = '#' + item.innerText;
$(item).html('<a href="' + url + '" style="color: inherit;" title="' + text + '">' + text + '</a>');
});
}
function stripScheme(url) {
return url.substring(url.indexOf("://")+3);
}
// splitTypeName splits a fully qualified type name into
// its package path and type name components, for example:
// "github.com/foo/bar.Type" => "github.com/foo/bar" and "Type".
function splitTypeName(fqtn) {
let lastDotPos = fqtn.lastIndexOf('.');
let pkg = fqtn.substr(0, lastDotPos);
let typeName = fqtn.substr(lastDotPos+1);
return {pkg: pkg, typeName: typeName};
}

139
src/on-demand-tls.html Normal file
View file

@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<title>Caddy is the best web server for HTTPS</title>
{{import "/includes/head.html"}}
{{template "head" .}}
<link rel="stylesheet" href="/resources/css/marketing.css">
<link rel="stylesheet" href="/resources/css/on-demand.css">
<link rel="canonical" href="https://caddyserver.com/on-demand-tls">
</head>
<body>
<div class="hero">
{{include "/includes/header.html" "dark-header"}}
<div class="wrapper">
<div class="hero-content">
<h1>
You just got served
<div class="subheading">
... a dynamically-provisioned TLS certificate by Caddy!
</div>
</h1>
</div>
</div>
</div>
<main>
<section class="diagonal up feature">
<div class="wrapper">
<h2>
What happened?
</h2>
<p>
Caddy automatically obtained a certificate for your domain, <code>{{.Req.Host}}</code>, without any change to the server's configuration. We call this technology On-Demand TLS, and it's an exclusive feature of Caddy.
</p>
<p>
With On-Demand TLS, no config changes are required to serve more domains over HTTPS. This is perfect for servers hosting content or APIs for customer-owned domains because your HTTPS deployment scales as tall and wide as your business does.
</p>
<p>
Caddy's technology is the secret sauce of many SaaS products that offer custom domains. It generates hundreds of thousands of dollars in revenue every year while saving businesses tens of thousands of dollars in development and maintenance costs.
</p>
<p>
Fun fact: this feature earned standing ovations at more than one tech demo back in 2015 and 2016 when it was first introduced.
</p>
</div>
</section>
<section class="diagonal down gray feature">
<div class="wrapper">
<h2>
Easy, self-hosted HTTPS for customer domains
</h2>
<p>
Use On-Demand TLS to grow your custom-domain SaaS business in a matter of minutes. A minimal config looks like this:
</p>
<div class="asides">
<div class="spacing">
<div class="rollover" data-rollover="rollover-abuse">
<h3 class="purple">1. Prevent abuse</h3>
<p>
First, you'll configure an internal endpoint that Caddy can "ask" if a certificate should be allowed for a domain. This endpoint usually looks up the domain in a list or database and returns <code>HTTP 200</code> if it's allowed. Make sure to reject domains you don't recognize. (This implies that customers have to tell your app what their domain is first.)
</p>
</div>
<div class="rollover" data-rollover="rollover-ondemand">
<h3 class="green">2. Enable On-Demand TLS</h3>
<p>
To finish, enable On-Demand TLS for a catch-all site.
</p>
</div>
</div>
<div>
<div class="display right">
{{ markdown (include "/includes/examples/on-demand.md") }}
</div>
</div>
</div>
<p>
Actual production configs typically have more, but this is the minimal configuration needed to serve domain names that aren't in your control. All that's left is for the domain owner to set their DNS records (described below).
</p>
</div>
</section>
<section class="diagonal up feature">
<div class="wrapper">
<h2>
Brilliant customer experience
</h2>
<p>
For domain owners, the flow is even simpler: set DNS records. The first visit to their site will provision a TLS certificate. Works like magic!
</p>
<div class="asides">
<div class="spacing">
<div>
<h3 class="purple">1. Point DNS records</h3>
<p>
The customer sets either a CNAME record or A/AAAA records on a domain or subdomain they control, so that <i>their</i> domain resolves to <i>your</i> server's IP address.
</p>
</div>
<!-- <div class="rollover" data-rollover="rollover-ondemand">
<h3 class="green">2. Visit site</h3>
<p>
Once the DNS propagates, the first request with their domain to your server will provision a TLS certificate.
</p>
</div> -->
</div>
<div>
<div class="display right">
<code class="light"><span class="comment"># Customer's DNS (example domains)</span>
your-app.customer.com CNAME -> your-app.com
<span class="comment"># Your DNS (example IPs)</span>
your-app.com A -> 198.51.100.1
your-app.com AAAA -> 2001:db8::
</code>
</div>
</div>
</div>
<p>
There is no step 2. Caddy will obtain and serve a certificate for their domain as soon as a connection is made to it. Caddy keeps the certificates renewed as long as connections keep coming in. Once they stop, Caddy will let the certificate expire and then delete it automatically.
</p>
<p>
And that is how you save tens of thousands of dollars in development and infrastructure costs every year.
</p>
</div>
</section>
</main>
{{include "/includes/footer.html"}}
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more