-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
203 lines (162 loc) · 7.24 KB
/
Copy pathMakefile
File metadata and controls
203 lines (162 loc) · 7.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
.PHONY: compose plugin-list plugin-add plugin-remove up down logs build restart status \
shell-indiekit shell-eleventy shell-cron shell-caddy backup restore init update-theme \
build-release tag push release version ci ci-status \
migrate-build migrate-detect migrate-convert migrate-preview migrate-apply migrate-shell
# ─── Registry compose ───
#
# Regenerate .compiled/{package.json,indiekit.config.js,plugin-loadout.json} from
# config/plugins.yaml + the plugin-registry submodule. Runs before every build so
# the Docker images always consume a fresh composed plugin set.
compose: | scripts/node_modules
node scripts/compose-site.mjs
# Host-side dependency for the compose step (js-yaml); auto-installed on a fresh
# clone so `make compose`/`build`/`up` work even before `make init` runs.
scripts/node_modules: scripts/package-lock.json
npm ci --prefix scripts
# Pretty-print the effective plugin set for this deployment.
plugin-list: compose
@node -e "const l=require('./.compiled/plugin-loadout.json'); \
console.log('Plugins for indiekit-deploy ('+l.summary.total+' total):'); \
for (const p of l.selected) console.log(' '+String(p.tier).padEnd(12)+' '+p.key+' ('+p.package+(p.version?'@'+p.version:'')+')'); \
if (l.warnings.length) { console.log('Warnings:'); for (const w of l.warnings) console.log(' '+w); }"
# Enable/disable a non-core plugin in config/plugins.yaml, then recompose.
# make plugin-add KEY=github
# make plugin-remove KEY=github
plugin-add:
@test -n "$(KEY)" || (echo "ERROR: KEY not set (usage: make plugin-add KEY=github)" && exit 1)
node scripts/plugin-edit.mjs add $(KEY)
$(MAKE) compose
plugin-remove:
@test -n "$(KEY)" || (echo "ERROR: KEY not set (usage: make plugin-remove KEY=github)" && exit 1)
node scripts/plugin-edit.mjs remove $(KEY)
$(MAKE) compose
# ─── Lifecycle ───
up: compose
docker compose up -d
down:
docker compose down
logs:
docker compose logs -f
build: compose
docker compose build --no-cache
restart:
docker compose restart
status:
docker compose ps
# ─── Shells ───
shell-indiekit:
docker compose exec indiekit sh
shell-eleventy:
docker compose exec eleventy sh
shell-cron:
docker compose exec cron sh
shell-caddy:
docker compose exec caddy sh
# ─── Maintenance ───
backup:
@echo "==> Backing up volumes..."
@mkdir -p backups
@TIMESTAMP=$$(date +%Y%m%d-%H%M%S); \
docker run --rm \
-v indiekit-deploy_content:/data/content:ro \
-v indiekit-deploy_uploads:/data/uploads:ro \
-v indiekit-deploy_mongodb_data:/data/mongodb:ro \
-v indiekit-deploy_indiekit_config:/data/config:ro \
-v $$(pwd)/backups:/backup \
alpine tar czf /backup/indiekit-$$TIMESTAMP.tar.gz -C /data .
@echo "==> Backup saved to backups/"
restore:
@echo "Usage: make restore FILE=backups/indiekit-YYYYMMDD-HHMMSS.tar.gz"
@echo "WARNING: This will overwrite all current data!"
@test -n "$(FILE)" || (echo "ERROR: FILE not set" && exit 1)
@read -p "Are you sure? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
docker compose down
docker run --rm \
-v indiekit-deploy_content:/data/content \
-v indiekit-deploy_uploads:/data/uploads \
-v indiekit-deploy_mongodb_data:/data/mongodb \
-v indiekit-deploy_indiekit_config:/data/config \
-v $$(pwd)/backups:/backup:ro \
alpine sh -c "cd /data && tar xzf /backup/$$(basename $(FILE))"
docker compose up -d
# ─── Submodule ───
# Initialize BOTH submodules: eleventy-site (theme) + plugin-registry (catalog).
init:
git submodule update --init --recursive
npm ci --prefix scripts
update-theme:
git submodule update --remote eleventy-site
@echo "==> Theme updated. Run 'make build' to rebuild."
# ─── Docker Hub ───
# Version from the root package.json (upstream Indiekit version pin)
VERSION := $(shell node -p "require('./package.json').dependencies['@indiekit/indiekit']")
REGISTRY := rmdes
# Build release images with version tags (composed plugin set)
build-release: compose
docker compose build --no-cache
# Tag images with version number (in addition to :latest)
tag:
docker tag $(REGISTRY)/indiekit-deploy-server:latest $(REGISTRY)/indiekit-deploy-server:$(VERSION)
docker tag $(REGISTRY)/indiekit-deploy-site:latest $(REGISTRY)/indiekit-deploy-site:$(VERSION)
docker tag $(REGISTRY)/indiekit-deploy-cron:latest $(REGISTRY)/indiekit-deploy-cron:$(VERSION)
docker tag $(REGISTRY)/indiekit-deploy-migrator:latest $(REGISTRY)/indiekit-deploy-migrator:$(VERSION)
# Push all images to Docker Hub
push: tag
docker push $(REGISTRY)/indiekit-deploy-server:latest
docker push $(REGISTRY)/indiekit-deploy-server:$(VERSION)
docker push $(REGISTRY)/indiekit-deploy-site:latest
docker push $(REGISTRY)/indiekit-deploy-site:$(VERSION)
docker push $(REGISTRY)/indiekit-deploy-cron:latest
docker push $(REGISTRY)/indiekit-deploy-cron:$(VERSION)
docker push $(REGISTRY)/indiekit-deploy-migrator:latest
docker push $(REGISTRY)/indiekit-deploy-migrator:$(VERSION)
# Full release: build + tag + push
release: build-release push
@echo "==> Released $(VERSION) to Docker Hub"
# Show current version
version:
@echo $(VERSION)
# ─── Migration (Jekyll, Hugo, micro.blog → Indiekit) ───
#
# Workflow:
# 1. Drop your old SSG export into migration/input/
# 2. make migrate-detect # what's in there?
# 3. make migrate-convert FROM=hugo # transform → migration/staged/
# 4. Inspect migration/staged/ in your editor
# 5. make migrate-preview # what would land in your live volumes?
# 6. make migrate-apply # copy into the content + uploads volumes
#
# All steps run inside a one-shot `migrator` Docker service. No host-side
# Node or Python required.
# Build the migrator image (cached after first run).
migrate-build:
docker compose --profile migrate build migrator
# Auto-detect which SSG the input directory looks like.
migrate-detect: migrate-build
docker compose --profile migrate run --rm migrator bin/detect.mjs /migration/input
# Convert. Set FROM=jekyll | hugo | microblog to override auto-detection.
migrate-convert: migrate-build
docker compose --profile migrate run --rm migrator bin/convert.mjs \
$(if $(FROM),--from $(FROM),) \
--input /migration/input --output /migration/staged
# Compare staged tree against live volumes. Read-only, never modifies anything.
migrate-preview: migrate-build
docker compose --profile migrate run --rm migrator bin/preview.mjs \
--staged /migration/staged --content /data/content --uploads /data/uploads
# Apply staged tree into the live volumes. Refuses on collisions unless FORCE=1.
# Also writes staged/Caddyfile.redirects → docker/caddy/migration-redirects so
# Caddy's `import migration-redirects` picks them up after a restart.
migrate-apply: migrate-build
docker compose --profile migrate run --rm migrator bin/apply.mjs \
--staged /migration/staged --content /data/content --uploads /data/uploads \
--caddy /migration-caddy \
$(if $(FORCE),--force,)
# Drop into a shell inside the migrator container for ad-hoc debugging.
migrate-shell: migrate-build
docker compose --profile migrate run --rm --entrypoint sh migrator
# ─── CI/CD ───
# Trigger GitHub Actions build from local machine
ci:
gh workflow run build-images.yml
ci-status:
gh run list --workflow=build-images.yml --limit=5