chore(*): adopt project templates
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"command": "bun fix --skip=correctness/noUnusedImports",
|
||||
"command": "cd frontend && bun run fix --skip=correctness/noUnusedImports",
|
||||
"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
|
||||
RUN_ENVIRONMENT=prod
|
||||
|
||||
# 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
|
||||
COMPOSE_FILE=docker-compose.yml:backend/docker-compose.override.yml:frontend/docker-compose.override.yml
|
||||
COMPOSE_PROFILES=external,services
|
||||
|
||||
+5
-3
@@ -1,6 +1,8 @@
|
||||
.idea
|
||||
docker-compose.override.yml
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
docker-compose.override.yml
|
||||
.DS_Store
|
||||
.idea
|
||||
docs
|
||||
storage
|
||||
backend/sessions
|
||||
|
||||
+18
-22
@@ -1,31 +1,27 @@
|
||||
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
|
||||
hooks:
|
||||
- id: ultracite
|
||||
name: ultracite
|
||||
entry: bash -c 'cd frontend && bun x ultracite fix'
|
||||
- id: backend-fmt
|
||||
name: backend fmt
|
||||
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
|
||||
files: ^frontend/
|
||||
pass_filenames: false
|
||||
|
||||
- id: svelte-check
|
||||
name: svelte check
|
||||
entry: bash -c 'cd frontend && bun check'
|
||||
- id: frontend-check
|
||||
name: frontend check
|
||||
entry: make -C frontend check
|
||||
language: system
|
||||
files: ^frontend/
|
||||
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
|
||||
- **Less Code = Less Debt**: Minimize code footprint
|
||||
- **NEVER write comments** - code should be self-documenting
|
||||
- **Docstrings ONLY if explicitly asked**
|
||||
|
||||
## Checking commands
|
||||
After writing code, always run:
|
||||
```shell
|
||||
bun check # svelte-check
|
||||
bun fix # biome linter
|
||||
make fmt
|
||||
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:
|
||||
docker compose up -d --force-recreate
|
||||
|
||||
rebuild: build
|
||||
docker compose up -d
|
||||
|
||||
restart:
|
||||
docker compose restart
|
||||
|
||||
logs:
|
||||
docker compose logs -f --tail=100
|
||||
|
||||
down:
|
||||
docker compose down
|
||||
|
||||
restart:
|
||||
$(MAKE) recreate
|
||||
|
||||
rebuild:
|
||||
docker compose build
|
||||
deploy: pre-deploy
|
||||
docker compose up -d
|
||||
$(MAKE) post-deploy
|
||||
|
||||
frontend:
|
||||
docker compose run --rm --no-deps frontend-dev sh -c "bun install && bun run build"
|
||||
|
||||
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
|
||||
|
||||
%:
|
||||
@:
|
||||
fmt check build pre-deploy post-deploy:
|
||||
@for part in $(PARTS); do $(MAKE) -C $$part $@ || exit 1; done
|
||||
|
||||
@@ -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).
|
||||
- `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
|
||||
|
||||
@@ -28,18 +28,17 @@ Read-only: `search_messages_tool`, `list_chats`, `get_chat_history` (with delete
|
||||
## Run
|
||||
|
||||
```sh
|
||||
cp .env.example .env # DB__*, STORAGE__ROOT, profiles
|
||||
cp backend/.env.example backend/.env # TG__*, API__*, AUTH__TOKEN
|
||||
make session-create # log the account in once; the session file stays in backend/sessions
|
||||
make migrate upgrade head
|
||||
make deploy # build the frontend, build and start the containers
|
||||
make env # .env and docker-compose.override.yml from the examples
|
||||
make -C backend session # log the account in once; the session file stays in backend/sessions
|
||||
make deploy # build what changed, migrate, 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
|
||||
|
||||
```sh
|
||||
cd backend && uv sync && uv run ruff check && uvx ty check src
|
||||
cd frontend && bun install && bun run dev && bun run check
|
||||
make fmt
|
||||
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__SESSIONS_DIR=sessions
|
||||
|
||||
API__HOST=0.0.0.0
|
||||
API__PORT=8080
|
||||
|
||||
AUTH__TOKEN=<AUTH__TOKEN>
|
||||
AUTH__TOKEN=
|
||||
|
||||
STORAGE__ROOT=./storage
|
||||
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
|
||||
|
||||
RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV PATH="/app/.venv/bin:$PATH" \
|
||||
@@ -7,10 +9,6 @@ ENV PATH="/app/.venv/bin:$PATH" \
|
||||
UV_COMPILE_BYTECODE=1 \
|
||||
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 ./
|
||||
RUN uv sync --frozen --no-install-project --no-dev
|
||||
|
||||
@@ -20,4 +18,7 @@ RUN uv sync --frozen --no-dev
|
||||
COPY alembic.ini ./
|
||||
COPY migrations ./migrations
|
||||
|
||||
COPY scripts ./scripts
|
||||
|
||||
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_DEV_DOMAIN=dev.beavergram.localhost
|
||||
|
||||
CLOUDFLARE_API_TOKEN=
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
Caddyfile
|
||||
.env
|
||||
Caddyfile
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
admin off
|
||||
# acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
||||
admin localhost:2019
|
||||
|
||||
log {
|
||||
format console
|
||||
@@ -12,8 +11,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
(compress) {
|
||||
encode zstd gzip
|
||||
}
|
||||
|
||||
import /etc/caddy/projects.d/*.caddy
|
||||
import /etc/caddy/projects.d/*/site.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
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./site.caddy:/etc/caddy/projects.d/beavergram.caddy:ro
|
||||
- .:/etc/caddy/projects.d/beavergram:ro
|
||||
- caddy_data:/data
|
||||
|
||||
networks:
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@
|
||||
|
||||
{$BEAVERGRAM_DEV_DOMAIN} {
|
||||
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:
|
||||
postgres:
|
||||
image: timescale/timescaledb:2.27.1-pg17
|
||||
profiles: [db]
|
||||
environment:
|
||||
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:
|
||||
include:
|
||||
- path: backend/docker-compose.yml
|
||||
project_directory: .
|
||||
- path: frontend/docker-compose.yml
|
||||
project_directory: .
|
||||
|
||||
@@ -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