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
+122
-92
No files matched your search
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
!cbreader
|
!cbreader
|
||||||
!comic
|
!comic
|
||||||
!comic_auth
|
|
||||||
!static
|
!static
|
||||||
!manage.py
|
!manage.py
|
||||||
!pyproject.toml
|
!pyproject.toml
|
||||||
@@ -14,6 +13,5 @@
|
|||||||
!package-lock.json
|
!package-lock.json
|
||||||
!package.json
|
!package.json
|
||||||
!frontend
|
!frontend
|
||||||
!uv.lock
|
|
||||||
/frontend/node_modules
|
/frontend/node_modules
|
||||||
/frontend/dist
|
/frontend/dist
|
||||||
+5
-3
@@ -15,8 +15,10 @@ DB_DATABASE=cbwebreader
|
|||||||
# https://github.com/jacobian/dj-database-url
|
# https://github.com/jacobian/dj-database-url
|
||||||
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}
|
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}
|
||||||
|
|
||||||
#Path to your comics.
|
# Path to your comics *inside* the container. Keep this as a container path.
|
||||||
COMIC_BOOK_VOLUME=/media/plex/comics
|
COMIC_BOOK_VOLUME=/comics
|
||||||
|
# Host path that is mounted to the path above.
|
||||||
|
COMIC_BOOK_HOST_PATH=/media/plex/comics
|
||||||
|
|
||||||
STATIC_ROOT='/static'
|
STATIC_ROOT='/static'
|
||||||
|
|
||||||
@@ -32,4 +34,4 @@ MEDIA_ROOT='/media'
|
|||||||
# DJANGO_RECAPTCHA_PUBLIC_KEY = ''
|
# DJANGO_RECAPTCHA_PUBLIC_KEY = ''
|
||||||
|
|
||||||
# Comment the following if not using a reverse proxy.
|
# Comment the following if not using a reverse proxy.
|
||||||
USE_X_FORWARDED_HOST=True
|
USE_X_FORWARDED_HOST=True
|
||||||
+5
-3
@@ -15,8 +15,10 @@ DB_DATABASE=cbwebreader
|
|||||||
# https://github.com/jacobian/dj-database-url
|
# https://github.com/jacobian/dj-database-url
|
||||||
DATABASE_URL='postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}'
|
DATABASE_URL='postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_DATABASE}'
|
||||||
|
|
||||||
# Path to your comics.
|
# Path to your comics *inside* the container. Keep this as a container path.
|
||||||
COMIC_BOOK_VOLUME=/path/to/comic/folder
|
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.
|
# Usually fine tp leave as is.
|
||||||
STATIC_ROOT=/static
|
STATIC_ROOT=/static
|
||||||
@@ -29,4 +31,4 @@ MEDIA_ROOT='/media'
|
|||||||
# UNRAR_TOOL = 'unrar.exe'
|
# UNRAR_TOOL = 'unrar.exe'
|
||||||
|
|
||||||
# Comment the following if not using a reverse proxy.
|
# Comment the following if not using a reverse proxy.
|
||||||
USE_X_FORWARDED_HOST=True
|
USE_X_FORWARDED_HOST=True
|
||||||
@@ -12,25 +12,21 @@ jobs:
|
|||||||
run: curl -fsSL https://get.docker.com | sh
|
run: curl -fsSL https://get.docker.com | sh
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
- name: install pip
|
- uses: actions/checkout@v4
|
||||||
run: apt update && apt install -y python3-pip
|
- name: Install uv
|
||||||
- uses: abatilo/actions-poetry@v2
|
run: pip install uv
|
||||||
with:
|
# Extract version from the project metadata
|
||||||
poetry-version: "1.6.1"
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
# Extract version from Poetry
|
|
||||||
- name: Get version
|
- 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
|
- name: Build and push Docker image
|
||||||
run: |
|
run: |
|
||||||
docker build -t ajurna/cbwebreader:latest -t ajurna/cbwebreader:${{ env.POETRY_VERSION }} .
|
docker build -t ajurna/cbwebreader:latest -t ajurna/cbwebreader:${{ env.PROJECT_VERSION }} .
|
||||||
docker push ajurna/cbwebreader:${{ env.POETRY_VERSION }}
|
docker push ajurna/cbwebreader:${{ env.PROJECT_VERSION }}
|
||||||
docker push ajurna/cbwebreader:latest
|
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/
|
# Frontend build stage
|
||||||
ENV PYTHONFAULTHANDLER=1 \
|
# ---------------------------------------------------------------------------
|
||||||
PYTHONHASHSEED=random \
|
FROM node:22-slim AS frontend
|
||||||
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
|
|
||||||
|
|
||||||
WORKDIR /src
|
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 \
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
||||||
&& apt install -y npm cron unrar libmariadb-dev libpq-dev pkg-config swig curl
|
|
||||||
|
|
||||||
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 uv sync --frozen --no-dev
|
||||||
|
|
||||||
RUN cd frontend \
|
COPY . /src/
|
||||||
&& npm install \
|
COPY --from=frontend /src/dist /src/frontend/dist
|
||||||
&& npm run build \
|
COPY --from=frontend /src/webpack-stats.json /src/frontend/webpack-stats.json
|
||||||
&& rm -r node_modules
|
|
||||||
|
|
||||||
|
RUN mkdir -p /static /media
|
||||||
|
|
||||||
RUN cat /src/cbreader/crontab >> /etc/crontab
|
RUN cat /src/cbreader/crontab >> /etc/crontab
|
||||||
|
|
||||||
EXPOSE 8000
|
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:
|
services:
|
||||||
|
|
||||||
cbwebreader:
|
cbwebreader:
|
||||||
|
build: ../
|
||||||
image: ajurna/cbwebreader
|
image: ajurna/cbwebreader
|
||||||
env_file: .env
|
env_file: .env
|
||||||
links:
|
|
||||||
- database
|
|
||||||
depends_on:
|
depends_on:
|
||||||
database:
|
database:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
expose:
|
expose:
|
||||||
- 8000
|
- 8000
|
||||||
volumes:
|
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
|
- static_files:/static
|
||||||
- media_files:/media
|
- media_files:/media
|
||||||
- .env:/src/.env
|
- .env:/src/.env
|
||||||
command: /bin/bash entrypoint.sh
|
command: sh entrypoint.sh
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
cbwebreader-cron:
|
cbwebreader-cron:
|
||||||
|
build: ../
|
||||||
image: ajurna/cbwebreader
|
image: ajurna/cbwebreader
|
||||||
env_file: .env
|
env_file: .env
|
||||||
links:
|
|
||||||
- database
|
|
||||||
depends_on:
|
depends_on:
|
||||||
database:
|
database:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
volumes:
|
volumes:
|
||||||
- ${COMIC_BOOK_VOLUME}:${COMIC_BOOK_VOLUME}
|
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||||
- media_files:/media
|
- media_files:/media
|
||||||
- .env:/src/.env
|
- .env:/src/.env
|
||||||
command: /bin/bash entrypoint-cron.sh
|
command: sh entrypoint-cron.sh
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: postgres:18-alpine
|
image: postgres:16-alpine
|
||||||
expose:
|
expose:
|
||||||
- 5432
|
- 5432
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
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
|
interval: 5s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
- POSTGRES_PASSWORD=${DB_PASS}
|
POSTGRES_PASSWORD: ${DB_PASS}
|
||||||
- POSTGRES_DB=${DB_DATABASE}
|
POSTGRES_DB: ${DB_DATABASE}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx
|
image: nginx:1-alpine
|
||||||
volumes:
|
volumes:
|
||||||
- static_files:/static
|
- static_files:/static
|
||||||
- media_files:/media
|
- media_files:/media
|
||||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
ports:
|
ports:
|
||||||
- 1337:80
|
- "${WEB_PORT:-8337}:80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- cbwebreader
|
cbwebreader:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
static_files:
|
static_files:
|
||||||
media_files:
|
media_files:
|
||||||
|
postgres_data:
|
||||||
+32
-28
@@ -1,65 +1,69 @@
|
|||||||
version: "2.4"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
cbwebreader:
|
cbwebreader:
|
||||||
build: .
|
build: .
|
||||||
|
image: ajurna/cbwebreader
|
||||||
env_file: .env
|
env_file: .env
|
||||||
links:
|
|
||||||
- database
|
|
||||||
depends_on:
|
depends_on:
|
||||||
database:
|
database:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
expose:
|
expose:
|
||||||
- 8000
|
- 8000
|
||||||
volumes:
|
volumes:
|
||||||
# - ${COMIC_BOOK_VOLUME}:/comics
|
# COMIC_BOOK_VOLUME is the path *inside* the container; the host path is
|
||||||
- c:/comics:/comics
|
# a separate variable so a Windows host path is not passed to Django.
|
||||||
|
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||||
- static_files:/static
|
- static_files:/static
|
||||||
- media_files:/media
|
- media_files:/media
|
||||||
- .env:/src/.env
|
- .env:/src/.env
|
||||||
command: /bin/bash /src/entrypoint.sh
|
command: sh entrypoint.sh
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
# cbwebreader-cron:
|
cbwebreader-cron:
|
||||||
# build: .
|
build: .
|
||||||
# env_file: .env
|
image: ajurna/cbwebreader
|
||||||
# links:
|
env_file: .env
|
||||||
# - database
|
depends_on:
|
||||||
# depends_on:
|
database:
|
||||||
# database:
|
condition: service_healthy
|
||||||
# condition: service_healthy
|
volumes:
|
||||||
# volumes:
|
- ${COMIC_BOOK_HOST_PATH}:${COMIC_BOOK_VOLUME}
|
||||||
# - ${COMIC_BOOK_VOLUME}:${COMIC_BOOK_VOLUME}
|
- media_files:/media
|
||||||
# - media_files:/media
|
- .env:/src/.env
|
||||||
# - .env:/src/.env
|
command: sh entrypoint-cron.sh
|
||||||
# command: /bin/bash entrypoint-cron.sh
|
restart: unless-stopped
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
expose:
|
expose:
|
||||||
- 5432
|
- 5432
|
||||||
volumes:
|
volumes:
|
||||||
- /var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
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
|
interval: 5s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
- POSTGRES_PASSWORD=${DB_PASS}
|
POSTGRES_PASSWORD: ${DB_PASS}
|
||||||
- POSTGRES_DB=${DB_DATABASE}
|
POSTGRES_DB: ${DB_DATABASE}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx
|
image: nginx:1-alpine
|
||||||
volumes:
|
volumes:
|
||||||
- static_files:/static
|
- static_files:/static
|
||||||
- media_files:/media
|
- media_files:/media
|
||||||
- ./cbreader/settings/nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./cbreader/settings/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
ports:
|
ports:
|
||||||
- 8337:80
|
- "${WEB_PORT:-8337}:80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- cbwebreader
|
cbwebreader:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
static_files:
|
static_files:
|
||||||
media_files:
|
media_files:
|
||||||
|
postgres_data:
|
||||||
+5
-3
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env sh
|
#!/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