Add post on static sites with traefik
This commit is contained in:
parent
80d6fff1bd
commit
e6a9494386
171
content/post/static-sites-with-mash.md
Normal file
171
content/post/static-sites-with-mash.md
Normal file
@ -0,0 +1,171 @@
|
||||
---
|
||||
title: "Hosting static sites with Traefik"
|
||||
date: 2023-07-16T15:10:10+02:00
|
||||
draft: false
|
||||
image: "/uploads/static-sites-with-traefik/html.png"
|
||||
categrories: ['English']
|
||||
tags: ['MASH', 'hugo', 'english', 'ansible', 'traefik', 'SWS']
|
||||
---
|
||||
|
||||
# Hosting Static Sites with [Traefik](https://traefik.io/) and [Static Web Server](https://static-web-server.net/features/docker/#run-a-container)
|
||||
|
||||
Traefik is amazing to host complex services like with containers. On the other hand it's harder than you'd think to host a simple static html site. I wanted to share my current approach that is based on [Static Web Server Project](https://static-web-server.net/features/docker/#run-a-container).
|
||||
|
||||
|
||||
## Static Web Server (SWS)
|
||||
|
||||
Static Web Server (or SWS abbreviated) is a simple and really fast web server with the goal to serve static web files or assets. The tiny docker image is only 4 MB with a small memory footprint. We can therefore afford to run a container for each static site.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
On the server we set up all static sites in one folder called `static-sites`. As we run the SWS with [docker-compose](https://docs.docker.com/compose/) we add the `docker-compose.yml` to this folder too. The following is an example setup with two static sites on seperate domains.
|
||||
|
||||
|
||||
```
|
||||
| static-sites
|
||||
|
|
||||
| docker-compose.yml
|
||||
| - domain1.example.org
|
||||
| - index.html
|
||||
| - domain2.example.org
|
||||
| - index.html
|
||||
| - fonts
|
||||
| - Open-Dyslexic.odf
|
||||
```
|
||||
|
||||
For each domain we add a folder. I like to name them by the domain name but this is not necessary (just remember the volume in the `docker-compose.yml` too).
|
||||
|
||||
With this done we can now fill the appropriate information in the `docker-compose.yml`. Copy the following and replace `domain1.example.org`, `domain2.example.org`, `site-one` and `site-two`.
|
||||
|
||||
|
||||
```yaml
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
domain1.example.org:
|
||||
image: joseluisq/static-web-server:2
|
||||
container_name: "domain1.example.org"
|
||||
environment:
|
||||
# Note: those envs are customizable but also optional
|
||||
- SERVER_PORT=8080
|
||||
- SERVER_ROOT=/public
|
||||
- SERVER_LOG_LEVEL=info
|
||||
volumes:
|
||||
- ./domain1.example.org:/public
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik"
|
||||
- "traefik.http.routers.site-one.rule=Host(`domain1.example.org`)"
|
||||
- "traefik.http.routers.site-one.service=site-one"
|
||||
- "traefik.http.routers.site-one.entrypoints=web-secure"
|
||||
- "traefik.http.routers.site-one.tls=true"
|
||||
- "traefik.http.routers.site-one.tls.certResolver=default"
|
||||
- "traefik.http.services.site-one.loadbalancer.server.port=8080"
|
||||
networks:
|
||||
- traefik
|
||||
|
||||
domain2.example.org:
|
||||
image: joseluisq/static-web-server:2
|
||||
container_name: "domain2.example.org"
|
||||
environment:
|
||||
# Note: those envs are customizable but also optional
|
||||
- SERVER_PORT=8080
|
||||
- SERVER_ROOT=/public
|
||||
- SERVER_LOG_LEVEL=info
|
||||
volumes:
|
||||
- ./domain2.example.org:/public
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik"
|
||||
- "traefik.http.routers.site-two.rule=Host(`domain2.example.org`)"
|
||||
- "traefik.http.routers.site-two.service=site-two"
|
||||
- "traefik.http.routers.site-two.entrypoints=web-secure"
|
||||
- "traefik.http.routers.site-two.tls=true"
|
||||
- "traefik.http.routers.site-two.tls.certResolver=default"
|
||||
- "traefik.http.services.site-two.loadbalancer.server.port=8080"
|
||||
networks:
|
||||
- traefik
|
||||
|
||||
networks:
|
||||
traefik:
|
||||
name: traefik
|
||||
external: true
|
||||
```
|
||||
|
||||
This assumes traefik runs in a docker-network called traefik. This network must already exist.
|
||||
|
||||
|
||||
As a last step add at least a `index.html` in the appropriate folder. Then you can start the webserver with `docker-compose up`. Add `-d` to run it in the background.
|
||||
|
||||
|
||||
# Deploying static sites
|
||||
|
||||
Deploying files manually (via Filezilla, scp or rsync) is not something I like to do. I therefore normally set up a CI job to automatically deploy the site when I push a new commit to GitHub, either via GitHub Actions or my [Woodpecker CI](https://woodpecker-ci.org/docs/usage/intro) instance.
|
||||
|
||||
I order to do that I
|
||||
|
||||
* create a new user on the server, specifically for that purpose (one per site). The command is `useradd USERNAME -m`
|
||||
* create a SSH key without a password `ssh-keygen -t ed25519 -a 100 -C "COMMENT" -f FILENAME`
|
||||
* copy the public key that was just created at `FILENAME.pub` on the server in the textfile `/home/USERNAME/.ssh/authorized_keys`
|
||||
* Add the private key to the secrets of your CI
|
||||
|
||||
A typical CI configuration will look like this with a static site and GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: Deploy Production Website via SSH
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Deploy to Server
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
ARGS: "-rltgoDzvO --delete"
|
||||
SOURCE: ""
|
||||
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.REMOTE_USER }}
|
||||
TARGET: ${{ secrets.REMOTE_PRODUCTION_TARGET }}
|
||||
EXCLUDE: ".github/, .gitignore"
|
||||
```
|
||||
|
||||
or this, when using [HUGO](https://gohugo.io/) and Woodpecker CI
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: klakegg/hugo
|
||||
commands:
|
||||
- hugo
|
||||
|
||||
deploy:
|
||||
image: appleboy/drone-scp
|
||||
settings:
|
||||
strip_components: 1
|
||||
host:
|
||||
- example.org
|
||||
username: moanos
|
||||
target: /home/USERNAME/static-sites/
|
||||
source: public/
|
||||
key:
|
||||
from_secret: ssh_key
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
not manually put the files on the server
|
BIN
static/uploads/static-sites-with-traefik/html.png
Normal file
BIN
static/uploads/static-sites-with-traefik/html.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue
Block a user