Single part at the root, COMPOSE_FILE in .env
This commit is contained in:
1 parent
321e4b6b35
commit
aac037676c
86 files changed
+68
-27
No files matched your search
@@ -1,8 +1,8 @@
|
|||||||
# backend-python
|
# backend-python
|
||||||
|
|
||||||
Copier template for a `backend/` part: a uv project with one Docker image and one `python -m <module>` entrypoint per service (`api`, `bot`, `userbot`, `worker`, `scheduler`), pydantic-settings, rich logging, optional Dishka, MongoDB or PostgreSQL, Redis, taskiq, CryptoPay, pydantic-ai and a DynamicConfig stored in the database.
|
Copier template for a Python backend, either as a `backend/` part next to other parts or alone at the root of the project (`layout`): a uv project with one Docker image and one `python -m <module>` entrypoint per service (`api`, `bot`, `userbot`, `worker`, `scheduler`), pydantic-settings, rich logging, optional Dishka, MongoDB or PostgreSQL, Redis, taskiq, CryptoPay, pydantic-ai and a DynamicConfig stored in the database.
|
||||||
|
|
||||||
Ships `backend/docker-compose.yml` with root-relative paths, `docker-compose.local.yml` (published ports) and `docker-compose.prod.yml` (the `caddy` network), a `Makefile` with `fmt`, `check`, `build` and service-specific targets, `.env.example` and `CLAUDE.md`. Meant to be applied on top of the `infra` template.
|
Ships `backend/docker-compose.yml` with root-relative paths, `docker-compose.local.yml` (published ports) and `docker-compose.prod.yml` (the `caddy` network), a `Makefile` with `fmt`, `check`, `build` and service-specific targets, `.env.example` and `CLAUDE.md`. Applied on top of the `infra` template, `layout: parts` or `layout: single` respectively.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
copier copy --trust -d project_name="My Thing" <this-repo> <dest>
|
copier copy --trust -d project_name="My Thing" <this-repo> <dest>
|
||||||
|
|||||||
+21
-3
@@ -25,6 +25,14 @@ author_email:
|
|||||||
type: str
|
type: str
|
||||||
default: ""
|
default: ""
|
||||||
|
|
||||||
|
layout:
|
||||||
|
type: str
|
||||||
|
help: Where the backend lives
|
||||||
|
choices:
|
||||||
|
In backend/ next to other parts: part
|
||||||
|
At the root of the project: root
|
||||||
|
default: part
|
||||||
|
|
||||||
backend_services:
|
backend_services:
|
||||||
type: str
|
type: str
|
||||||
multiselect: true
|
multiselect: true
|
||||||
@@ -84,7 +92,7 @@ dynamic_config:
|
|||||||
|
|
||||||
serve_spa:
|
serve_spa:
|
||||||
type: bool
|
type: bool
|
||||||
when: "{{ 'api' in backend_services }}"
|
when: "{{ layout == 'part' and 'api' in backend_services }}"
|
||||||
help: Serve the frontend build from the api as a SPA
|
help: Serve the frontend build from the api as a SPA
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
@@ -93,6 +101,16 @@ install_deps:
|
|||||||
help: uv sync after generation
|
help: uv sync after generation
|
||||||
default: true
|
default: true
|
||||||
|
|
||||||
|
part_dir:
|
||||||
|
type: str
|
||||||
|
when: false
|
||||||
|
default: "{{ 'backend' if layout == 'part' else '.' }}"
|
||||||
|
|
||||||
|
prefix:
|
||||||
|
type: str
|
||||||
|
when: false
|
||||||
|
default: "{{ 'backend/' if layout == 'part' else '' }}"
|
||||||
|
|
||||||
_tasks:
|
_tasks:
|
||||||
- "{% if _copier_operation == 'copy' and install_deps %}sh -c 'cd backend && uv sync'{% else %}true{% endif %}"
|
- "{% if _copier_operation == 'copy' and install_deps %}sh -c 'cd {{ part_dir }} && uv sync'{% else %}true{% endif %}"
|
||||||
- "{% if install_deps %}sh -c 'cd backend && uv run ruff format -q'{% else %}true{% endif %}"
|
- "{% if install_deps %}sh -c 'cd {{ part_dir }} && uv run ruff format -q'{% else %}true{% endif %}"
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
[environment]
|
|
||||||
python = "backend/.venv"
|
|
||||||
|
|
||||||
[src]
|
|
||||||
exclude = ["backend/migrations"]
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
[environment]
|
||||||
|
python = "{{ prefix }}.venv"
|
||||||
|
|
||||||
|
[src]
|
||||||
|
exclude = ["{{ prefix }}migrations"]
|
||||||
File renamed without changes.
@@ -1,4 +1,5 @@
|
|||||||
RUN_ENVIRONMENT=dev
|
{% if layout == 'root' %}COMPOSE_FILE=docker-compose.yml:docker-compose.local.yml
|
||||||
|
{% endif %}RUN_ENVIRONMENT=dev
|
||||||
LOG__LEVEL=INFO
|
LOG__LEVEL=INFO
|
||||||
LOG__LEVEL_EXTERNAL=WARNING
|
LOG__LEVEL_EXTERNAL=WARNING
|
||||||
LOG__SHOW_TIME=false
|
LOG__SHOW_TIME=false
|
||||||
File renamed without changes.
File renamed without changes.
@@ -5,9 +5,11 @@
|
|||||||
{%- if 'kurigram_userbot' in backend_services %}{% set _ = svc_modules.append("userbot") %}{% endif -%}
|
{%- if 'kurigram_userbot' in backend_services %}{% set _ = svc_modules.append("userbot") %}{% endif -%}
|
||||||
{%- if 'scheduler' in backend_services and 'taskiq_worker' not in backend_services %}{% set _ = svc_modules.append("scheduler") %}{% endif -%}
|
{%- if 'scheduler' in backend_services and 'taskiq_worker' not in backend_services %}{% set _ = svc_modules.append("scheduler") %}{% endif -%}
|
||||||
{%- set has_script = dynamic_config and svc_modules -%}
|
{%- set has_script = dynamic_config and svc_modules -%}
|
||||||
COMPOSE := docker compose --project-directory ..
|
COMPOSE := docker compose{% if layout == 'part' %} --project-directory ..{% endif %}
|
||||||
|
{% if layout == 'root' %}SERVICES := $(COMPOSE) --profile services
|
||||||
.PHONY: fmt check build{% if database == 'postgres' %} migrate revision{% endif %}{% if has_script %} script{% endif %}{% if 'kurigram_userbot' in backend_services %} session{% endif %}
|
EXTERNAL := $(COMPOSE) --profile external
|
||||||
|
{% endif %}
|
||||||
|
.PHONY: {% if layout == 'root' %}env external recreate rebuild restart logs down {% endif %}fmt check build{% if database == 'postgres' %} migrate revision{% endif %}{% if has_script %} script{% endif %}{% if 'kurigram_userbot' in backend_services %} session{% endif %}
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
uv run ruff format
|
uv run ruff format
|
||||||
@@ -20,7 +22,27 @@ check:
|
|||||||
|
|
||||||
build:
|
build:
|
||||||
$(COMPOSE) build {{ svc_modules[0] }}
|
$(COMPOSE) build {{ svc_modules[0] }}
|
||||||
{% if database == 'postgres' %}
|
{% if layout == 'root' %}
|
||||||
|
env:
|
||||||
|
@test -f .env || cp .env.example .env
|
||||||
|
|
||||||
|
external:
|
||||||
|
$(EXTERNAL) up -d
|
||||||
|
|
||||||
|
recreate: external
|
||||||
|
$(SERVICES) up -d --force-recreate
|
||||||
|
|
||||||
|
rebuild: build recreate
|
||||||
|
|
||||||
|
restart:
|
||||||
|
$(SERVICES) restart
|
||||||
|
|
||||||
|
logs:
|
||||||
|
$(SERVICES) logs -f --tail=100
|
||||||
|
|
||||||
|
down:
|
||||||
|
$(EXTERNAL) --profile services down
|
||||||
|
{% endif %}{% if database == 'postgres' %}
|
||||||
migrate:
|
migrate:
|
||||||
$(COMPOSE) --profile external run --rm migrator
|
$(COMPOSE) --profile external run --rm migrator
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
+12
-12
@@ -9,21 +9,21 @@
|
|||||||
{%- if 'kurigram_userbot' in backend_services %}{% set _ = app_services.append({'name': 'userbot', 'command': '[userbot]'}) %}{% endif -%}
|
{%- if 'kurigram_userbot' in backend_services %}{% set _ = app_services.append({'name': 'userbot', 'command': '[userbot]'}) %}{% endif -%}
|
||||||
{%- if 'scheduler' in backend_services %}{% set _ = app_services.append({'name': 'scheduler', 'command': ('[worker, scheduler]' if 'taskiq_worker' in backend_services else '[scheduler]')}) %}{% endif -%}
|
{%- if 'scheduler' in backend_services %}{% set _ = app_services.append({'name': 'scheduler', 'command': ('[worker, scheduler]' if 'taskiq_worker' in backend_services else '[scheduler]')}) %}{% endif -%}
|
||||||
{%- macro backend_service(name, command) %} {{ name }}:
|
{%- macro backend_service(name, command) %} {{ name }}:
|
||||||
build: backend
|
build: {{ part_dir }}
|
||||||
image: {{ project_slug }}/backend
|
image: {{ project_slug }}/backend
|
||||||
profiles: [{{ name }}, services]
|
profiles: [{{ name }}, services]
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
- path: .env
|
- path: .env
|
||||||
required: false
|
required: false
|
||||||
- path: backend/.env
|
{% if layout == 'part' %} - path: backend/.env
|
||||||
required: false
|
required: false
|
||||||
environment:
|
{% endif %} environment:
|
||||||
RUN_ENVIRONMENT: prod
|
RUN_ENVIRONMENT: prod
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend/src:/app/src
|
- ./{{ prefix }}src:/app/src
|
||||||
{% if has_scripts %} - ./backend/scripts:/app/scripts
|
{% if has_scripts %} - ./{{ prefix }}scripts:/app/scripts
|
||||||
{% endif %}{% if name == 'userbot' %} - ./backend/sessions:/app/sessions
|
{% endif %}{% if name == 'userbot' %} - ./{{ prefix }}sessions:/app/sessions
|
||||||
{% endif %}{% if name == 'api' and serve_spa %} - ./frontend/build:/app/static:ro
|
{% endif %}{% if name == 'api' and serve_spa %} - ./frontend/build:/app/static:ro
|
||||||
{% endif %} command: {{ command }}
|
{% endif %} command: {{ command }}
|
||||||
{% if svc_networks %} networks:
|
{% if svc_networks %} networks:
|
||||||
@@ -70,20 +70,20 @@ services:
|
|||||||
- ${DB__HOST:-postgres}
|
- ${DB__HOST:-postgres}
|
||||||
|
|
||||||
migrator:
|
migrator:
|
||||||
build: backend
|
build: {{ part_dir }}
|
||||||
image: {{ project_slug }}/backend
|
image: {{ project_slug }}/backend
|
||||||
profiles: [migrate]
|
profiles: [migrate]
|
||||||
env_file:
|
env_file:
|
||||||
- path: .env
|
- path: .env
|
||||||
required: false
|
required: false
|
||||||
- path: backend/.env
|
{% if layout == 'part' %} - path: backend/.env
|
||||||
required: false
|
required: false
|
||||||
environment:
|
{% endif %} environment:
|
||||||
RUN_ENVIRONMENT: prod
|
RUN_ENVIRONMENT: prod
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend/src:/app/src
|
- ./{{ prefix }}src:/app/src
|
||||||
- ./backend/migrations:/app/migrations
|
- ./{{ prefix }}migrations:/app/migrations
|
||||||
- ./backend/alembic.ini:/app/alembic.ini
|
- ./{{ prefix }}alembic.ini:/app/alembic.ini
|
||||||
entrypoint: [alembic]
|
entrypoint: [alembic]
|
||||||
command: [upgrade, head]
|
command: [upgrade, head]
|
||||||
depends_on:
|
depends_on:
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user