build: add per-environment (test/prod) Makefile targets
Split env config into local vs remote: - .env: local/shared config, always loaded (docker compose + make test) - .env.test / .env.prod: full remote config, loaded on demand via ENV Remote targets now generate -test/-prod variants (e.g. remote-install-prod); a guard-env prerequisite blocks bare remote targets with no environment set. Refresh .env.example to document the two-tier layout and add .env.prod/.env.test to gitignore and the never-read list in CLAUDE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+52
-12
@@ -1,27 +1,67 @@
|
||||
# SSH connection
|
||||
REMOTE_USER=root
|
||||
# .env.example — template for the project's environment files.
|
||||
#
|
||||
# There are TWO kinds of env file, loaded by the Makefile in this order:
|
||||
#
|
||||
# .env → LOCAL / shared config. ALWAYS loaded. NO remote credentials.
|
||||
# Used by local targets (docker compose ${UID}/${GID} + the
|
||||
# travel-memories env_file, and `make test-post` / `make test`).
|
||||
# Copy the LOCAL section below into it.
|
||||
#
|
||||
# .env.test → REMOTE config for the test environment.
|
||||
# .env.prod → REMOTE config for production.
|
||||
# Loaded only when a remote target sets ENV, e.g.
|
||||
# `make remote-install-prod`. Copy the REMOTE section below into
|
||||
# each, with the values for that environment.
|
||||
#
|
||||
# .env, .env.test and .env.prod are all gitignored — never commit real values.
|
||||
# This .example file is the only one that IS committed; keep its values as
|
||||
# placeholders.
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# LOCAL → copy into .env
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# Host user/group id for container file ownership (docker-compose ${UID}:${GID}).
|
||||
# Match your local user: run `id -u` / `id -g` (usually 1000 on a single-user box).
|
||||
UID=1000
|
||||
GID=1000
|
||||
|
||||
# Local Grav dev server + test login, used by `make test-post` / `make test`
|
||||
# (scripts/test-post.sh). Must be a valid Grav site login on the local instance.
|
||||
GRAV_BASE_URL=http://localhost:8081
|
||||
GRAV_TEST_USER=your-local-grav-user
|
||||
GRAV_TEST_PASS=your-local-grav-password
|
||||
GRAV_USER_DIR=/absolute/path/to/travel-blog-intotheeast/user
|
||||
|
||||
# travel-memories service (docker-compose `env_file: .env`). Fill in whatever
|
||||
# that Flask app needs — e.g. its Immich connection. Leave commented until set.
|
||||
# IMMICH_URL=
|
||||
# IMMICH_API_KEY=
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# REMOTE → copy into .env.test AND .env.prod (with per-env values)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# SSH connection to the target server.
|
||||
REMOTE_USER=deploy
|
||||
REMOTE_HOST=example.com
|
||||
REMOTE_PORT=22
|
||||
REMOTE_HOME=/home/example.com
|
||||
|
||||
# Server paths (override here if your setup differs from the Makefile defaults)
|
||||
# Server paths. Optional — default to $(REMOTE_HOME)/public_html and
|
||||
# $(REMOTE_HOME)/site-config. Set explicitly only if the layout differs
|
||||
# (e.g. a per-domain webroot like /home/deploy/domains/test.example.com/public_html).
|
||||
WEBROOT=/home/example.com/public_html
|
||||
SITE_CONFIG_DIR=/home/example.com/site-config
|
||||
|
||||
# Grav
|
||||
# Grav version installed by scripts/server-install.sh (remote-install).
|
||||
GRAV_VERSION=2.0.0-rc.10
|
||||
|
||||
# Repos
|
||||
# Repos cloned/pulled on the server.
|
||||
USER_REPO=https://gitea.example.com/org/intotheeast-user.git
|
||||
MAIN_REPO=https://gitea.example.com/org/travel-blog-intotheeast.git
|
||||
|
||||
# Gitea credentials — never commit these; only ever in .env (local) or ~/.env-project (server, temporary)
|
||||
# Gitea credentials used by remote-install / remote-env-setup.
|
||||
GITEA_HOST=gitea.example.com
|
||||
GITEA_USER=deploy-user
|
||||
GITEA_TOKEN=your-gitea-personal-access-token
|
||||
|
||||
# Test credentials — used by 'make test-post' (must be a valid Grav site login user)
|
||||
GRAV_TEST_USER=mischa
|
||||
GRAV_TEST_PASS=TravelBlog2026!
|
||||
GRAV_BASE_URL=http://localhost:8081
|
||||
GRAV_USER_DIR=/home/mischa/Projects/travel-blog-intotheeast/user
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Environment
|
||||
.env
|
||||
.env.prod
|
||||
.env.test
|
||||
|
||||
# Grav CMS
|
||||
/user/
|
||||
|
||||
@@ -113,7 +113,7 @@ After updating, also create the new trip's page tree under `user/pages/01.trips/
|
||||
|
||||
### Environment
|
||||
|
||||
**Never read `.env`** — it contains sensitive credentials. You may pass it to commands (e.g. `docker compose`, `make`) but never read its contents directly. Ask the user if you need environment-specific information.
|
||||
**Never read `.env`, `.env.prod`, or `.env.test`** — they contain sensitive credentials. You may pass them to commands (e.g. `docker compose`, `make`) but never read their contents directly. Ask the user if you need environment-specific information.
|
||||
|
||||
### Remote operations
|
||||
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
# Local/shared config — always loaded. Keep remote credentials OUT of here;
|
||||
# those live in .env.test / .env.prod. (docker compose also reads .env directly
|
||||
# for ${UID}/${GID} substitution and the travel-memories env_file.)
|
||||
-include .env
|
||||
|
||||
# Remote config — loaded only when targeting an environment. ENV is set
|
||||
# automatically by the env-suffixed remote targets (e.g. `make remote-install-prod`);
|
||||
# each .env.<ENV> holds a full, self-contained set of remote vars.
|
||||
ENV ?=
|
||||
-include .env.$(ENV)
|
||||
export
|
||||
|
||||
REMOTE_PORT ?= 22
|
||||
@@ -6,6 +15,24 @@ SSH := ssh -p $(REMOTE_PORT) $(REMOTE_USER)@$(REMOTE_HOST)
|
||||
WEBROOT ?= $(REMOTE_HOME)/public_html
|
||||
SITE_CONFIG_DIR ?= $(REMOTE_HOME)/site-config
|
||||
|
||||
# ── Environment guard + generated per-env remote targets ──────────────────────
|
||||
# Every remote-* target below gains `-test` / `-prod` variants, e.g.
|
||||
# make remote-install-prod → runs remote-install with ENV=prod
|
||||
# Calling a bare remote target (no ENV) fails via guard-env.
|
||||
REMOTE_TARGETS := remote-env-setup remote-env-remove remote-wipe remote-install \
|
||||
remote-fetch remote-fetch-content remote-install-plugins remote-upgrade-grav \
|
||||
remote-clean remote-maintenance-on remote-maintenance-off
|
||||
ENVS := test prod
|
||||
|
||||
guard-env:
|
||||
@test -n "$(ENV)" || { echo "ERROR: no environment. Use an env-suffixed target, e.g. 'make remote-install-prod'."; exit 1; }
|
||||
@test -f ".env.$(ENV)" || { echo "ERROR: missing .env.$(ENV)"; exit 1; }
|
||||
|
||||
define make-env-target
|
||||
$(1)-$(2): ; @$$(MAKE) --no-print-directory $(1) ENV=$(2)
|
||||
endef
|
||||
$(foreach t,$(REMOTE_TARGETS),$(foreach e,$(ENVS),$(eval $(call make-env-target,$(t),$(e)))))
|
||||
|
||||
# ── Tests ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
test-config:
|
||||
@@ -80,21 +107,21 @@ content-pull:
|
||||
|
||||
# ── Remote credentials ─────────────────────────────────────────────────────────
|
||||
|
||||
remote-env-setup:
|
||||
remote-env-setup: guard-env
|
||||
@$(SSH) "printf 'GITEA_HOST=%s\nGITEA_USER=%s\nGITEA_TOKEN=%s\n' \
|
||||
'$(GITEA_HOST)' '$(GITEA_USER)' '$(GITEA_TOKEN)' > ~/.env-intotheeast && chmod 600 ~/.env-intotheeast"
|
||||
@echo "Credentials written to server. Run 'make remote-env-remove' when done."
|
||||
|
||||
remote-env-remove:
|
||||
remote-env-remove: guard-env
|
||||
@$(SSH) "rm -f ~/.env-intotheeast"
|
||||
@echo "Credentials removed from server."
|
||||
|
||||
# ── Remote: initial install ────────────────────────────────────────────────────
|
||||
|
||||
remote-wipe:
|
||||
remote-wipe: guard-env
|
||||
$(SSH) "cd $(WEBROOT) && rm -rf assets backup bin cache images logs system tmp vendor webserver-configs index.php .htaccess CHANGELOG.md LICENSE.txt README.md"
|
||||
|
||||
remote-install:
|
||||
remote-install: guard-env
|
||||
$(SSH) "WEBROOT=$(WEBROOT) \
|
||||
SITE_CONFIG_DIR=$(SITE_CONFIG_DIR) \
|
||||
USER_REPO=$(USER_REPO) \
|
||||
@@ -108,24 +135,24 @@ remote-install:
|
||||
|
||||
# ── Remote: ongoing maintenance ────────────────────────────────────────────────
|
||||
|
||||
remote-fetch:
|
||||
remote-fetch: guard-env
|
||||
$(SSH) "git -C $(SITE_CONFIG_DIR) checkout main && git -C $(SITE_CONFIG_DIR) pull"
|
||||
|
||||
remote-fetch-content:
|
||||
remote-fetch-content: guard-env
|
||||
$(SSH) "git -C $(WEBROOT)/user fetch origin main && git -C $(WEBROOT)/user sparse-checkout disable && git -C $(WEBROOT)/user reset --hard origin/main"
|
||||
|
||||
remote-install-plugins:
|
||||
remote-install-plugins: guard-env
|
||||
$(SSH) "cd $(WEBROOT) && php bin/gpm install $(shell cat plugins.txt | tr '\n' ' ') -y"
|
||||
|
||||
|
||||
remote-upgrade-grav:
|
||||
remote-upgrade-grav: guard-env
|
||||
$(SSH) "cd $(WEBROOT) && php bin/grav upgrade"
|
||||
|
||||
remote-clean:
|
||||
remote-clean: guard-env
|
||||
$(SSH) "cd $(WEBROOT) && php bin/grav clearcache"
|
||||
|
||||
remote-maintenance-on:
|
||||
remote-maintenance-on: guard-env
|
||||
$(SSH) "bash -s on $(WEBROOT)" < scripts/server-maintenance.sh
|
||||
|
||||
remote-maintenance-off:
|
||||
remote-maintenance-off: guard-env
|
||||
$(SSH) "bash -s off $(WEBROOT)" < scripts/server-maintenance.sh
|
||||
|
||||
Reference in New Issue
Block a user