Single part at the root, COMPOSE_FILE in .env

This commit is contained in:
hh
2026-09-08 20:38:27 +02:00
parent a950161b00
commit 1c628625e9
10 changed files with 47 additions and 19 deletions
+3 -3
View File
@@ -1,10 +1,10 @@
# infra
Copier template for the root of a project: `docker-compose.yml` that includes every part, a `Makefile` that drives compose and delegates `fmt`, `check` and `build` to parts, `.env.example`, `.gitignore`, `CLAUDE.md` and pre-commit hooks.
Copier template for the root of a project. With `layout: parts` it ships a `docker-compose.yml` that includes every part, a `Makefile` that drives compose and delegates `fmt`, `check` and `build` to parts, and an `.env.example` whose `COMPOSE_FILE` adds each part's `docker-compose.local.yml`. With `layout: single` a part template renders straight into the root and infra ships only `.gitignore`, `CLAUDE.md` and pre-commit hooks.
A part is a directory with:
- `docker-compose.yml` with root-relative paths, plus `docker-compose.local.yml` and `docker-compose.prod.yml` selected by `COMPOSE_ENV`
- `docker-compose.yml` with root-relative paths, plus `docker-compose.local.yml` and `docker-compose.prod.yml` picked through `COMPOSE_FILE` in the root `.env`
- `Makefile` with `fmt`, `check` and `build` targets
- `.env.example` appended to the root `.env` by `make env`
- `CLAUDE.md` with the part's checking commands
@@ -12,6 +12,6 @@ A part is a directory with:
Application services carry the `services` profile, databases and other infrastructure carry `external`.
```sh
copier copy --trust -d 'parts=["backend","frontend"]' <this-repo> <dest>
copier copy --trust -d layout=parts -d 'parts=["backend","frontend"]' <this-repo> <dest>
copier update -a .copier/infra.yml
```
+9
View File
@@ -4,9 +4,18 @@ _answers_file: .copier/infra.yml
_envops:
keep_trailing_newline: true
layout:
type: str
help: Where the code lives
choices:
Parts in their own directories: parts
A single part at the root: single
default: parts
parts:
type: str
multiselect: true
when: "{{ layout == 'parts' }}"
help: Parts that live in their own directory with a docker-compose.yml and a Makefile
choices:
backend: backend
-1
View File
@@ -1 +0,0 @@
COMPOSE_ENV=local
-6
View File
@@ -1,6 +0,0 @@
.env
.env.*
!.env.example
docker-compose.override.yml
.DS_Store
.idea
+16
View File
@@ -0,0 +1,16 @@
.env
.env.*
!.env.example
docker-compose.override.yml
.DS_Store
.idea
{% if layout == 'single' %}.venv/
__pycache__/
*.pyc
.ruff_cache/
.pytest_cache/
sessions/*.session*
node_modules/
.svelte-kit/
/build/
{% endif %}
+12 -2
View File
@@ -1,7 +1,17 @@
repos:
- repo: local
hooks:{% if not parts %} []{% endif %}
{% for part in parts %} - id: {{ part }}-fmt
hooks:{% if layout == 'parts' and not parts %} []{% endif %}
{% if layout == 'single' %} - id: fmt
name: fmt
entry: make fmt
language: system
pass_filenames: false
- id: check
name: check
entry: make check
language: system
pass_filenames: false
{% endif %}{% for part in parts %} - id: {{ part }}-fmt
name: {{ part }} fmt
entry: make -C {{ part }} fmt
language: system
-7
View File
@@ -1,7 +0,0 @@
{% if parts %}include:
{% for part in parts %} - path:
- {{ part }}/docker-compose.yml
- {{ part }}/docker-compose.${COMPOSE_ENV:-local}.yml
project_directory: .
{% endfor %}{% else %}services: {}
{% endif %}
@@ -0,0 +1,2 @@
{% if parts %}COMPOSE_FILE=docker-compose.yml{% for part in parts %}:{{ part }}/docker-compose.local.yml{% endfor %}
{% endif %}
@@ -0,0 +1,5 @@
{% if parts %}include:
{% for part in parts %} - path: {{ part }}/docker-compose.yml
project_directory: .
{% endfor %}{% else %}services: {}
{% endif %}