Initial commit: Hugo site with Caddy infra and deploy tooling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
24
infra/Caddyfile
Normal file
24
infra/Caddyfile
Normal file
@@ -0,0 +1,24 @@
|
||||
monotrope.au {
|
||||
root * /var/www/monotrope
|
||||
file_server
|
||||
|
||||
# Compression
|
||||
encode zstd gzip
|
||||
|
||||
# Cache headers for static assets
|
||||
@static {
|
||||
path *.css *.js *.ico *.gif *.jpg *.jpeg *.png *.webp *.svg *.woff *.woff2 *.ttf *.eot
|
||||
}
|
||||
header @static Cache-Control "public, max-age=31536000, immutable"
|
||||
|
||||
# HTML and RSS — revalidate each time
|
||||
@html {
|
||||
path *.html / /posts/ /posts/*
|
||||
}
|
||||
header @html Cache-Control "public, max-age=0, must-revalidate"
|
||||
}
|
||||
|
||||
# Redirect www to apex
|
||||
www.monotrope.au {
|
||||
redir https://monotrope.au{uri} permanent
|
||||
}
|
||||
188
infra/ansible/playbook.yml
Normal file
188
infra/ansible/playbook.yml
Normal file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
- name: Provision monotrope.au server
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
site_dir: /var/www/monotrope
|
||||
deploy_user: deploy
|
||||
deploy_pubkey: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/id_ed25519.pub') }}"
|
||||
|
||||
tasks:
|
||||
|
||||
# ── System ──────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Update apt cache and upgrade packages
|
||||
apt:
|
||||
update_cache: true
|
||||
upgrade: dist
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Install common dependencies
|
||||
apt:
|
||||
name:
|
||||
- debian-keyring
|
||||
- debian-archive-keyring
|
||||
- apt-transport-https
|
||||
- curl
|
||||
- ufw
|
||||
state: present
|
||||
|
||||
# ── Caddy ───────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Add Caddy GPG key
|
||||
shell: |
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
|
||||
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
args:
|
||||
creates: /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
|
||||
- name: Add Caddy apt repository
|
||||
shell: |
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
|
||||
| tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
args:
|
||||
creates: /etc/apt/sources.list.d/caddy-stable.list
|
||||
|
||||
- name: Install Caddy
|
||||
apt:
|
||||
name: caddy
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install Caddyfile
|
||||
copy:
|
||||
src: ../Caddyfile
|
||||
dest: /etc/caddy/Caddyfile
|
||||
owner: root
|
||||
group: caddy
|
||||
mode: '0640'
|
||||
notify: Restart Caddy
|
||||
|
||||
- name: Enable and start Caddy
|
||||
systemd:
|
||||
name: caddy
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
# ── Site directory ───────────────────────────────────────────────────────
|
||||
|
||||
- name: Create www system user
|
||||
user:
|
||||
name: www
|
||||
system: true
|
||||
create_home: false
|
||||
shell: /usr/sbin/nologin
|
||||
state: present
|
||||
|
||||
# ── UFW ─────────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Set UFW default incoming policy to deny
|
||||
ufw:
|
||||
default: deny
|
||||
direction: incoming
|
||||
|
||||
- name: Set UFW default outgoing policy to allow
|
||||
ufw:
|
||||
default: allow
|
||||
direction: outgoing
|
||||
|
||||
- name: Allow SSH
|
||||
ufw:
|
||||
rule: allow
|
||||
name: OpenSSH
|
||||
|
||||
- name: Allow HTTP
|
||||
ufw:
|
||||
rule: allow
|
||||
port: '80'
|
||||
proto: tcp
|
||||
|
||||
- name: Allow HTTPS
|
||||
ufw:
|
||||
rule: allow
|
||||
port: '443'
|
||||
proto: tcp
|
||||
|
||||
- name: Enable UFW
|
||||
ufw:
|
||||
state: enabled
|
||||
|
||||
# ── Docker ──────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Create Docker keyring directory
|
||||
file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Add Docker GPG key
|
||||
shell: |
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
args:
|
||||
creates: /etc/apt/keyrings/docker.gpg
|
||||
|
||||
- name: Add Docker apt repository
|
||||
shell: |
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
| tee /etc/apt/sources.list.d/docker.list
|
||||
args:
|
||||
creates: /etc/apt/sources.list.d/docker.list
|
||||
|
||||
- name: Install Docker
|
||||
apt:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-buildx-plugin
|
||||
- docker-compose-plugin
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Enable Docker
|
||||
systemd:
|
||||
name: docker
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
# ── Deploy user ──────────────────────────────────────────────────────────
|
||||
|
||||
- name: Create deploy user
|
||||
user:
|
||||
name: "{{ deploy_user }}"
|
||||
create_home: true
|
||||
shell: /bin/bash
|
||||
state: present
|
||||
|
||||
- name: Set up deploy user SSH directory
|
||||
file:
|
||||
path: "/home/{{ deploy_user }}/.ssh"
|
||||
state: directory
|
||||
owner: "{{ deploy_user }}"
|
||||
group: "{{ deploy_user }}"
|
||||
mode: '0700'
|
||||
|
||||
- name: Install deploy user SSH public key
|
||||
ansible.posix.authorized_key:
|
||||
user: "{{ deploy_user }}"
|
||||
key: "{{ deploy_pubkey }}"
|
||||
state: present
|
||||
|
||||
- name: Create site directory
|
||||
file:
|
||||
path: "{{ site_dir }}"
|
||||
state: directory
|
||||
owner: "{{ deploy_user }}"
|
||||
group: www
|
||||
mode: '0775'
|
||||
|
||||
handlers:
|
||||
|
||||
- name: Restart Caddy
|
||||
systemd:
|
||||
name: caddy
|
||||
state: restarted
|
||||
97
infra/setup.sh
Executable file
97
infra/setup.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# setup.sh — Provision a fresh Ubuntu 24.04 droplet for monotrope.au
|
||||
# Run as root via: ssh root@<DROPLET_IP> 'bash -s' < infra/setup.sh
|
||||
|
||||
DEPLOY_USER="deploy"
|
||||
SITE_DIR="/var/www/monotrope"
|
||||
DEPLOY_PUBKEY="${DEPLOY_PUBKEY:-}" # Set this env var before running, or edit below
|
||||
|
||||
echo "==> Updating packages"
|
||||
apt-get update -y
|
||||
apt-get upgrade -y
|
||||
|
||||
# ── Caddy ─────────────────────────────────────────────────────────────────
|
||||
echo "==> Installing Caddy"
|
||||
apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl
|
||||
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
|
||||
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
|
||||
| tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
|
||||
apt-get update -y
|
||||
apt-get install -y caddy
|
||||
|
||||
# ── Site directory ─────────────────────────────────────────────────────────
|
||||
echo "==> Creating www user and site directory"
|
||||
id -u www &>/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www
|
||||
mkdir -p "$SITE_DIR"
|
||||
chown www:www "$SITE_DIR"
|
||||
chmod 755 "$SITE_DIR"
|
||||
|
||||
# ── Caddyfile ──────────────────────────────────────────────────────────────
|
||||
echo "==> Installing Caddyfile"
|
||||
cp "$(dirname "$0")/Caddyfile" /etc/caddy/Caddyfile
|
||||
chown root:caddy /etc/caddy/Caddyfile
|
||||
chmod 640 /etc/caddy/Caddyfile
|
||||
|
||||
systemctl enable caddy
|
||||
systemctl restart caddy
|
||||
|
||||
# ── UFW ────────────────────────────────────────────────────────────────────
|
||||
echo "==> Configuring UFW"
|
||||
apt-get install -y ufw
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow http
|
||||
ufw allow https
|
||||
ufw --force enable
|
||||
|
||||
# ── Docker ────────────────────────────────────────────────────────────────
|
||||
echo "==> Installing Docker"
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
| tee /etc/apt/sources.list.d/docker.list
|
||||
|
||||
apt-get update -y
|
||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
systemctl enable docker
|
||||
|
||||
# ── Deploy user ───────────────────────────────────────────────────────────
|
||||
echo "==> Creating deploy user"
|
||||
id -u "$DEPLOY_USER" &>/dev/null || useradd --create-home --shell /bin/bash "$DEPLOY_USER"
|
||||
|
||||
# Give deploy user write access to the site directory
|
||||
chown -R "$DEPLOY_USER":www "$SITE_DIR"
|
||||
chmod 775 "$SITE_DIR"
|
||||
|
||||
# Set up SSH key auth
|
||||
DEPLOY_HOME="/home/$DEPLOY_USER"
|
||||
mkdir -p "$DEPLOY_HOME/.ssh"
|
||||
chmod 700 "$DEPLOY_HOME/.ssh"
|
||||
touch "$DEPLOY_HOME/.ssh/authorized_keys"
|
||||
chmod 600 "$DEPLOY_HOME/.ssh/authorized_keys"
|
||||
chown -R "$DEPLOY_USER":"$DEPLOY_USER" "$DEPLOY_HOME/.ssh"
|
||||
|
||||
if [[ -n "$DEPLOY_PUBKEY" ]]; then
|
||||
echo "$DEPLOY_PUBKEY" >> "$DEPLOY_HOME/.ssh/authorized_keys"
|
||||
echo "==> Deploy public key installed"
|
||||
else
|
||||
echo "WARNING: DEPLOY_PUBKEY not set. Add your public key to $DEPLOY_HOME/.ssh/authorized_keys manually."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "==> Done. Checklist:"
|
||||
echo " - Point DNS A records for monotrope.au and www.monotrope.au to this server's IP"
|
||||
echo " - If DEPLOY_PUBKEY was not set, add your key to $DEPLOY_HOME/.ssh/authorized_keys"
|
||||
echo " - Run 'make deploy' from your local machine to push the site"
|
||||
Reference in New Issue
Block a user