mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-27 06:39:24 +00:00
remove monolith
This commit is contained in:
parent
117d906be3
commit
cba59a77ab
176
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
176
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
@ -2,7 +2,7 @@ name: Auto PR V2 Deployment
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, reopened]
|
types: [opened, synchronize, reopened, closed]
|
||||||
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@ -12,6 +12,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-pr:
|
check-pr:
|
||||||
|
if: github.event.action != 'closed'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
should_deploy: ${{ steps.check-conditions.outputs.should_deploy }}
|
should_deploy: ${{ steps.check-conditions.outputs.should_deploy }}
|
||||||
@ -212,13 +213,62 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_HUB_API }}
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
- name: Build and push V2 monolith image
|
- name: Get commit hashes for frontend and backend
|
||||||
|
id: commit-hashes
|
||||||
|
run: |
|
||||||
|
# Get commit hash for frontend folder
|
||||||
|
FRONTEND_HASH=$(git log -1 --format="%H" -- frontend/ || echo "no-frontend-changes")
|
||||||
|
echo "frontend_hash=$FRONTEND_HASH" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# Get commit hash for backend folder (excluding frontend)
|
||||||
|
BACKEND_HASH=$(git log -1 --format="%H" -- . ':!frontend/' || echo "no-backend-changes")
|
||||||
|
echo "backend_hash=$BACKEND_HASH" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# Short hashes for tags
|
||||||
|
echo "frontend_short=${FRONTEND_HASH:0:8}" >> $GITHUB_OUTPUT
|
||||||
|
echo "backend_short=${BACKEND_HASH:0:8}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Check if frontend image exists
|
||||||
|
id: check-frontend
|
||||||
|
run: |
|
||||||
|
if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} >/dev/null 2>&1; then
|
||||||
|
echo "exists=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "Frontend image already exists, skipping build"
|
||||||
|
else
|
||||||
|
echo "exists=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "Frontend image needs to be built"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check if backend image exists
|
||||||
|
id: check-backend
|
||||||
|
run: |
|
||||||
|
if docker manifest inspect ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }} >/dev/null 2>&1; then
|
||||||
|
echo "exists=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "Backend image already exists, skipping build"
|
||||||
|
else
|
||||||
|
echo "exists=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "Backend image needs to be built"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build and push V2 frontend image
|
||||||
|
if: steps.check-frontend.outputs.exists == 'false'
|
||||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/monolith/Dockerfile
|
file: ./docker/frontend/Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-pr-${{ needs.check-pr.outputs.pr_number }}
|
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }}
|
||||||
|
build-args: VERSION_TAG=v2-alpha
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
- name: Build and push V2 backend image
|
||||||
|
if: steps.check-backend.outputs.exists == 'false'
|
||||||
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./docker/backend/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }}
|
||||||
build-args: VERSION_TAG=v2-alpha
|
build-args: VERSION_TAG=v2-alpha
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
|
|
||||||
@ -233,16 +283,17 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# Use same port strategy as regular PRs - just the PR number
|
# Use same port strategy as regular PRs - just the PR number
|
||||||
V2_PORT=${{ needs.check-pr.outputs.pr_number }}
|
V2_PORT=${{ needs.check-pr.outputs.pr_number }}
|
||||||
|
BACKEND_PORT=$((V2_PORT + 10000)) # Backend on higher port to avoid conflicts
|
||||||
|
|
||||||
# Create docker-compose for V2 monolith
|
# Create docker-compose for V2 with separate frontend and backend
|
||||||
cat > docker-compose.yml << EOF
|
cat > docker-compose.yml << EOF
|
||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
stirling-pdf-v2:
|
stirling-pdf-v2-backend:
|
||||||
container_name: stirling-pdf-v2-pr-${{ needs.check-pr.outputs.pr_number }}
|
container_name: stirling-pdf-v2-backend-pr-${{ needs.check-pr.outputs.pr_number }}
|
||||||
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-pr-${{ needs.check-pr.outputs.pr_number }}
|
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }}
|
||||||
ports:
|
ports:
|
||||||
- "${V2_PORT}:80" # Frontend port (same as regular PRs)
|
- "${BACKEND_PORT}:8080" # Backend API port
|
||||||
volumes:
|
volumes:
|
||||||
- /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/data:/usr/share/tessdata:rw
|
- /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/data:/usr/share/tessdata:rw
|
||||||
- /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/config:/configs:rw
|
- /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/config:/configs:rw
|
||||||
@ -258,6 +309,17 @@ jobs:
|
|||||||
METRICS_ENABLED: "true"
|
METRICS_ENABLED: "true"
|
||||||
SYSTEM_GOOGLEVISIBILITY: "false"
|
SYSTEM_GOOGLEVISIBILITY: "false"
|
||||||
restart: on-failure:5
|
restart: on-failure:5
|
||||||
|
|
||||||
|
stirling-pdf-v2-frontend:
|
||||||
|
container_name: stirling-pdf-v2-frontend-pr-${{ needs.check-pr.outputs.pr_number }}
|
||||||
|
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }}
|
||||||
|
ports:
|
||||||
|
- "${V2_PORT}:80" # Frontend port (same as regular PRs)
|
||||||
|
environment:
|
||||||
|
VITE_API_BASE_URL: "http://${{ secrets.VPS_HOST }}:${BACKEND_PORT}"
|
||||||
|
depends_on:
|
||||||
|
- stirling-pdf-v2-backend
|
||||||
|
restart: on-failure:5
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Deploy to VPS
|
# Deploy to VPS
|
||||||
@ -325,3 +387,99 @@ jobs:
|
|||||||
body: commentBody
|
body: commentBody
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cleanup-v2-deployment:
|
||||||
|
if: github.event.action == 'closed'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Harden Runner
|
||||||
|
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
||||||
|
with:
|
||||||
|
egress-policy: audit
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Setup GitHub App Bot
|
||||||
|
if: github.actor != 'dependabot[bot]'
|
||||||
|
id: setup-bot
|
||||||
|
uses: ./.github/actions/setup-bot
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: Clean up V2 deployment comments
|
||||||
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
|
with:
|
||||||
|
github-token: ${{ steps.setup-bot.outputs.token }}
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo;
|
||||||
|
const prNumber = ${{ github.event.pull_request.number }};
|
||||||
|
|
||||||
|
// Find and delete V2 deployment comments
|
||||||
|
const { data: comments } = await github.rest.issues.listComments({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: prNumber
|
||||||
|
});
|
||||||
|
|
||||||
|
const v2Comments = comments.filter(c =>
|
||||||
|
c.body?.includes("## 🚀 V2 Auto-Deployment Complete!") &&
|
||||||
|
c.user?.type === "Bot"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const comment of v2Comments) {
|
||||||
|
await github.rest.issues.deleteComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
comment_id: comment.id
|
||||||
|
});
|
||||||
|
console.log(`Deleted V2 deployment comment (ID: ${comment.id})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Set up SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
|
||||||
|
sudo chmod 600 ../private.key
|
||||||
|
|
||||||
|
- name: Cleanup V2 deployment
|
||||||
|
run: |
|
||||||
|
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
|
||||||
|
if [ -d "/stirling/V2-PR-${{ github.event.pull_request.number }}" ]; then
|
||||||
|
echo "Found V2 PR directory, proceeding with cleanup..."
|
||||||
|
|
||||||
|
# Stop and remove V2 containers
|
||||||
|
cd /stirling/V2-PR-${{ github.event.pull_request.number }}
|
||||||
|
docker-compose down || true
|
||||||
|
|
||||||
|
# Go back to root before removal
|
||||||
|
cd /
|
||||||
|
|
||||||
|
# Remove V2 PR-specific directories
|
||||||
|
rm -rf /stirling/V2-PR-${{ github.event.pull_request.number }}
|
||||||
|
|
||||||
|
# Clean up V2 containers by name (in case compose cleanup missed them)
|
||||||
|
docker rm -f stirling-pdf-v2-frontend-pr-${{ github.event.pull_request.number }} || true
|
||||||
|
docker rm -f stirling-pdf-v2-backend-pr-${{ github.event.pull_request.number }} || true
|
||||||
|
|
||||||
|
echo "V2 cleanup completed"
|
||||||
|
else
|
||||||
|
echo "V2 PR directory not found, nothing to clean up"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Note: We don't remove the commit-based images since they can be reused across PRs
|
||||||
|
# Only remove PR-specific containers and directories
|
||||||
|
ENDSSH
|
||||||
|
|
||||||
|
- name: Cleanup temporary files
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
rm -f ../private.key
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
@ -14,15 +14,10 @@ docker/
|
|||||||
│ ├── Dockerfile # React/Vite frontend with nginx
|
│ ├── Dockerfile # React/Vite frontend with nginx
|
||||||
│ ├── nginx.conf # Nginx configuration
|
│ ├── nginx.conf # Nginx configuration
|
||||||
│ └── entrypoint.sh # Dynamic backend URL setup
|
│ └── entrypoint.sh # Dynamic backend URL setup
|
||||||
├── monolith/ # Single container setup
|
|
||||||
│ ├── Dockerfile # Combined frontend + backend
|
|
||||||
│ ├── nginx-monolith.conf # Nginx config for monolith
|
|
||||||
│ └── start-monolith.sh # Startup script
|
|
||||||
└── compose/ # Docker Compose files
|
└── compose/ # Docker Compose files
|
||||||
├── docker-compose.yml # Standard setup
|
├── docker-compose.yml # Standard setup
|
||||||
├── docker-compose.ultra-lite.yml # Ultra-lite setup
|
├── docker-compose.ultra-lite.yml # Ultra-lite setup
|
||||||
├── docker-compose.fat.yml # Full-featured setup
|
└── docker-compose.fat.yml # Full-featured setup
|
||||||
└── docker-compose.monolith.yml # Single container setup
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -42,12 +37,6 @@ docker-compose -f docker/compose/docker-compose.ultra-lite.yml up --build
|
|||||||
docker-compose -f docker/compose/docker-compose.fat.yml up --build
|
docker-compose -f docker/compose/docker-compose.fat.yml up --build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Single Container (Monolith)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Single container with both frontend and backend
|
|
||||||
docker-compose -f docker/compose/docker-compose.monolith.yml up --build
|
|
||||||
```
|
|
||||||
|
|
||||||
## Access Points
|
## Access Points
|
||||||
|
|
||||||
@ -57,7 +46,7 @@ docker-compose -f docker/compose/docker-compose.monolith.yml up --build
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
- **Backend URL**: Set `BACKEND_URL` environment variable for custom backend locations
|
- **Backend URL**: Set `VITE_API_BASE_URL` environment variable for custom backend locations
|
||||||
- **Custom Ports**: Modify port mappings in docker-compose files
|
- **Custom Ports**: Modify port mappings in docker-compose files
|
||||||
- **Memory Limits**: Adjust memory limits per variant (2G ultra-lite, 4G standard, 6G fat)
|
- **Memory Limits**: Adjust memory limits per variant (2G ultra-lite, 4G standard, 6G fat)
|
||||||
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
services:
|
|
||||||
stirling-pdf-monolith:
|
|
||||||
build:
|
|
||||||
context: ../..
|
|
||||||
dockerfile: docker/monolith/Dockerfile
|
|
||||||
container_name: stirling-pdf-monolith
|
|
||||||
restart: on-failure:5
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 4G
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "curl -f http://localhost:80/ && curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 15s
|
|
||||||
retries: 16
|
|
||||||
ports:
|
|
||||||
- "3000:80" # Frontend access
|
|
||||||
- "8080:8080" # Direct backend access (for debugging)
|
|
||||||
volumes:
|
|
||||||
- ../../stirling/latest/data:/usr/share/tessdata:rw
|
|
||||||
- ../../stirling/latest/config:/configs:rw
|
|
||||||
- ../../stirling/latest/logs:/logs:rw
|
|
||||||
environment:
|
|
||||||
DISABLE_ADDITIONAL_FEATURES: "true"
|
|
||||||
SECURITY_ENABLELOGIN: "false"
|
|
||||||
LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID"
|
|
||||||
SYSTEM_DEFAULTLOCALE: en-US
|
|
||||||
UI_APPNAME: Stirling-PDF
|
|
||||||
UI_HOMEDESCRIPTION: Single container Stirling-PDF
|
|
||||||
UI_APPNAMENAVBAR: Stirling-PDF Monolith
|
|
||||||
SYSTEM_MAXFILESIZE: "100"
|
|
||||||
METRICS_ENABLED: "true"
|
|
||||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
|
||||||
SHOW_SURVEY: "true"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
stirling-data:
|
|
||||||
stirling-config:
|
|
||||||
stirling-logs:
|
|
@ -32,7 +32,7 @@ RUN chmod +x /entrypoint.sh
|
|||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
# Environment variables for flexibility
|
# Environment variables for flexibility
|
||||||
ENV BACKEND_URL=http://backend:8080
|
ENV VITE_API_BASE_URL=http://backend:8080
|
||||||
|
|
||||||
# Use custom entrypoint
|
# Use custom entrypoint
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
@ -1,10 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Set default backend URL if not provided
|
# Set default backend URL if not provided
|
||||||
BACKEND_URL=${BACKEND_URL:-"http://backend:8080"}
|
VITE_API_BASE_URL=${VITE_API_BASE_URL:-"http://backend:8080"}
|
||||||
|
|
||||||
# Replace the placeholder in nginx.conf with the actual backend URL
|
# Replace the placeholder in nginx.conf with the actual backend URL
|
||||||
sed -i "s|\${BACKEND_URL}|${BACKEND_URL}|g" /etc/nginx/nginx.conf
|
sed -i "s|\${VITE_API_BASE_URL}|${VITE_API_BASE_URL}|g" /etc/nginx/nginx.conf
|
||||||
|
|
||||||
# Start nginx
|
# Start nginx
|
||||||
exec nginx -g "daemon off;"
|
exec nginx -g "daemon off;"
|
@ -28,7 +28,7 @@ http {
|
|||||||
|
|
||||||
# Proxy API calls to backend
|
# Proxy API calls to backend
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass ${BACKEND_URL}/api/;
|
proxy_pass ${VITE_API_BASE_URL}/api/;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
# Monolith Dockerfile - Frontend + Backend in same container
|
|
||||||
# Build the application
|
|
||||||
FROM gradle:8.14-jdk21 AS 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
|
|
||||||
|
|
||||||
# Set the working directory
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Copy the entire project to the working directory
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Build the application with DISABLE_ADDITIONAL_FEATURES=true
|
|
||||||
RUN DISABLE_ADDITIONAL_FEATURES=true \
|
|
||||||
STIRLING_PDF_DESKTOP_UI=false \
|
|
||||||
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
|
||||||
|
|
||||||
# Build frontend
|
|
||||||
FROM node:20-alpine AS frontend-build
|
|
||||||
|
|
||||||
WORKDIR /app/frontend
|
|
||||||
|
|
||||||
# Copy frontend package files
|
|
||||||
COPY frontend/package*.json ./
|
|
||||||
|
|
||||||
# Install frontend dependencies
|
|
||||||
RUN npm ci
|
|
||||||
|
|
||||||
# Copy frontend source
|
|
||||||
COPY frontend/ ./
|
|
||||||
|
|
||||||
# Build frontend
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# Main stage - Backend with frontend files
|
|
||||||
FROM alpine:3.22.0@sha256:8a1f59ffb675680d47db6337b49d22281a139e9d709335b492be023728e11715
|
|
||||||
|
|
||||||
# Copy necessary files
|
|
||||||
COPY scripts /scripts
|
|
||||||
COPY pipeline /pipeline
|
|
||||||
COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
|
||||||
# first /app directory is for the build stage, second is for the final image
|
|
||||||
COPY --from=build /app/app/core/build/libs/*.jar app.jar
|
|
||||||
|
|
||||||
# Copy built frontend files
|
|
||||||
COPY --from=frontend-build /app/frontend/dist /usr/share/nginx/html
|
|
||||||
|
|
||||||
ARG VERSION_TAG
|
|
||||||
|
|
||||||
LABEL org.opencontainers.image.title="Stirling-PDF Monolith"
|
|
||||||
LABEL org.opencontainers.image.description="Single container with both frontend and backend for Stirling-PDF"
|
|
||||||
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, monolith, single-container"
|
|
||||||
|
|
||||||
# Set Environment Variables
|
|
||||||
ENV DISABLE_ADDITIONAL_FEATURES=true \
|
|
||||||
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
|
|
||||||
|
|
||||||
# Install nginx and 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 for descew and other advanced features)
|
|
||||||
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 && \
|
|
||||||
fc-cache -f -v && \
|
|
||||||
chmod +x /scripts/* && \
|
|
||||||
chmod +x /scripts/init.sh && \
|
|
||||||
# User permissions
|
|
||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
|
||||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/nginx/html
|
|
||||||
|
|
||||||
# Copy nginx configuration for monolith
|
|
||||||
COPY docker/monolith/nginx-monolith.conf /etc/nginx/nginx.conf
|
|
||||||
|
|
||||||
# Copy startup script
|
|
||||||
COPY docker/monolith/start-monolith.sh /start-monolith.sh
|
|
||||||
RUN chmod +x /start-monolith.sh
|
|
||||||
|
|
||||||
# Expose both ports
|
|
||||||
EXPOSE 80 8080
|
|
||||||
|
|
||||||
# Set user and run command
|
|
||||||
ENTRYPOINT ["tini", "--"]
|
|
||||||
CMD ["/start-monolith.sh"]
|
|
@ -1,49 +0,0 @@
|
|||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
# 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 80;
|
|
||||||
server_name _;
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html index.htm;
|
|
||||||
|
|
||||||
# Handle client-side routing - support subpaths
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy API calls to backend running on same container
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://localhost:8080/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;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Start the Java backend in the background
|
|
||||||
echo "Starting Java backend..."
|
|
||||||
su-exec stirlingpdfuser:stirlingpdfgroup bash -c "
|
|
||||||
cd /home/stirlingpdfuser && \
|
|
||||||
java -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/tmp/stirling-pdf -jar /app.jar &
|
|
||||||
/opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1 &
|
|
||||||
"
|
|
||||||
|
|
||||||
# Wait for backend to start
|
|
||||||
echo "Waiting for backend to start..."
|
|
||||||
until curl -f http://localhost:8080/api/v1/info/status >/dev/null 2>&1; do
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Backend started, starting nginx..."
|
|
||||||
|
|
||||||
# Start nginx in the foreground
|
|
||||||
nginx -g "daemon off;"
|
|
Loading…
x
Reference in New Issue
Block a user