-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
193 lines (153 loc) · 6.41 KB
/
Copy pathMakefile
File metadata and controls
193 lines (153 loc) · 6.41 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
.PHONY: up up-full down logs build restart shell-indiekit shell-eleventy shell-cron backup status \
build-release tag push release version ci ci-status \
migrate-build migrate-detect migrate-convert migrate-preview migrate-apply migrate-shell
# ─── Core profile ───
up:
docker compose up -d
down:
docker compose down
logs:
docker compose logs -f
build:
docker compose build --no-cache
restart:
docker compose restart
status:
docker compose ps
# ─── Full profile ───
#
# Compose 2.39+ no longer honors `profiles: []` overrides to clear a parent's
# profile gate, so we activate the redis profile explicitly here. Removing
# the `--profile redis` flag will reproduce the "service indiekit depends on
# undefined service redis" error.
#
# When -f flags are passed, Compose disables auto-loading of
# docker-compose.override.yml. We include it conditionally so dev settings
# (Caddyfile.dev, PASSWORD_SECRET, etc.) still apply.
COMPOSE_FULL := docker compose --profile redis \
-f docker-compose.yml \
-f docker-compose.full.yml \
$(if $(wildcard docker-compose.override.yml),-f docker-compose.override.yml,)
up-full:
$(COMPOSE_FULL) up -d
build-full:
$(COMPOSE_FULL) build --no-cache
restart-full:
$(COMPOSE_FULL) restart
logs-full:
$(COMPOSE_FULL) logs -f
# ─── 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 ───
init:
git submodule update --init --recursive
update-theme:
git submodule update --remote eleventy-site
@echo "==> Theme updated. Run 'make build' to rebuild."
# ─── Docker Hub ───
# Version from package.core.json (upstream Indiekit version)
VERSION := $(shell node -p "require('./docker/indiekit/package.core.json').dependencies['@indiekit/indiekit']")
REGISTRY := rmdes
# Build full-profile images with version tags
build-release:
docker compose -f docker-compose.yml -f docker-compose.full.yml 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