feat(ghost-me): add personal site deployment

This commit is contained in:
Eduardo David Paredes Vara
2026-08-09 16:56:56 +00:00
parent a012c914a8
commit 9f7dbaba41
4 changed files with 141 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
TZ=Europe/Madrid
GHOST_ME_IMAGE=ghost:6-alpine
GHOST_ME_DOMAIN=me.thehomelesssherlock.com
GHOST_ME_CONTENT_PATH=/opt/ghost-me/content
GHOST_ME_ROUTES_PATH=./routes.yaml
GHOST_ME_DB_IMAGE=mysql:8.4
GHOST_ME_DB_DATA_PATH=/opt/ghost-me/mysql
GHOST_ME_DB_NAME=ghost_me
GHOST_ME_DB_USER=ghost_me
GHOST_ME_DB_PASSWORD=change-me
GHOST_ME_DB_ROOT_PASSWORD=change-me
GHOST_ME_MAIL_FROM="Eduardo Paredes <noreply@thehomelesssherlock.com>"
TRAEFIK_DOCKER_NETWORK=proxy
TRAEFIK_ENTRYPOINT_SECURE=websecure
TRAEFIK_CERTRESOLVER=letsencrypt
+13
View File
@@ -0,0 +1,13 @@
# Ghost Me
Ghost publication for the personal site currently exposed as:
- `https://me.thehomelesssherlock.com`
Deploy with Docker Compose from this directory:
```bash
docker compose --env-file .env up -d
```
Copy `.env.example` to `.env` and keep real secrets only in `.env`.
+91
View File
@@ -0,0 +1,91 @@
services:
ghost-me-db:
image: ${GHOST_ME_DB_IMAGE}
container_name: ghost-me-db
restart: unless-stopped
labels:
prune.protect: "true"
environment:
MYSQL_ROOT_PASSWORD: ${GHOST_ME_DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${GHOST_ME_DB_NAME}
MYSQL_USER: ${GHOST_ME_DB_USER}
MYSQL_PASSWORD: ${GHOST_ME_DB_PASSWORD}
TZ: ${TZ}
volumes:
- ${GHOST_ME_DB_DATA_PATH}:/var/lib/mysql:Z
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u${GHOST_ME_DB_USER} -p${GHOST_ME_DB_PASSWORD} --silent"]
interval: 10s
timeout: 5s
retries: 20
start_period: 30s
networks:
- ghost_me_internal
ghost-me:
image: ${GHOST_ME_IMAGE}
container_name: ghost-me
restart: unless-stopped
depends_on:
ghost-me-db:
condition: service_healthy
environment:
NODE_ENV: production
TZ: ${TZ}
url: https://${GHOST_ME_DOMAIN}
database__client: mysql
database__connection__host: ghost-me-db
database__connection__user: ${GHOST_ME_DB_USER}
database__connection__password: ${GHOST_ME_DB_PASSWORD}
database__connection__database: ${GHOST_ME_DB_NAME}
mail__transport: SMTP
mail__from: ${GHOST_ME_MAIL_FROM}
mail__options__host: mail-relay
mail__options__port: 587
mail__options__secure: "false"
mail__options__ignoreTLS: "true"
volumes:
- ${GHOST_ME_CONTENT_PATH}:/var/lib/ghost/content:Z
- ${GHOST_ME_ROUTES_PATH}:/var/lib/ghost/content/settings/routes.yaml:Z
- ./theme-source-personal:/var/lib/ghost/content/themes/source-personal:Z
networks:
- ghost_me_internal
- proxy
- mail_internal
labels:
prune.protect: "true"
traefik.enable: "true"
traefik.docker.network: "${TRAEFIK_DOCKER_NETWORK}"
traefik.http.routers.ghost-me.rule: "Host(`${GHOST_ME_DOMAIN}`)"
traefik.http.routers.ghost-me.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
traefik.http.routers.ghost-me.tls: "true"
traefik.http.routers.ghost-me.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
traefik.http.routers.ghost-me.service: "ghost-me"
traefik.http.routers.ghost-me.middlewares: "crowdsec-bouncer@file"
traefik.http.services.ghost-me.loadbalancer.server.port: "2368"
traefik.http.routers.ghost-me-alt.rule: "Host(`${GHOST_ME_DOMAIN_ALT}`)"
traefik.http.routers.ghost-me-alt.entrypoints: "${TRAEFIK_ENTRYPOINT_SECURE}"
traefik.http.routers.ghost-me-alt.tls: "true"
traefik.http.routers.ghost-me-alt.tls.certresolver: "${TRAEFIK_CERTRESOLVER}"
traefik.http.routers.ghost-me-alt.service: "ghost-me"
traefik.http.routers.ghost-me-alt.middlewares: "crowdsec-bouncer@file,ghost-me-alt-redirect"
traefik.http.middlewares.ghost-me-alt-redirect.redirectregex.permanent: "true"
traefik.http.middlewares.ghost-me-alt-redirect.redirectregex.regex: "^https://${GHOST_ME_DOMAIN_ALT}(:443)?/(.*)"
traefik.http.middlewares.ghost-me-alt-redirect.redirectregex.replacement: "https://${GHOST_ME_DOMAIN}/$${2}"
homepage.group: "Personal"
homepage.name: "Me"
homepage.icon: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/ghost.svg"
homepage.description: "Sitio personal y CV de Eduardo Paredes"
homepage.href: "https://${GHOST_ME_DOMAIN}/"
homepage.siteMonitor: "http://ghost-me:2368/"
homepage.weight: "140"
networks:
ghost_me_internal:
driver: bridge
labels:
prune.protect: "true"
mail_internal:
external: true
proxy:
external: true
+18
View File
@@ -0,0 +1,18 @@
routes:
/:
data: page.inicio
template: page-inicio
collections:
/blog/:
permalink: /blog/{slug}/
template: index
filter: tag:-hash-project
/proyectos/:
permalink: /proyectos/{slug}/
template: projects
filter: tag:hash-project
taxonomies:
tag: /tag/{slug}/
author: /author/{slug}/