Skip to content

Commit 83120ac

Browse files
eviosclaude
andcommitted
auto-update Ghost/Caddy/MySQL on reboot via @reboot cron + pull_policy
On boot: Docker restarts containers instantly (old images), then 30s later cron pulls latest images and recreates only changed containers. Data volumes are untouched. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c430168 commit 83120ac

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

infra/ghost/deploy-ghost.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# - Prompt for your FQDN
2222
# - Generate random DB credentials in /opt/ghost/.env
2323
# - Start Ghost + MySQL + Caddy (auto SSL) at /opt/ghost/
24+
# - Enable auto-update on boot (pulls latest images via systemd)
2425
#
2526
# 4. Open https://<your-fqdn>/ghost to create admin account
2627
#
@@ -97,6 +98,17 @@ if [ "$SCRIPT_DIR" != "$GHOST_DIR" ]; then
9798
cp "$SCRIPT_DIR/docker-compose.yml" "$GHOST_DIR/docker-compose.yml"
9899
fi
99100

101+
# Auto-update on boot:
102+
# 1. Docker restart:always brings containers up instantly (old images)
103+
# 2. 30s later this cron pulls latest ghost:6/mysql:9/caddy:2 images
104+
# 3. docker compose up -d recreates only containers whose image changed
105+
# Data volumes are untouched — only container binaries update
106+
CRON_JOB="@reboot sleep 30 && cd $GHOST_DIR && /usr/bin/docker compose pull --quiet && /usr/bin/docker compose up -d"
107+
if ! crontab -l 2>/dev/null | grep -qF "ghost"; then
108+
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
109+
echo "Added @reboot cron job (auto-pulls latest images on boot)"
110+
fi
111+
100112
# Start
101113
cd "$GHOST_DIR"
102114
docker compose up -d

infra/ghost/docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ services:
22
# Reverse proxy — terminates SSL via Let's Encrypt, forwards to Ghost
33
caddy:
44
image: caddy:2
5+
pull_policy: always
56
container_name: caddy
67
restart: always
78
ports:
@@ -17,6 +18,7 @@ services:
1718
# Blog engine — internal only, not exposed to the internet
1819
ghost:
1920
image: ghost:6
21+
pull_policy: always
2022
container_name: ghost
2123
restart: always
2224
expose:
@@ -37,6 +39,7 @@ services:
3739
# Database — persistent storage for all Ghost content
3840
ghost-db:
3941
image: mysql:9
42+
pull_policy: always
4043
container_name: ghost-db
4144
restart: always
4245
environment:

0 commit comments

Comments
 (0)