chore(*): adopt project templates
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"command": "bun fix --skip=correctness/noUnusedImports",
|
"command": "cd frontend && bun run fix --skip=correctness/noUnusedImports",
|
||||||
"type": "command"
|
"type": "command"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
_commit: v0.3.2
|
||||||
|
_src_path: https://git.kotikot.com/templates/backend-python.git
|
||||||
|
author_email: h@kotikot.com
|
||||||
|
author_name: h
|
||||||
|
backend_services:
|
||||||
|
- api
|
||||||
|
- kurigram_userbot
|
||||||
|
database: postgres
|
||||||
|
dynamic_config: false
|
||||||
|
install_deps: false
|
||||||
|
layout: part
|
||||||
|
project_description: A read-only Telegram client that keeps everything
|
||||||
|
project_name: beavergram
|
||||||
|
project_slug: beavergram
|
||||||
|
serve_spa: true
|
||||||
|
use_llm: false
|
||||||
|
use_redis: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
_commit: v0.1.2
|
||||||
|
_src_path: https://git.kotikot.com/templates/caddy.git
|
||||||
|
project_slug: beavergram
|
||||||
|
routes:
|
||||||
|
- api
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
_commit: v0.3.1
|
||||||
|
_src_path: https://git.kotikot.com/templates/frontend-svelte.git
|
||||||
|
include_impeccable: false
|
||||||
|
install_deps: false
|
||||||
|
layout: part
|
||||||
|
project_name: beavergram
|
||||||
|
project_slug: beavergram
|
||||||
|
serve: api
|
||||||
|
ui_library: none
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
_commit: v0.3.1
|
||||||
|
_src_path: https://git.kotikot.com/templates/infra.git
|
||||||
|
init_git: false
|
||||||
|
layout: parts
|
||||||
|
parts:
|
||||||
|
- backend
|
||||||
|
- frontend
|
||||||
|
project_description: A read-only Telegram client that keeps everything
|
||||||
|
project_name: beavergram
|
||||||
+2
-16
@@ -1,16 +1,2 @@
|
|||||||
COMPOSE_PROFILES=db,userbot,api
|
COMPOSE_FILE=docker-compose.yml:backend/docker-compose.override.yml:frontend/docker-compose.override.yml
|
||||||
RUN_ENVIRONMENT=prod
|
COMPOSE_PROFILES=external,services
|
||||||
|
|
||||||
# Leave empty for *.localhost.
|
|
||||||
FRONTEND_DEV_HOST=
|
|
||||||
|
|
||||||
DB__HOST=postgres
|
|
||||||
DB__PORT=5432
|
|
||||||
DB__USER=beavergram
|
|
||||||
DB__PASSWORD=beavergram
|
|
||||||
DB__DB_NAME=beavergram
|
|
||||||
DB__MIN_POOL_SIZE=5
|
|
||||||
DB__MAX_POOL_SIZE=20
|
|
||||||
DB__SCRIPTS_CONNECTION_URL=postgresql://beavergram:beavergram@localhost:5433/beavergram
|
|
||||||
|
|
||||||
STORAGE__ROOT=./storage
|
|
||||||
|
|||||||
+5
-3
@@ -1,6 +1,8 @@
|
|||||||
.idea
|
|
||||||
docker-compose.override.yml
|
|
||||||
.env
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
docker-compose.override.yml
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
docs
|
docs
|
||||||
storage
|
storage
|
||||||
backend/sessions
|
|
||||||
|
|||||||
+18
-22
@@ -1,31 +1,27 @@
|
|||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
||||||
rev: v0.15.15
|
|
||||||
hooks:
|
|
||||||
- id: ruff-check
|
|
||||||
types_or: [ python, pyi ]
|
|
||||||
args: [ --fix ]
|
|
||||||
- id: ruff-format
|
|
||||||
types_or: [ python, pyi ]
|
|
||||||
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: ultracite
|
- id: backend-fmt
|
||||||
name: ultracite
|
name: backend fmt
|
||||||
entry: bash -c 'cd frontend && bun x ultracite fix'
|
entry: make -C backend fmt
|
||||||
|
language: system
|
||||||
|
files: ^backend/
|
||||||
|
pass_filenames: false
|
||||||
|
- id: backend-check
|
||||||
|
name: backend check
|
||||||
|
entry: make -C backend check
|
||||||
|
language: system
|
||||||
|
files: ^backend/
|
||||||
|
pass_filenames: false
|
||||||
|
- id: frontend-fmt
|
||||||
|
name: frontend fmt
|
||||||
|
entry: make -C frontend fmt
|
||||||
language: system
|
language: system
|
||||||
files: ^frontend/
|
files: ^frontend/
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
- id: frontend-check
|
||||||
- id: svelte-check
|
name: frontend check
|
||||||
name: svelte check
|
entry: make -C frontend check
|
||||||
entry: bash -c 'cd frontend && bun check'
|
|
||||||
language: system
|
language: system
|
||||||
files: ^frontend/
|
files: ^frontend/
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
|
||||||
- id: ty
|
|
||||||
name: ty check
|
|
||||||
entry: uvx ty check
|
|
||||||
language: python
|
|
||||||
types_or: [ python, pyi ]
|
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
- **Reusability**: Create reusable components and functions
|
- **Reusability**: Create reusable components and functions
|
||||||
- **Less Code = Less Debt**: Minimize code footprint
|
- **Less Code = Less Debt**: Minimize code footprint
|
||||||
- **NEVER write comments** - code should be self-documenting
|
- **NEVER write comments** - code should be self-documenting
|
||||||
|
- **Docstrings ONLY if explicitly asked**
|
||||||
|
|
||||||
## Checking commands
|
## Checking commands
|
||||||
After writing code, always run:
|
After writing code, always run:
|
||||||
```shell
|
```shell
|
||||||
bun check # svelte-check
|
make fmt
|
||||||
bun fix # biome linter
|
make check
|
||||||
```
|
```
|
||||||
@@ -1,30 +1,29 @@
|
|||||||
.PHONY: recreate down restart rebuild deploy migrate session-create frontend
|
PARTS := $(patsubst %/Makefile,%,$(wildcard */Makefile))
|
||||||
|
|
||||||
|
.PHONY: env recreate rebuild restart logs down deploy fmt check build pre-deploy post-deploy
|
||||||
|
|
||||||
|
env:
|
||||||
|
@test -f .env || awk 'FNR == 1 && NR > 1 { print "" } 1' .env.example $(addsuffix /.env.example,$(PARTS)) > .env
|
||||||
|
@for part in $(PARTS); do test -f $$part/docker-compose.override.yml || cp $$part/docker-compose.override.yml.example $$part/docker-compose.override.yml; done
|
||||||
|
|
||||||
recreate:
|
recreate:
|
||||||
docker compose up -d --force-recreate
|
docker compose up -d --force-recreate
|
||||||
|
|
||||||
|
rebuild: build
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
restart:
|
||||||
|
docker compose restart
|
||||||
|
|
||||||
|
logs:
|
||||||
|
docker compose logs -f --tail=100
|
||||||
|
|
||||||
down:
|
down:
|
||||||
docker compose down
|
docker compose down
|
||||||
|
|
||||||
restart:
|
deploy: pre-deploy
|
||||||
$(MAKE) recreate
|
|
||||||
|
|
||||||
rebuild:
|
|
||||||
docker compose build
|
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
$(MAKE) post-deploy
|
||||||
|
|
||||||
frontend:
|
fmt check build pre-deploy post-deploy:
|
||||||
docker compose run --rm --no-deps frontend-dev sh -c "bun install && bun run build"
|
@for part in $(PARTS); do $(MAKE) -C $$part $@ || exit 1; done
|
||||||
|
|
||||||
deploy:
|
|
||||||
$(MAKE) frontend
|
|
||||||
$(MAKE) rebuild
|
|
||||||
|
|
||||||
migrate:
|
|
||||||
docker compose --profile db --profile migrate run --rm migrator $(filter-out $@,$(MAKECMDGOALS))
|
|
||||||
|
|
||||||
session-create:
|
|
||||||
cd backend && uv run python scripts/session/create.py
|
|
||||||
|
|
||||||
%:
|
|
||||||
@:
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Nothing is ever deleted from the archive.
|
|||||||
|
|
||||||
- `backend/` - `userbot` (kurigram, the capture loop and jobs) and `api` (FastAPI: the web API, the MCP server, and the built frontend as static files).
|
- `backend/` - `userbot` (kurigram, the capture loop and jobs) and `api` (FastAPI: the web API, the MCP server, and the built frontend as static files).
|
||||||
- `frontend/` - SvelteKit, `adapter-static`; a chat client over the archive: folders, chat list, thread with media, versions and the deleted messages inline, search, stories, presence graphs.
|
- `frontend/` - SvelteKit, `adapter-static`; a chat client over the archive: folders, chat list, thread with media, versions and the deleted messages inline, search, stories, presence graphs.
|
||||||
- `docker-compose.yml` - Postgres with TimescaleDB, `userbot`, `api`; profiles `db,userbot,api`.
|
- `docker-compose.yml` - includes `backend/` (Postgres with TimescaleDB, `userbot`, `api`) and `frontend/` (the dev server); profiles `external` and `services`.
|
||||||
|
|
||||||
## MCP
|
## MCP
|
||||||
|
|
||||||
@@ -28,18 +28,17 @@ Read-only: `search_messages_tool`, `list_chats`, `get_chat_history` (with delete
|
|||||||
## Run
|
## Run
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp .env.example .env # DB__*, STORAGE__ROOT, profiles
|
make env # .env and docker-compose.override.yml from the examples
|
||||||
cp backend/.env.example backend/.env # TG__*, API__*, AUTH__TOKEN
|
make -C backend session # log the account in once; the session file stays in backend/sessions
|
||||||
make session-create # log the account in once; the session file stays in backend/sessions
|
make deploy # build what changed, migrate, start the containers
|
||||||
make migrate upgrade head
|
|
||||||
make deploy # build the frontend, build and start the containers
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The web client and the MCP endpoint are served by `api`; the bearer for both is `AUTH__TOKEN`.
|
`COMPOSE_PROFILES` in `.env` selects what runs on the machine, `docker-compose.override.yml` in each part holds the published ports and the `caddy` network aliases. The web client and the MCP endpoint are served by `api`; the bearer for both is `AUTH__TOKEN`.
|
||||||
|
|
||||||
## Develop
|
## Develop
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd backend && uv sync && uv run ruff check && uvx ty check src
|
make fmt
|
||||||
cd frontend && bun install && bun run dev && bun run check
|
make check
|
||||||
|
make -C frontend dev
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
.venv
|
||||||
|
.env
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
.ruff_cache
|
||||||
|
.pytest_cache
|
||||||
|
sessions
|
||||||
+19
-6
@@ -1,14 +1,27 @@
|
|||||||
|
RUN_ENVIRONMENT=prod
|
||||||
|
TZ=UTC
|
||||||
|
|
||||||
|
LOG__LEVEL=INFO
|
||||||
|
LOG__LEVEL_EXTERNAL=WARNING
|
||||||
|
LOG__SHOW_TIME=false
|
||||||
|
LOG__CONSOLE_WIDTH=150
|
||||||
|
|
||||||
|
DB__HOST=postgres
|
||||||
|
DB__PORT=5432
|
||||||
|
DB__USER=beavergram
|
||||||
|
DB__PASSWORD=beavergram
|
||||||
|
DB__DB_NAME=beavergram
|
||||||
|
DB__MIN_POOL_SIZE=5
|
||||||
|
DB__MAX_POOL_SIZE=20
|
||||||
|
DB__SCRIPTS_CONNECTION_URL=postgresql://beavergram:beavergram@localhost:5432/beavergram
|
||||||
|
|
||||||
TG__SESSION_NAME=beavergram
|
TG__SESSION_NAME=beavergram
|
||||||
TG__SESSIONS_DIR=sessions
|
TG__SESSIONS_DIR=sessions
|
||||||
|
|
||||||
API__HOST=0.0.0.0
|
API__HOST=0.0.0.0
|
||||||
API__PORT=8080
|
API__PORT=8080
|
||||||
|
|
||||||
AUTH__TOKEN=<AUTH__TOKEN>
|
AUTH__TOKEN=
|
||||||
|
|
||||||
|
STORAGE__ROOT=./storage
|
||||||
STORAGE__SHARD_DEPTH=2
|
STORAGE__SHARD_DEPTH=2
|
||||||
|
|
||||||
LOG__LEVEL=INFO
|
|
||||||
LOG__LEVEL_EXTERNAL=WARNING
|
|
||||||
LOG__SHOW_TIME=false
|
|
||||||
LOG__CONSOLE_WIDTH=150
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
## Checking commands
|
||||||
|
After writing code, always run from `backend/`:
|
||||||
|
```shell
|
||||||
|
ruff format
|
||||||
|
ruff check --fix
|
||||||
|
ty check
|
||||||
|
```
|
||||||
+5
-4
@@ -1,5 +1,7 @@
|
|||||||
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV PATH="/app/.venv/bin:$PATH" \
|
ENV PATH="/app/.venv/bin:$PATH" \
|
||||||
@@ -7,10 +9,6 @@ ENV PATH="/app/.venv/bin:$PATH" \
|
|||||||
UV_COMPILE_BYTECODE=1 \
|
UV_COMPILE_BYTECODE=1 \
|
||||||
UV_LINK_MODE=copy
|
UV_LINK_MODE=copy
|
||||||
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get install -y --no-install-recommends build-essential \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
COPY pyproject.toml uv.lock ./
|
COPY pyproject.toml uv.lock ./
|
||||||
RUN uv sync --frozen --no-install-project --no-dev
|
RUN uv sync --frozen --no-install-project --no-dev
|
||||||
|
|
||||||
@@ -20,4 +18,7 @@ RUN uv sync --frozen --no-dev
|
|||||||
COPY alembic.ini ./
|
COPY alembic.ini ./
|
||||||
COPY migrations ./migrations
|
COPY migrations ./migrations
|
||||||
|
|
||||||
|
COPY scripts ./scripts
|
||||||
|
|
||||||
ENTRYPOINT ["python", "-m"]
|
ENTRYPOINT ["python", "-m"]
|
||||||
|
CMD ["api"]
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
COMPOSE := cd .. && docker compose
|
||||||
|
IMAGE := beavergram/backend
|
||||||
|
IMAGE_INPUTS := pyproject.toml uv.lock Dockerfile
|
||||||
|
CODE := src scripts ../frontend
|
||||||
|
SERVICES := api userbot
|
||||||
|
changed = ! git diff --quiet $(1) -- $(2) 2>/dev/null
|
||||||
|
stamp = { git update-ref $(1) HEAD 2>/dev/null || true; }
|
||||||
|
|
||||||
|
.PHONY: fmt check build pre-deploy post-deploy migrate revision session
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
uv run ruff format
|
||||||
|
uv run ruff check --fix
|
||||||
|
|
||||||
|
check:
|
||||||
|
uv run ruff format --check
|
||||||
|
uv run ruff check
|
||||||
|
uv run ty check
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(COMPOSE) build api
|
||||||
|
|
||||||
|
pre-deploy:
|
||||||
|
@if $(call changed,refs/deploy/backend,$(IMAGE_INPUTS)) || ! docker image inspect $(IMAGE) >/dev/null 2>&1; then \
|
||||||
|
$(MAKE) build && $(call stamp,refs/deploy/backend) && $(call stamp,refs/deploy/backend-code); \
|
||||||
|
fi
|
||||||
|
@$(COMPOSE) config --services | grep -qx postgres && $(COMPOSE) up -d postgres || true
|
||||||
|
$(MAKE) migrate
|
||||||
|
|
||||||
|
post-deploy:
|
||||||
|
@if $(call changed,refs/deploy/backend-code,$(CODE)); then \
|
||||||
|
running=$$($(COMPOSE) ps --services --status running | grep -x $(addprefix -e ,$(SERVICES))); \
|
||||||
|
[ -z "$$running" ] || $(COMPOSE) restart $$running; \
|
||||||
|
$(call stamp,refs/deploy/backend-code); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
$(COMPOSE) run --rm migrator $(or $(filter-out $@,$(MAKECMDGOALS)),upgrade head)
|
||||||
|
|
||||||
|
revision:
|
||||||
|
$(COMPOSE) run --rm migrator revision --autogenerate -m "$(m)"
|
||||||
|
|
||||||
|
%:
|
||||||
|
@:
|
||||||
|
|
||||||
|
session:
|
||||||
|
uv run python scripts/session/create.py
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
services:
|
||||||
|
api:
|
||||||
|
networks:
|
||||||
|
default: {}
|
||||||
|
caddy:
|
||||||
|
aliases:
|
||||||
|
- beavergram-api
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${DB__PORT:-5432}:5432"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
caddy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
services:
|
||||||
|
api:
|
||||||
|
build: backend
|
||||||
|
image: beavergram/backend
|
||||||
|
profiles: [api, services]
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
- path: backend/.env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
RUN_ENVIRONMENT: prod
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
STORAGE__ROOT: /app/storage
|
||||||
|
volumes:
|
||||||
|
- ./backend/src:/app/src
|
||||||
|
- ./backend/scripts:/app/scripts
|
||||||
|
- ./backend/sessions:/app/sessions
|
||||||
|
- ./frontend/build:/app/static:ro
|
||||||
|
- ${STORAGE__ROOT:-./storage}:/app/storage
|
||||||
|
command: [api]
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
required: false
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
database:
|
||||||
|
|
||||||
|
userbot:
|
||||||
|
build: backend
|
||||||
|
image: beavergram/backend
|
||||||
|
profiles: [userbot, services]
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
- path: backend/.env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
RUN_ENVIRONMENT: prod
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
STORAGE__ROOT: /app/storage
|
||||||
|
volumes:
|
||||||
|
- ./backend/src:/app/src
|
||||||
|
- ./backend/scripts:/app/scripts
|
||||||
|
- ./backend/sessions:/app/sessions
|
||||||
|
- ${STORAGE__ROOT:-./storage}:/app/storage
|
||||||
|
command: [userbot]
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
required: false
|
||||||
|
networks:
|
||||||
|
database:
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: timescale/timescaledb:2.27.1-pg17
|
||||||
|
profiles: [postgres, external]
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${DB__USER:-beavergram}
|
||||||
|
POSTGRES_PASSWORD: ${DB__PASSWORD:-beavergram}
|
||||||
|
POSTGRES_DB: ${DB__DB_NAME:-beavergram}
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
- ./backend/migrations/init:/docker-entrypoint-initdb.d:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${DB__USER:-beavergram}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
networks:
|
||||||
|
database:
|
||||||
|
aliases:
|
||||||
|
- ${DB__HOST:-postgres}
|
||||||
|
|
||||||
|
migrator:
|
||||||
|
build: backend
|
||||||
|
image: beavergram/backend
|
||||||
|
profiles: [migrate]
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
- path: backend/.env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
RUN_ENVIRONMENT: prod
|
||||||
|
volumes:
|
||||||
|
- ./backend/src:/app/src
|
||||||
|
- ./backend/migrations:/app/migrations
|
||||||
|
- ./backend/alembic.ini:/app/alembic.ini
|
||||||
|
entrypoint: [alembic]
|
||||||
|
command: [upgrade, head]
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
required: false
|
||||||
|
networks:
|
||||||
|
database:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
database:
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
BEAVERGRAM_DOMAIN=beavergram.localhost
|
BEAVERGRAM_DOMAIN=beavergram.localhost
|
||||||
BEAVERGRAM_DEV_DOMAIN=dev.beavergram.localhost
|
BEAVERGRAM_DEV_DOMAIN=dev.beavergram.localhost
|
||||||
|
|
||||||
CLOUDFLARE_API_TOKEN=
|
CLOUDFLARE_API_TOKEN=
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
Caddyfile
|
|
||||||
.env
|
.env
|
||||||
|
Caddyfile
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
admin off
|
admin localhost:2019
|
||||||
# acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
|
||||||
|
|
||||||
log {
|
log {
|
||||||
format console
|
format console
|
||||||
@@ -12,8 +11,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(compress) {
|
import /etc/caddy/projects.d/*/site.caddy
|
||||||
encode zstd gzip
|
|
||||||
}
|
|
||||||
|
|
||||||
import /etc/caddy/projects.d/*.caddy
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# caddy
|
||||||
|
|
||||||
|
`site.caddy` routes `{$BEAVERGRAM_DOMAIN}` to the project's services over the external `caddy` docker network. It works standalone and inside a shared Caddy that fronts several projects.
|
||||||
|
|
||||||
|
Standalone:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker network create caddy
|
||||||
|
cp Caddyfile.example Caddyfile
|
||||||
|
cp .env.example .env
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Shared Caddy: mount this directory as `/etc/caddy/projects.d/beavergram:ro`, keep `import /etc/caddy/projects.d/*/site.caddy` in its Caddyfile and put `BEAVERGRAM_DOMAIN` in its environment.
|
||||||
|
|
||||||
|
Rules that keep `site.caddy` portable:
|
||||||
|
|
||||||
|
- the domain comes only from the environment variable
|
||||||
|
- no `tls` block, certificates are configured by the host Caddy (`acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}` in the global block)
|
||||||
|
- snippets are prefixed with the project slug because Caddy snippets are global
|
||||||
|
- mount the directory, not the file: a single-file bind mount goes stale when git replaces the inode
|
||||||
|
- keep `admin localhost:2019`, `admin off` makes `caddy reload` impossible
|
||||||
@@ -12,7 +12,7 @@ services:
|
|||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
- ./site.caddy:/etc/caddy/projects.d/beavergram.caddy:ro
|
- .:/etc/caddy/projects.d/beavergram:ro
|
||||||
- caddy_data:/data
|
- caddy_data:/data
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
+1
-1
@@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
{$BEAVERGRAM_DEV_DOMAIN} {
|
{$BEAVERGRAM_DEV_DOMAIN} {
|
||||||
encode zstd gzip
|
encode zstd gzip
|
||||||
reverse_proxy beavergram-frontend:5173
|
reverse_proxy beavergram-frontend:3000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
services:
|
|
||||||
# postgres:
|
|
||||||
# ports:
|
|
||||||
# - "127.0.0.1:5432:5432"
|
|
||||||
|
|
||||||
api:
|
|
||||||
# ports:
|
|
||||||
# - "127.0.0.1:8080:8080"
|
|
||||||
networks:
|
|
||||||
default: {}
|
|
||||||
caddy:
|
|
||||||
aliases:
|
|
||||||
- beavergram-api
|
|
||||||
|
|
||||||
frontend-dev:
|
|
||||||
# ports:
|
|
||||||
# - "127.0.0.1:5173:5173"
|
|
||||||
networks:
|
|
||||||
default: { }
|
|
||||||
caddy:
|
|
||||||
aliases:
|
|
||||||
- beavergram-frontend
|
|
||||||
|
|
||||||
networks:
|
|
||||||
caddy:
|
|
||||||
external: true
|
|
||||||
+5
-98
@@ -1,98 +1,5 @@
|
|||||||
services:
|
include:
|
||||||
postgres:
|
- path: backend/docker-compose.yml
|
||||||
image: timescale/timescaledb:2.27.1-pg17
|
project_directory: .
|
||||||
profiles: [db]
|
- path: frontend/docker-compose.yml
|
||||||
environment:
|
project_directory: .
|
||||||
POSTGRES_USER: ${DB__USER:-beavergram}
|
|
||||||
POSTGRES_PASSWORD: ${DB__PASSWORD:-beavergram}
|
|
||||||
POSTGRES_DB: ${DB__DB_NAME:-beavergram}
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- pgdata:/var/lib/postgresql/data
|
|
||||||
- ./backend/migrations/init:/docker-entrypoint-initdb.d:ro
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${DB__USER:-beavergram}"]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
|
|
||||||
userbot:
|
|
||||||
build: ./backend
|
|
||||||
profiles: [userbot]
|
|
||||||
command: [userbot]
|
|
||||||
env_file:
|
|
||||||
- path: backend/.env
|
|
||||||
required: false
|
|
||||||
- path: .env
|
|
||||||
required: false
|
|
||||||
environment:
|
|
||||||
RUN_ENVIRONMENT: prod
|
|
||||||
STORAGE__ROOT: /app/storage
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ./backend/src:/app/src
|
|
||||||
- ./backend/sessions:/app/sessions
|
|
||||||
- ${STORAGE__ROOT:-./storage}:/app/storage
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
api:
|
|
||||||
build: ./backend
|
|
||||||
profiles: [api]
|
|
||||||
command: [api]
|
|
||||||
env_file:
|
|
||||||
- path: backend/.env
|
|
||||||
required: false
|
|
||||||
- path: .env
|
|
||||||
required: false
|
|
||||||
environment:
|
|
||||||
RUN_ENVIRONMENT: prod
|
|
||||||
STORAGE__ROOT: /app/storage
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- ./backend/src:/app/src
|
|
||||||
- ./backend/sessions:/app/sessions
|
|
||||||
- ./frontend/build:/app/static:ro
|
|
||||||
- ${STORAGE__ROOT:-./storage}:/app/storage
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
migrator:
|
|
||||||
build: ./backend
|
|
||||||
profiles: [migrate]
|
|
||||||
env_file:
|
|
||||||
- path: backend/.env
|
|
||||||
required: false
|
|
||||||
- path: .env
|
|
||||||
required: false
|
|
||||||
environment:
|
|
||||||
RUN_ENVIRONMENT: prod
|
|
||||||
volumes:
|
|
||||||
- ./backend/src:/app/src
|
|
||||||
- ./backend/migrations:/app/migrations
|
|
||||||
- ./backend/alembic.ini:/app/alembic.ini
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
entrypoint: [alembic]
|
|
||||||
command: [upgrade, head]
|
|
||||||
|
|
||||||
frontend-dev:
|
|
||||||
image: oven/bun:1
|
|
||||||
profiles: [frontend]
|
|
||||||
working_dir: /app
|
|
||||||
command: ["sh", "-c", "bun install && bun run dev --host 0.0.0.0 --port 5173"]
|
|
||||||
environment:
|
|
||||||
API_PROXY_TARGET: http://api:8080
|
|
||||||
ALLOWED_HOSTS: ${FRONTEND_DEV_HOST:-}
|
|
||||||
volumes:
|
|
||||||
- ./frontend:/app
|
|
||||||
- frontend_node_modules:/app/node_modules
|
|
||||||
- frontend_svelte_kit:/app/.svelte-kit
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
pgdata:
|
|
||||||
frontend_node_modules:
|
|
||||||
frontend_svelte_kit:
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
node_modules
|
||||||
|
.svelte-kit
|
||||||
|
build
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
PUBLIC_API_BASE_URL=/api
|
||||||
|
ALLOWED_HOSTS=
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
## Checking commands
|
||||||
|
After writing code, always run from `frontend/`:
|
||||||
|
```shell
|
||||||
|
bun fix
|
||||||
|
bun check
|
||||||
|
```
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
COMPOSE := cd .. && docker compose
|
||||||
|
changed = ! git diff --quiet $(1) -- $(2) 2>/dev/null
|
||||||
|
stamp = { git update-ref $(1) HEAD 2>/dev/null || true; }
|
||||||
|
|
||||||
|
.PHONY: fmt check build pre-deploy post-deploy dev
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
bun run fix
|
||||||
|
|
||||||
|
check:
|
||||||
|
bun run check
|
||||||
|
bun run lint
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(COMPOSE) run --rm frontend-dev sh -c "bun install && bun run build"
|
||||||
|
|
||||||
|
pre-deploy:
|
||||||
|
@if $(call changed,refs/deploy/frontend,.) || ! test -d build; then \
|
||||||
|
$(MAKE) build && $(call stamp,refs/deploy/frontend); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
post-deploy:
|
||||||
|
@:
|
||||||
|
|
||||||
|
dev:
|
||||||
|
bun run dev
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
frontend-dev:
|
||||||
|
networks:
|
||||||
|
default: {}
|
||||||
|
caddy:
|
||||||
|
aliases:
|
||||||
|
- beavergram-frontend
|
||||||
|
|
||||||
|
networks:
|
||||||
|
caddy:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
frontend-dev:
|
||||||
|
image: oven/bun:alpine
|
||||||
|
profiles: [frontend-dev]
|
||||||
|
restart: unless-stopped
|
||||||
|
working_dir: /app
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
- path: frontend/.env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
API_PROXY_TARGET: http://api:8080
|
||||||
|
volumes:
|
||||||
|
- ./frontend:/app
|
||||||
|
- frontend_node_modules:/app/node_modules
|
||||||
|
- frontend_svelte_kit:/app/.svelte-kit
|
||||||
|
command: [sh, -c, "bun install && bun run dev --host 0.0.0.0 --port 3000"]
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
frontend_node_modules:
|
||||||
|
frontend_svelte_kit:
|
||||||
Reference in New Issue
Block a user