mirror of
https://github.com/ajurna/cbwebreader.git
synced 2026-11-02 10:36:55 +00:00
**Refactor Docker and Compose for enhanced compatibility and efficiency**
- Restructured `Dockerfile` to include a dedicated frontend build stage and improved runtime configurations. - Added new health checks and adjusted environment variables for better container management. - Updated cron job configurations to leverage `/opt/venv` and align with new paths. - Refined `docker-compose` files for multi-service setups, including better volume and environment variable handling. - Migrated `cbwebreader-cron` service setup and improved restart policies across the board. - Enhanced `.gitea` CI workflow to use updated tools (`uv`), streamline buildx processes, and ensure proper version extraction from metadata.
This commit is contained in:
1 parent
9b9db755e6
commit
147a3a54ef
9 files changed
+120
-90
No files matched your search
@@ -3,7 +3,6 @@
|
||||
|
||||
!cbreader
|
||||
!comic
|
||||
!comic_auth
|
||||
!static
|
||||
!manage.py
|
||||
!pyproject.toml
|
||||
@@ -14,6 +13,5 @@
|
||||
!package-lock.json
|
||||
!package.json
|
||||
!frontend
|
||||
!uv.lock
|
||||
/frontend/node_modules
|
||||
/frontend/dist
|
||||
+4
-2
@@ -15,8 +15,10 @@ DB_DATABASE=cbwebreader
|
||||
# https://github.com/jacobian/dj-database-url
|
||||
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}
|
||||
|
||||
#Path to your comics.
|
||||
COMIC_BOOK_VOLUME=/media/plex/comics
|
||||
# Path to your comics *inside* the container. Keep this as a container path.
|
||||
COMIC_BOOK_VOLUME=/comics
|
||||
# Host path that is mounted to the path above.
|
||||
COMIC_BOOK_HOST_PATH=/media/plex/comics
|
||||
|
||||
STATIC_ROOT='/static'
|
||||
|
||||
|
||||
+4
-2
@@ -15,8 +15,10 @@ DB_DATABASE=cbwebreader
|
||||
# https://github.com/jacobian/dj-database-url
|
||||
DATABASE_URL='postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}'
|
||||
|
||||
# Path to your comics.
|
||||
COMIC_BOOK_VOLUME=/path/to/comic/folder
|
||||
# Path to your comics *inside* the container. Keep this as a container path.
|
||||
COMIC_BOOK_VOLUME=/comics
|
||||
# Host path that is mounted to the path above (this is the one that varies per machine).
|
||||
COMIC_BOOK_HOST_PATH=/path/to/comic/folder
|
||||
|
||||
# Usually fine tp leave as is.
|
||||
STATIC_ROOT=/static
|
||||
|
||||
@@ -12,25 +12,21 @@ jobs:
|
||||
run: curl -fsSL https://get.docker.com | sh
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
- name: Set up Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: install pip
|
||||
run: apt update && apt install -y python3-pip
|
||||
- uses: abatilo/actions-poetry@v2
|
||||
with:
|
||||
poetry-version: "1.6.1"
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@v3
|
||||
# Extract version from Poetry
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install uv
|
||||
run: pip install uv
|
||||
# Extract version from the project metadata
|
||||
- name: Get version
|
||||
run: echo "POETRY_VERSION=$(poetry version --short)" >> $GITHUB_ENV
|
||||
run: echo "PROJECT_VERSION=$(uv version --short)" >> $GITHUB_ENV
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
docker build -t ajurna/cbwebreader:latest -t ajurna/cbwebreader:${{ env.POETRY_VERSION }} .
|
||||
docker push ajurna/cbwebreader:${{ env.POETRY_VERSION }}
|
||||
docker build -t ajurna/cbwebreader:latest -t ajurna/cbwebreader:${{ env.PROJECT_VERSION }} .
|
||||
docker push ajurna/cbwebreader:${{ env.PROJECT_VERSION }}
|
||||
docker push ajurna/cbwebreader:latest
|
||||
+42
-21
@@ -1,36 +1,57 @@
|
||||
FROM python:3.14-slim-trixie
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||
PIP_NO_CACHE_DIR=1
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
RUN mkdir /src
|
||||
RUN mkdir /static
|
||||
# ---------------------------------------------------------------------------
|
||||
# Frontend build stage
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM node:22-slim AS frontend
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY frontend/package.json frontend/package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY frontend/ ./
|
||||
RUN npm run build
|
||||
|
||||
RUN echo "deb http://ftp.uk.debian.org/debian trixie non-free non-free-firmware" > /etc/apt/sources.list.d/non-free.list
|
||||
# ---------------------------------------------------------------------------
|
||||
# Runtime stage
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM python:3.14-slim-trixie
|
||||
|
||||
RUN apt update \
|
||||
&& apt install -y npm cron unrar libmariadb-dev libpq-dev pkg-config swig curl
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
||||
|
||||
COPY . /src/
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
# unrar lives in the non-free component; resolve the codename from the base image
|
||||
# instead of hardcoding it.
|
||||
RUN . /etc/os-release \
|
||||
&& echo "deb http://deb.debian.org/debian ${VERSION_CODENAME} non-free non-free-firmware" \
|
||||
> /etc/apt/sources.list.d/non-free.list \
|
||||
&& apt update \
|
||||
&& apt install -y --no-install-recommends cron unrar libmariadb-dev pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Lockfiles first so dependency installation is cached independently of the source.
|
||||
COPY pyproject.toml uv.lock ./
|
||||
RUN uv sync --frozen --no-dev
|
||||
|
||||
RUN cd frontend \
|
||||
&& npm install \
|
||||
&& npm run build \
|
||||
&& rm -r node_modules
|
||||
COPY . /src/
|
||||
COPY --from=frontend /src/dist /src/frontend/dist
|
||||
COPY --from=frontend /src/webpack-stats.json /src/frontend/webpack-stats.json
|
||||
|
||||
RUN mkdir -p /static /media
|
||||
|
||||
RUN cat /src/cbreader/crontab >> /etc/crontab
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s \
|
||||
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/')" || exit 1
|
||||
|
||||
CMD ["sh", "entrypoint.sh"]
|
||||
+1
-1
@@ -1 +1 @@
|
||||
*/15 * * * * root /src/.venv/bin/python /src/manage.py scan_comics --settings=cbreader.settings.base
|
||||
*/15 * * * * root /opt/venv/bin/python /src/manage.py scan_comics --settings=cbreader.settings.base
|
||||
+24
-19
@@ -1,64 +1,69 @@
|
||||
version: "2.4"
|
||||
|
||||
services:
|
||||
|
||||
cbwebreader:
|
||||
build: ../
|
||||
image: ajurna/cbwebreader
|
||||
env_file: .env
|
||||
links:
|
||||
- database
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
expose:
|
||||
- 8000
|
||||
volumes:
|
||||
- ${COMIC_BOOK_VOLUME}:${COMIC_BOOK_VOLUME}
|
||||
# COMIC_BOOK_VOLUME is the path *inside* the container; the host path is
|
||||
# a separate variable so a Windows host path is not passed to Django.
|
||||
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||
- static_files:/static
|
||||
- media_files:/media
|
||||
- .env:/src/.env
|
||||
command: /bin/bash entrypoint.sh
|
||||
command: sh entrypoint.sh
|
||||
restart: unless-stopped
|
||||
|
||||
cbwebreader-cron:
|
||||
build: ../
|
||||
image: ajurna/cbwebreader
|
||||
env_file: .env
|
||||
links:
|
||||
- database
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ${COMIC_BOOK_VOLUME}:${COMIC_BOOK_VOLUME}
|
||||
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||
- media_files:/media
|
||||
- .env:/src/.env
|
||||
command: /bin/bash entrypoint-cron.sh
|
||||
command: sh entrypoint-cron.sh
|
||||
restart: unless-stopped
|
||||
|
||||
database:
|
||||
image: postgres:18-alpine
|
||||
image: postgres:16-alpine
|
||||
expose:
|
||||
- 5432
|
||||
volumes:
|
||||
- ./data:/var/lib/postgresql/data
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $DB_USER -d $DB_DATABASE"]
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASS}
|
||||
- POSTGRES_DB=${DB_DATABASE}
|
||||
POSTGRES_USER: ${DB_USER}
|
||||
POSTGRES_PASSWORD: ${DB_PASS}
|
||||
POSTGRES_DB: ${DB_DATABASE}
|
||||
restart: unless-stopped
|
||||
|
||||
nginx:
|
||||
image: nginx
|
||||
image: nginx:1-alpine
|
||||
volumes:
|
||||
- static_files:/static
|
||||
- media_files:/media
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- 1337:80
|
||||
- "${WEB_PORT:-8337}:80"
|
||||
depends_on:
|
||||
- cbwebreader
|
||||
cbwebreader:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
static_files:
|
||||
media_files:
|
||||
postgres_data:
|
||||
+32
-28
@@ -1,65 +1,69 @@
|
||||
version: "2.4"
|
||||
|
||||
services:
|
||||
|
||||
cbwebreader:
|
||||
build: .
|
||||
image: ajurna/cbwebreader
|
||||
env_file: .env
|
||||
links:
|
||||
- database
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
expose:
|
||||
- 8000
|
||||
volumes:
|
||||
# - ${COMIC_BOOK_VOLUME}:/comics
|
||||
- c:/comics:/comics
|
||||
# COMIC_BOOK_VOLUME is the path *inside* the container; the host path is
|
||||
# a separate variable so a Windows host path is not passed to Django.
|
||||
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||
- static_files:/static
|
||||
- media_files:/media
|
||||
- .env:/src/.env
|
||||
command: /bin/bash /src/entrypoint.sh
|
||||
command: sh entrypoint.sh
|
||||
restart: unless-stopped
|
||||
|
||||
# cbwebreader-cron:
|
||||
# build: .
|
||||
# env_file: .env
|
||||
# links:
|
||||
# - database
|
||||
# depends_on:
|
||||
# database:
|
||||
# condition: service_healthy
|
||||
# volumes:
|
||||
# - ${COMIC_BOOK_VOLUME}:${COMIC_BOOK_VOLUME}
|
||||
# - media_files:/media
|
||||
# - .env:/src/.env
|
||||
# command: /bin/bash entrypoint-cron.sh
|
||||
cbwebreader-cron:
|
||||
build: .
|
||||
image: ajurna/cbwebreader
|
||||
env_file: .env
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||
- media_files:/media
|
||||
- .env:/src/.env
|
||||
command: sh entrypoint-cron.sh
|
||||
restart: unless-stopped
|
||||
|
||||
database:
|
||||
image: postgres:16-alpine
|
||||
expose:
|
||||
- 5432
|
||||
volumes:
|
||||
- /var/lib/postgresql/data
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $DB_USER -d $DB_DATABASE"]
|
||||
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
environment:
|
||||
- POSTGRES_USER=${DB_USER}
|
||||
- POSTGRES_PASSWORD=${DB_PASS}
|
||||
- POSTGRES_DB=${DB_DATABASE}
|
||||
POSTGRES_USER: ${DB_USER}
|
||||
POSTGRES_PASSWORD: ${DB_PASS}
|
||||
POSTGRES_DB: ${DB_DATABASE}
|
||||
restart: unless-stopped
|
||||
|
||||
nginx:
|
||||
image: nginx
|
||||
image: nginx:1-alpine
|
||||
volumes:
|
||||
- static_files:/static
|
||||
- media_files:/media
|
||||
- ./cbreader/settings/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- 8337:80
|
||||
- "${WEB_PORT:-8337}:80"
|
||||
depends_on:
|
||||
- cbwebreader
|
||||
cbwebreader:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
static_files:
|
||||
media_files:
|
||||
postgres_data:
|
||||
+5
-3
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env sh
|
||||
uv run manage.py migrate --settings=cbreader.settings.base
|
||||
set -e
|
||||
|
||||
uv run manage.py collectstatic --settings=cbreader.settings.base --noinput --clear
|
||||
python manage.py migrate --settings=cbreader.settings.base
|
||||
|
||||
uv run gunicorn --workers 3 --bind 0.0.0.0:8000 cbreader.wsgi:application
|
||||
python manage.py collectstatic --settings=cbreader.settings.base --noinput --clear
|
||||
|
||||
exec gunicorn --workers 3 --bind 0.0.0.0:8000 cbreader.wsgi:application
|
||||
Reference in new issue
Block a user