mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
docker (#4711)
# Description of Changes <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com>
This commit is contained in:
parent
81dec53488
commit
2e932f30bf
141
docker/Dockerfile.unified
Normal file
141
docker/Dockerfile.unified
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Unified Dockerfile - Frontend + Backend in single container
|
||||||
|
# Supports MODE parameter: BOTH (default), FRONTEND, BACKEND
|
||||||
|
|
||||||
|
# Stage 1: Build Frontend
|
||||||
|
FROM node:20-alpine AS frontend-build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY frontend/package.json frontend/package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY frontend .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 2: Build Backend
|
||||||
|
FROM gradle:8.14-jdk21 AS backend-build
|
||||||
|
|
||||||
|
COPY build.gradle .
|
||||||
|
COPY settings.gradle .
|
||||||
|
COPY gradlew .
|
||||||
|
COPY gradle gradle/
|
||||||
|
COPY app/core/build.gradle core/.
|
||||||
|
COPY app/common/build.gradle common/.
|
||||||
|
COPY app/proprietary/build.gradle proprietary/.
|
||||||
|
RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN DISABLE_ADDITIONAL_FEATURES=false \
|
||||||
|
STIRLING_PDF_DESKTOP_UI=false \
|
||||||
|
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
||||||
|
|
||||||
|
# Stage 3: Final unified image
|
||||||
|
FROM alpine:3.22.1
|
||||||
|
|
||||||
|
ARG VERSION_TAG
|
||||||
|
|
||||||
|
# Labels
|
||||||
|
LABEL org.opencontainers.image.title="Stirling-PDF Unified"
|
||||||
|
LABEL org.opencontainers.image.description="Unified container for Stirling-PDF - Frontend + Backend with MODE parameter"
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF"
|
||||||
|
LABEL org.opencontainers.image.licenses="MIT"
|
||||||
|
LABEL org.opencontainers.image.vendor="Stirling-Tools"
|
||||||
|
LABEL org.opencontainers.image.url="https://www.stirlingpdf.com"
|
||||||
|
LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com"
|
||||||
|
LABEL maintainer="Stirling-Tools"
|
||||||
|
LABEL org.opencontainers.image.authors="Stirling-Tools"
|
||||||
|
LABEL org.opencontainers.image.version="${VERSION_TAG}"
|
||||||
|
LABEL org.opencontainers.image.keywords="PDF, manipulation, unified, API, Spring Boot, React"
|
||||||
|
|
||||||
|
# Copy backend files
|
||||||
|
COPY scripts /scripts
|
||||||
|
COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
||||||
|
COPY --from=backend-build /app/app/core/build/libs/*.jar app.jar
|
||||||
|
|
||||||
|
# Copy frontend files
|
||||||
|
COPY --from=frontend-build /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy nginx configuration
|
||||||
|
COPY docker/unified/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
COPY docker/unified/entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
# Environment Variables
|
||||||
|
ENV DISABLE_ADDITIONAL_FEATURES=false \
|
||||||
|
VERSION_TAG=$VERSION_TAG \
|
||||||
|
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||||
|
JAVA_CUSTOM_OPTS="" \
|
||||||
|
HOME=/home/stirlingpdfuser \
|
||||||
|
PUID=1000 \
|
||||||
|
PGID=1000 \
|
||||||
|
UMASK=022 \
|
||||||
|
PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \
|
||||||
|
UNO_PATH=/usr/lib/libreoffice/program \
|
||||||
|
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc \
|
||||||
|
PATH=$PATH:/opt/venv/bin \
|
||||||
|
STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \
|
||||||
|
TMPDIR=/tmp/stirling-pdf \
|
||||||
|
TEMP=/tmp/stirling-pdf \
|
||||||
|
TMP=/tmp/stirling-pdf \
|
||||||
|
MODE=BOTH \
|
||||||
|
BACKEND_INTERNAL_PORT=8081 \
|
||||||
|
VITE_API_BASE_URL=http://localhost:8080
|
||||||
|
|
||||||
|
# Install all dependencies
|
||||||
|
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||||
|
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||||
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||||
|
apk upgrade --no-cache -a && \
|
||||||
|
apk add --no-cache \
|
||||||
|
ca-certificates \
|
||||||
|
tzdata \
|
||||||
|
tini \
|
||||||
|
bash \
|
||||||
|
curl \
|
||||||
|
shadow \
|
||||||
|
su-exec \
|
||||||
|
openssl \
|
||||||
|
openssl-dev \
|
||||||
|
openjdk21-jre \
|
||||||
|
nginx \
|
||||||
|
# Doc conversion
|
||||||
|
gcompat \
|
||||||
|
libc6-compat \
|
||||||
|
libreoffice \
|
||||||
|
# pdftohtml
|
||||||
|
poppler-utils \
|
||||||
|
# OCR MY PDF
|
||||||
|
unpaper \
|
||||||
|
tesseract-ocr-data-eng \
|
||||||
|
tesseract-ocr-data-chi_sim \
|
||||||
|
tesseract-ocr-data-deu \
|
||||||
|
tesseract-ocr-data-fra \
|
||||||
|
tesseract-ocr-data-por \
|
||||||
|
ocrmypdf \
|
||||||
|
# CV
|
||||||
|
py3-opencv \
|
||||||
|
python3 \
|
||||||
|
py3-pip \
|
||||||
|
py3-pillow@testing \
|
||||||
|
py3-pdf2image@testing && \
|
||||||
|
python3 -m venv /opt/venv && \
|
||||||
|
/opt/venv/bin/pip install --upgrade pip setuptools && \
|
||||||
|
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||||
|
ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \
|
||||||
|
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
||||||
|
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf /pipeline/watchedFolders /pipeline/finishedFolders && \
|
||||||
|
mkdir -p /var/lib/nginx/tmp /var/log/nginx && \
|
||||||
|
fc-cache -f -v && \
|
||||||
|
chmod +x /scripts/* && \
|
||||||
|
chmod +x /entrypoint.sh && \
|
||||||
|
# User permissions
|
||||||
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /pipeline /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf /var/lib/nginx /var/log/nginx /usr/share/nginx && \
|
||||||
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
|
|
||||||
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
|
ENTRYPOINT ["tini", "--", "/entrypoint.sh"]
|
||||||
58
docker/compose/docker-compose-unified-backend.yml
Normal file
58
docker/compose/docker-compose-unified-backend.yml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Example Docker Compose for Unified Stirling-PDF Container
|
||||||
|
# MODE=BACKEND: Backend API only (no frontend)
|
||||||
|
|
||||||
|
services:
|
||||||
|
stirling-pdf-backend-only:
|
||||||
|
container_name: Stirling-PDF-Backend-Only
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: docker/Dockerfile.unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./stirling/data:/usr/share/tessdata:rw
|
||||||
|
- ./stirling/config:/configs:rw
|
||||||
|
- ./stirling/logs:/logs:rw
|
||||||
|
- ./stirling/customFiles:/customFiles:rw
|
||||||
|
- ./stirling/pipeline:/pipeline:rw
|
||||||
|
environment:
|
||||||
|
# MODE parameter: BACKEND only
|
||||||
|
MODE: BACKEND
|
||||||
|
|
||||||
|
# Standard Stirling-PDF configuration
|
||||||
|
DISABLE_ADDITIONAL_FEATURES: "false"
|
||||||
|
DOCKER_ENABLE_SECURITY: "false"
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
UMASK: "022"
|
||||||
|
|
||||||
|
# Application settings
|
||||||
|
SYSTEM_DEFAULTLOCALE: en-US
|
||||||
|
UI_APPNAME: Stirling-PDF
|
||||||
|
SYSTEM_MAXFILESIZE: "100"
|
||||||
|
METRICS_ENABLED: "true"
|
||||||
|
|
||||||
|
# Optional: Add OCR languages (comma-separated)
|
||||||
|
# TESSERACT_LANGS: "deu,fra,spa"
|
||||||
|
|
||||||
|
# Optional: Java memory settings
|
||||||
|
# JAVA_CUSTOM_OPTS: "-Xmx4g"
|
||||||
|
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 4G
|
||||||
|
reservations:
|
||||||
|
memory: 2G
|
||||||
|
|
||||||
|
# Access the API at: http://localhost:8080/api
|
||||||
|
# Swagger UI at: http://localhost:8080/swagger-ui/index.html
|
||||||
59
docker/compose/docker-compose-unified-both.yml
Normal file
59
docker/compose/docker-compose-unified-both.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Example Docker Compose for Unified Stirling-PDF Container
|
||||||
|
# MODE=BOTH (default): Frontend + Backend in single container on port 8080
|
||||||
|
|
||||||
|
services:
|
||||||
|
stirling-pdf-unified:
|
||||||
|
container_name: Stirling-PDF-Unified-Both
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: docker/Dockerfile.unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./stirling/data:/usr/share/tessdata:rw
|
||||||
|
- ./stirling/config:/configs:rw
|
||||||
|
- ./stirling/logs:/logs:rw
|
||||||
|
- ./stirling/customFiles:/customFiles:rw
|
||||||
|
- ./stirling/pipeline:/pipeline:rw
|
||||||
|
environment:
|
||||||
|
# MODE parameter: BOTH (default), FRONTEND, or BACKEND
|
||||||
|
MODE: BOTH
|
||||||
|
|
||||||
|
# Backend runs internally on this port when MODE=BOTH
|
||||||
|
BACKEND_INTERNAL_PORT: 8081
|
||||||
|
|
||||||
|
# Standard Stirling-PDF configuration
|
||||||
|
DISABLE_ADDITIONAL_FEATURES: "false"
|
||||||
|
DOCKER_ENABLE_SECURITY: "false"
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
UMASK: "022"
|
||||||
|
|
||||||
|
# Application settings
|
||||||
|
SYSTEM_DEFAULTLOCALE: en-US
|
||||||
|
UI_APPNAME: Stirling-PDF
|
||||||
|
UI_HOMEDESCRIPTION: Your locally hosted one-stop-shop for all your PDF needs
|
||||||
|
SYSTEM_MAXFILESIZE: "100"
|
||||||
|
METRICS_ENABLED: "true"
|
||||||
|
|
||||||
|
# Optional: Add OCR languages (comma-separated)
|
||||||
|
# TESSERACT_LANGS: "deu,fra,spa"
|
||||||
|
|
||||||
|
# Optional: Java memory settings
|
||||||
|
# JAVA_CUSTOM_OPTS: "-Xmx4g"
|
||||||
|
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 4G
|
||||||
|
reservations:
|
||||||
|
memory: 2G
|
||||||
63
docker/compose/docker-compose-unified-frontend.yml
Normal file
63
docker/compose/docker-compose-unified-frontend.yml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# Example Docker Compose for Unified Stirling-PDF Container
|
||||||
|
# MODE=FRONTEND: Frontend only, connects to separate backend
|
||||||
|
|
||||||
|
services:
|
||||||
|
stirling-pdf-backend:
|
||||||
|
container_name: Stirling-PDF-Backend
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: docker/Dockerfile.unified
|
||||||
|
ports:
|
||||||
|
- "8081:8080"
|
||||||
|
volumes:
|
||||||
|
- ./stirling/data:/usr/share/tessdata:rw
|
||||||
|
- ./stirling/config:/configs:rw
|
||||||
|
- ./stirling/logs:/logs:rw
|
||||||
|
- ./stirling/customFiles:/customFiles:rw
|
||||||
|
- ./stirling/pipeline:/pipeline:rw
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
DISABLE_ADDITIONAL_FEATURES: "false"
|
||||||
|
DOCKER_ENABLE_SECURITY: "false"
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
UMASK: "022"
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 4G
|
||||||
|
|
||||||
|
stirling-pdf-frontend:
|
||||||
|
container_name: Stirling-PDF-Frontend
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: docker/Dockerfile.unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
MODE: FRONTEND
|
||||||
|
|
||||||
|
# Point to the backend service
|
||||||
|
VITE_API_BASE_URL: http://stirling-pdf-backend:8080
|
||||||
|
|
||||||
|
# Minimal config needed for frontend
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
depends_on:
|
||||||
|
- stirling-pdf-backend
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
458
docker/unified/README.md
Normal file
458
docker/unified/README.md
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
# Stirling-PDF Unified Container
|
||||||
|
|
||||||
|
Single Docker container that can run as **frontend + backend**, **frontend only**, or **backend only** using the `MODE` environment variable.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### MODE=BOTH (Default)
|
||||||
|
Single container with both frontend and backend on port 8080:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 8080:8080 \
|
||||||
|
-e MODE=BOTH \
|
||||||
|
stirlingtools/stirling-pdf:unified
|
||||||
|
```
|
||||||
|
|
||||||
|
Access at: `http://localhost:8080`
|
||||||
|
|
||||||
|
### MODE=FRONTEND
|
||||||
|
Frontend only, connecting to separate backend:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 8080:8080 \
|
||||||
|
-e MODE=FRONTEND \
|
||||||
|
-e VITE_API_BASE_URL=http://backend:8080 \
|
||||||
|
stirlingtools/stirling-pdf:unified
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=BACKEND
|
||||||
|
Backend API only:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 8080:8080 \
|
||||||
|
-e MODE=BACKEND \
|
||||||
|
stirlingtools/stirling-pdf:unified
|
||||||
|
```
|
||||||
|
|
||||||
|
Access API at: `http://localhost:8080/api`
|
||||||
|
Swagger UI at: `http://localhost:8080/swagger-ui/index.html`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### MODE=BOTH (Default)
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Port 8080 (External) │
|
||||||
|
│ ┌───────────────────────────────┐ │
|
||||||
|
│ │ Nginx │ │
|
||||||
|
│ │ • Serves frontend (/) │ │
|
||||||
|
│ │ • Proxies /api/* → backend │ │
|
||||||
|
│ └───────────┬───────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌───────────▼───────────────────┐ │
|
||||||
|
│ │ Backend (Internal 8081) │ │
|
||||||
|
│ │ • Spring Boot │ │
|
||||||
|
│ │ • PDF Processing │ │
|
||||||
|
│ │ • UnoServer │ │
|
||||||
|
│ └───────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=FRONTEND
|
||||||
|
```
|
||||||
|
┌─────────────────────────────┐ ┌──────────────────┐
|
||||||
|
│ Frontend Container │ │ Backend │
|
||||||
|
│ Port 8080 │ │ (External) │
|
||||||
|
│ ┌───────────────────────┐ │ │ │
|
||||||
|
│ │ Nginx │ │──────▶ :8080/api │
|
||||||
|
│ │ • Serves frontend │ │ │ │
|
||||||
|
│ │ • Proxies to backend │ │ │ │
|
||||||
|
│ └───────────────────────┘ │ └──────────────────┘
|
||||||
|
└─────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=BACKEND
|
||||||
|
```
|
||||||
|
┌─────────────────────────────┐
|
||||||
|
│ Backend Container │
|
||||||
|
│ Port 8080 │
|
||||||
|
│ ┌───────────────────────┐ │
|
||||||
|
│ │ Spring Boot │ │
|
||||||
|
│ │ • API Endpoints │ │
|
||||||
|
│ │ • PDF Processing │ │
|
||||||
|
│ │ • UnoServer │ │
|
||||||
|
│ └───────────────────────┘ │
|
||||||
|
└─────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
### MODE Configuration
|
||||||
|
|
||||||
|
| Variable | Values | Default | Description |
|
||||||
|
|----------|--------|---------|-------------|
|
||||||
|
| `MODE` | `BOTH`, `FRONTEND`, `BACKEND` | `BOTH` | Container operation mode |
|
||||||
|
|
||||||
|
### MODE=BOTH Specific
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `BACKEND_INTERNAL_PORT` | `8081` | Internal port for backend when MODE=BOTH |
|
||||||
|
|
||||||
|
### MODE=FRONTEND Specific
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `VITE_API_BASE_URL` | `http://backend:8080` | Backend URL for API proxying |
|
||||||
|
|
||||||
|
### Standard Configuration
|
||||||
|
|
||||||
|
All modes support standard Stirling-PDF environment variables:
|
||||||
|
|
||||||
|
- `DISABLE_ADDITIONAL_FEATURES` - Enable/disable OCR and LibreOffice features
|
||||||
|
- `DOCKER_ENABLE_SECURITY` - Enable authentication
|
||||||
|
- `PUID` / `PGID` - User/Group IDs
|
||||||
|
- `SYSTEM_MAXFILESIZE` - Max upload size (MB)
|
||||||
|
- `TESSERACT_LANGS` - Comma-separated OCR language codes
|
||||||
|
- `JAVA_CUSTOM_OPTS` - Additional JVM options
|
||||||
|
|
||||||
|
See full configuration docs at: https://docs.stirlingpdf.com
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Compose Examples
|
||||||
|
|
||||||
|
### Example 1: All-in-One (MODE=BOTH)
|
||||||
|
|
||||||
|
**File:** `docker/compose/docker-compose-unified-both.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
stirling-pdf:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./data:/usr/share/tessdata:rw
|
||||||
|
- ./config:/configs:rw
|
||||||
|
environment:
|
||||||
|
MODE: BOTH
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Separate Frontend & Backend
|
||||||
|
|
||||||
|
**File:** `docker/compose/docker-compose-unified-frontend.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports:
|
||||||
|
- "8081:8080"
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
volumes:
|
||||||
|
- ./data:/usr/share/tessdata:rw
|
||||||
|
- ./config:/configs:rw
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
MODE: FRONTEND
|
||||||
|
VITE_API_BASE_URL: http://backend:8080
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Backend API Only
|
||||||
|
|
||||||
|
**File:** `docker/compose/docker-compose-unified-backend.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
stirling-pdf-api:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
volumes:
|
||||||
|
- ./data:/usr/share/tessdata:rw
|
||||||
|
- ./config:/configs:rw
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Building the Image
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From repository root
|
||||||
|
docker build -t stirlingtools/stirling-pdf:unified -f docker/Dockerfile.unified .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Arguments
|
||||||
|
|
||||||
|
| Argument | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `VERSION_TAG` | Version tag for the image |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```bash
|
||||||
|
docker build \
|
||||||
|
--build-arg VERSION_TAG=v1.0.0 \
|
||||||
|
-t stirlingtools/stirling-pdf:unified \
|
||||||
|
-f docker/Dockerfile.unified .
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
### 1. Simple Deployment (MODE=BOTH)
|
||||||
|
- **Best for:** Personal use, small teams, simple deployments
|
||||||
|
- **Pros:** Single container, easy setup, minimal configuration
|
||||||
|
- **Cons:** Frontend and backend scale together
|
||||||
|
|
||||||
|
### 2. Scaled Frontend (MODE=FRONTEND + BACKEND)
|
||||||
|
- **Best for:** High traffic, need to scale frontend independently
|
||||||
|
- **Pros:** Scale frontend containers separately, CDN-friendly
|
||||||
|
- **Example:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
environment:
|
||||||
|
MODE: FRONTEND
|
||||||
|
VITE_API_BASE_URL: http://backend:8080
|
||||||
|
deploy:
|
||||||
|
replicas: 5 # Scale frontend independently
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. API-Only (MODE=BACKEND)
|
||||||
|
- **Best for:** Headless deployments, custom frontends, API integrations
|
||||||
|
- **Pros:** Minimal resources, no nginx overhead
|
||||||
|
- **Example:** Use with external frontend or API consumers
|
||||||
|
|
||||||
|
### 4. Multi-Backend Setup
|
||||||
|
- **Best for:** Load balancing, high availability
|
||||||
|
- **Example:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend-1:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
|
||||||
|
backend-2:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
environment:
|
||||||
|
MODE: FRONTEND
|
||||||
|
VITE_API_BASE_URL: http://load-balancer:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Port Configuration
|
||||||
|
|
||||||
|
All modes use **port 8080** by default:
|
||||||
|
|
||||||
|
- **MODE=BOTH**: Nginx listens on 8080, proxies to backend on internal 8081
|
||||||
|
- **MODE=FRONTEND**: Nginx listens on 8080
|
||||||
|
- **MODE=BACKEND**: Spring Boot listens on 8080
|
||||||
|
|
||||||
|
**Expose port 8080** in all configurations:
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
### MODE=BOTH and MODE=BACKEND
|
||||||
|
```yaml
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=FRONTEND
|
||||||
|
```yaml
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check logs
|
||||||
|
```bash
|
||||||
|
docker logs stirling-pdf-container
|
||||||
|
```
|
||||||
|
|
||||||
|
Look for the startup banner:
|
||||||
|
```
|
||||||
|
===================================
|
||||||
|
Stirling-PDF Unified Container
|
||||||
|
MODE: BOTH
|
||||||
|
===================================
|
||||||
|
```
|
||||||
|
|
||||||
|
### Invalid MODE error
|
||||||
|
```
|
||||||
|
ERROR: Invalid MODE 'XYZ'. Must be BOTH, FRONTEND, or BACKEND
|
||||||
|
```
|
||||||
|
**Fix:** Set `MODE` to one of the three valid values.
|
||||||
|
|
||||||
|
### Frontend can't connect to backend (MODE=FRONTEND)
|
||||||
|
**Check:**
|
||||||
|
1. `VITE_API_BASE_URL` points to correct backend URL
|
||||||
|
2. Backend container is running and accessible
|
||||||
|
3. Network connectivity between containers
|
||||||
|
|
||||||
|
### Backend not starting (MODE=BOTH or BACKEND)
|
||||||
|
**Check:**
|
||||||
|
1. Sufficient memory allocated (4GB recommended)
|
||||||
|
2. Java heap size (`JAVA_CUSTOM_OPTS`)
|
||||||
|
3. Volume permissions for `/tmp/stirling-pdf`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration Guide
|
||||||
|
|
||||||
|
### From Separate Containers → MODE=BOTH
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
frontend:
|
||||||
|
image: stirlingtools/stirling-pdf:frontend
|
||||||
|
ports: ["80:80"]
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image: stirlingtools/stirling-pdf:backend
|
||||||
|
ports: ["8080:8080"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
stirling-pdf:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports: ["8080:8080"]
|
||||||
|
environment:
|
||||||
|
MODE: BOTH
|
||||||
|
```
|
||||||
|
|
||||||
|
### From Legacy → MODE=BACKEND
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
stirling-pdf:
|
||||||
|
image: stirlingtools/stirling-pdf:latest
|
||||||
|
ports: ["8080:8080"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Becomes:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
stirling-pdf:
|
||||||
|
image: stirlingtools/stirling-pdf:unified
|
||||||
|
ports: ["8080:8080"]
|
||||||
|
environment:
|
||||||
|
MODE: BACKEND
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Tuning
|
||||||
|
|
||||||
|
### MODE=BOTH
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
JAVA_CUSTOM_OPTS: "-Xmx4g -XX:MaxRAMPercentage=75"
|
||||||
|
BACKEND_INTERNAL_PORT: 8081
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 4G
|
||||||
|
reservations:
|
||||||
|
memory: 2G
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=FRONTEND (Lightweight)
|
||||||
|
```yaml
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
```
|
||||||
|
|
||||||
|
### MODE=BACKEND (Heavy Processing)
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
JAVA_CUSTOM_OPTS: "-Xmx8g"
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 10G
|
||||||
|
reservations:
|
||||||
|
memory: 4G
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **MODE=BOTH**: Backend not exposed externally (runs on internal port)
|
||||||
|
2. **MODE=BACKEND**: API exposed directly - consider API authentication
|
||||||
|
3. **MODE=FRONTEND**: Only serves static files - minimal attack surface
|
||||||
|
|
||||||
|
Enable security features:
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
DOCKER_ENABLE_SECURITY: "true"
|
||||||
|
SECURITY_ENABLELOGIN: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- Documentation: https://docs.stirlingpdf.com
|
||||||
|
- GitHub Issues: https://github.com/Stirling-Tools/Stirling-PDF/issues
|
||||||
|
- Docker Hub: https://hub.docker.com/r/stirlingtools/stirling-pdf
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License - See repository for full details
|
||||||
38
docker/unified/build.sh
Normal file
38
docker/unified/build.sh
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Build script for Stirling-PDF Unified Container
|
||||||
|
# Usage: ./build.sh [version-tag]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VERSION_TAG=${1:-latest}
|
||||||
|
IMAGE_NAME="stirlingtools/stirling-pdf:unified-${VERSION_TAG}"
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "Building Stirling-PDF Unified Container"
|
||||||
|
echo "Version: $VERSION_TAG"
|
||||||
|
echo "Image: $IMAGE_NAME"
|
||||||
|
echo "==================================="
|
||||||
|
|
||||||
|
# Navigate to repository root (assuming script is in docker/unified/)
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
REPO_ROOT="$SCRIPT_DIR/../.."
|
||||||
|
|
||||||
|
cd "$REPO_ROOT"
|
||||||
|
|
||||||
|
# Build the image
|
||||||
|
docker build \
|
||||||
|
--build-arg VERSION_TAG="$VERSION_TAG" \
|
||||||
|
-t "$IMAGE_NAME" \
|
||||||
|
-f docker/Dockerfile.unified \
|
||||||
|
.
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "✓ Build complete!"
|
||||||
|
echo "Image: $IMAGE_NAME"
|
||||||
|
echo ""
|
||||||
|
echo "Test the image:"
|
||||||
|
echo " MODE=BOTH: docker run -p 8080:8080 -e MODE=BOTH $IMAGE_NAME"
|
||||||
|
echo " MODE=FRONTEND: docker run -p 8080:8080 -e MODE=FRONTEND $IMAGE_NAME"
|
||||||
|
echo " MODE=BACKEND: docker run -p 8080:8080 -e MODE=BACKEND $IMAGE_NAME"
|
||||||
|
echo "==================================="
|
||||||
176
docker/unified/entrypoint.sh
Normal file
176
docker/unified/entrypoint.sh
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Default MODE to BOTH if not set
|
||||||
|
MODE=${MODE:-BOTH}
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "Stirling-PDF Unified Container"
|
||||||
|
echo "MODE: $MODE"
|
||||||
|
echo "==================================="
|
||||||
|
|
||||||
|
# Function to setup OCR (from init.sh)
|
||||||
|
setup_ocr() {
|
||||||
|
echo "Setting up OCR languages..."
|
||||||
|
|
||||||
|
# Copy tessdata
|
||||||
|
mkdir -p /usr/share/tessdata
|
||||||
|
cp -rn /usr/share/tessdata-original/* /usr/share/tessdata 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -d /usr/share/tesseract-ocr/4.00/tessdata ]; then
|
||||||
|
cp -r /usr/share/tesseract-ocr/4.00/tessdata/* /usr/share/tessdata 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /usr/share/tesseract-ocr/5/tessdata ]; then
|
||||||
|
cp -r /usr/share/tesseract-ocr/5/tessdata/* /usr/share/tessdata 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install additional languages if specified
|
||||||
|
if [[ -n "$TESSERACT_LANGS" ]]; then
|
||||||
|
SPACE_SEPARATED_LANGS=$(echo $TESSERACT_LANGS | tr ',' ' ')
|
||||||
|
pattern='^[a-zA-Z]{2,4}(_[a-zA-Z]{2,4})?$'
|
||||||
|
for LANG in $SPACE_SEPARATED_LANGS; do
|
||||||
|
if [[ $LANG =~ $pattern ]]; then
|
||||||
|
apk add --no-cache "tesseract-ocr-data-$LANG" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to setup user permissions (from init-without-ocr.sh)
|
||||||
|
setup_permissions() {
|
||||||
|
echo "Setting up user permissions..."
|
||||||
|
|
||||||
|
export JAVA_TOOL_OPTIONS="${JAVA_BASE_OPTS} ${JAVA_CUSTOM_OPTS}"
|
||||||
|
|
||||||
|
# Update user and group IDs
|
||||||
|
if [ ! -z "$PUID" ] && [ "$PUID" != "$(id -u stirlingpdfuser)" ]; then
|
||||||
|
usermod -o -u "$PUID" stirlingpdfuser || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -f3)" ]; then
|
||||||
|
groupmod -o -g "$PGID" stirlingpdfgroup || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
umask "$UMASK" || true
|
||||||
|
|
||||||
|
# Install fonts if needed
|
||||||
|
if [[ -n "$LANGS" ]]; then
|
||||||
|
/scripts/installFonts.sh $LANGS
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure directories exist with correct permissions
|
||||||
|
mkdir -p /tmp/stirling-pdf || true
|
||||||
|
|
||||||
|
# Set ownership and permissions
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup \
|
||||||
|
$HOME /logs /scripts /usr/share/fonts/opentype/noto \
|
||||||
|
/configs /customFiles /pipeline /tmp/stirling-pdf \
|
||||||
|
/var/lib/nginx /var/log/nginx /usr/share/nginx \
|
||||||
|
/app.jar 2>/dev/null || echo "[WARN] Some chown operations failed, may run as host user"
|
||||||
|
|
||||||
|
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto \
|
||||||
|
/configs /customFiles /pipeline /tmp/stirling-pdf 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to configure nginx
|
||||||
|
configure_nginx() {
|
||||||
|
local backend_url=$1
|
||||||
|
echo "Configuring nginx with backend URL: $backend_url"
|
||||||
|
sed -i "s|\${BACKEND_URL}|${backend_url}|g" /etc/nginx/nginx.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to run as user or root depending on permissions
|
||||||
|
run_as_user() {
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
# Running as root, use su-exec
|
||||||
|
su-exec stirlingpdfuser "$@"
|
||||||
|
else
|
||||||
|
# Already running as non-root
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup OCR and permissions
|
||||||
|
setup_ocr
|
||||||
|
setup_permissions
|
||||||
|
|
||||||
|
# Handle different modes
|
||||||
|
case "$MODE" in
|
||||||
|
BOTH)
|
||||||
|
echo "Starting in BOTH mode: Frontend + Backend on port 8080"
|
||||||
|
|
||||||
|
# Configure nginx to proxy to internal backend
|
||||||
|
configure_nginx "http://localhost:${BACKEND_INTERNAL_PORT:-8081}"
|
||||||
|
|
||||||
|
# Start backend on internal port
|
||||||
|
echo "Starting backend on port ${BACKEND_INTERNAL_PORT:-8081}..."
|
||||||
|
run_as_user sh -c "java -Dfile.encoding=UTF-8 \
|
||||||
|
-Djava.io.tmpdir=/tmp/stirling-pdf \
|
||||||
|
-Dserver.port=${BACKEND_INTERNAL_PORT:-8081} \
|
||||||
|
-jar /app.jar" &
|
||||||
|
BACKEND_PID=$!
|
||||||
|
|
||||||
|
# Start unoserver for document conversion
|
||||||
|
run_as_user /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1 &
|
||||||
|
UNO_PID=$!
|
||||||
|
|
||||||
|
# Wait for backend to start
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# Start nginx on port 8080
|
||||||
|
echo "Starting nginx on port 8080..."
|
||||||
|
run_as_user nginx -g "daemon off;" &
|
||||||
|
NGINX_PID=$!
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "✓ Frontend available at: http://localhost:8080"
|
||||||
|
echo "✓ Backend API at: http://localhost:8080/api"
|
||||||
|
echo "✓ Backend running internally on port ${BACKEND_INTERNAL_PORT:-8081}"
|
||||||
|
echo "==================================="
|
||||||
|
;;
|
||||||
|
|
||||||
|
FRONTEND)
|
||||||
|
echo "Starting in FRONTEND mode: Frontend only on port 8080"
|
||||||
|
|
||||||
|
# Configure nginx with external backend URL
|
||||||
|
BACKEND_URL=${VITE_API_BASE_URL:-http://backend:8080}
|
||||||
|
configure_nginx "$BACKEND_URL"
|
||||||
|
|
||||||
|
# Start nginx on port 8080
|
||||||
|
echo "Starting nginx on port 8080..."
|
||||||
|
run_as_user nginx -g "daemon off;" &
|
||||||
|
NGINX_PID=$!
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "✓ Frontend available at: http://localhost:8080"
|
||||||
|
echo "✓ Proxying API calls to: $BACKEND_URL"
|
||||||
|
echo "==================================="
|
||||||
|
;;
|
||||||
|
|
||||||
|
BACKEND)
|
||||||
|
echo "Starting in BACKEND mode: Backend only on port 8080"
|
||||||
|
|
||||||
|
# Start backend on port 8080
|
||||||
|
echo "Starting backend on port 8080..."
|
||||||
|
run_as_user sh -c "java -Dfile.encoding=UTF-8 \
|
||||||
|
-Djava.io.tmpdir=/tmp/stirling-pdf \
|
||||||
|
-Dserver.port=8080 \
|
||||||
|
-jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1" &
|
||||||
|
BACKEND_PID=$!
|
||||||
|
|
||||||
|
echo "==================================="
|
||||||
|
echo "✓ Backend API available at: http://localhost:8080/api"
|
||||||
|
echo "✓ Swagger UI at: http://localhost:8080/swagger-ui/index.html"
|
||||||
|
echo "==================================="
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "ERROR: Invalid MODE '$MODE'. Must be BOTH, FRONTEND, or BACKEND"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Wait for all background processes
|
||||||
|
wait
|
||||||
118
docker/unified/nginx.conf
Normal file
118
docker/unified/nginx.conf
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
# Add .mjs MIME type mapping
|
||||||
|
types {
|
||||||
|
text/javascript mjs;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
|
||||||
|
# Global settings for file uploads
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
# Handle client-side routing - support subpaths
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy API calls to backend
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass ${BACKEND_URL}/api/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
|
# Additional headers for proper API proxying
|
||||||
|
proxy_set_header Connection '';
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
|
||||||
|
# Timeout settings for large file uploads
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Request size limits for file uploads
|
||||||
|
client_max_body_size 100m;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy Swagger UI to backend (including versioned paths)
|
||||||
|
location ~ ^/swagger-ui(.*)$ {
|
||||||
|
proxy_pass ${BACKEND_URL}/swagger-ui$1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
|
proxy_set_header Connection '';
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy API docs to backend (with query parameters and sub-paths)
|
||||||
|
location ~ ^/v3/api-docs(.*)$ {
|
||||||
|
proxy_pass ${BACKEND_URL}/v3/api-docs$1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Proxy v1 API docs to backend (with query parameters and sub-paths)
|
||||||
|
location ~ ^/v1/api-docs(.*)$ {
|
||||||
|
proxy_pass ${BACKEND_URL}/v1/api-docs$1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Serve .mjs files with correct MIME type (must come before general static assets)
|
||||||
|
location ~* \.mjs$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
add_header Content-Type "text/javascript; charset=utf-8" always;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user