Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Jan 24, 2020
0 parents commit 03b6fdd
Show file tree
Hide file tree
Showing 77 changed files with 7,599 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_gitignore/
12 changes: 12 additions & 0 deletions Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
:2015

root * src

file_server
templates

redir /docs/json /docs/json/
rewrite /docs/json/* /docs/json/index.html
rewrite /docs/* /docs/index.html

reverse_proxy /api/* localhost:4444
29 changes: 29 additions & 0 deletions src/docs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{$pathParts := splitList "/" .OriginalReq.URL.Path}}
{{$markdownFilename := default "index" (slice $pathParts 2 | join "/")}}
{{$markdownFilePath := printf "/docs/markdown/%s.md" $markdownFilename}}
{{$markdownFile := (include $markdownFilePath | splitFrontMatter)}}
<!DOCTYPE html>
<html>
<head>
<title>{{default $markdownFilename $markdownFile.Meta.title}} &mdash; Caddy Documentation</title>
{{include "/includes/docs-head.html"}}
<link rel="stylesheet" href="/resources/css/chroma.css">
</head>
<body>
{{include "/includes/docs-header.html"}}
<main>
{{include "/includes/docs-nav.html"}}
<div class="article-container">
<div class="beta-warning">
<b>Caddy 2 is beta software.</b> It is ready for production, but some things will change between releases; check the <a href="https://github.com/caddyserver/caddy/releases">release notes</a> before upgrading.
</div>
<article class="centered">
{{markdown $markdownFile.Body}}
</article>
</div>
<div class="sidebar"></div>
</main>

{{include "/includes/footer.html"}}
</body>
</html>
52 changes: 52 additions & 0 deletions src/docs/json/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<title>JSON Structure - Caddy Documentation</title>
{{include "/includes/docs-head.html"}}
<link rel="stylesheet" href="/resources/css/docs-json.css">
<script src="/resources/js/marked-0.8.0.min.js"></script>
<script src="/resources/js/docs-json.js"></script>
</head>
<body>
{{include "/includes/docs-header.html"}}
<main>
{{include "/includes/docs-nav.html"}}
<div class="article-container">
<div class="breadcrumbs">
<!--Populated by JS-->
</div>

<pre><code class="json" id="renderbox"><!--Populated by JS--></code></pre>

<article>
<p id="top-doc">
<!--Populated by JS-->
</p>
<h2 id="field-list-header">Field List</h2>
<dl id="field-list">
<!--Populated by JS-->
</dl>
</article>
</div>
<div class="sidebar"></div>
</main>


<div id="hovercard" class="arrow-box">
<div id="hovercard-docs" class="hovercard-elem"><!--Populated by JS--></div>
<div id="hovercard-module" class="hovercard-elem">
<p id="hovercard-namespace-box">
Fulfilled by modules in namespace: <span id="hovercard-namespace"><!--Populated by JS--></span>
</p>
<div id="hovercard-module-list"><!--Populated by JS--></div>
</div>
<div id="hovercard-inline-key" class="hovercard-elem">
<p class="explain">This property is <b>required</b> because it specifies the module name.</p>
</div>
<div id="hovercard-breadcrumb-siblings" class="hovercard-elem"><!--Populated by JS--></div>
<div id="hovercard-inline-link" class="hovercard-elem"><!--Populated by JS--></div>
</div>

{{include "/includes/footer.html"}}
</body>
</html>
208 changes: 208 additions & 0 deletions src/docs/markdown/api-tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
---
title: "API Tutorial"
---

# API Tutorial

This tutorial will show you how to use Caddy's [admin API](/docs/api), which makes it possible to automate in a programmable fashion.

**Objectives:**
- 🔲 Run the daemon
- 🔲 Give Caddy a config
- 🔲 Test config
- 🔲 Replace active config
- 🔲 Traverse config
- 🔲 Use `@id` tags

**Prerequisites:**
- Basic terminal / command line skills
- Basic JSON experience
- `caddy` and `curl` in your PATH

---

To start the Caddy daemon, use the `run` subcommand:

<pre><code class="cmd bash">caddy run</code></pre>

<aside class="complete">✅ Run the daemon</aside>

This blocks forever, but what is it doing? At the moment... nothing. By default, Caddy's configuration ("config") is blank. We can verify this using the [admin API](/docs/api) in another terminal:

<pre><code class="cmd bash">curl localhost:2019/config/</code></pre>

We can make Caddy useful by giving it a config. One way to do this is by making a POST request to the [/load](/docs/api#post-load) endpoint. Just like any HTTP request, there are many ways to do this, but in this tutorial we'll use `curl`.

## Your first config

To prepare our request, we need to make a config. Caddy's configuration is simply a [JSON document](/docs/json/) (or [anything that converts to JSON](/docs/config-adapters)).

<aside class="tip">
Config files are not required. The configuration API can always be used without files, which is handy for automating things. This tutorial uses a file because it is convenient when editing by hand.
</aside>

Save this to a JSON file:

```json
{
"apps": {
"http": {
"servers": {
"example": {
"listen": [":2015"],
"routes": [
{
"handle": [{
"handler": "static_response",
"body": "Hello, world!"
}]
}
]
}
}
}
}
}
```

Then upload it:

<pre><code class="cmd bash">curl localhost:2019/load \
-X POST \
-H "Content-Type: application/json" \
-d @caddy.json
</code></pre>

<aside class="complete">✅ Give Caddy a config</aside>

We can verify that Caddy applied our new config with another GET request:

<pre><code class="cmd bash">curl localhost:2019/config/</code></pre>

Test that it works by going to [localhost:2015](http://localhost:2015) in your browser or using `curl`:

<pre><code class="cmd"><span class="bash">curl localhost:2015</span>
Hello, world!</code></pre>

<aside class="complete">✅ Test config</aside>

If you see _Hello, world!_, then congrats -- it's working! It's always a good idea to make sure your config works as you expect, especially before deploying into production.

Let's change our welcome message from "Hello world!" to something a little more motivational: "I can do hard things." Make this change in your config file, so that the handler object now looks like this:

```json
{
"handler": "static_response",
"body": "I can do hard things."
}
```

Save the config file, then update Caddy's active configuration by running the same POST request again:

<pre><code class="cmd bash">curl localhost:2019/load \
-X POST \
-H "Content-Type: application/json" \
-d @caddy.json
</code></pre>

<aside class="complete">✅ Replace active config</aside>

For good measure, verify that the config was updated:

<pre><code class="cmd bash">curl localhost:2019/config/</code></pre>

Test it by refreshing the page in your browser (or running `curl` again), and you will see an inspirational message!


## Config traversal

<aside class="tip">
Making little changes to production servers by replacing the entire config like we did above can be dangerous; it's like having root access to a file system. Caddy's API lets you limit the scope of your changes to guarantee that other parts of your config don't get changed accidentally.
</aside>

Instead of uploading the entire config file for a small change, let's use a powerful feature of Caddy's API to make the change without ever touching our config file.

Using the request URI's path, we can traverse into the config structure and update only the message string (be sure to scroll right if clipped):

<pre><code class="cmd bash">curl \
localhost:2019/config/apps/http/servers/example/routes/0/handle/0/body \
-X POST \
-H "Content-Type: application/json" \
-d '"Work smarter, not harder."'
</code></pre>

<aside class="tip">
Every time you change the config using the API, Caddy persists a copy of the new config so you can <a href="/docs/command-line#caddy-run"><b>--resume</b> it later</a>!
</aside>

You can verify that it worked with a similar GET request, for example:

<pre><code class="cmd bash">curl localhost:2019/config/apps/http/servers/example/routes</code></pre>

You should see:

```json
[{"handle":[{"body":"Work smarter, not harder.","handler":"static_response"}]}]
```

<aside class="tip">
You can use the <a href="https://stedolan.github.io/jq/">jq command</a> to prettify JSON output: <b><code>curl ... | jq</code></b>
</aside>

**Important note:** This should be obvious, but once you use the API to make a change that is not in your original config file, your config file becomes obsolete. There are a few ways to handle this:

- Use the `--resume` of the [caddy run](/docs/command-line#caddy-run) command to use the last active config.
- [Export Caddy's new configuration](/docs/api#get-configpath) with a subsequent GET request.
- Don't mix the use of config files with changes via the API; have one source of truth.

<aside class="complete">✅ Traverse config</aside>



## Using `@id` in JSON

Config traversal is certainly useful, but the paths are little long, don't you think?

We can give our handler object an [`@id` tag](/docs/api#using-id-in-json) to make it easier to access:

<pre><code class="cmd bash">curl \
localhost:2019/config/apps/http/servers/example/routes/0/handle/0/@id \
-X POST \
-H "Content-Type: application/json" \
-d '"msg"'
</code></pre>

This adds a property to our handler object: `"@id": "msg"`, so it now looks like this:

```json
{
"@id": "msg",
"body": "Work smarter, not harder.",
"handler": "static_response"
}
```

<aside class="tip">
<b>@id</b> tags can go in any object and can have any primitive value (usually a string). <a href="/docs/api#using-id-in-json">Learn more</a>
</aside>

We can then access it directly:

<pre><code class="cmd bash">curl localhost:2019/id/msg</code></pre>

And now we can change the message with a shorter path:

<pre><code class="cmd bash">curl \
localhost:2019/id/msg/body \
-X POST \
-H "Content-Type: application/json" \
-d '"Some shortcuts are good."'
</code></pre>

And check it again:

<pre><code class="cmd bash">curl localhost:2019/id/msg/body</code></pre>

<aside class="complete">✅ Use <code>@id</code> tags</aside>


Loading

0 comments on commit 03b6fdd

Please sign in to comment.