mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-05 11:52:48 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36b98eb1af | ||
|
|
b059ac6ada | ||
|
|
21b9b58610 | ||
|
|
bf6e212a2d | ||
|
|
fb8c8c07ae | ||
|
|
b9b98294b5 | ||
|
|
61390d97fe | ||
|
|
8f628e2b5a | ||
|
|
7787e1d9ac |
@@ -51,10 +51,11 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
docker-build-and-push:
|
||||
# Build each platform natively in parallel, then merge manifests
|
||||
build-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -69,9 +70,6 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
@@ -88,7 +86,7 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version and determine release type
|
||||
- name: Extract version
|
||||
id: version
|
||||
run: |
|
||||
if [[ $GITHUB_REF == refs/tags/v* ]]; then
|
||||
@@ -103,8 +101,7 @@ jobs:
|
||||
echo "is_release=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Build and push for releases (with 'latest' tag)
|
||||
- name: Build and push ${{ matrix.mode.name }} image (release)
|
||||
- name: Build and push amd64 ${{ matrix.mode.name }} (release)
|
||||
if: steps.version.outputs.is_release == 'true'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
@@ -112,18 +109,13 @@ jobs:
|
||||
build-args: |
|
||||
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
|
||||
tags: |
|
||||
bentopdf/bentopdf${{ matrix.mode.suffix }}:latest
|
||||
bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }}
|
||||
bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }}
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha,scope=amd64-${{ matrix.mode.name }}
|
||||
cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }}
|
||||
|
||||
# Build and push for main branch (with 'edge' tag)
|
||||
- name: Build and push ${{ matrix.mode.name }} image (edge)
|
||||
- name: Build and push amd64 ${{ matrix.mode.name }} (edge)
|
||||
if: steps.version.outputs.is_release == 'false'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
@@ -131,10 +123,178 @@ jobs:
|
||||
build-args: |
|
||||
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
|
||||
tags: |
|
||||
bentopdf/bentopdf${{ matrix.mode.suffix }}:edge
|
||||
bentopdf/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }}
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-amd64
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64
|
||||
platforms: linux/amd64
|
||||
cache-from: type=gha,scope=amd64-${{ matrix.mode.name }}
|
||||
cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }}
|
||||
|
||||
build-arm64:
|
||||
runs-on: ubuntu-24.04-arm # Native ARM64 runner
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
matrix:
|
||||
mode:
|
||||
- name: default
|
||||
simple_mode: false
|
||||
suffix: ""
|
||||
- name: simple
|
||||
simple_mode: true
|
||||
suffix: "-simple"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version
|
||||
id: version
|
||||
run: |
|
||||
if [[ $GITHUB_REF == refs/tags/v* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
|
||||
echo "is_release=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
SHORT_SHA=${GITHUB_SHA::7}
|
||||
echo "version=edge" >> $GITHUB_OUTPUT
|
||||
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
|
||||
echo "is_release=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build and push arm64 ${{ matrix.mode.name }} (release)
|
||||
if: steps.version.outputs.is_release == 'true'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
build-args: |
|
||||
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
|
||||
tags: |
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
platforms: linux/arm64
|
||||
cache-from: type=gha,scope=arm64-${{ matrix.mode.name }}
|
||||
cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }}
|
||||
|
||||
- name: Build and push arm64 ${{ matrix.mode.name }} (edge)
|
||||
if: steps.version.outputs.is_release == 'false'
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
build-args: |
|
||||
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
|
||||
tags: |
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
platforms: linux/arm64
|
||||
cache-from: type=gha,scope=arm64-${{ matrix.mode.name }}
|
||||
cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }}
|
||||
|
||||
# Merge manifests after both platforms are built
|
||||
merge-manifests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-amd64, build-arm64]
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
strategy:
|
||||
matrix:
|
||||
mode:
|
||||
- name: default
|
||||
suffix: ""
|
||||
- name: simple
|
||||
suffix: "-simple"
|
||||
steps:
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version
|
||||
id: version
|
||||
run: |
|
||||
if [[ $GITHUB_REF == refs/tags/v* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
|
||||
echo "is_release=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
SHORT_SHA=${GITHUB_SHA::7}
|
||||
echo "version=edge" >> $GITHUB_OUTPUT
|
||||
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
|
||||
echo "is_release=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create and push manifest (release)
|
||||
if: steps.version.outputs.is_release == 'true'
|
||||
run: |
|
||||
# DockerHub manifests
|
||||
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:latest \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
# GHCR manifests
|
||||
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
|
||||
|
||||
- name: Create and push manifest (edge)
|
||||
if: steps.version.outputs.is_release == 'false'
|
||||
run: |
|
||||
# DockerHub manifests
|
||||
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
|
||||
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
|
||||
bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
|
||||
# GHCR manifests
|
||||
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
|
||||
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
|
||||
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
|
||||
|
||||
+5
-1
@@ -8,7 +8,11 @@ WORKDIR /app
|
||||
COPY package*.json ./
|
||||
COPY vendor ./vendor
|
||||
ENV HUSKY=0
|
||||
RUN npm ci
|
||||
RUN npm config set fetch-retries 5 && \
|
||||
npm config set fetch-retry-mintimeout 60000 && \
|
||||
npm config set fetch-retry-maxtimeout 300000 && \
|
||||
npm config set fetch-timeout 600000 && \
|
||||
npm ci
|
||||
COPY . .
|
||||
|
||||
# Build without type checking (vite build only)
|
||||
|
||||
@@ -3,13 +3,47 @@
|
||||
|
||||
**BentoPDF** is a powerful, privacy-first, client-side PDF toolkit that is self hostable and allows you to manipulate, edit, merge, and process PDF files directly in your browser. No server-side processing is required, ensuring your files remain secure and private.
|
||||
|
||||
 [](https://ko-fi.com/alio01) 
|
||||
 [](https://ko-fi.com/alio01) 
|
||||
[](https://github.com/sponsors/alam00000)
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Join Us on Discord](#-join-us-on-discord)
|
||||
- [Documentation](#-documentation)
|
||||
- [Licensing](#-licensing)
|
||||
- [Stargazers over time](#-stargazers-over-time)
|
||||
- [Thank You to Our Sponsors](#-thank-you-to-our-sponsors)
|
||||
- [Why BentoPDF?](#-why-bentopdf)
|
||||
- [Features / Tools Supported](#️-features--tools-supported)
|
||||
- [Organize & Manage PDFs](#organize--manage-pdfs)
|
||||
- [Edit & Modify PDFs](#edit--modify-pdfs)
|
||||
- [Convert to PDF](#convert-to-pdf)
|
||||
- [Convert from PDF](#convert-from-pdf)
|
||||
- [Secure & Optimize PDFs](#secure--optimize-pdfs)
|
||||
- [Translations](#-translations)
|
||||
- [Getting Started](#-getting-started)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Quick Start](#-quick-start)
|
||||
- [Static Hosting](#static-hosting-using-netlify-vercel-and-github-pages)
|
||||
- [Self-Hosting Locally](#-self-hosting-locally)
|
||||
- [Docker Compose / Podman Compose](#-run-with-docker-compose--podman-compose-recommended)
|
||||
- [Podman Quadlet](#-podman-quadlet-systemd-integration)
|
||||
- [Simple Mode](#-simple-mode-for-internal-use)
|
||||
- [Security Features](#-security-features)
|
||||
- [Digital Signature CORS Proxy](#digital-signature-cors-proxy-required)
|
||||
- [Version Management](#-version-management)
|
||||
- [Development Setup](#-development-setup)
|
||||
- [Tech Stack & Background](#️-tech-stack--background)
|
||||
- [Roadmap](#️-roadmap)
|
||||
- [Contributing](#-contributing)
|
||||
- [Special Thanks](#special-thanks)
|
||||
|
||||
---
|
||||
|
||||
## 📢 Join Us on Discord
|
||||
|
||||
[](https://discord.gg/Bgq3Ay3f2w)
|
||||
@@ -34,12 +68,22 @@ Visit our [Documentation](https://bentopdf.com/docs/) for:
|
||||
|
||||
## 📜 Licensing
|
||||
|
||||
BentoPDF is dual-licensed:
|
||||
BentoPDF is **dual-licensed** to fit your needs:
|
||||
|
||||
- **AGPL-3.0** for open-source projects where you share your full source code publicly
|
||||
- **Commercial License** for proprietary/closed-source applications - **[Get Lifetime License for $49](https://ko-fi.com/s/f32ca4cb75)** (a one-time lifetime purchase, includes all feature updates forever)
|
||||
| License | Best For | Price |
|
||||
| -------------- | -------------------------------------------- | ------------------ |
|
||||
| **AGPL-3.0** | Open-source projects with public source code | **Free** |
|
||||
| **Commercial** | Proprietary / closed-source applications | **$49** (lifetime) |
|
||||
|
||||
For more details, see our [Licensing Page](https://bentopdf.com/licensing.html)
|
||||
<p align="center">
|
||||
<a href="https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd">
|
||||
<img src="https://img.shields.io/badge/🚀_Get_Commercial_License-$49_Lifetime-6366f1?style=for-the-badge&labelColor=1f2937" alt="Get Commercial License">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
> **One-time purchase** · **Unlimited devices & users** · **Lifetime updates** · **No AGPL obligations**
|
||||
|
||||
📖 For more details, see our [Licensing Page](https://bentopdf.com/licensing.html)
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -76,44 +120,48 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs.
|
||||
|
||||
### Organize & Manage PDFs
|
||||
|
||||
| Tool Name | Description |
|
||||
| :------------------------- | :------------------------------------------------------------------------------------------------------ |
|
||||
| **Merge PDFs** | Combine multiple PDF files into one. |
|
||||
| **Split PDFs** | Extract specific pages or divide a document into smaller files. |
|
||||
| **Organize Pages** | Reorder, duplicate, or delete pages with a simple drag-and-drop interface. |
|
||||
| **Extract Pages** | Save a specific range of pages as a new PDF. |
|
||||
| **Delete Pages** | Remove unwanted pages from your document. |
|
||||
| **Rotate PDF** | Rotate individual or all pages in a document. |
|
||||
| **N-Up PDF** | Combine multiple pages onto a single page. |
|
||||
| **View PDF** | A powerful, integrated PDF viewer. |
|
||||
| **Alternate & Mix pages** | Merge pages by alternating pages from each PDF. |
|
||||
| **Posterize PDF** | Split a PDF into multiple smaller pages for print. |
|
||||
| **PDF Multi Tool** | Merge, Split, Organize, Delete, Rotate, Add Blank Pages, Extract and Duplicate in an unified interface. |
|
||||
| **Add Attachments** | Embed one or more files into your PDF. |
|
||||
| **Extract Attachments** | Extract all embedded files from PDF(s) as a ZIP. |
|
||||
| **Edit Attachments** | View or remove attachments in your PDF. |
|
||||
| **Divide Pages** | Divide pages horizontally or vertically. |
|
||||
| **Combine to Single Page** | Stitch all pages into one continuous scroll. |
|
||||
| **Add Blank Page** | Insert an empty page anywhere in your PDF. |
|
||||
| **Reverse Pages** | Flip the order of all pages in your document. |
|
||||
| **View Metadata** | Inspect the hidden properties of your PDF. |
|
||||
| **PDFs to ZIP** | Package multiple PDF files into a ZIP archive. |
|
||||
| **Compare PDFs** | Compare two PDFs side by side. |
|
||||
| Tool Name | Description |
|
||||
| :--------------------------- | :------------------------------------------------------------------------------------------------------ |
|
||||
| **Merge PDFs** | Combine multiple PDF files into one. Preserves Bookmarks. |
|
||||
| **Split PDFs** | Extract specific pages or divide a document into smaller files. |
|
||||
| **Organize Pages** | Reorder, duplicate, or delete pages with a simple drag-and-drop interface. |
|
||||
| **Extract Pages** | Save a specific range of pages as a new PDF. |
|
||||
| **Delete Pages** | Remove unwanted pages from your document. |
|
||||
| **Rotate PDF** | Rotate individual or all pages in a document. |
|
||||
| **Rotate by Custom Degrees** | Rotate pages by any custom angle. |
|
||||
| **N-Up PDF** | Combine multiple pages onto a single page. |
|
||||
| **View PDF** | A powerful, integrated PDF viewer. |
|
||||
| **Alternate & Mix Pages** | Merge pages by alternating pages from each PDF. Preserves Bookmarks. |
|
||||
| **Posterize PDF** | Split a PDF into multiple smaller pages for print. |
|
||||
| **PDF Multi Tool** | Merge, Split, Organize, Delete, Rotate, Add Blank Pages, Extract and Duplicate in an unified interface. |
|
||||
| **PDF Booklet** | Rearrange pages for double-sided booklet printing. Fold and staple to create a booklet. |
|
||||
| **Add Attachments** | Embed one or more files into your PDF. |
|
||||
| **Extract Attachments** | Extract all embedded files from PDF(s) as a ZIP. |
|
||||
| **Edit Attachments** | View or remove attachments in your PDF. |
|
||||
| **Divide Pages** | Divide pages horizontally or vertically. |
|
||||
| **Combine to Single Page** | Stitch all pages into one continuous scroll. |
|
||||
| **Add Blank Page** | Insert an empty page anywhere in your PDF. |
|
||||
| **Reverse Pages** | Flip the order of all pages in your document. |
|
||||
| **View Metadata** | Inspect the hidden properties of your PDF. |
|
||||
| **PDFs to ZIP** | Package multiple PDF files into a ZIP archive. |
|
||||
| **Compare PDFs** | Compare two PDFs side by side. |
|
||||
|
||||
### Edit & Modify PDFs
|
||||
|
||||
| Tool Name | Description |
|
||||
| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **PDF Editor** | A comprehensive editor to modify your PDFs. |
|
||||
| **PDF Editor** | Annotate, highlight, redact, comment, add shapes/images, search, and view PDFs. |
|
||||
| **Create Fillable Forms** | Create professional fillable PDF forms with text fields, checkboxes, dropdowns, radio buttons, signatures, and more. Fully compliant with PDF standards for compatibility with all PDF viewers. |
|
||||
| **PDF Form Filler** | Fill in forms directly in the browser. Also supports XFA forms. |
|
||||
| **Add Page Numbers** | Easily add page numbers with customizable formatting. |
|
||||
| **Add Watermark** | Add text or image watermarks to protect your documents. |
|
||||
| **Header & Footer** | Add customizable headers and footers. |
|
||||
| **Crop PDF** | Crop specific pages or the entire document. |
|
||||
| **Deskew PDF** | Automatically straighten tilted scanned pages using OpenCV. |
|
||||
| **Font to Outline** | Convert all fonts to vector outlines for consistent rendering across all devices. |
|
||||
| **Invert Colors** | Invert the colors of your PDF pages for better readability. |
|
||||
| **Change Background** | Modify the background color of your PDF. |
|
||||
| **Change Text Color** | Change the color of text content within the PDF. |
|
||||
| **Fill Forms** | Fill out PDF forms directly in your browser. |
|
||||
| **Flatten PDF** | Flatten form fields and annotations into static content. |
|
||||
| **Remove Annotations** | Remove comments, highlights, and other annotations. |
|
||||
| **Remove Blank Pages** | Auto detect and remove blank pages in a PDF. |
|
||||
@@ -124,20 +172,41 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs.
|
||||
|
||||
### Convert to PDF
|
||||
|
||||
| Tool Name | Description |
|
||||
| :------------------ | :-------------------------------------------------------------- |
|
||||
| **Image to PDF** | Convert JPG, PNG, WebP, SVG, BMP, HEIC, and TIFF images to PDF. |
|
||||
| **JPG to PDF** | Convert JPG images to PDF. |
|
||||
| **PNG to PDF** | Convert PNG images to PDF. |
|
||||
| **WebP to PDF** | Convert WebP images to PDF. |
|
||||
| **SVG to PDF** | Convert SVG images to PDF. |
|
||||
| **BMP to PDF** | Convert BMP images to PDF. |
|
||||
| **HEIC to PDF** | Convert HEIC images to PDF. |
|
||||
| **TIFF to PDF** | Convert TIFF images to PDF. |
|
||||
| **Markdown to PDF** | Convert `.md` files into professional PDF documents. |
|
||||
| **Text to PDF** | Convert plain text files into a PDF. |
|
||||
| **EPUB to PDF** | Convert EPUB e-books to PDF format. |
|
||||
| **JSON to PDF** | Convert JSON to PDF. |
|
||||
| Tool Name | Description |
|
||||
| :-------------------- | :----------------------------------------------------------------------------------------------------- |
|
||||
| **Image to PDF** | Convert JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2, PSD, SVG, HEIC, WebP to PDF. |
|
||||
| **JPG to PDF** | Convert JPG, JPEG, and JPEG2000 (JP2/JPX) images to PDF. |
|
||||
| **PNG to PDF** | Convert PNG images to PDF. |
|
||||
| **WebP to PDF** | Convert WebP images to PDF. |
|
||||
| **SVG to PDF** | Convert SVG images to PDF. |
|
||||
| **BMP to PDF** | Convert BMP images to PDF. |
|
||||
| **HEIC to PDF** | Convert HEIC images to PDF. |
|
||||
| **TIFF to PDF** | Convert TIFF images to PDF. |
|
||||
| **PSD to PDF** | Convert Adobe Photoshop (PSD) files to PDF. |
|
||||
| **Word to PDF** | Convert Word documents (DOCX, DOC, ODT, RTF) to PDF. |
|
||||
| **Excel to PDF** | Convert Excel spreadsheets (XLSX, XLS, ODS, CSV) to PDF. |
|
||||
| **PowerPoint to PDF** | Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF. |
|
||||
| **ODT to PDF** | Convert OpenDocument Text files to PDF. |
|
||||
| **ODS to PDF** | Convert OpenDocument Spreadsheet (ODS) files to PDF. |
|
||||
| **ODP to PDF** | Convert OpenDocument Presentation (ODP) files to PDF. |
|
||||
| **ODG to PDF** | Convert OpenDocument Graphics (ODG) files to PDF. |
|
||||
| **RTF to PDF** | Convert Rich Text Format documents to PDF. |
|
||||
| **CSV to PDF** | Convert CSV spreadsheet files to PDF. |
|
||||
| **Markdown to PDF** | Write or paste Markdown and export it as a beautifully formatted PDF. |
|
||||
| **Text to PDF** | Convert plain text files into a PDF. |
|
||||
| **JSON to PDF** | Convert JSON files to PDF. |
|
||||
| **XML to PDF** | Convert XML documents to PDF. |
|
||||
| **EPUB to PDF** | Convert EPUB e-books to PDF. |
|
||||
| **MOBI to PDF** | Convert MOBI e-books to PDF. |
|
||||
| **FB2 to PDF** | Convert FictionBook (FB2) e-books to PDF. |
|
||||
| **CBZ to PDF** | Convert comic book archives (CBZ/CBR) to PDF. |
|
||||
| **XPS to PDF** | Convert XPS/OXPS documents to PDF. |
|
||||
| **Email to PDF** | Convert email files (EML, MSG) to PDF. Supports Outlook exports. |
|
||||
| **Pages to PDF** | Convert Apple Pages documents to PDF. |
|
||||
| **WPD to PDF** | Convert WordPerfect documents (WPD) to PDF. |
|
||||
| **WPS to PDF** | Convert WPS Office documents to PDF. |
|
||||
| **PUB to PDF** | Convert Microsoft Publisher (PUB) files to PDF. |
|
||||
| **VSD to PDF** | Convert Microsoft Visio (VSD, VSDX) files to PDF. |
|
||||
|
||||
### Convert from PDF
|
||||
|
||||
@@ -149,30 +218,35 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs.
|
||||
| **PDF to WebP** | Convert each PDF page into a WebP image. |
|
||||
| **PDF to BMP** | Convert each PDF page into a BMP image. |
|
||||
| **PDF to TIFF** | Convert each PDF page into a TIFF image. |
|
||||
| **PDF to SVG** | Convert each page into a scalable vector graphic (SVG) for perfect quality. |
|
||||
| **PDF to Greyscale** | Convert a color PDF into a black-and-white version. |
|
||||
| **OCR PDF** | Make scanned PDFs searchable and copyable using Optical Character Recognition. |
|
||||
| **PDF to Text** | Extract text from PDF files and save as plain text (.txt). |
|
||||
| **PDF to JSON** | Convert PDF files to JSON format. |
|
||||
| **PDF to CSV** | Extract tables from PDF and convert to CSV format. |
|
||||
| **PDF to Excel** | Extract tables from PDF and convert to Excel (XLSX) format. |
|
||||
| **Extract Tables** | Extract tables from PDF files and export as CSV, JSON, or Markdown. |
|
||||
| **OCR PDF** | Make scanned PDFs searchable and copyable using Optical Character Recognition. |
|
||||
|
||||
### Secure & Optimize PDFs
|
||||
|
||||
| Tool Name | Description |
|
||||
| :---------------------- | :----------------------------------------------------------------------------------------------- |
|
||||
| **Compress PDF** | Reduce file size while maintaining quality. |
|
||||
| **Repair PDF** | Attempt to repair and recover data from a corrupted PDF. |
|
||||
| **Encrypt PDF** | Add a password to protect your PDF from unauthorized access. |
|
||||
| **Decrypt PDF** | Remove password protection from a PDF (password required). |
|
||||
| **Change Permissions** | Set or modify user permissions for printing, copying, and editing. |
|
||||
| **Sign PDF** | Add your digital signature to a document. |
|
||||
| **Digital Signature** | Add cryptographic digital signatures using X.509 certificates (PFX/PEM). |
|
||||
| **Validate Signature** | Verify digital signatures and view certificate details. |
|
||||
| **Redact Content** | Permanently remove sensitive content from your PDFs. |
|
||||
| **Edit Metadata** | View and modify PDF metadata (author, title, keywords, etc.). |
|
||||
| **Remove Metadata** | Strip all metadata from your PDF for privacy. |
|
||||
| **Linearize PDF** | Optimize PDF for fast web view. |
|
||||
| **Sanitize PDF** | Remove potentially unwanted or malicous files from PDF. |
|
||||
| **Fix Page Size** | Standardize all pages to a uniform size. |
|
||||
| **Page Dimensions** | Analyze page size, orientation, and units. |
|
||||
| **Remove Restrictions** | Remove password protection and security restrictions associated with digitally signed PDF files. |
|
||||
| Tool Name | Description |
|
||||
| :---------------------- | :--------------------------------------------------------------------------------------------------------- |
|
||||
| **Compress PDF** | Reduce file size while maintaining quality. |
|
||||
| **Repair PDF** | Attempt to repair and recover data from a corrupted PDF. |
|
||||
| **Encrypt PDF** | Add a password to protect your PDF from unauthorized access. |
|
||||
| **Decrypt PDF** | Remove password protection from a PDF (password required). |
|
||||
| **Change Permissions** | Set or modify user permissions for printing, copying, and editing. |
|
||||
| **Sign PDF** | Draw, type, or upload your signature. |
|
||||
| **Digital Signature** | Add cryptographic digital signatures using X.509 certificates (PFX/PEM). Private key never leaves browser. |
|
||||
| **Validate Signature** | Verify digital signatures, check certificate validity, and confirm document integrity. |
|
||||
| **Redact Content** | Permanently remove sensitive content from your PDFs. |
|
||||
| **Edit Metadata** | View and modify PDF metadata (author, title, keywords, etc.). |
|
||||
| **Remove Metadata** | Strip all metadata from your PDF for privacy. |
|
||||
| **Linearize PDF** | Optimize PDF for fast web viewing. |
|
||||
| **Sanitize PDF** | Remove metadata, annotations, scripts, and more. |
|
||||
| **Fix Page Size** | Standardize all pages to a uniform size. |
|
||||
| **Page Dimensions** | Analyze page size, orientation, and units. |
|
||||
| **Remove Restrictions** | Remove password protection and security restrictions associated with digitally signed PDF files. |
|
||||
|
||||
---
|
||||
|
||||
@@ -207,22 +281,9 @@ You can run BentoPDF locally for development or personal use.
|
||||
- [npm](https://www.npmjs.com/) (or yarn/pnpm)
|
||||
- [Docker](https://www.docker.com/) & [Docker Compose](https://docs.docker.com/compose/install/) (for containerized setup)
|
||||
|
||||
### 🚀 Quick Start with Docker
|
||||
### 🚀 Quick Start
|
||||
|
||||
[](https://zeabur.com/templates/K4AU2B)
|
||||
|
||||
You can run BentoPDF directly from Docker Hub or GitHub Container Registry without cloning the repository:
|
||||
|
||||
You can also watch the video on how to set it up 👉
|
||||
[BentoPDF Docker Setup](https://drive.google.com/file/d/1C4eJ2nqeaH__1Tlad-xuBHaF2Ha4fSBf/view?usp=drive_link)
|
||||
|
||||
**Using Docker Hub:**
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 bentopdf/bentopdf:latest
|
||||
```
|
||||
|
||||
**Using GitHub Container Registry:**
|
||||
Run BentoPDF instantly from GitHub Container Registry (Recommended):
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
@@ -230,11 +291,34 @@ docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
|
||||
Open your browser at: http://localhost:3000
|
||||
|
||||
This is the fastest way to try BentoPDF without setting up a development environment.
|
||||
<details>
|
||||
<summary><b>Alternative: Using Docker Hub or Podman</b></summary>
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 bentopdfteam/bentopdf:latest
|
||||
```
|
||||
|
||||
**Podman (GHCR):**
|
||||
|
||||
```bash
|
||||
podman run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
```
|
||||
|
||||
**Podman (Docker Hub):**
|
||||
|
||||
```bash
|
||||
podman run -p 3000:8080 docker.io/bentopdfteam/bentopdf:latest
|
||||
```
|
||||
|
||||
> **Note:** All `docker` commands in this documentation work with Podman by replacing `docker` with `podman`.
|
||||
|
||||
</details>
|
||||
|
||||
### Static Hosting using Netlify, Vercel, and GitHub Pages
|
||||
|
||||
It is very straightforward to host your own instance of BentoPDF using a static web page hosting service. Plus, services such as Netlify, Vercel, and GitHub Pages all offer a free tier for getting started. See [Static Hosting](https://github.com/alam00000/bentopdf/blob/main/STATIC-HOSTING.md)) for details.
|
||||
It is very straightforward to host your own instance of BentoPDF using a static web page hosting service. Plus, services such as Netlify, Vercel, and GitHub Pages all offer a free tier for getting started. See [Static Hosting](https://github.com/alam00000/bentopdf/blob/main/STATIC-HOSTING.md) for details.
|
||||
|
||||
### 🏠 Self-Hosting Locally
|
||||
|
||||
@@ -391,7 +475,7 @@ docker run -p 3000:8080 bentopdf-simple
|
||||
> - Always include trailing slashes in `BASE_URL` (e.g., `/bentopdf/` not `/bentopdf`)
|
||||
> - The default value is `/` for root deployment
|
||||
|
||||
### 🚀 Run with Docker Compose (Recommended)
|
||||
### 🚀 Run with Docker Compose / Podman Compose (Recommended)
|
||||
|
||||
For a more robust setup with auto-restart capabilities:
|
||||
|
||||
@@ -400,7 +484,8 @@ For a more robust setup with auto-restart capabilities:
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
image: bentopdf/bentopdf:latest
|
||||
image: ghcr.io/alam00000/bentopdf:latest # Recommended
|
||||
# image: bentopdfteam/bentopdf:latest # Alternative: Docker Hub
|
||||
container_name: bentopdf
|
||||
ports:
|
||||
- '3000:8080'
|
||||
@@ -410,11 +495,48 @@ services:
|
||||
2. **Start the application**:
|
||||
|
||||
```bash
|
||||
# Docker Compose
|
||||
docker-compose up -d
|
||||
|
||||
# Podman Compose
|
||||
podman-compose up -d
|
||||
```
|
||||
|
||||
The application will be available at `http://localhost:3000`.
|
||||
|
||||
### 🐧 Podman Quadlet (Systemd Integration)
|
||||
|
||||
For Linux production deployments, you can run BentoPDF as a systemd service using [Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html).
|
||||
|
||||
Create `~/.config/containers/systemd/bentopdf.container`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF - Privacy-first PDF toolkit
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Then enable and start:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now bentopdf
|
||||
```
|
||||
|
||||
For detailed Quadlet configuration, see [Self-Hosting Docker Guide](https://bentopdf.com/docs/self-hosting/docker).
|
||||
|
||||
### 🏢 Simple Mode for Internal Use
|
||||
|
||||
For organizations that want a clean, distraction-free interface focused solely on PDF tools, BentoPDF supports a **Simple Mode** that hides all branding and marketing content.
|
||||
@@ -534,20 +656,20 @@ VITE_CORS_PROXY_SECRET=your-secret npm run build
|
||||
|
||||
### 📦 Version Management
|
||||
|
||||
BentoPDF supports semantic versioning with multiple Docker tags available on both Docker Hub and GitHub Container Registry:
|
||||
BentoPDF supports semantic versioning with multiple container tags available:
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
- **Latest**: `bentopdf/bentopdf:latest`
|
||||
- **Specific Version**: `bentopdf/bentopdf:1.0.0`
|
||||
- **Version with Prefix**: `bentopdf/bentopdf:v1.0.0`
|
||||
|
||||
**GitHub Container Registry:**
|
||||
**GitHub Container Registry (Recommended):**
|
||||
|
||||
- **Latest**: `ghcr.io/alam00000/bentopdf:latest`
|
||||
- **Specific Version**: `ghcr.io/alam00000/bentopdf:1.0.0`
|
||||
- **Version with Prefix**: `ghcr.io/alam00000/bentopdf:v1.0.0`
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
- **Latest**: `bentopdfteam/bentopdf:latest`
|
||||
- **Specific Version**: `bentopdfteam/bentopdf:1.0.0`
|
||||
- **Version with Prefix**: `bentopdfteam/bentopdf:v1.0.0`
|
||||
|
||||
#### Quick Release
|
||||
|
||||
```bash
|
||||
|
||||
+4
-4
@@ -215,16 +215,16 @@ git reset --hard HEAD~1
|
||||
1. **GitHub Actions Triggered**: Workflow starts building Docker image
|
||||
2. **Docker Build**: Multi-architecture image created
|
||||
3. **Docker Push**: Images pushed to Docker Hub with tags:
|
||||
- `bentopdf/bentopdf:latest`
|
||||
- `bentopdf/bentopdf:1.0.1`
|
||||
- `bentopdf/bentopdf:v1.0.1`
|
||||
- `bentopdfteam/bentopdf:latest`
|
||||
- `bentopdfteam/bentopdf:1.0.1`
|
||||
- `bentopdfteam/bentopdf:v1.0.1`
|
||||
|
||||
### **End Result:**
|
||||
|
||||
Users can immediately pull your new version:
|
||||
|
||||
```bash
|
||||
docker pull bentopdf/bentopdf:1.0.1
|
||||
docker pull bentopdfteam/bentopdf:1.0.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+79
-35
@@ -23,27 +23,35 @@ When enabled, Simple Mode will:
|
||||
|
||||
Use the pre-built Simple Mode image directly:
|
||||
|
||||
**Using GitHub Container Registry (Recommended):**
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Podman
|
||||
podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
**Using Docker Hub:**
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest
|
||||
# Docker
|
||||
docker run -p 3000:8080 bentopdfteam/bentopdf-simple:latest
|
||||
|
||||
# Podman
|
||||
podman run -p 3000:8080 docker.io/bentopdfteam/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
**Using GitHub Container Registry:**
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
Or with Docker Compose:
|
||||
Or with Docker Compose / Podman Compose:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
# Using Docker Hub
|
||||
image: bentopdf/bentopdf-simple:latest
|
||||
# Or using GitHub Container Registry
|
||||
# image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
# Using GitHub Container Registry (Recommended)
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
# Or using Docker Hub
|
||||
# image: bentopdfteam/bentopdf-simple:latest
|
||||
container_name: bentopdf
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
@@ -105,9 +113,13 @@ This automatically builds and serves Simple Mode on `http://localhost:3000`.
|
||||
### Method 2: Using Pre-built Image (Easiest for Production)
|
||||
|
||||
```bash
|
||||
# Pull and run the Simple Mode image
|
||||
docker pull bentopdf/bentopdf-simple:latest
|
||||
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest
|
||||
# Docker - Pull and run the Simple Mode image
|
||||
docker pull ghcr.io/alam00000/bentopdf-simple:latest
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Podman
|
||||
podman pull ghcr.io/alam00000/bentopdf-simple:latest
|
||||
podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
Open `http://localhost:3000` in your browser.
|
||||
@@ -127,11 +139,13 @@ Open `http://localhost:3000` in your browser.
|
||||
### Method 4: Compare Both Modes
|
||||
|
||||
```bash
|
||||
# Test Normal Mode
|
||||
docker run -p 3000:8080 bentopdf/bentopdf:latest
|
||||
# Test Normal Mode (Docker)
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
|
||||
# Test Simple Mode
|
||||
docker run -p 3001:8080 bentopdf/bentopdf-simple:latest
|
||||
# Test Simple Mode (Docker)
|
||||
docker run -p 3001:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Podman users: replace 'docker' with 'podman'
|
||||
```
|
||||
|
||||
- Normal Mode: `http://localhost:3000`
|
||||
@@ -149,52 +163,82 @@ When Simple Mode is working correctly, you should see:
|
||||
- ❌ No hero section with "The PDF Toolkit built for privacy"
|
||||
- ❌ No features, FAQ, testimonials, or footer sections
|
||||
|
||||
## 📦 Available Docker Images
|
||||
## 📦 Available Container Images
|
||||
|
||||
### Normal Mode (Full Branding)
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
- `bentopdf/bentopdf:latest`
|
||||
- `bentopdf/bentopdf:v1.0.0` (versioned)
|
||||
|
||||
**GitHub Container Registry:**
|
||||
**GitHub Container Registry (Recommended):**
|
||||
|
||||
- `ghcr.io/alam00000/bentopdf:latest`
|
||||
- `ghcr.io/alam00000/bentopdf:v1.0.0` (versioned)
|
||||
|
||||
### Simple Mode (Clean Interface)
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
- `bentopdf/bentopdf-simple:latest`
|
||||
- `bentopdf/bentopdf-simple:v1.0.0` (versioned)
|
||||
- `bentopdfteam/bentopdf:latest`
|
||||
- `bentopdfteam/bentopdf:v1.0.0` (versioned)
|
||||
|
||||
**GitHub Container Registry:**
|
||||
### Simple Mode (Clean Interface)
|
||||
|
||||
**GitHub Container Registry (Recommended):**
|
||||
|
||||
- `ghcr.io/alam00000/bentopdf-simple:latest`
|
||||
- `ghcr.io/alam00000/bentopdf-simple:v1.0.0` (versioned)
|
||||
|
||||
**Docker Hub:**
|
||||
|
||||
- `bentopdfteam/bentopdf-simple:latest`
|
||||
- `bentopdfteam/bentopdf-simple:v1.0.0` (versioned)
|
||||
|
||||
## 🚀 Production Deployment Examples
|
||||
|
||||
### Internal Company Tool
|
||||
### Docker Compose / Podman Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
image: bentopdf/bentopdf-simple:latest
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest # Recommended
|
||||
# image: bentopdfteam/bentopdf-simple:latest # Alternative: Docker Hub
|
||||
container_name: bentopdf
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '80:80'
|
||||
- '80:8080'
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
```
|
||||
|
||||
### Podman Quadlet (Linux Systemd)
|
||||
|
||||
Create `~/.config/containers/systemd/bentopdf-simple.container`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF Simple Mode
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ContainerName=bentopdf-simple
|
||||
PublishPort=80:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now bentopdf-simple
|
||||
```
|
||||
|
||||
## ⚠️ Important Notes
|
||||
|
||||
- **Pre-built images**: Use `bentopdf/bentopdf-simple:latest` for Simple Mode
|
||||
- **Pre-built images**: Use `ghcr.io/alam00000/bentopdf-simple:latest` for Simple Mode (recommended)
|
||||
- **Environment variables**: `SIMPLE_MODE=true` only works during build, not runtime
|
||||
- **Build-time optimization**: Simple Mode uses dead code elimination for smaller bundles
|
||||
- **Same functionality**: All PDF tools work identically in both modes
|
||||
|
||||
+7
-3
@@ -1,8 +1,12 @@
|
||||
services:
|
||||
bentopdf:
|
||||
# simple mode - bentopdf/bentopdf-simple:latest
|
||||
# default mode - bentopdf/bentopdf:latest
|
||||
image: bentopdf/bentopdf-simple:latest
|
||||
# GitHub Container Registry (Recommended)
|
||||
# simple mode - ghcr.io/alam00000/bentopdf-simple:latest
|
||||
# default mode - ghcr.io/alam00000/bentopdf:latest
|
||||
# Docker Hub (Alternative)
|
||||
# simple mode - bentopdfteam/bentopdf-simple:latest
|
||||
# default mode - bentopdfteam/bentopdf:latest
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
container_name: bentopdf
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
|
||||
+179
-29
@@ -1,27 +1,38 @@
|
||||
# Deploy with Docker
|
||||
# Deploy with Docker / Podman
|
||||
|
||||
The easiest way to self-host BentoPDF in a production environment.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Required Headers for Office File Conversion**
|
||||
>
|
||||
>
|
||||
> LibreOffice-based tools (Word, Excel, PowerPoint conversion) require these HTTP headers for `SharedArrayBuffer` support:
|
||||
>
|
||||
> - `Cross-Origin-Opener-Policy: same-origin`
|
||||
> - `Cross-Origin-Embedder-Policy: require-corp`
|
||||
>
|
||||
> The official Docker images include these headers. If using a reverse proxy (Traefik, Caddy, etc.), ensure these headers are preserved or added.
|
||||
>
|
||||
> The official container images include these headers. If using a reverse proxy (Traefik, Caddy, etc.), ensure these headers are preserved or added.
|
||||
|
||||
> [!TIP]
|
||||
> **Podman Users:** All `docker` commands work with Podman by replacing `docker` with `podman` and `docker-compose` with `podman-compose`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -d \
|
||||
--name bentopdf \
|
||||
-p 3000:8080 \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/alam00000/bentopdf:latest
|
||||
|
||||
# Podman
|
||||
podman run -d \
|
||||
--name bentopdf \
|
||||
-p 3000:8080 \
|
||||
ghcr.io/alam00000/bentopdf:latest
|
||||
```
|
||||
|
||||
## Docker Compose
|
||||
## Docker Compose / Podman Compose
|
||||
|
||||
Create `docker-compose.yml`:
|
||||
|
||||
@@ -31,10 +42,10 @@ services:
|
||||
image: ghcr.io/alam00000/bentopdf:latest
|
||||
container_name: bentopdf
|
||||
ports:
|
||||
- "3000:8080"
|
||||
- '3000:8080'
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080"]
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:8080']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -43,7 +54,11 @@ services:
|
||||
Run:
|
||||
|
||||
```bash
|
||||
# Docker Compose
|
||||
docker compose up -d
|
||||
|
||||
# Podman Compose
|
||||
podman-compose up -d
|
||||
```
|
||||
|
||||
## Build Your Own Image
|
||||
@@ -73,10 +88,10 @@ docker run -d -p 3000:8080 bentopdf:custom
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| Variable | Description | Default |
|
||||
| ------------- | ------------------------------- | ------- |
|
||||
| `SIMPLE_MODE` | Build without LibreOffice tools | `false` |
|
||||
| `BASE_URL` | Deploy to subdirectory | `/` |
|
||||
| `BASE_URL` | Deploy to subdirectory | `/` |
|
||||
|
||||
Example:
|
||||
|
||||
@@ -94,15 +109,15 @@ services:
|
||||
traefik:
|
||||
image: traefik:v2.10
|
||||
command:
|
||||
- "--providers.docker=true"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "[email protected]"
|
||||
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
|
||||
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
|
||||
- '--providers.docker=true'
|
||||
- '--entrypoints.web.address=:80'
|
||||
- '--entrypoints.websecure.address=:443'
|
||||
- '[email protected]'
|
||||
- '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'
|
||||
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web'
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./letsencrypt:/letsencrypt
|
||||
@@ -110,15 +125,15 @@ services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf:latest
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.bentopdf.rule=Host(`pdf.example.com`)"
|
||||
- "traefik.http.routers.bentopdf.entrypoints=websecure"
|
||||
- "traefik.http.routers.bentopdf.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.bentopdf.loadbalancer.server.port=8080"
|
||||
- 'traefik.enable=true'
|
||||
- 'traefik.http.routers.bentopdf.rule=Host(`pdf.example.com`)'
|
||||
- 'traefik.http.routers.bentopdf.entrypoints=websecure'
|
||||
- 'traefik.http.routers.bentopdf.tls.certresolver=letsencrypt'
|
||||
- 'traefik.http.services.bentopdf.loadbalancer.server.port=8080'
|
||||
# Required headers for SharedArrayBuffer (LibreOffice WASM)
|
||||
- "traefik.http.routers.bentopdf.middlewares=bentopdf-headers"
|
||||
- "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin"
|
||||
- "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp"
|
||||
- 'traefik.http.routers.bentopdf.middlewares=bentopdf-headers'
|
||||
- 'traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin'
|
||||
- 'traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp'
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
@@ -129,12 +144,12 @@ services:
|
||||
caddy:
|
||||
image: caddy:2
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
|
||||
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf:latest
|
||||
restart: unless-stopped
|
||||
@@ -169,6 +184,141 @@ services:
|
||||
memory: 128M
|
||||
```
|
||||
|
||||
## Podman Quadlet (Systemd Integration)
|
||||
|
||||
[Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) allows you to run Podman containers as systemd services. This is ideal for production deployments on Linux systems.
|
||||
|
||||
### Basic Quadlet Setup
|
||||
|
||||
Create a container unit file at `~/.config/containers/systemd/bentopdf.container` (user) or `/etc/containers/systemd/bentopdf.container` (system):
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF - Privacy-first PDF toolkit
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
### Enable and Start
|
||||
|
||||
```bash
|
||||
# Reload systemd to detect new unit
|
||||
systemctl --user daemon-reload
|
||||
|
||||
# Start the service
|
||||
systemctl --user start bentopdf
|
||||
|
||||
# Enable on boot
|
||||
systemctl --user enable bentopdf
|
||||
|
||||
# Check status
|
||||
systemctl --user status bentopdf
|
||||
|
||||
# View logs
|
||||
journalctl --user -u bentopdf -f
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> For system-wide deployment, use `systemctl` without `--user` flag and place the file in `/etc/containers/systemd/`.
|
||||
|
||||
### Simple Mode Quadlet
|
||||
|
||||
For Simple Mode deployment, create `bentopdf-simple.container`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF Simple Mode - Clean PDF toolkit
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ContainerName=bentopdf-simple
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
### Quadlet with Health Check
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF with health monitoring
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
HealthCmd=curl -f http://localhost:8080 || exit 1
|
||||
HealthInterval=30s
|
||||
HealthTimeout=10s
|
||||
HealthRetries=3
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
### Auto-Update with Quadlet
|
||||
|
||||
Podman can automatically update containers when new images are available:
|
||||
|
||||
```bash
|
||||
# Enable auto-update timer
|
||||
systemctl --user enable --now podman-auto-update.timer
|
||||
|
||||
# Check for updates manually
|
||||
podman auto-update
|
||||
|
||||
# Dry run (check without updating)
|
||||
podman auto-update --dry-run
|
||||
```
|
||||
|
||||
### Quadlet Network Configuration
|
||||
|
||||
For custom network configuration, create a network file `bentopdf.network`:
|
||||
|
||||
```ini
|
||||
[Network]
|
||||
Subnet=10.89.0.0/24
|
||||
Gateway=10.89.0.1
|
||||
```
|
||||
|
||||
Then reference it in your container file:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
Network=bentopdf.network
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
BentoPDF can be self-hosted on your own infrastructure. This guide covers various deployment options.
|
||||
|
||||
## Quick Start with Docker
|
||||
## Quick Start with Docker / Podman
|
||||
|
||||
The fastest way to self-host BentoPDF:
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -d -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
|
||||
# Podman
|
||||
podman run -d -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
```
|
||||
|
||||
Or with Docker Compose:
|
||||
Or with Docker Compose / Podman Compose:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
@@ -18,14 +22,43 @@ services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf:latest
|
||||
ports:
|
||||
- "3000:8080"
|
||||
- '3000:8080'
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
```bash
|
||||
# Docker Compose
|
||||
docker compose up -d
|
||||
|
||||
# Podman Compose
|
||||
podman-compose up -d
|
||||
```
|
||||
|
||||
## Podman Quadlet (Linux Systemd)
|
||||
|
||||
Run BentoPDF as a systemd service. Create `~/.config/containers/systemd/bentopdf.container`:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now bentopdf
|
||||
```
|
||||
|
||||
See [Docker deployment guide](/self-hosting/docker) for full Quadlet documentation.
|
||||
|
||||
## Building from Source
|
||||
|
||||
```bash
|
||||
@@ -45,6 +78,7 @@ npm run build
|
||||
Simple Mode is designed for internal organizational use where you want to hide all branding and marketing content, showing only the essential PDF tools.
|
||||
|
||||
**What Simple Mode hides:**
|
||||
|
||||
- Navigation bar
|
||||
- Hero section with marketing content
|
||||
- Features, FAQ, testimonials sections
|
||||
@@ -56,7 +90,7 @@ Simple Mode is designed for internal organizational use where you want to hide a
|
||||
SIMPLE_MODE=true npm run build
|
||||
|
||||
# Or use the pre-built Docker image
|
||||
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest
|
||||
docker run -p 3000:8080 bentopdfteam/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
See [SIMPLE_MODE.md](https://github.com/alam00000/bentopdf/blob/main/SIMPLE_MODE.md) for full details.
|
||||
@@ -85,11 +119,11 @@ Choose your platform:
|
||||
|
||||
## System Requirements
|
||||
|
||||
| Requirement | Minimum |
|
||||
|-------------|---------|
|
||||
| Storage | ~500 MB (with all WASM modules) |
|
||||
| RAM | 512 MB |
|
||||
| CPU | Any modern processor |
|
||||
| Requirement | Minimum |
|
||||
| ----------- | ------------------------------- |
|
||||
| Storage | ~500 MB (with all WASM modules) |
|
||||
| RAM | 512 MB |
|
||||
| CPU | Any modern processor |
|
||||
|
||||
::: tip
|
||||
BentoPDF is a static site—there's no database or backend server required!
|
||||
|
||||
+203
-81
@@ -94,6 +94,131 @@
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Prominent Pricing Section -->
|
||||
<section id="pricing-hero" class="py-12 max-w-3xl mx-auto">
|
||||
<div class="bg-gray-900 rounded-2xl p-8 md:p-10 border border-gray-700">
|
||||
<!-- Badge -->
|
||||
<span
|
||||
class="inline-block bg-indigo-500 text-white text-xs font-bold px-4 py-1.5 rounded-full mb-6"
|
||||
>
|
||||
LIFETIME LICENSE
|
||||
</span>
|
||||
|
||||
<!-- Title -->
|
||||
<h2 class="text-3xl md:text-4xl font-bold text-white mb-6">
|
||||
Commercial License
|
||||
</h2>
|
||||
|
||||
<!-- Divider -->
|
||||
<div class="border-t border-gray-700 mb-8"></div>
|
||||
|
||||
<!-- Features Grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4 mb-8">
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Proprietary Use</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Unlimited Devices</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Enterprise Support</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Unlimited Users</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Early Access Features</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Lifetime Updates</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">No AGPL Obligations</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-6 h-6 rounded-full bg-indigo-500/20 flex items-center justify-center flex-shrink-0"
|
||||
>
|
||||
<i data-lucide="check" class="w-4 h-4 text-indigo-400"></i>
|
||||
</div>
|
||||
<span class="text-gray-200">Flexible Terms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Divider -->
|
||||
<div class="border-t border-gray-700 mb-6"></div>
|
||||
|
||||
<!-- Price and CTA -->
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center justify-between gap-4"
|
||||
>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<span class="text-gray-500 text-xl line-through">$99</span>
|
||||
<span class="text-white text-4xl font-bold">$49</span>
|
||||
<span class="text-gray-400 text-lg"> one-time</span>
|
||||
</div>
|
||||
<a
|
||||
href="https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-2 px-8 py-3 rounded-full bg-indigo-500 text-white font-semibold hover:bg-indigo-400 transition-all duration-200 group"
|
||||
>
|
||||
Get License Now
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-transform group-hover:translate-x-1"
|
||||
>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="section-divider"></div>
|
||||
|
||||
<section id="licensing-options" class="py-16 max-w-6xl mx-auto">
|
||||
@@ -242,72 +367,31 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-8 bg-gradient-to-r from-indigo-900/40 to-purple-900/40 rounded-lg p-6 border border-indigo-500/50"
|
||||
<!-- CTA Button -->
|
||||
<a
|
||||
href="https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="mt-8 inline-flex items-center gap-2 px-8 py-3 rounded-full bg-indigo-500 text-white font-semibold hover:bg-indigo-400 transition-all duration-200 group"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div
|
||||
class="inline-block bg-red-500 text-white text-xs font-bold px-3 py-1 rounded-full mb-3 animate-pulse"
|
||||
>
|
||||
LIMITED TIME OFFER
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold mb-2">
|
||||
Lifetime License
|
||||
</p>
|
||||
<div class="flex items-center justify-center gap-3 mb-3">
|
||||
<span class="text-gray-400 text-2xl line-through">$99</span>
|
||||
<span class="text-indigo-300 text-4xl font-bold">$49</span>
|
||||
<span class="text-lg font-normal text-gray-400"
|
||||
>one-time</span
|
||||
>
|
||||
</div>
|
||||
<p class="text-gray-300 text-sm mb-4">
|
||||
Includes all feature updates forever
|
||||
</p>
|
||||
|
||||
<!-- Unlimited Usage Info -->
|
||||
<div
|
||||
class="bg-indigo-900/30 rounded-lg p-4 mb-4 border border-indigo-500/30"
|
||||
>
|
||||
<div class="flex items-start gap-3 text-left">
|
||||
<i
|
||||
data-lucide="infinity"
|
||||
class="w-6 h-6 text-indigo-400 flex-shrink-0 mt-0.5"
|
||||
></i>
|
||||
<div>
|
||||
<h4 class="text-white font-semibold text-sm mb-2">
|
||||
Unlimited Usage
|
||||
</h4>
|
||||
<p class="text-gray-300 text-xs leading-relaxed">
|
||||
The BentoPDF commercial license permits use on an
|
||||
<strong class="text-white"
|
||||
>unrestricted, unlimited number of devices, servers,
|
||||
and user machines</strong
|
||||
>
|
||||
within your organization. There are
|
||||
<strong class="text-white"
|
||||
>no per-user, per-machine, or per-seat
|
||||
limitations</strong
|
||||
>. Once you purchase the license, all your internal
|
||||
users may use BentoPDF through your browser-based system
|
||||
without requiring additional licenses.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="https://ko-fi.com/s/f32ca4cb75"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-block px-8 py-3 rounded-lg bg-indigo-600 text-white font-semibold hover:bg-indigo-700 transition-colors shadow-lg hover:shadow-indigo-500/50 transform hover:scale-105 transition-all duration-200"
|
||||
>
|
||||
Purchase Lifetime License
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-4 text-sm text-gray-400 italic text-center">
|
||||
Get Commercial License
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-transform group-hover:translate-x-1"
|
||||
>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</a>
|
||||
<p class="mt-4 text-sm text-gray-400 italic">
|
||||
💡 Custom requests and development are available for separate
|
||||
charges.
|
||||
<a href="contact.html" class="text-indigo-400 hover:underline"
|
||||
@@ -468,6 +552,29 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-8 text-center">
|
||||
<a
|
||||
href="https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center gap-2 px-8 py-3 rounded-full bg-indigo-500 text-white font-semibold hover:bg-indigo-400 transition-all duration-200 group mb-4"
|
||||
>
|
||||
Get Commercial License - $49
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-transform group-hover:translate-x-1"
|
||||
>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</a>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Still not sure?
|
||||
<a
|
||||
@@ -791,8 +898,10 @@
|
||||
BentoPDF is available under a lifetime, one-time purchase
|
||||
commercial license. You can purchase it directly here:
|
||||
<a
|
||||
href="https://ko-fi.com/s/f32ca4cb75"
|
||||
class="text-indigo-400 hover:underline"
|
||||
href="https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-indigo-400 hover:underline font-semibold"
|
||||
>Buy Commercial License</a
|
||||
>. <br /><br />
|
||||
If you have specific requirements or want a custom licensing
|
||||
@@ -956,10 +1065,17 @@
|
||||
<ul class="space-y-3 text-gray-400">
|
||||
<li class="flex items-start gap-3">
|
||||
<i
|
||||
data-lucide="info"
|
||||
class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5"
|
||||
data-lucide="check-circle"
|
||||
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
|
||||
></i>
|
||||
<span>Ko-fi does not automatically issue invoices.</span>
|
||||
<span
|
||||
>We use <strong class="text-white">Polar</strong> for
|
||||
payments, which
|
||||
<strong class="text-white"
|
||||
>automatically sends invoices</strong
|
||||
>
|
||||
via email after purchase.</span
|
||||
>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<i
|
||||
@@ -967,20 +1083,26 @@
|
||||
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
|
||||
></i>
|
||||
<span
|
||||
>An official invoice will be provided immediately upon
|
||||
request.</span
|
||||
>Polar handles
|
||||
<strong class="text-white">VAT invoices</strong> for
|
||||
businesses in applicable regions.</span
|
||||
>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<i
|
||||
data-lucide="info"
|
||||
class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5"
|
||||
></i>
|
||||
<span
|
||||
>For VAT invoices, select
|
||||
<strong class="text-white"
|
||||
>"I'm purchasing as a business"</strong
|
||||
>
|
||||
during checkout and enter your billing address and Tax/VAT
|
||||
number.</span
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="mt-4 text-gray-300">
|
||||
<strong class="text-white">Contact us:</strong>
|
||||
<a
|
||||
href="mailto:[email protected]"
|
||||
class="text-indigo-400 hover:underline"
|
||||
>[email protected]</a
|
||||
>
|
||||
with your purchase details.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "bento-pdf",
|
||||
"private": true,
|
||||
"version": "1.16.0",
|
||||
"version": "1.16.1",
|
||||
"license": "AGPL-3.0-only",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
+4
-2
@@ -80,7 +80,9 @@ function main() {
|
||||
execSync('npm run update-version', { stdio: 'inherit' });
|
||||
|
||||
// 3. Add and commit changes
|
||||
execSync('git add package.json *.html src/pages/*.html', { stdio: 'inherit' });
|
||||
execSync('git add package.json *.html src/pages/*.html', {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
execSync(`git commit -m "Release v${newVersion}"`, { stdio: 'inherit' });
|
||||
console.log(`💾 Committed version change`);
|
||||
|
||||
@@ -98,7 +100,7 @@ function main() {
|
||||
execSync(`git push origin ${tagName}`, { stdio: 'inherit' });
|
||||
|
||||
console.log(`🎉 Release v${newVersion} complete!`);
|
||||
console.log(`📦 Docker image: bentopdf/bentopdf:${newVersion}`);
|
||||
console.log(`📦 Docker image: bentopdfteam/bentopdf:${newVersion}`);
|
||||
console.log(`📦 Distribution: dist-${newVersion}.zip`);
|
||||
console.log(
|
||||
`🏷️ GitHub release: https://github.com/alam00000/bentopdf/releases/tag/${tagName}`
|
||||
|
||||
@@ -255,6 +255,38 @@
|
||||
"created_at": "2026-01-11T10:30:42Z",
|
||||
"repoId": 1074785178,
|
||||
"pullRequestNo": 380
|
||||
},
|
||||
{
|
||||
"name": "sheing-google",
|
||||
"id": 231310897,
|
||||
"comment_id": 3751831626,
|
||||
"created_at": "2026-01-14T21:38:06Z",
|
||||
"repoId": 1074785178,
|
||||
"pullRequestNo": 386
|
||||
},
|
||||
{
|
||||
"name": "spwoodcock",
|
||||
"id": 78538841,
|
||||
"comment_id": 3754368312,
|
||||
"created_at": "2026-01-15T11:53:51Z",
|
||||
"repoId": 1074785178,
|
||||
"pullRequestNo": 388
|
||||
},
|
||||
{
|
||||
"name": "LoganK",
|
||||
"id": 1298025,
|
||||
"comment_id": 3767178117,
|
||||
"created_at": "2026-01-19T08:56:58Z",
|
||||
"repoId": 1074785178,
|
||||
"pullRequestNo": 405
|
||||
},
|
||||
{
|
||||
"name": "JaL-P",
|
||||
"id": 10429222,
|
||||
"comment_id": 3774929591,
|
||||
"created_at": "2026-01-20T21:00:39Z",
|
||||
"repoId": 1074785178,
|
||||
"pullRequestNo": 410
|
||||
}
|
||||
]
|
||||
}
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<Container version="2">
|
||||
<Name>bentopdf</Name>
|
||||
<Repository>bentopdf/bentopdf</Repository>
|
||||
<Registry>https://hub.docker.com/r/bentopdf/bentopdf/</Registry>
|
||||
<Repository>bentopdfteam/bentopdf</Repository>
|
||||
<Registry>https://hub.docker.com/r/bentopdfteam/bentopdf/</Registry>
|
||||
<Network>bridge</Network>
|
||||
<MyIP/>
|
||||
<Shell>sh</Shell>
|
||||
@@ -12,7 +12,7 @@
|
||||
<Overview>Uploaded on behalf of creator: alam00000
|
||||
BentoPDF is a privacy first PDF Toolkit
|
||||
|
||||
https://hub.docker.com/r/bentopdf/bentopdf/</Overview>
|
||||
https://hub.docker.com/r/bentopdfteam/bentopdf/</Overview>
|
||||
<Category>Tools:</Category>
|
||||
<WebUI>http://[IP]:[PORT:8080]/</WebUI>
|
||||
<TemplateURL/>
|
||||
|
||||
Reference in New Issue
Block a user