|
| 1 | +--- |
| 2 | +theme: seriph |
| 3 | +highlighter: shiki |
| 4 | +layout: image-right |
| 5 | +themeConfig: {'primary': '#479d2d'} |
| 6 | +image: ./images/caddy-circle-lock.svg |
| 7 | +class: 'flex flex-col justify-center' |
| 8 | +title: 'Caddy - SSAST 2021 Summer Codecamp' |
| 9 | +--- |
| 10 | + |
| 11 | +<div> |
| 12 | +<h1>Caddy</h1> |
| 13 | +Ultimate Server with Automatic HTTPS |
| 14 | +</div> |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Why you need a web server |
| 19 | + |
| 20 | +- Serving static files |
| 21 | + - Traditional HTML Pages |
| 22 | + - SPA Apps built with Vue / React |
| 23 | + - `npm run serve` is not suitable for production use! |
| 24 | +- Reverse Proxy |
| 25 | + - Load-balance requests onto different instances |
| 26 | + - Split API / static content requests |
| 27 | + - HTTPS support |
| 28 | +- Virtual Host |
| 29 | + - Multiple services, multiple domains |
| 30 | + - Same host machine |
| 31 | + |
| 32 | +--- |
| 33 | +layout: two-cols |
| 34 | +class: mx-1 |
| 35 | +--- |
| 36 | + |
| 37 | +## Examples |
| 38 | + |
| 39 | +### Serving static files with httpd on Ubuntu |
| 40 | + |
| 41 | +```sh |
| 42 | +$ ls /var/www/html # default folder for static files |
| 43 | +css img index.html js |
| 44 | +``` |
| 45 | + |
| 46 | +### Virtual Host |
| 47 | + |
| 48 | +```mermaid |
| 49 | +graph LR |
| 50 | + s1(www.example.com ) --> ip(154.17.5.12) |
| 51 | + s2(admin.example.com) --> ip(154.17.5.12) |
| 52 | + s3(db.example.com) --> ip(154.17.5.12) |
| 53 | +``` |
| 54 | + |
| 55 | +::right:: |
| 56 | + |
| 57 | +### Reverse proxy |
| 58 | + |
| 59 | +```nginx |
| 60 | +upstream api_backend { server api_backend.example.com:80; } |
| 61 | +upstream filebrowser { server filebrowser.example.com:80; } |
| 62 | +server { |
| 63 | + listen 80; |
| 64 | + location / { |
| 65 | + proxy_pass http://api_backend; |
| 66 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 67 | + proxy_set_header Host $host; |
| 68 | + proxy_redirect off; |
| 69 | + } |
| 70 | + location /upload_media_files/ { |
| 71 | + proxy_pass http://filebrowser; |
| 72 | + proxy_set_header X-Real-IP $remote_addr; |
| 73 | + proxy_set_header Host $http_host; |
| 74 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 75 | + proxy_set_header Upgrade $http_upgrade; |
| 76 | + proxy_set_header Connection "upgrade"; |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## Common Web Servers |
| 84 | + |
| 85 | +<div> |
| 86 | + <div> |
| 87 | + <logos-apache class="inline" /><a href="https://httpd.apache.org/">Apache</a> |
| 88 | + </div> |
| 89 | + <div> |
| 90 | + <logos-nginx class="inline" /> <a href="https://nginx.org/en/">Nginx</a> |
| 91 | + </div> |
| 92 | + <div> |
| 93 | + <logos-lighttpd class="inline" /> <a href="https://www.lighttpd.net/">Lighttpd</a> |
| 94 | + </div> |
| 95 | + <div> |
| 96 | + <vscode-icons-file-type-caddy class="inline" /> <a href="https://caddyserver.com/">Caddy</a> |
| 97 | + </div> |
| 98 | + <div> |
| 99 | + <grommet-icons-golang class="inline" /> <a href="https://traefik.io/traefik/">Traefik</a> |
| 100 | + </div> |
| 101 | +</div> |
| 102 | + |
| 103 | +First 2 of them are widely used, but too hard for beginners. |
| 104 | + |
| 105 | +### Example: using NGINX |
| 106 | + |
| 107 | +```bash {4,5,7|9,10,11} |
| 108 | +$ sudo apt install nginx |
| 109 | +$ ls /etc/nginx/ |
| 110 | +conf.d koi-utf scgi_params.default |
| 111 | +default.d koi-win sites-available |
| 112 | +fastcgi.conf mime.types sites-enabled |
| 113 | +fastcgi.conf.default mime.types.default uwsgi_params |
| 114 | +fastcgi_params nginx.conf uwsgi_params.default |
| 115 | +fastcgi_params.default scgi_params win-utf |
| 116 | +$ ls /etc/nginx/sites-available/ # after configuration |
| 117 | +mapping.conf overleaf-create-user.conf root.conf wp.conf |
| 118 | +overleaf.conf recruit.conf static.conf |
| 119 | +``` |
| 120 | + |
| 121 | +--- |
| 122 | + |
| 123 | +## HTTPS Support |
| 124 | + |
| 125 | +- Crucial to privacy and safety |
| 126 | +- In 10 years ago, you need to configure HTTPS certificates manually. |
| 127 | +- Usually one has to pay ~$10/yr for a certificate. |
| 128 | + |
| 129 | +## Free certificates with Let's Encrypt |
| 130 | + |
| 131 | +- Once you've owned a domain, you can use this service to get free certificates |
| 132 | +- However, rate limits apply, and you need to **renew** them on a regular basis |
| 133 | + - Otherwise, Certificate Errors! [Example of Expired Cert](https://expired.badssl.com/) |
| 134 | +- [Certbot](https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx)+NGINX or [**Caddy**](https://caddyserver.com/) both renew your certificates automatically |
| 135 | +- Enable HTTPS with a few lines of code |
| 136 | + |
| 137 | +```bash |
| 138 | +$ sudo snap install --classic certbot |
| 139 | +$ sudo ln -s /snap/bin/certbot /usr/bin/certbot |
| 140 | +$ sudo certbot --nginx |
| 141 | +``` |
| 142 | + |
| 143 | +--- |
| 144 | + |
| 145 | +## Get your hands dirty! |
| 146 | + |
| 147 | +### Configure DNS Records |
| 148 | + |
| 149 | +`www.example.com` is resolved to `93.184.216.34`. Website root is `/var/www/html/`. |
| 150 | + |
| 151 | +### Install Caddy on your server |
| 152 | + |
| 153 | +```bash |
| 154 | +$ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https |
| 155 | +$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add - |
| 156 | +$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list |
| 157 | +$ sudo apt update |
| 158 | +$ sudo apt install caddy |
| 159 | +``` |
| 160 | + |
| 161 | +### Configuration |
| 162 | + |
| 163 | +copy-paste the following lines into `/etc/caddy/Caddyfile`: |
| 164 | +``` |
| 165 | +www.example.com |
| 166 | +root /var/www/html/ |
| 167 | +file_server |
| 168 | +``` |
| 169 | + |
| 170 | +### Restart Caddy |
| 171 | + |
| 172 | +```bash |
| 173 | +$ sudo systemctl restart caddy # Now you've got a fully-featured HTTPS server! |
| 174 | +``` |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Virtual Hosts |
| 179 | + |
| 180 | +- Multiple domains on a single server |
| 181 | +- easy to deal with in `Caddyfile` |
| 182 | + |
| 183 | +``` |
| 184 | +www.example.com { |
| 185 | + # configurations specific to `www' |
| 186 | +} |
| 187 | +admin.example.com { |
| 188 | + # configurations specific to `admin' |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +Files under different VHosts are completed seperate |
| 193 | + |
| 194 | +```mermaid |
| 195 | +graph LR |
| 196 | + Client1 --"a.example.com/1.txt"--> Caddy |
| 197 | + Client2 --"b.example.com/1.txt"--> Caddy |
| 198 | + Caddy --"Website a"--> webA(/var/www/a/1.txt) |
| 199 | + Caddy --"Website b"--> webB(/var/www/b/1.txt) |
| 200 | +``` |
| 201 | + |
| 202 | +--- |
| 203 | +layout: two-cols |
| 204 | +--- |
| 205 | + |
| 206 | +## Reverse Proxy |
| 207 | + |
| 208 | +- Typical use case: Python / PHP Servers |
| 209 | +- Forward API requests to backend |
| 210 | + |
| 211 | +### Typical Config |
| 212 | + |
| 213 | +Suppose that [Gunicorn](https://gunicorn.org/) runs at `localhost:8001` & `localhost:8002`. |
| 214 | + |
| 215 | +``` |
| 216 | +www.example.com { |
| 217 | + reverse_proxy /api/* localhost:8001 localhost:8002 |
| 218 | + root /var/www/html/ |
| 219 | + file_server |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +::right:: |
| 224 | + |
| 225 | +```mermaid |
| 226 | +graph TD |
| 227 | + Client --> Caddy |
| 228 | + Caddy --HTTP--> wsgi(WSGI Gateway) |
| 229 | + Caddy --FastCGI--> PHP |
| 230 | + Caddy --> static(Static Files) |
| 231 | + wsgi --WSGI--> Flask |
| 232 | +``` |
| 233 | + |
| 234 | +--- |
| 235 | + |
| 236 | +## Caddy is powerful! |
| 237 | + |
| 238 | +- 🌐 Forward Proxy |
| 239 | +- ✏️ Logging |
| 240 | +- 📗 Template Rendering |
| 241 | +- 🗜️ Compression |
| 242 | +- 🔥 Dynamic Config Update |
| 243 | +- ➕ Plugins |
| 244 | + |
| 245 | +## Resources |
| 246 | + |
| 247 | +- [**Official Caddyfile Tutorial**](https://caddyserver.com/docs/caddyfile-tutorial) - Recommended |
| 248 | +- [Let's Encrypt](https://letsencrypt.org/), which makes automatic HTTPS possible |
0 commit comments