- HTML 38.5%
- Shell 36.1%
- CSS 25.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| _openring | ||
| archetypes | ||
| content | ||
| layouts | ||
| scripts | ||
| static | ||
| themes | ||
| .gitignore | ||
| .gitmodules | ||
| build.sh | ||
| hugo.toml | ||
| README.md | ||
betoissues.com
Personal site built with Hugo. Notes, blog posts, and a photo gallery served via Fastly CDN.
Setup
Dependencies: hugo, openring, node (for pagefind), rclone, jq, exiftool
git clone --recurse-submodules ssh://git@aurora-01.caracal-locrian.ts.net:2222/beto/betoissues.com.git
Copy .env.example to .env and fill in your values (see below). Configure ~/.config/rclone/rclone.conf with your Fastly Object Storage credentials.
Building
./build.sh # openring + hugo + pagefind
./build.sh build-only # hugo + pagefind (skip openring fetch)
./build.sh deploy # rsync public/ to golden
./build.sh build-deploy # full build + deploy
hugo server # local dev server
Content
content/log/ # dated posts (YYYY-MM-DD-slug.md, .es.md for Spanish)
content/notes/ # evergreen wiki-style notes
content/photos/ # photo gallery (see below)
content/links.md
content/tools.md
New content:
hugo new content/log/YYYY-MM-DD-slug.md
hugo new content/notes/slug.md
Photo gallery
Photos are stored in Fastly Object Storage and served via cdn.betoissues.com. Nothing photo-related is committed to git — albums are fully dynamic. At build time, albums-sync.sh lists all album directories in S3, downloads each meta.json, and generates index.md before Hugo runs.
Publishing a new album (local)
# 1. Export from Lightroom to a local folder
# 2. Read EXIF, scaffold meta.json into the export folder
scripts/album-init.sh <slug> ~/path/to/exports/
# 3. Edit ~/path/to/exports/meta.json
# - Add captions for each photo
# - Set correct date and cover filename
# - Fix camera name if needed (e.g. "Sony α6000")
# 4. Upload images + meta.json to S3, purge CDN cache
scripts/album-push.sh <slug> ~/path/to/exports/
# 5. Build and deploy (albums-sync.sh pulls meta.json from S3 automatically)
./build.sh build-deploy
Updating an existing album
Edit meta.json in your export folder (or directly on the mount), then:
scripts/album-push.sh <slug> ~/path/to/exports/
./build.sh build-deploy
meta.json format
{
"title": "Album Title",
"date": "2026-04-26",
"cover": "DSC08658.jpg",
"photos": [
{
"src": "DSC08658.jpg",
"caption": "Datsun 240Z",
"camera": "Sony α6000",
"lens": "Sigma 30mm F1.4 DC DN | Contemporary 016",
"focal": "30",
"aperture": "1.4",
"shutter": "1/200",
"iso": "400"
}
]
}
EXIF fields (camera, lens, focal, aperture, shutter, iso) are optional — omit or leave empty to hide.
rclone config (~/.config/rclone/rclone.conf)
[fastly]
type = s3
provider = Other
access_key_id = <key>
secret_access_key = <secret>
endpoint = <fastly-object-storage-endpoint>
acl = public-read
.env
FASTLY_BUCKET=betoissues-assets
RCLONE_REMOTE=fastly
CDN_BASE=https://cdn.betoissues.com
Deploy
The site is hosted on golden (/var/www/html/notes.betoissues.com/) served via nginx.
CI deploy (automatic): .forgejo/workflows/deploy.yml runs on the nebula-01 runner on every push to main, daily (to refresh openring), and on workflow_dispatch. It runs ./build.sh build-deploy with DEPLOY_TARGET pointing at golden's Tailscale IP. The deploy key on golden is restricted with rrsync -wo to the web root, so the target path is relative (./).
Repo secrets: RCLONE_CONF (contents of the [fastly] rclone remote, used by albums-sync.sh) and DEPLOY_SSH_KEY (private key for blog-deploy@forgejo).
Local deploy (manual): ./build.sh deploy rsyncs directly to golden over SSH.