Add simple dev stack

This commit is contained in:
Jonas Kamsker 2025-12-17 17:43:09 +01:00
parent 4e14f19bee
commit ba6c4f6956
5 changed files with 199 additions and 1 deletions

1
.gitignore vendored
View File

@ -12,5 +12,6 @@ backend/.env
# JavaScript stuff
node_modules
frontend/dist
.editorconfig

View File

@ -184,7 +184,41 @@ And the frontend should be available at [localhost:3000](localhost:3000).
### Docker Instructions
Edit the `docker-compose.yml` file and replace the [`image: bbilly1/tubearchivist` line](https://github.com/tubearchivist/tubearchivist/blob/4af12aee15620e330adf3624c984c3acf6d0ac8b/docker-compose.yml#L7) with `build: .`. Also make any other changes to the environment variables and so on necessary to run the application, just like you're launching the application as normal.
There are two docker-based development workflows:
#### Dev stack (hot reload, recommended)
Use the local dev stack in `dev/docker/docker-compose.dev.yml`. This runs:
- Elasticsearch + Redis
- Django dev server (`runserver`) with source mounted from your host
- Celery worker
- Frontend dev server (Vite)
From the repo root:
```bash
docker compose -f dev/docker/docker-compose.dev.yml up -d --build
```
Then:
- Frontend: [localhost:3000](localhost:3000)
- Backend health: [localhost:8000/api/health/](localhost:8000/api/health/)
Stop everything with:
```bash
docker compose -f dev/docker/docker-compose.dev.yml down
```
This compose file uses persistent docker volumes for Elasticsearch, Redis and frontend `node_modules`. If you want a clean slate, remove the volumes:
```bash
docker compose -f dev/docker/docker-compose.dev.yml down -v
```
#### Production-like rebuild (full image)
If you want to test closer to the production container, edit the `docker-compose.yml` file and replace the `image: bbilly1/tubearchivist` line with `build: .`. Also make any other changes to the environment variables and so on necessary to run the application, just like you're launching the application as normal.
Run `docker compose up --build`. This will bring up the application. Kill it with `ctrl-c` or by running `docker compose down` from a new terminal window in the same directory.

21
backend/.env.example Normal file
View File

@ -0,0 +1,21 @@
# Local development example (place a copy as backend/.env)
#
# Note:
# - This repo's .gitignore ignores backend/.env, backend/static, backend/staticfiles.
# - Frontend dev server (Vite) expects backend on http://localhost:8000 in DEV mode.
TA_HOST="http://localhost:8000"
TA_USERNAME=tubearchivist
TA_PASSWORD=verysecret
TA_MEDIA_DIR="static/volume/media"
TA_CACHE_DIR="static"
TA_APP_DIR="."
REDIS_CON=redis://localhost:6379
ES_URL="http://localhost:9200"
ELASTIC_PASSWORD=verysecret
TZ=America/New_York
DJANGO_DEBUG=True

21
dev/docker/Dockerfile.dev Normal file
View File

@ -0,0 +1,21 @@
FROM denoland/deno:bin AS deno-bin
FROM python:3.11.13-slim-bookworm
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
COPY --from=deno-bin /deno /usr/local/bin/deno
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential gcc libldap2-dev libsasl2-dev libssl-dev \
ffmpeg atomicparsley curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
COPY backend/requirements.txt backend/requirements.txt
COPY requirements-dev.txt requirements-dev.txt
RUN pip install --no-cache-dir -r requirements-dev.txt

View File

@ -0,0 +1,121 @@
name: tubearchivist-dev
services:
frontend-dev:
image: node:lts-alpine
container_name: tubearchivist-frontend-dev
restart: unless-stopped
working_dir: /workspace/frontend
volumes:
- ../../:/workspace
- frontend-node-modules:/workspace/frontend/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
ports:
- "3000:3000"
depends_on:
- backend-dev
command: >
sh -lc
"if [ ! -x node_modules/.bin/vite ]; then npm ci; fi; npm run dev -- --host 0.0.0.0 --port 3000"
backend-dev:
build:
context: ../../
dockerfile: dev/docker/Dockerfile.dev
container_name: tubearchivist-backend-dev
restart: unless-stopped
working_dir: /workspace/backend
volumes:
- ../../:/workspace
environment:
- TA_HOST=http://localhost:8000 http://localhost:3000
- TA_USERNAME=tubearchivist
- TA_PASSWORD=verysecret
- TA_MEDIA_DIR=static/volume/media
- TA_CACHE_DIR=static
- TA_APP_DIR=.
- REDIS_CON=redis://archivist-redis:6379
- ES_URL=http://archivist-es:9200
- ELASTIC_PASSWORD=verysecret
- TZ=America/New_York
- DJANGO_DEBUG=True
ports:
- "8000:8000"
depends_on:
- archivist-es
- archivist-redis
command: >
bash -lc
"mkdir -p static static/img static/volume/media &&
cp -an /workspace/frontend/public/img/. static/img/ || true &&
python manage.py ta_stop_on_error &&
python manage.py migrate &&
python manage.py ta_envcheck &&
python manage.py ta_connection &&
python manage.py ta_startup &&
python manage.py runserver 0.0.0.0:8000"
celery-dev:
build:
context: ../../
dockerfile: dev/docker/Dockerfile.dev
container_name: tubearchivist-celery-dev
restart: unless-stopped
working_dir: /workspace/backend
volumes:
- ../../:/workspace
environment:
- TA_HOST=http://localhost:8000 http://localhost:3000
- TA_USERNAME=tubearchivist
- TA_PASSWORD=verysecret
- TA_MEDIA_DIR=static/volume/media
- TA_CACHE_DIR=static
- TA_APP_DIR=.
- REDIS_CON=redis://archivist-redis:6379
- ES_URL=http://archivist-es:9200
- ELASTIC_PASSWORD=verysecret
- TZ=America/New_York
- DJANGO_DEBUG=True
depends_on:
- backend-dev
command: >
bash -lc
"mkdir -p static static/img static/volume/media &&
cp -an /workspace/frontend/public/img/. static/img/ || true &&
celery -A task.celery worker --loglevel=DEBUG --concurrency 2 --max-tasks-per-child 5 --max-memory-per-child 150000"
archivist-redis:
image: redis
container_name: archivist-redis-dev
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis-dev:/data
archivist-es:
# This is the same ES image as the default docker-compose.yml uses.
# If your Docker host errors on ulimits/rlimits, omit ulimits (see README.md).
image: bbilly1/tubearchivist-es
container_name: archivist-es-dev
restart: unless-stopped
environment:
- "ELASTIC_PASSWORD=verysecret"
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
- "xpack.security.enabled=true"
- "discovery.type=single-node"
- "path.repo=/usr/share/elasticsearch/data/snapshot"
ulimits:
memlock:
soft: -1
hard: -1
ports:
- "9200:9200"
volumes:
- es-dev:/usr/share/elasticsearch/data
volumes:
frontend-node-modules: {}
redis-dev: {}
es-dev: {}