mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-12 01:33:36 +01:00
feat: translate all pages, UI messages and docs and fix SEO redirects and indexing
This commit is contained in:
1 parent
5e019de5ae
commit
4edb1718cc
3344 files changed
+415643
-4759
No files matched your search
@@ -0,0 +1,275 @@
|
||||
# Apache ile Dağıtım
|
||||
|
||||
BentoPDF'i Apache HTTP Server ile barındırın.
|
||||
|
||||
## Gereksinimler
|
||||
|
||||
- Apache 2.4+
|
||||
- mod_rewrite etkin
|
||||
- SSL sertifikası (önerilir)
|
||||
|
||||
## Adım 1: Projeyi Derleyin
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Markayı özelleştirmek için derlemeden önce ortam değişkenlerini ayarlayın:
|
||||
|
||||
```bash
|
||||
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
|
||||
```
|
||||
|
||||
## Adım 2: Dosyaları Kopyalayın
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /var/www/bentopdf
|
||||
sudo cp -r dist/* /var/www/bentopdf/
|
||||
sudo chown -R www-data:www-data /var/www/bentopdf
|
||||
```
|
||||
|
||||
## Adım 3: Apache Yapılandırması
|
||||
|
||||
`/etc/apache2/sites-available/bentopdf.conf` dosyasını oluşturun:
|
||||
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName your-domain.com
|
||||
Redirect permanent / https://your-domain.com/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName your-domain.com
|
||||
DocumentRoot /var/www/bentopdf
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
|
||||
|
||||
<Directory /var/www/bentopdf>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# WASM MIME type
|
||||
AddType application/wasm .wasm
|
||||
|
||||
# Prevent double-compression of pre-compressed files
|
||||
SetEnvIfNoCase Request_URI "\.gz$" no-gzip
|
||||
|
||||
# Compression
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json application/wasm
|
||||
</IfModule>
|
||||
|
||||
# Cache headers
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType application/javascript "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 year"
|
||||
ExpiresByType application/wasm "access plus 1 year"
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
</IfModule>
|
||||
|
||||
# Required headers for SharedArrayBuffer (LibreOffice WASM)
|
||||
Header always set Cross-Origin-Embedder-Policy "require-corp"
|
||||
Header always set Cross-Origin-Opener-Policy "same-origin"
|
||||
Header always set Cross-Origin-Resource-Policy "cross-origin"
|
||||
|
||||
# Security headers
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
|
||||
# Pre-compressed LibreOffice WASM files
|
||||
<FilesMatch "soffice\.wasm\.gz$">
|
||||
ForceType application/wasm
|
||||
Header set Content-Encoding "gzip"
|
||||
</FilesMatch>
|
||||
<FilesMatch "soffice\.data\.gz$">
|
||||
ForceType application/octet-stream
|
||||
Header set Content-Encoding "gzip"
|
||||
</FilesMatch>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
## Adım 4: Yönlendirme için .htaccess
|
||||
|
||||
`/var/www/bentopdf/.htaccess` dosyasını oluşturun:
|
||||
|
||||
```apache
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# Existing files/dirs - serve directly
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# ============================================
|
||||
# LANGUAGE ROUTES
|
||||
# ============================================
|
||||
# Supported languages: de, es, zh, zh-TW, vi, it, id, tr, fr, pt
|
||||
# English has no prefix - served from root
|
||||
|
||||
# English prefix redirects to root
|
||||
RewriteRule ^en/?$ / [R=301,L]
|
||||
RewriteRule ^en/(.+)$ /$1 [R=301,L]
|
||||
|
||||
# Language prefix root (e.g., /de/ -> /de/index.html)
|
||||
RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L]
|
||||
|
||||
# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html)
|
||||
RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L]
|
||||
|
||||
# ============================================
|
||||
# ADD .HTML EXTENSION (ROOT LEVEL)
|
||||
# ============================================
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME}.html -f
|
||||
RewriteRule ^([^/]+)$ $1.html [L]
|
||||
|
||||
ErrorDocument 404 /404.html
|
||||
```
|
||||
|
||||
## Adım 5: Gerekli Modülleri Etkinleştirin
|
||||
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod ssl
|
||||
sudo a2enmod headers
|
||||
sudo a2enmod expires
|
||||
sudo a2enmod deflate
|
||||
```
|
||||
|
||||
## Adım 6: Siteyi Etkinleştirin
|
||||
|
||||
```bash
|
||||
sudo a2ensite bentopdf.conf
|
||||
sudo apache2ctl configtest
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
## Alt Dizinde Dağıtım
|
||||
|
||||
`/pdf/` altında barındırmak için:
|
||||
|
||||
1. Temel URL ile derleyin:
|
||||
|
||||
```bash
|
||||
BASE_URL=/pdf/ npm run build
|
||||
```
|
||||
|
||||
2. `.htaccess` dosyasını güncelleyin:
|
||||
|
||||
```apache
|
||||
RewriteEngine On
|
||||
RewriteBase /pdf/
|
||||
|
||||
# Existing files/dirs - serve directly
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# Language routes
|
||||
RewriteRule ^en/?$ /pdf/ [R=301,L]
|
||||
RewriteRule ^en/(.+)$ /pdf/$1 [R=301,L]
|
||||
|
||||
RewriteCond %{DOCUMENT_ROOT}/pdf/$1/index.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /pdf/$1/index.html [L]
|
||||
|
||||
RewriteCond %{DOCUMENT_ROOT}/pdf/$1/$2.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /pdf/$1/$2.html [L]
|
||||
|
||||
# Root level .html extension
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME}.html -f
|
||||
RewriteRule ^([^/]+)$ $1.html [L]
|
||||
|
||||
ErrorDocument 404 /pdf/404.html
|
||||
```
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### WASM 404 Hataları
|
||||
|
||||
MIME türünün yapılandırıldığından emin olun:
|
||||
|
||||
```apache
|
||||
AddType application/wasm .wasm
|
||||
```
|
||||
|
||||
### PDF İmzala veya Form Doldurucu Boş Görüntüleyici Gösteriyor (`.mjs` MIME hatası)
|
||||
|
||||
Tarayıcı konsolunda şu görünüyorsa:
|
||||
|
||||
```
|
||||
Failed to load module script: The server responded with a non-JavaScript
|
||||
MIME type of "application/octet-stream". Strict MIME type checking is
|
||||
enforced for module scripts per HTML spec.
|
||||
```
|
||||
|
||||
...ve başarısız olan istek `.mjs` ile bitiyorsa, Apache yapılandırmanızda `.mjs → application/javascript` eşlemesi eksik demektir. Paketle gelen PDF görüntüleyici ES modül dosyalarını `.mjs` uzantısıyla sunar ve Apache'nin varsayılan `mime.types` dosyası bunları içermez.
|
||||
|
||||
VirtualHost veya `.htaccess` dosyanıza ekleyin:
|
||||
|
||||
```apache
|
||||
AddType application/javascript .mjs
|
||||
```
|
||||
|
||||
Ardından Apache'yi yeniden yükleyin:
|
||||
|
||||
```bash
|
||||
sudo apache2ctl configtest && sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
Doğrulamak için: tarayıcı DevTools → Network sekmesinde başarısız olan `.mjs` isteğini bulun ve `Content-Type` yanıt başlığına bakın. Artık `application/octet-stream` değil, `application/javascript` olmalıdır.
|
||||
|
||||
### Rewrite Çalışmıyor
|
||||
|
||||
mod_rewrite'ın etkin olduğunu kontrol edin:
|
||||
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
```
|
||||
|
||||
### Word/ODT/Excel'den PDF'e Dönüştürme Çalışmıyor
|
||||
|
||||
LibreOffice WASM, `SharedArrayBuffer` gerektirir ve bunun için şu başlıklar gerekir:
|
||||
|
||||
```apache
|
||||
Header always set Cross-Origin-Embedder-Policy "require-corp"
|
||||
Header always set Cross-Origin-Opener-Policy "same-origin"
|
||||
```
|
||||
|
||||
Ayrıca güvenli bir bağlam da gerekir. `http://localhost` yerel testler için çalışır, ancak `http://192.168.x.x` gibi yerel ağ IP'leri genellikle HTTPS gerektirir. Başlıklar mevcut olduğu halde `window.crossOriginIsolated` hâlâ `false` ise, sayfanın geri döngü olmayan bir kaynakta düz HTTP üzerinden açılıp açılmadığını kontrol edin.
|
||||
|
||||
Önceden sıkıştırılmış `.wasm.gz` ve `.data.gz` dosyaları da doğru `Content-Encoding` gerektirir:
|
||||
|
||||
```apache
|
||||
<FilesMatch "soffice\.wasm\.gz$">
|
||||
ForceType application/wasm
|
||||
Header set Content-Encoding "gzip"
|
||||
</FilesMatch>
|
||||
<FilesMatch "soffice\.data\.gz$">
|
||||
ForceType application/octet-stream
|
||||
Header set Content-Encoding "gzip"
|
||||
</FilesMatch>
|
||||
```
|
||||
|
||||
`mod_headers`'ın etkin olduğundan emin olun: `sudo a2enmod headers`
|
||||
|
||||
### İzin Reddedildi
|
||||
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/bentopdf
|
||||
sudo chmod -R 755 /var/www/bentopdf
|
||||
```
|
||||
@@ -0,0 +1,200 @@
|
||||
# AWS S3 + CloudFront'a Dağıtım
|
||||
|
||||
Azami kontrol ve ölçeklenebilirlik için BentoPDF'i AWS üzerinde barındırın.
|
||||
|
||||
## Mimari
|
||||
|
||||
```
|
||||
User → CloudFront (CDN) → S3 (Static Files)
|
||||
```
|
||||
|
||||
## Adım 1: S3 Bucket Oluşturun
|
||||
|
||||
```bash
|
||||
# Create bucket
|
||||
aws s3 mb s3://your-bentopdf-bucket --region us-east-1
|
||||
|
||||
# Enable static website hosting
|
||||
aws s3 website s3://your-bentopdf-bucket \
|
||||
--index-document index.html \
|
||||
--error-document index.html
|
||||
```
|
||||
|
||||
## Adım 2: Derleyin ve Yükleyin
|
||||
|
||||
```bash
|
||||
# Build the project (optionally with custom branding)
|
||||
# VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
|
||||
npm run build
|
||||
|
||||
# Sync to S3
|
||||
aws s3 sync dist/ s3://your-bentopdf-bucket \
|
||||
--delete \
|
||||
--cache-control "max-age=31536000"
|
||||
|
||||
# Set correct MIME types for WASM
|
||||
aws s3 cp s3://your-bentopdf-bucket/ s3://your-bentopdf-bucket/ \
|
||||
--recursive \
|
||||
--exclude "*" \
|
||||
--include "*.wasm" \
|
||||
--content-type "application/wasm" \
|
||||
--metadata-directive REPLACE
|
||||
|
||||
# Set correct MIME type for ES module files (.mjs)
|
||||
# S3 defaults .mjs to application/octet-stream, which browsers refuse to
|
||||
# execute as ES modules. The bundled PDF viewer (Sign PDF, Form Filler)
|
||||
# ships ES modules with .mjs extensions and will fail without this step.
|
||||
aws s3 cp s3://your-bentopdf-bucket/ s3://your-bentopdf-bucket/ \
|
||||
--recursive \
|
||||
--exclude "*" \
|
||||
--include "*.mjs" \
|
||||
--content-type "application/javascript" \
|
||||
--metadata-directive REPLACE
|
||||
```
|
||||
|
||||
## Adım 3: CloudFront Dağıtımı Oluşturun
|
||||
|
||||
```bash
|
||||
aws cloudfront create-distribution \
|
||||
--origin-domain-name your-bentopdf-bucket.s3.amazonaws.com \
|
||||
--default-root-object index.html
|
||||
```
|
||||
|
||||
Veya AWS Console'u kullanın:
|
||||
|
||||
1. CloudFront → Create distribution bölümüne gidin
|
||||
2. Origin domain: S3 bucket'ınızı seçin
|
||||
3. "Origin Access Control" seçeneğini etkinleştirin
|
||||
4. Default root object: `index.html`
|
||||
5. Dağıtımı oluşturun
|
||||
|
||||
## Adım 3b: Response Headers Policy (LibreOffice WASM için Gerekli)
|
||||
|
||||
LibreOffice tabanlı dönüştürmeler (Word, Excel, PowerPoint'ten PDF'e) `SharedArrayBuffer` gerektirir ve bunun için belirli yanıt başlıkları gerekir. Bir CloudFront Response Headers Policy oluşturun:
|
||||
|
||||
1. CloudFront → Policies → Response headers bölümüne gidin
|
||||
2. Şu başlıklarla özel bir politika oluşturun:
|
||||
|
||||
| Başlık | Değer |
|
||||
| ------------------------------ | -------------- |
|
||||
| `Cross-Origin-Embedder-Policy` | `require-corp` |
|
||||
| `Cross-Origin-Opener-Policy` | `same-origin` |
|
||||
| `Cross-Origin-Resource-Policy` | `cross-origin` |
|
||||
|
||||
3. Politikayı dağıtımınızın varsayılan önbellek davranışına bağlayın
|
||||
|
||||
Veya CLI ile:
|
||||
|
||||
```bash
|
||||
aws cloudfront create-response-headers-policy \
|
||||
--response-headers-policy-config '{
|
||||
"Name": "BentoPDF-COEP-COOP",
|
||||
"CustomHeadersConfig": {
|
||||
"Quantity": 3,
|
||||
"Items": [
|
||||
{"Header": "Cross-Origin-Embedder-Policy", "Value": "require-corp", "Override": true},
|
||||
{"Header": "Cross-Origin-Opener-Policy", "Value": "same-origin", "Override": true},
|
||||
{"Header": "Cross-Origin-Resource-Policy", "Value": "cross-origin", "Override": true}
|
||||
]
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Adım 3c: Önceden Sıkıştırılmış WASM Dosyaları için S3 Metadata
|
||||
|
||||
LibreOffice WASM dosyaları önceden sıkıştırılmıştır (`.wasm.gz`, `.data.gz`). Tarayıcıların bunları açabilmesi için doğru Content-Type ve Content-Encoding değerlerini ayarlayın:
|
||||
|
||||
```bash
|
||||
# Set correct headers for soffice.wasm.gz
|
||||
aws s3 cp s3://your-bentopdf-bucket/libreoffice-wasm/soffice.wasm.gz \
|
||||
s3://your-bentopdf-bucket/libreoffice-wasm/soffice.wasm.gz \
|
||||
--content-type "application/wasm" \
|
||||
--content-encoding "gzip" \
|
||||
--metadata-directive REPLACE
|
||||
|
||||
# Set correct headers for soffice.data.gz
|
||||
aws s3 cp s3://your-bentopdf-bucket/libreoffice-wasm/soffice.data.gz \
|
||||
s3://your-bentopdf-bucket/libreoffice-wasm/soffice.data.gz \
|
||||
--content-type "application/octet-stream" \
|
||||
--content-encoding "gzip" \
|
||||
--metadata-directive REPLACE
|
||||
```
|
||||
|
||||
::: warning Önemli
|
||||
Response headers policy olmadan `SharedArrayBuffer` kullanılamaz ve LibreOffice WASM dönüştürmeleri yaklaşık %55'te takılır. `.gz` dosyalarında doğru Content-Encoding yoksa tarayıcı ham gzip baytlarını alır ve WASM derlemesi başarısız olur.
|
||||
:::
|
||||
|
||||
## Adım 4: S3 Bucket Policy
|
||||
|
||||
CloudFront'un bucket'a erişmesine izin verin:
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowCloudFrontAccess",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": "cloudfront.amazonaws.com"
|
||||
},
|
||||
"Action": "s3:GetObject",
|
||||
"Resource": "arn:aws:s3:::your-bentopdf-bucket/*",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Adım 5: Özel Hata Sayfaları
|
||||
|
||||
SPA yönlendirmesi için 404'ün `index.html` döndürmesini yapılandırın:
|
||||
|
||||
1. CloudFront → Error pages
|
||||
2. Özel hata yanıtı oluşturun:
|
||||
- HTTP error code: 404
|
||||
- Response page path: `/index.html`
|
||||
- HTTP response code: 200
|
||||
|
||||
## Maliyet Tahmini
|
||||
|
||||
| Kaynak | Tahmini Maliyet |
|
||||
| ------------------------- | --------------- |
|
||||
| S3 Depolama (~500MB) | ~$0.01/ay |
|
||||
| CloudFront (1TB aktarım) | ~$85/ay |
|
||||
| CloudFront (10GB aktarım) | ~$0.85/ay |
|
||||
|
||||
::: tip
|
||||
Seyrek erişilen dosyalarda maliyet optimizasyonu için S3 Intelligent Tiering kullanın.
|
||||
:::
|
||||
|
||||
## Terraform ile Otomasyon
|
||||
|
||||
```hcl
|
||||
# main.tf
|
||||
resource "aws_s3_bucket" "bentopdf" {
|
||||
bucket = "your-bentopdf-bucket"
|
||||
}
|
||||
|
||||
resource "aws_cloudfront_distribution" "bentopdf" {
|
||||
origin {
|
||||
domain_name = aws_s3_bucket.bentopdf.bucket_regional_domain_name
|
||||
origin_id = "S3Origin"
|
||||
}
|
||||
|
||||
enabled = true
|
||||
default_root_object = "index.html"
|
||||
|
||||
default_cache_behavior {
|
||||
allowed_methods = ["GET", "HEAD"]
|
||||
cached_methods = ["GET", "HEAD"]
|
||||
target_origin_id = "S3Origin"
|
||||
|
||||
viewer_protocol_policy = "redirect-to-https"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,154 @@
|
||||
# Cloudflare Pages'e Dağıtım
|
||||
|
||||
[Cloudflare Pages](https://pages.cloudflare.com), sınırsız bant genişliğiyle hızlı, küresel statik site barındırma sunar.
|
||||
|
||||
## Hızlı Dağıtım
|
||||
|
||||
1. [Cloudflare Pages](https://dash.cloudflare.com/?to=/:account/pages) sayfasına gidin
|
||||
2. "Create a project" düğmesine tıklayın
|
||||
3. GitHub deponuzu bağlayın
|
||||
|
||||
## Derleme Yapılandırması
|
||||
|
||||
| Ayar | Değer |
|
||||
| ---------------------- | --------------- |
|
||||
| Framework preset | None |
|
||||
| Build command | `npm run build` |
|
||||
| Build output directory | `dist` |
|
||||
| Root directory | `/` |
|
||||
|
||||
## Ortam Değişkenleri
|
||||
|
||||
Bunları Settings → Environment variables bölümüne ekleyin:
|
||||
|
||||
| Değişken | Değer |
|
||||
| ----------------------- | ------------------------------------------------- |
|
||||
| `NODE_VERSION` | `18` |
|
||||
| `SIMPLE_MODE` | `false` (isteğe bağlı) |
|
||||
| `VITE_BRAND_NAME` | Özel marka adı (isteğe bağlı) |
|
||||
| `VITE_BRAND_LOGO` | `public/` klasörüne göre logo yolu (isteğe bağlı) |
|
||||
| `VITE_FOOTER_TEXT` | Özel alt bilgi/telif hakkı metni (isteğe bağlı) |
|
||||
| `VITE_DEFAULT_LANGUAGE` | Varsayılan arayüz dili, örn. `fr` (isteğe bağlı) |
|
||||
|
||||
## Yapılandırma Dosyası
|
||||
|
||||
`public` klasörünüzde `_headers` dosyasını oluşturun:
|
||||
|
||||
```
|
||||
# Required security headers for SharedArrayBuffer (used by LibreOffice WASM)
|
||||
/*
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Resource-Policy: cross-origin
|
||||
|
||||
# Pre-compressed LibreOffice WASM binary
|
||||
/libreoffice-wasm/soffice.wasm.gz
|
||||
Content-Type: application/wasm
|
||||
Content-Encoding: gzip
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
# Pre-compressed LibreOffice WASM data
|
||||
/libreoffice-wasm/soffice.data.gz
|
||||
Content-Type: application/octet-stream
|
||||
Content-Encoding: gzip
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
# Cache WASM files aggressively
|
||||
/*.wasm
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
Content-Type: application/wasm
|
||||
|
||||
# Service worker
|
||||
/sw.js
|
||||
Cache-Control: no-cache
|
||||
```
|
||||
|
||||
::: warning Önemli
|
||||
`Cross-Origin-Embedder-Policy` ve `Cross-Origin-Opener-Policy` başlıkları Word/ODT/Excel/PowerPoint'ten PDF'e dönüştürmeler için gereklidir. Bunlar olmadan `SharedArrayBuffer` kullanılamaz ve LibreOffice WASM motoru başlatılamaz.
|
||||
:::
|
||||
|
||||
SPA yönlendirmesi için `_redirects` dosyasını oluşturun:
|
||||
|
||||
```
|
||||
/* /index.html 200
|
||||
```
|
||||
|
||||
## Özel Alan Adı
|
||||
|
||||
1. Pages projenize gidin
|
||||
2. "Custom domains" düğmesine tıklayın
|
||||
3. Alan adınızı ekleyin
|
||||
4. Alan adı Cloudflare'deyse Cloudflare DNS'i otomatik yapılandırır
|
||||
|
||||
## Avantajlar
|
||||
|
||||
- **Ücretsiz sınırsız bant genişliği**
|
||||
- 300'den fazla uç noktası olan **küresel CDN**
|
||||
- **Otomatik HTTPS**
|
||||
- Pull request'ler için **önizleme dağıtımları**
|
||||
- **Hızlı derlemeler**
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### Büyük Dosya Yüklemeleri
|
||||
|
||||
Cloudflare Pages 25 MB'a kadar dosyaları destekler. WASM modüllerinde sorun olmaması gerekir, ancak sınırlara takılırsanız şunu düşünün:
|
||||
|
||||
```bash
|
||||
# Split large files during build
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Worker Boyut Sınırları
|
||||
|
||||
Gelişmiş yönlendirme için Cloudflare Workers kullanıyorsanız, ücretsiz planlardaki 1 MB sınırını göz önünde bulundurun.
|
||||
|
||||
## CORS Proxy Worker (Dijital İmzalar için)
|
||||
|
||||
Dijital İmza aracı, sertifika zincirlerini almak için bir CORS proxy gerektirir. Pakete dahil worker'ı dağıtın:
|
||||
|
||||
```bash
|
||||
cd cloudflare
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
### Güvenlik Özellikleri
|
||||
|
||||
| Özellik | Açıklama |
|
||||
| ----------------------- | ------------------------------------------ |
|
||||
| **URL Kısıtlamaları** | Yalnızca sertifika URL'lerine izin verilir |
|
||||
| **Dosya Boyutu Sınırı** | İstek başına en fazla 10MB |
|
||||
| **Hız Sınırlama** | 60 istek/IP/dk (KV gerekir) |
|
||||
| **Özel IP Engelleme** | localhost ve dahili IP'leri engeller |
|
||||
|
||||
### Hız Sınırlamayı Etkinleştirme
|
||||
|
||||
```bash
|
||||
# Create KV namespace
|
||||
npx wrangler kv namespace create "RATE_LIMIT_KV"
|
||||
|
||||
# Add to wrangler.toml with returned ID:
|
||||
# [[kv_namespaces]]
|
||||
# binding = "RATE_LIMIT_KV"
|
||||
# id = "YOUR_ID"
|
||||
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
### Proxy URL ile Derleme
|
||||
|
||||
```bash
|
||||
VITE_CORS_PROXY_URL=https://your-worker.workers.dev npm run build
|
||||
```
|
||||
|
||||
Veya Docker ile:
|
||||
|
||||
```bash
|
||||
export VITE_CORS_PROXY_URL="https://your-worker.workers.dev"
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--secret id=VITE_CORS_PROXY_URL,env=VITE_CORS_PROXY_URL \
|
||||
-t your-bentopdf .
|
||||
```
|
||||
|
||||
> **Not:** HMAC imza kurulumu için [README](https://github.com/alam00000/bentopdf#digital-signature-cors-proxy-required) dosyasına bakın.
|
||||
@@ -0,0 +1,180 @@
|
||||
# Sertifika Alımı için CORS Proxy
|
||||
|
||||
Dijital imza aracı, harici Sertifika Otoritelerinden (CA) düzenleyici sertifikaları almak için bir CORS proxy kullanır. Bu gereklidir, çünkü birçok CA sunucusu yanıtlarında CORS başlıkları içermez ve bu da tarayıcıdan doğrudan almayı engeller.
|
||||
|
||||
Ayrıca birçok CA sunucusu sertifikaları düz HTTP üzerinden sunar. BentoPDF örneğiniz HTTPS üzerinden barındırıldığında tarayıcılar bu HTTP isteklerini engeller (karma içerik politikası). CORS proxy, istekleri uygun başlıklara sahip bir HTTPS uç noktası üzerinden yönlendirerek her iki sorunu da çözer.
|
||||
|
||||
## Nasıl Çalışır
|
||||
|
||||
Bir PDF'i sertifikayla imzalarken:
|
||||
|
||||
1. `zgapdfsigner` kütüphanesi eksiksiz bir sertifika zinciri oluşturmaya çalışır
|
||||
2. Düzenleyici sertifikaları, sertifikanızın AIA (Authority Information Access) uzantısına gömülü URL'lerden alır
|
||||
3. Bu istekler, gerekli `Access-Control-Allow-Origin` başlıklarını ekleyen bir CORS proxy üzerinden yönlendirilir
|
||||
4. Proxy, sertifika verilerini tarayıcıya döndürür
|
||||
|
||||
## CORS Proxy'yi Kendi Sunucunuzda Barındırma
|
||||
|
||||
BentoPDF'i kendi sunucunuzda barındırıyorsanız, zincir alımı gerektiren sertifikalarla dijital imzaların çalışması için kendi CORS proxy'nizi dağıtmanız gerekir.
|
||||
|
||||
### Seçenek 1: Cloudflare Workers (Önerilir)
|
||||
|
||||
1. **Wrangler CLI'ı kurun**:
|
||||
|
||||
```bash
|
||||
npm install -g wrangler
|
||||
```
|
||||
|
||||
2. **Cloudflare'e giriş yapın**:
|
||||
|
||||
```bash
|
||||
wrangler login
|
||||
```
|
||||
|
||||
3. **BentoPDF'i klonlayın ve izin verilen kaynakları güncelleyin**:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf/cloudflare
|
||||
```
|
||||
|
||||
`cors-proxy-worker.js` dosyasını açın ve `ALLOWED_ORIGINS` dizisini kendi alan adınıza göre değiştirin:
|
||||
|
||||
```js
|
||||
const ALLOWED_ORIGINS = [
|
||||
'https://your-domain.com',
|
||||
'https://www.your-domain.com',
|
||||
];
|
||||
```
|
||||
|
||||
::: warning Önemli
|
||||
Bu değişiklik olmadan proxy, sitenizden gelen tüm istekleri **403 Forbidden** hatasıyla reddeder. Varsayılan yalnızca `bentopdf.com` kaynağından gelen isteklere izin verir.
|
||||
:::
|
||||
|
||||
4. **Proxy'yi dağıtın**:
|
||||
|
||||
```bash
|
||||
wrangler deploy
|
||||
```
|
||||
|
||||
Worker URL'nizi not edin (örn. `https://bentopdf-cors-proxy.your-subdomain.workers.dev`).
|
||||
|
||||
5. **BentoPDF'i proxy URL ile yeniden derleyin**:
|
||||
|
||||
Docker kullanıyorsanız:
|
||||
|
||||
```bash
|
||||
export VITE_CORS_PROXY_URL="https://your-worker.workers.dev"
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--secret id=VITE_CORS_PROXY_URL,env=VITE_CORS_PROXY_URL \
|
||||
-t your-bentopdf .
|
||||
```
|
||||
|
||||
Kaynaktan derliyorsanız:
|
||||
|
||||
```bash
|
||||
VITE_CORS_PROXY_URL=https://your-worker.workers.dev npm run build
|
||||
```
|
||||
|
||||
### Seçenek 2: Özel Arka Uç Proxy
|
||||
|
||||
Kendi proxy uç noktanızı da oluşturabilirsiniz. Gereksinimler:
|
||||
|
||||
1. `url` sorgu parametresiyle GET isteklerini kabul edin
|
||||
2. URL'yi sunucunuzdan alın (sunucu tarafında CORS kısıtlaması yoktur)
|
||||
3. Yanıtı şu başlıklarla döndürün:
|
||||
- `Access-Control-Allow-Origin: https://your-domain.com`
|
||||
- `Access-Control-Allow-Methods: GET, OPTIONS`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
|
||||
Örnek Express.js uygulaması:
|
||||
|
||||
```javascript
|
||||
app.get('/api/cert-proxy', async (req, res) => {
|
||||
const targetUrl = req.query.url;
|
||||
|
||||
// Validate it's a certificate URL
|
||||
if (!isValidCertUrl(targetUrl)) {
|
||||
return res.status(400).json({ error: 'Invalid URL' });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(targetUrl);
|
||||
const data = await response.arrayBuffer();
|
||||
|
||||
res.set('Access-Control-Allow-Origin', 'https://your-domain.com');
|
||||
res.set('Content-Type', 'application/octet-stream');
|
||||
res.set('X-Content-Type-Options', 'nosniff');
|
||||
res.send(Buffer.from(data));
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Proxy error' });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Güvenlik Hususları
|
||||
|
||||
Pakete dahil Cloudflare Worker'ın çeşitli güvenlik önlemleri vardır:
|
||||
|
||||
| Özellik | Açıklama |
|
||||
| -------------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| **Kaynak Doğrulama** | Yalnızca `ALLOWED_ORIGINS` içinde listelenen alan adlarından gelen isteklere izin verir |
|
||||
| **URL Kısıtlamaları** | Yalnızca sertifika URL'lerine izin verir (`.crt`, `.cer`, `.pem`, `/certs/`, `/ocsp`, `/crl`) |
|
||||
| **Özel IP Engelleme** | IPv4/IPv6 özel aralıklarını, link-local, loopback, ondalık IP'leri ve bulut metadata'sını engeller |
|
||||
| **Content-Type Güvenliği** | Yalnızca güvenli sertifika MIME türlerini döndürür, üst kaynaktan content-type enjeksiyonunu engeller |
|
||||
| **Dosya Boyutu Sınırı** | Yanıtı 10MB sınırıyla akıtır, aşılırsa indirmeyi yarıda keser |
|
||||
| **Hız Sınırlama** | IP veya IPv6 /64 başına dakikada 60 istek (KV gerekir, KV hatalarında açık kalır) |
|
||||
| **HMAC İmzaları** | İsteğe bağlı istemci tarafı imzalama (sıradan kötüye kullanımı caydırır) |
|
||||
|
||||
### DNS rebinding (Cloudflare dışında kendi sunucunuzda barındırma)
|
||||
|
||||
Worker, özel veya dahili bir IP'ye çözümlenen her URL'yi reddeder. Sabit bir ana bilgisayar izin listesi kullanamaz, çünkü sertifika zinciri URL'leri sertifikayı hangi CA verdiyse ona işaret eder (FNMT, kurumsal CA'lar vb.), dolayısıyla hedefler önceden bilinmez. Bu da küçük bir rebinding penceresi bırakır: kendi alan adının DNS'ini yöneten biri, güvenlik kontrolüne genel bir IP, bir an sonra gerçek isteğe ise özel bir IP verebilir.
|
||||
|
||||
Cloudflare üzerinde bu istismar edilemez: Workers özel IP'lere veya `169.254.169.254` metadata uç noktasına erişemez, dolayısıyla bir rebind hiçbir yere ulaşmaz. Yeter ki worker'a bir giriş yolu vermeyin: Tunnel, Service veya özel ağ binding'i eklemeyin (yalnızca `RATE_LIMIT_KV` gerekir).
|
||||
|
||||
Bunu Cloudflare dışında (workerd, Node vb.) bir VPC içinde çalıştırırsanız, çalışma zamanı dahili IP'lere _erişebilir_. Önüne bir çıkış güvenlik duvarı koyun ve özel aralıkları engelleyin: `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `127.0.0.0/8`, `169.254.0.0/16` ve bunların IPv6 karşılıkları. Cloudflare dışına çıktığınızda uygulama kodu bunu zorunlu kılamaz.
|
||||
|
||||
## Proxy'yi Devre Dışı Bırakma
|
||||
|
||||
CORS proxy kullanmak istemiyorsanız, ortam değişkenini boş bir dizeye ayarlayın:
|
||||
|
||||
```
|
||||
VITE_CORS_PROXY_URL=
|
||||
```
|
||||
|
||||
**Not**: Proxy olmadan, harici zincir alımı gerektiren sertifikalarla (FNMT veya bazı kurumsal CA'lar gibi) imzalama "Failed to fetch" hatasıyla başarısız olur.
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### "Signing error: TypeError: Failed to fetch"
|
||||
|
||||
Bu genellikle şunlardan birini ifade eder:
|
||||
|
||||
1. **CORS proxy yapılandırılmamış**: `VITE_CORS_PROXY_URL` değerini ayarlayın ve yeniden derleyin
|
||||
2. **Karma içerik engellendi**: Siteniz HTTPS, ancak sertifikanın düzenleyici URL'si HTTP. CORS proxy bunu çözer.
|
||||
3. **CORS proxy kaynağınızı reddediyor**: Alan adınızın `cors-proxy-worker.js` içindeki `ALLOWED_ORIGINS` dizisinde olduğunu kontrol edin
|
||||
|
||||
### Proxy'den "403 Forbidden"
|
||||
|
||||
Alan adınız `ALLOWED_ORIGINS` listesinde değil. `cors-proxy-worker.js` dosyasını düzenleyin:
|
||||
|
||||
```js
|
||||
const ALLOWED_ORIGINS = ['https://your-domain.com'];
|
||||
```
|
||||
|
||||
Ardından yeniden dağıtın: `npx wrangler deploy`
|
||||
|
||||
### Proxy'yi test etme
|
||||
|
||||
```bash
|
||||
curl -H "Origin: https://your-domain.com" \
|
||||
"https://your-proxy.workers.dev?url=http://www.cert.fnmt.es/certs/ACUSU.crt"
|
||||
```
|
||||
|
||||
### Proxy Olmadan Çalışan Sertifikalar
|
||||
|
||||
Bazı sertifikalar tam zinciri P12/PFX dosyasında içerir ve harici alım gerektirmez:
|
||||
|
||||
- Kendinden imzalı sertifikalar
|
||||
- Ara sertifikaları paketleyen bazı ticari CA'lar
|
||||
- Tam zincirle elle oluşturduğunuz sertifikalar
|
||||
@@ -0,0 +1,622 @@
|
||||
# Docker / Podman ile Dağıtım
|
||||
|
||||
BentoPDF'i üretim ortamında kendi sunucunuzda barındırmanın en kolay yolu.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Office Dosya Dönüştürme için Gerekli Başlıklar**
|
||||
>
|
||||
> LibreOffice tabanlı araçlar (Word, Excel, PowerPoint dönüştürme), `SharedArrayBuffer` desteği için şu HTTP başlıklarını gerektirir:
|
||||
>
|
||||
> - `Cross-Origin-Opener-Policy: same-origin`
|
||||
> - `Cross-Origin-Embedder-Policy: require-corp`
|
||||
>
|
||||
> Sayfa ayrıca güvenli bir bağlamdan sunulmalıdır. `http://localhost` yerel testler için çalışır, ancak `http://192.168.x.x` gibi yerel ağ IP'leri genellikle bu koşulu karşılamaz. Bu yüzden başlıklar mevcut olsa bile düz HTTP üzerinden Office dönüştürme başarısız olur.
|
||||
>
|
||||
> Resmi konteyner görüntüleri bu başlıkları içerir. Bir ters proxy kullanıyorsanız (Traefik, Caddy vb.), bu başlıkların korunduğundan veya eklendiğinden emin olun ve geri döngü dışı erişim için HTTPS kullanın.
|
||||
|
||||
> [!TIP]
|
||||
> **Podman Kullanıcıları:** Tüm `docker` komutları, `docker` yerine `podman` ve `docker-compose` yerine `podman-compose` yazılarak Podman ile çalışır.
|
||||
|
||||
## Hızlı Başlangıç
|
||||
|
||||
> [!TIP]
|
||||
> BentoPDF iki sürüm olarak sunulur:
|
||||
>
|
||||
> - **Kendi Sunucunda Barındırma sürümü**: `ghcr.io/alam00000/bentopdf-simple:latest`. Tüm PDF araçları, tanıtım bölümleri **olmadan** (ana sayfa bölümü, SSS, kullanıcı yorumları, alt bilgi yok). Dahili/ekip/kurum dağıtımları için bunu kullanın. Özellikleri kısıtlanmış bir "lite" sürüm **değildir**.
|
||||
> - **Ticari sürüm**: `ghcr.io/alam00000/bentopdf:latest`. Tam tanıtım sitesi; bentopdf.com'un kendisi ve herkese açık dağıtım yapan ticari lisans sahipleri tarafından kullanılır.
|
||||
>
|
||||
> Emin değilseniz: Kendi Sunucunda Barındırma sürümünü çekin.
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -d \
|
||||
--name bentopdf \
|
||||
-p 3000:8080 \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Podman
|
||||
podman run -d \
|
||||
--name bentopdf \
|
||||
-p 3000:8080 \
|
||||
ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
## Docker Compose / Podman Compose
|
||||
|
||||
`docker-compose.yml` dosyasını oluşturun:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
container_name: bentopdf
|
||||
ports:
|
||||
- '3000:8080'
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:8080']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
Çalıştırın:
|
||||
|
||||
```bash
|
||||
# Docker Compose
|
||||
docker compose up -d
|
||||
|
||||
# Podman Compose
|
||||
podman-compose up -d
|
||||
```
|
||||
|
||||
## Kendi Görüntünüzü Derleyin
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginxinc/nginx-unprivileged:alpine
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
EXPOSE 8080
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
Derleyin ve çalıştırın:
|
||||
|
||||
```bash
|
||||
docker build -t bentopdf:custom .
|
||||
docker run -d -p 3000:8080 bentopdf:custom
|
||||
```
|
||||
|
||||
## Ortam Değişkenleri
|
||||
|
||||
| Değişken | Açıklama | Varsayılan |
|
||||
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `SIMPLE_MODE` | Kendi Sunucunda Barındırma varyantını derler (bentopdf.com tanıtım bölümlerini gizler: ana sayfa bölümü, SSS, kullanıcı yorumları, alt bilgi). Tüm PDF araçları kalır. | `false` |
|
||||
| `BASE_URL` | Alt dizine dağıtım | `/` |
|
||||
| `VITE_WASM_PYMUPDF_URL` | PyMuPDF WASM modül URL'si | `https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm@0.11.16/` |
|
||||
| `VITE_WASM_GS_URL` | Ghostscript WASM modül URL'si | `https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm@0.1.1/assets/` |
|
||||
| `VITE_WASM_CPDF_URL` | CoherentPDF WASM modül URL'si | `https://cdn.jsdelivr.net/npm/coherentpdf@2.5.5/dist/` |
|
||||
| `VITE_TESSERACT_WORKER_URL` | OCR worker betik URL'si | _(boş; Tesseract.js varsayılan CDN'i kullanılır)_ |
|
||||
| `VITE_TESSERACT_CORE_URL` | OCR çekirdek çalışma zamanı dizini | _(boş; Tesseract.js varsayılan CDN'i kullanılır)_ |
|
||||
| `VITE_TESSERACT_LANG_URL` | OCR traineddata dizini | _(boş; Tesseract.js varsayılan CDN'i kullanılır)_ |
|
||||
| `VITE_TESSERACT_AVAILABLE_LANGUAGES` | Arayüzde gösterilen virgülle ayrılmış OCR dilleri | _(boş; tam katalog gösterilir)_ |
|
||||
| `VITE_OCR_FONT_BASE_URL` | OCR metin katmanı yazı tipi dizini | _(boş; uzak Noto yazı tipi URL'leri kullanılır)_ |
|
||||
| `VITE_DEFAULT_LANGUAGE` | Varsayılan arayüz dili | `en` |
|
||||
| `VITE_BRAND_NAME` | Özel marka adı | `BentoPDF` |
|
||||
| `VITE_BRAND_LOGO` | `public/` klasörüne göre logo yolu | `images/favicon-no-bg.svg` |
|
||||
| `VITE_FOOTER_TEXT` | Özel alt bilgi/telif hakkı metni | `© 2026 BentoPDF. All rights reserved.` |
|
||||
| `DISABLE_TOOLS` | Gizlenecek araç kimlikleri (virgülle ayrılmış) | _(boş; tüm araçlar etkin)_ |
|
||||
| `DISABLE_GITHUB_STARS` | Sayfa yüklenirken GitHub yıldız sayısı çekimini atlar ve `api.github.com` adresini CSP'den çıkarır. Simple Mode derlemeleri bunu her zaman atlar. | `false` |
|
||||
| `SITE_URL` | Canonical, hreflang ve sitemap bağlantılarına yazılan herkese açık URL. Arama motorlarının dağıtımınızı ayrı bir site olarak görmesini istemiyorsanız varsayılan değerde bırakın. | `https://www.bentopdf.com` |
|
||||
| `ALLOW_INDEXING` | Özel bir `SITE_URL` ile her sayfa `noindex` olarak işaretlenir, böylece kopyanız arama sonuçlarında bentopdf.com ile rekabet etmez. Arama motorlarının dizinlemesine izin vermek için `true` yapın. | `false` |
|
||||
|
||||
WASM modül URL'leri CDN varsayılanlarıyla önceden yapılandırılmıştır, tüm gelişmiş özellikler kutudan çıktığı gibi çalışır. İnternetten yalıtılmış veya kendi sunucunuzdaki dağıtımlar için bunları geçersiz kılın.
|
||||
|
||||
### Arama motorları
|
||||
|
||||
Varsayılan olarak her sayfa, arama motorlarını asıl kaynak olarak bentopdf.com'a yönlendirir, böylece dağıtımınız kopya olarak görünmez. Özel veya dahili bir örnek için hiçbir şeyi değiştirmeniz gerekmez.
|
||||
|
||||
- **Örneğinizi arama sonuçlarının tamamen dışında tutun:** konteyneri `-e ROBOTS_NOINDEX=true` ile çalıştırın. Bunun için yalnızca yeniden başlatma gerekir, yeniden derleme gerekmez.
|
||||
- **Örneğinizi arama sonuçlarında ayrı bir site yapın:** `--build-arg SITE_URL=https://your-domain.example --build-arg ALLOW_INDEXING=true` ile derleyin. `ALLOW_INDEXING=true` olmadan, özel bir `SITE_URL` her sayfayı `noindex` olarak işaretler.
|
||||
|
||||
### Content-Security-Policy
|
||||
|
||||
nginx görüntüsü, uygulanan bir `Content-Security-Policy` başlığıyla gelir. CSP'nin `script-src`, `connect-src` ve `font-src` yönergeleri, yukarıdaki `VITE_*` URL değişkenlerinden **derleme zamanında oluşturulur**. `--build-arg` ile verdiğiniz tüm ana bilgisayarlar politikaya otomatik olarak eklenir.
|
||||
|
||||
Sonuç olarak:
|
||||
|
||||
- Derleme zamanında `VITE_CORS_PROXY_URL` veya `VITE_WASM_*_URL` değerlerini geçersiz kılarsanız, CSP bu kaynaklara otomatik izin verir, ek yapılandırma gerekmez.
|
||||
- `cdn.jsdelivr.net` üzerindeki URL'lerde `script-src`, tüm CDN'e değil yalnızca tam sürümlü paket klasörüne izin verir, örneğin `https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm@0.11.16/`. jsDelivr herhangi bir herkese açık npm paketini veya GitHub deposunu sunar, bu yüzden ana bilgisayarın tamamına izin vermek bunların hepsinin örneğinizde çalışmasına izin verirdi. Diğer ana bilgisayarlardaki URL'lere kaynak bazında izin verilir.
|
||||
- Özel WASM URL'lerini _çalışma zamanında_ uygulama içi Gelişmiş Ayarlar sayfasından yapılandırırsanız, bu kaynaklar CSP'de **yer almaz** ve tarayıcı bunlara yapılan istekleri engeller. Bu, `cdn.jsdelivr.net` üzerindeki aynı paketin farklı bir sürümü için de geçerlidir, çünkü yalnızca derleme zamanında ayarlanan sürüme izin verilir. Çalışma zamanı yapılandırması deneme amaçlıdır. Kalıcı özel URL'ler için ilgili `VITE_*` build arg değerini ayarlayın.
|
||||
- Üç `VITE_WASM_*_URL` değerinin tümünü geçersiz kılan internetten yalıtılmış dağıtımlarda, bu `cdn.jsdelivr.net` paket klasörleri de CSP'den çıkarılır (her varsayılan değiştirilir, eklenmez). `cdn.jsdelivr.net` üzerindeki Tesseract OCR varsayılanları, üç `VITE_TESSERACT_*` değerini de ayarlayana kadar politikada kalır. Benzer şekilde, `VITE_CORS_PROXY_URL` ayarlamak herkese açık `bentopdf-cors-proxy.bentopdf.workers.dev` varsayılanının yerini alır.
|
||||
|
||||
CSP, `script-src` içinde `'unsafe-eval'` içerir, çünkü LibreOffice WASM çalışma zamanı (Word/Excel/PowerPoint dönüştürme araçlarınca kullanılır) ve wasm-vips görüntü kütüphanesi (PDF'den TIFF'e dönüştürmede kullanılır) dahili dağıtım kodunu `new Function()` ile derler. Bunu kaldırmak bu araçları bozar. `SIMPLE_MODE` ile (LibreOffice olmadan) derliyor ve PDF'den TIFF'e dönüştürmeye ihtiyaç duymuyorsanız, daha sıkı bir politika için oluşturulan `security-headers.conf` dosyasını elle düzenleyip `'unsafe-eval'` değerini çıkarabilirsiniz.
|
||||
|
||||
OCR için, varsayılan çevrimiçi varlıkları kullanmak üzere `VITE_TESSERACT_*` değişkenlerini boş bırakın veya kendi sunucunuzdaki/çevrimdışı OCR için üçünü birlikte ayarlayın. Kısmi OCR geçersiz kılmaları reddedilir, çünkü worker, çekirdek çalışma zamanı ve traineddata dizini birbiriyle eşleşmelidir. Tamamen çevrimdışı aranabilir PDF çıktısı için ayrıca `VITE_OCR_FONT_BASE_URL` değerini ayarlayın, böylece OCR metin katmanı yazı tipleri herkese açık Noto yazı tipi URL'leri yerine dahili sunucunuzdan yüklenir.
|
||||
|
||||
`VITE_DEFAULT_LANGUAGE`, ilk kez gelen ziyaretçiler için arayüz dilini belirler. Desteklenen değerler: `en`, `ar`, `be`, `fr`, `de`, `es`, `zh`, `zh-TW`, `vi`, `tr`, `id`, `it`, `pt`, `nl`, `da`. Kullanıcılar dili yine değiştirebilir, bu yalnızca varsayılanı değiştirir.
|
||||
|
||||
Örnek:
|
||||
|
||||
```bash
|
||||
# Build with French as the default language
|
||||
docker build --build-arg VITE_DEFAULT_LANGUAGE=fr -t bentopdf .
|
||||
docker run -d -p 3000:8080 bentopdf
|
||||
```
|
||||
|
||||
### Özel Marka
|
||||
|
||||
Varsayılan BentoPDF logosunu, adını ve alt bilgi metnini kendinizinkilerle değiştirin. Logo dosyanızı `public/` klasörüne koyun (veya mevcut bir görseli kullanın), ardından marka değişkenlerini derleme zamanında verin:
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg VITE_BRAND_NAME="AcmePDF" \
|
||||
--build-arg VITE_BRAND_LOGO="images/acme-logo.svg" \
|
||||
--build-arg VITE_FOOTER_TEXT="© 2026 Acme Corp. Internal use only." \
|
||||
-t acmepdf .
|
||||
```
|
||||
|
||||
Marka özelleştirme hem tam modda hem Simple Mode'da çalışır ve diğer tüm derleme zamanı seçenekleriyle birleştirilebilir.
|
||||
|
||||
### Belirli Araçları Devre Dışı Bırakma
|
||||
|
||||
Uyumluluk veya güvenlik gereksinimleri için araçları arayüzden gizleyin. Devre dışı bırakılan araçlar ana sayfadan, arama sonuçlarından, klavye kısayollarından ve iş akışı oluşturucudan kaldırılır. Doğrudan URL ile erişim "araç kullanılamıyor" sayfasını gösterir.
|
||||
|
||||
Araç kimlikleri, sayfa URL'sinin `.html` olmayan halidir. Örneğin araç `bentopdf.com/edit-pdf.html` adresindeyse kimliği `edit-pdf` olur.
|
||||
|
||||
#### Araç Kimliklerini Bulma
|
||||
|
||||
En kolay yol: BentoPDF'te herhangi bir aracı açıp URL'ye bakın. Yolun son kısmı (`.html` olmadan) araç kimliğidir.
|
||||
|
||||
<details>
|
||||
<summary>Araç kimliklerinin tam listesi</summary>
|
||||
|
||||
**Düzenle ve Not Ekle:** `edit-pdf`, `bookmark`, `table-of-contents`, `page-numbers`, `add-page-labels`, `bates-numbering`, `add-watermark`, `header-footer`, `invert-colors`, `scanner-effect`, `adjust-colors`, `background-color`, `text-color`, `sign-pdf`, `add-stamps`, `remove-annotations`, `crop-pdf`, `form-filler`, `form-creator`, `remove-blank-pages`
|
||||
|
||||
**PDF'e Dönüştür:** `image-to-pdf`, `jpg-to-pdf`, `png-to-pdf`, `webp-to-pdf`, `svg-to-pdf`, `bmp-to-pdf`, `heic-to-pdf`, `tiff-to-pdf`, `txt-to-pdf`, `markdown-to-pdf`, `json-to-pdf`, `csv-to-pdf`, `rtf-to-pdf`, `odt-to-pdf`, `word-to-pdf`, `excel-to-pdf`, `powerpoint-to-pdf`, `xps-to-pdf`, `mobi-to-pdf`, `epub-to-pdf`, `fb2-to-pdf`, `cbz-to-pdf`, `wpd-to-pdf`, `wps-to-pdf`, `xml-to-pdf`, `pages-to-pdf`, `odg-to-pdf`, `ods-to-pdf`, `odp-to-pdf`, `pub-to-pdf`, `vsd-to-pdf`, `psd-to-pdf`, `email-to-pdf`
|
||||
|
||||
**PDF'den Dönüştür:** `pdf-to-jpg`, `pdf-to-png`, `pdf-to-webp`, `pdf-to-bmp`, `pdf-to-tiff`, `pdf-to-cbz`, `pdf-to-svg`, `pdf-to-csv`, `pdf-to-excel`, `pdf-to-greyscale`, `pdf-to-json`, `pdf-to-docx`, `extract-images`, `pdf-to-markdown`, `prepare-pdf-for-ai`, `pdf-to-text`
|
||||
|
||||
**Düzenle ve Yönet:** `ocr-pdf`, `merge-pdf`, `alternate-merge`, `organize-pdf`, `add-attachments`, `extract-attachments`, `edit-attachments`, `pdf-multi-tool`, `pdf-layers`, `extract-tables`, `split-pdf`, `divide-pages`, `extract-pages`, `delete-pages`, `add-blank-page`, `reverse-pages`, `rotate-pdf`, `rotate-custom`, `n-up-pdf`, `pdf-booklet`, `combine-single-page`, `view-metadata`, `edit-metadata`, `pdf-to-zip`, `compare-pdfs`, `posterize-pdf`, `page-dimensions`
|
||||
|
||||
**Optimize Et ve Onar:** `compress-pdf`, `pdf-to-pdfa`, `fix-page-size`, `linearize-pdf`, `remove-restrictions`, `repair-pdf`, `rasterize-pdf`, `deskew-pdf`, `font-to-outline`
|
||||
|
||||
**Güvenlik:** `encrypt-pdf`, `sanitize-pdf`, `decrypt-pdf`, `flatten-pdf`, `remove-metadata`, `change-permissions`, `digital-sign-pdf`, `validate-signature-pdf`, `timestamp-pdf`
|
||||
|
||||
</details>
|
||||
|
||||
#### Seçenek 1: Derleme zamanı (Docker build arg)
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg DISABLE_TOOLS="edit-pdf,sign-pdf,encrypt-pdf" \
|
||||
-t bentopdf .
|
||||
```
|
||||
|
||||
Bu, devre dışı listesini JavaScript paketine gömer. Değiştirmek için yeniden derleme gerekir.
|
||||
|
||||
#### Seçenek 2: Çalışma zamanı (config.json)
|
||||
|
||||
Sunulan dizine bir `config.json` dosyası bağlayın, yeniden derleme gerekmez:
|
||||
|
||||
```json
|
||||
{
|
||||
"disabledTools": ["edit-pdf", "sign-pdf", "encrypt-pdf"]
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 3000:8080 \
|
||||
-v ./config.json:/usr/share/nginx/html/config.json:ro \
|
||||
ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
Veya Docker Compose ile:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ports:
|
||||
- '3000:8080'
|
||||
volumes:
|
||||
- ./config.json:/usr/share/nginx/html/config.json:ro
|
||||
```
|
||||
|
||||
İki yöntem birlikte kullanılabilir, listeler birleştirilir. Bir araç herhangi birinde yer alıyorsa devre dışı bırakılır.
|
||||
|
||||
#### Düzenleyici Özelliklerini Devre Dışı Bırakma
|
||||
|
||||
PDF Düzenleyici içindeki belirli özellikleri (örn. karartma, ek açıklamalar, formlar) tüm düzenleyici aracını devre dışı bırakmadan da kapatabilirsiniz. `config.json` dosyanıza `editorDisabledCategories` ekleyin:
|
||||
|
||||
```json
|
||||
{
|
||||
"editorDisabledCategories": ["redaction", "annotation-stamp"]
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Düzenleyici kategorilerinin tam listesi</summary>
|
||||
|
||||
**Yakınlaştırma:** `zoom`, `zoom-in`, `zoom-out`, `zoom-fit-page`, `zoom-fit-width`, `zoom-marquee`, `zoom-level`
|
||||
|
||||
**Ek Açıklama:** `annotation`, `annotation-markup`, `annotation-highlight`, `annotation-underline`, `annotation-strikeout`, `annotation-squiggly`, `annotation-ink`, `annotation-text`, `annotation-stamp`
|
||||
|
||||
**Şekiller:** `annotation-shape`, `annotation-rectangle`, `annotation-circle`, `annotation-line`, `annotation-arrow`, `annotation-polygon`, `annotation-polyline`
|
||||
|
||||
**Form:** `form`, `form-textfield`, `form-checkbox`, `form-radio`, `form-select`, `form-listbox`, `form-fill-mode`
|
||||
|
||||
**Karartma:** `redaction`, `redaction-area`, `redaction-text`, `redaction-apply`, `redaction-clear`
|
||||
|
||||
**Belge:** `document`, `document-open`, `document-close`, `document-print`, `document-capture`, `document-export`, `document-fullscreen`, `document-protect`
|
||||
|
||||
**Sayfa:** `page`, `spread`, `rotate`, `scroll`, `navigation`
|
||||
|
||||
**Panel:** `panel`, `panel-sidebar`, `panel-search`, `panel-comment`
|
||||
|
||||
**Araçlar:** `tools`, `pan`, `pointer`, `capture`
|
||||
|
||||
**Seçim:** `selection`, `selection-copy`
|
||||
|
||||
**Geçmiş:** `history`, `history-undo`, `history-redo`
|
||||
|
||||
</details>
|
||||
|
||||
Kategoriler hiyerarşiktir: bir üst kategoriyi (örn. `annotation`) devre dışı bırakmak tüm alt kategorilerini de devre dışı bırakır.
|
||||
|
||||
### GitHub Yıldız Sayacını Devre Dışı Bırakma
|
||||
|
||||
Gezinme çubuğu, sayfa yüklenirken `api.github.com` adresinden çekilen canlı bir GitHub yıldız sayısı gösterir. Bir PDF özelliğine hizmet etmeyen tek harici istek budur. Çekme kodunu paketten kaldırmak ve `api.github.com` adresini Content-Security-Policy'den çıkarmak için derleme zamanında devre dışı bırakın:
|
||||
|
||||
```bash
|
||||
docker build --build-arg DISABLE_GITHUB_STARS=true -t bentopdf .
|
||||
```
|
||||
|
||||
Simple Mode derlemeleri (`bentopdf-simple`) yıldız sayacını her zaman atlar. Bu bayrak yalnızca Ticari sürümde veya özel tam derlemelerde gereklidir.
|
||||
|
||||
### Özel WASM URL'leri (İnternetten Yalıtılmış / Kendi Sunucunuzda)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> WASM URL'leri JavaScript'e **derleme zamanında** gömülür. WASM dosyaları çalışma zamanında **kullanıcının tarayıcısı** tarafından indirilir, Docker bunları derleme sırasında indirmez. İnternetten yalıtılmış ağlarda WASM dosyalarını tarayıcıların erişebildiği dahili bir sunucuda barındırmanız gerekir.
|
||||
|
||||
**Tam air-gapped iş akışı:**
|
||||
|
||||
```bash
|
||||
# 1. On a machine WITH internet — download WASM packages
|
||||
bash scripts/prepare-airgap.sh --list-ocr-languages
|
||||
bash scripts/prepare-airgap.sh --search-ocr-language german
|
||||
|
||||
# 2. Download WASM/OCR packages
|
||||
npm pack @bentopdf/pymupdf-wasm@0.11.14
|
||||
npm pack @bentopdf/gs-wasm
|
||||
npm pack coherentpdf
|
||||
npm pack tesseract.js@7.0.0
|
||||
npm pack tesseract.js-core@7.0.0
|
||||
mkdir -p tesseract-langdata
|
||||
curl -fsSL https://cdn.jsdelivr.net/npm/@tesseract.js-data/eng/4.0.0_best_int/eng.traineddata.gz -o tesseract-langdata/eng.traineddata.gz
|
||||
mkdir -p ocr-fonts
|
||||
curl -fsSL https://raw.githack.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSans/NotoSans-Regular.ttf -o ocr-fonts/NotoSans-Regular.ttf
|
||||
|
||||
# 3. Build the image with your internal server URLs
|
||||
docker build \
|
||||
--build-arg VITE_WASM_PYMUPDF_URL=https://internal-server.example.com/wasm/pymupdf/ \
|
||||
--build-arg VITE_WASM_GS_URL=https://internal-server.example.com/wasm/gs/ \
|
||||
--build-arg VITE_WASM_CPDF_URL=https://internal-server.example.com/wasm/cpdf/ \
|
||||
--build-arg VITE_TESSERACT_WORKER_URL=https://internal-server.example.com/wasm/ocr/worker.min.js \
|
||||
--build-arg VITE_TESSERACT_CORE_URL=https://internal-server.example.com/wasm/ocr/core \
|
||||
--build-arg VITE_TESSERACT_LANG_URL=https://internal-server.example.com/wasm/ocr/lang-data \
|
||||
--build-arg VITE_TESSERACT_AVAILABLE_LANGUAGES=eng,deu \
|
||||
--build-arg VITE_OCR_FONT_BASE_URL=https://internal-server.example.com/wasm/ocr/fonts \
|
||||
-t bentopdf .
|
||||
|
||||
# 4. Export the image
|
||||
docker save bentopdf -o bentopdf.tar
|
||||
|
||||
# 5. Transfer bentopdf.tar + the .tgz packages + tesseract-langdata/ + ocr-fonts/ into the air-gapped network
|
||||
|
||||
# 6. Inside the air-gapped network — load and run
|
||||
docker load -i bentopdf.tar
|
||||
|
||||
# Extract WASM packages to your internal web server
|
||||
mkdir -p /var/www/wasm/pymupdf /var/www/wasm/gs /var/www/wasm/cpdf /var/www/wasm/ocr/core /var/www/wasm/ocr/lang-data /var/www/wasm/ocr/fonts
|
||||
tar xzf bentopdf-pymupdf-wasm-0.11.14.tgz -C /var/www/wasm/pymupdf --strip-components=1
|
||||
tar xzf bentopdf-gs-wasm-*.tgz -C /var/www/wasm/gs --strip-components=1
|
||||
tar xzf coherentpdf-*.tgz -C /var/www/wasm/cpdf --strip-components=1
|
||||
TEMP_TESS=$(mktemp -d)
|
||||
tar xzf tesseract.js-7.0.0.tgz -C "$TEMP_TESS"
|
||||
cp "$TEMP_TESS/package/dist/worker.min.js" /var/www/wasm/ocr/worker.min.js
|
||||
rm -rf "$TEMP_TESS"
|
||||
tar xzf tesseract.js-core-7.0.0.tgz -C /var/www/wasm/ocr/core --strip-components=1
|
||||
cp ./tesseract-langdata/*.traineddata.gz /var/www/wasm/ocr/lang-data/
|
||||
cp ./ocr-fonts/* /var/www/wasm/ocr/fonts/
|
||||
|
||||
# Run BentoPDF
|
||||
docker run -d -p 3000:8080 --restart unless-stopped bentopdf
|
||||
```
|
||||
|
||||
`--ocr-languages` için `bash scripts/prepare-airgap.sh --list-ocr-languages` komutunun yazdırdığı kodları kullanın veya `bash scripts/prepare-airgap.sh --search-ocr-language <term>` ile ada göre arayın. Kısıtlı bir OCR alt kümesiyle derlerken, uygulamanın yalnızca pakete dahil dilleri göstermesi için aynı kodları `VITE_TESSERACT_AVAILABLE_LANGUAGES` değerine verin. Tam çevrimdışı OCR çıktısı için ayrıca paketle gelen `ocr-fonts/` dizinini barındırın ve `VITE_OCR_FONT_BASE_URL` değerini ona yönlendirin.
|
||||
|
||||
Bir modülü devre dışı bırakmak için değişkeni boş bir dizeye ayarlayın (kullanıcıların Gelişmiş Ayarlar üzerinden elle yapılandırması gerekir).
|
||||
|
||||
## Özel Port
|
||||
|
||||
Varsayılan olarak BentoPDF, konteyner içinde `8080` portunu dinler. Bunu değiştirmek için çalışma zamanında `PORT` ortam değişkenini ayarlayın:
|
||||
|
||||
```bash
|
||||
docker run -p 3000:9090 -e PORT=9090 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
| Değişken | Açıklama | Varsayılan |
|
||||
| -------- | ------------------------------- | ---------- |
|
||||
| `PORT` | Konteynerde Nginx dinleme portu | `8080` |
|
||||
|
||||
Bu, hem standart hem nonroot Dockerfile'larla çalışır.
|
||||
|
||||
## Özel Kullanıcı Kimliği (PUID/PGID)
|
||||
|
||||
Belirli bir root olmayan kullanıcı olarak çalışmayı gerektiren ortamlar için (NAS cihazları, güvenlik bağlamlı Kubernetes, kurumsal politikalar), BentoPDF, LSIO tarzı PUID/PGID desteğine sahip ayrı bir Dockerfile sunar.
|
||||
|
||||
### Derleme ve Çalıştırma
|
||||
|
||||
```bash
|
||||
# Build the non-root image
|
||||
docker build -f Dockerfile.nonroot -t bentopdf-nonroot .
|
||||
|
||||
# Run with custom UID/GID
|
||||
docker run -d \
|
||||
--name bentopdf \
|
||||
-p 3000:8080 \
|
||||
-e PUID=1000 \
|
||||
-e PGID=1000 \
|
||||
--restart unless-stopped \
|
||||
bentopdf-nonroot
|
||||
```
|
||||
|
||||
### Ortam Değişkenleri
|
||||
|
||||
| Değişken | Açıklama | Varsayılan |
|
||||
| -------------- | ----------------------------------- | ---------- |
|
||||
| `PUID` | Çalıştırılacak kullanıcı kimliği | `1000` |
|
||||
| `PGID` | Çalıştırılacak grup kimliği | `1000` |
|
||||
| `PORT` | Nginx dinleme portu | `8080` |
|
||||
| `DISABLE_IPV6` | IPv6 dinleyicisini devre dışı bırak | `false` |
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.nonroot
|
||||
container_name: bentopdf
|
||||
ports:
|
||||
- '3000:8080'
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### Nasıl Çalışır
|
||||
|
||||
Konteyner root olarak başlar, belirtilen PUID/PGID ile bir kullanıcı oluşturur, yazılabilir tüm dizinlerin sahipliğini ayarlar, ardından `su-exec` ile ayrıcalıkları düşürür. nginx süreci tamamen belirttiğiniz kullanıcı olarak çalışır.
|
||||
|
||||
> [!NOTE]
|
||||
> Standart `Dockerfile`, `nginx-unprivileged` (UID 101) kullanır ve çoğu dağıtım için önerilir. `Dockerfile.nonroot` dosyasını yalnızca belirli bir UID/GID gerektiğinde kullanın.
|
||||
|
||||
> [!WARNING]
|
||||
> PUID/PGID `0` (root) olamaz. Giriş noktası girdileri doğrular ve geçersiz değerlerde hatayla çıkar.
|
||||
|
||||
## Traefik ile (Ters Proxy)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v2.10
|
||||
command:
|
||||
- '--providers.docker=true'
|
||||
- '--entrypoints.web.address=:80'
|
||||
- '--entrypoints.websecure.address=:443'
|
||||
- '--certificatesresolvers.letsencrypt.acme.email=you@example.com'
|
||||
- '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'
|
||||
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web'
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./letsencrypt:/letsencrypt
|
||||
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple: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'
|
||||
# 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'
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## Caddy ile (Ters Proxy)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
```
|
||||
|
||||
Caddyfile:
|
||||
|
||||
```
|
||||
pdf.example.com {
|
||||
reverse_proxy bentopdf:8080
|
||||
header Cross-Origin-Opener-Policy "same-origin"
|
||||
header Cross-Origin-Embedder-Policy "require-corp"
|
||||
}
|
||||
```
|
||||
|
||||
## Kaynak Sınırları
|
||||
|
||||
```yaml
|
||||
services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 128M
|
||||
```
|
||||
|
||||
## Podman Quadlet (Systemd Entegrasyonu)
|
||||
|
||||
[Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) Podman konteynerlerini systemd servisleri olarak çalıştırmanızı sağlar. Linux sistemlerdeki üretim dağıtımları için idealdir.
|
||||
|
||||
### Temel Quadlet Kurulumu
|
||||
|
||||
`~/.config/containers/systemd/bentopdf.container` (kullanıcı) veya `/etc/containers/systemd/bentopdf.container` (sistem) konumunda bir konteyner birim dosyası oluşturun:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF - Privacy-first PDF toolkit
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
### Etkinleştirme ve Başlatma
|
||||
|
||||
```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]
|
||||
> Sistem genelinde dağıtım için `systemctl` komutunu `--user` bayrağı olmadan kullanın ve dosyayı `/etc/containers/systemd/` içine yerleştirin.
|
||||
|
||||
### Sağlık Kontrollü Quadlet
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=BentoPDF with health monitoring
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
AutoUpdate=registry
|
||||
HealthCmd=wget --spider -q http://localhost:8080 || exit 1
|
||||
HealthInterval=30s
|
||||
HealthTimeout=10s
|
||||
HealthRetries=3
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
### Quadlet ile Otomatik Güncelleme
|
||||
|
||||
Podman, yeni görüntüler mevcut olduğunda konteynerleri otomatik güncelleyebilir:
|
||||
|
||||
```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 Ağ Yapılandırması
|
||||
|
||||
Özel ağ yapılandırması için `bentopdf.network` ağ dosyasını oluşturun:
|
||||
|
||||
```ini
|
||||
[Network]
|
||||
Subnet=10.89.0.0/24
|
||||
Gateway=10.89.0.1
|
||||
```
|
||||
|
||||
Ardından konteyner dosyanızda ona başvurun:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ContainerName=bentopdf
|
||||
PublishPort=3000:8080
|
||||
Network=bentopdf.network
|
||||
```
|
||||
|
||||
## Güncelleme
|
||||
|
||||
```bash
|
||||
# Pull latest image
|
||||
docker compose pull
|
||||
|
||||
# Recreate container
|
||||
docker compose up -d
|
||||
```
|
||||
@@ -0,0 +1,266 @@
|
||||
# Hostinger'a Dağıtım
|
||||
|
||||
[Hostinger](https://hostinger.com) popüler bir paylaşımlı barındırma sağlayıcısıdır. Bu rehber, BentoPDF'in Hostinger paylaşımlı barındırmasına dağıtımını anlatır.
|
||||
|
||||
## Gereksinimler
|
||||
|
||||
- Dosya yöneticisi erişimi olan bir Hostinger barındırma planı
|
||||
- Derleme için yerel olarak kurulu Node.js
|
||||
|
||||
## Adım 1: Projeyi Derleyin
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Derlenen dosyalar `dist` klasöründe olacaktır.
|
||||
|
||||
## Adım 2: Hostinger'a Yükleyin
|
||||
|
||||
### Kök Alan Adına Dağıtım
|
||||
|
||||
1. Hostinger hesabınıza giriş yapın
|
||||
2. **File Manager** → **public_html** bölümüne gidin
|
||||
3. Mevcut tüm dosyaları **silin** (gerekirse yedekleyin)
|
||||
4. Yerel `dist` klasörünüzün tüm içeriğini `public_html` içine **yükleyin**
|
||||
|
||||
### Alt Dizine Dağıtım
|
||||
|
||||
Bir alt dizine dağıtıyorsanız (örn. `yourdomain.com/pdf-tools/`):
|
||||
|
||||
1. Doğru temel URL ile derleyin:
|
||||
|
||||
```bash
|
||||
BASE_URL=/pdf-tools/ npm run build
|
||||
```
|
||||
|
||||
2. Hostinger'da klasörü oluşturun:
|
||||
- **File Manager** → **public_html** bölümüne gidin
|
||||
- Yeni bir klasör oluşturun: `pdf-tools`
|
||||
3. `dist` içeriğinin tamamını `public_html/pdf-tools/` içine yükleyin
|
||||
|
||||
## Adım 3: .htaccess Dosyası Oluşturun
|
||||
|
||||
Dağıtım klasörünüzün köküne (`public_html` veya `public_html/pdf-tools/`) bir `.htaccess` dosyası oluşturun:
|
||||
|
||||
::: warning Önemli
|
||||
Alt dizine dağıtımda `RewriteBase /` değerini `RewriteBase /pdf-tools/` (veya klasör adınız) olarak değiştirin.
|
||||
:::
|
||||
|
||||
```apache
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
|
||||
# ============================================
|
||||
# 1. SECURITY HEADERS (CRITICAL FOR WASM)
|
||||
# ============================================
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set X-XSS-Protection "1; mode=block"
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
|
||||
|
||||
# REQUIRED for soffice.js (SharedArrayBuffer)
|
||||
Header always set Cross-Origin-Opener-Policy "same-origin"
|
||||
Header always set Cross-Origin-Embedder-Policy "require-corp"
|
||||
</IfModule>
|
||||
|
||||
# ============================================
|
||||
# 2. BROWSER CACHING
|
||||
# ============================================
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType image/jpeg "access plus 1 year"
|
||||
ExpiresByType image/png "access plus 1 year"
|
||||
ExpiresByType image/gif "access plus 1 year"
|
||||
ExpiresByType image/webp "access plus 1 year"
|
||||
ExpiresByType image/svg+xml "access plus 1 year"
|
||||
ExpiresByType image/x-icon "access plus 1 year"
|
||||
ExpiresByType font/woff2 "access plus 1 year"
|
||||
ExpiresByType font/woff "access plus 1 year"
|
||||
ExpiresByType font/ttf "access plus 1 year"
|
||||
ExpiresByType text/css "access plus 1 month"
|
||||
ExpiresByType application/javascript "access plus 1 month"
|
||||
ExpiresByType application/wasm "access plus 1 year"
|
||||
ExpiresByType application/gzip "access plus 1 year"
|
||||
ExpiresByType text/html "access plus 0 seconds"
|
||||
</IfModule>
|
||||
|
||||
# ============================================
|
||||
# 3. COMPRESSION (STANDARD)
|
||||
# ============================================
|
||||
# Prevent server from double-compressing files
|
||||
SetEnvIfNoCase Request_URI "\.gz$" no-gzip
|
||||
SetEnvIfNoCase Request_URI "\.br$" no-gzip
|
||||
SetEnvIfNoCase Request_URI "\.wasm$" no-gzip
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/plain
|
||||
AddOutputFilterByType DEFLATE text/html
|
||||
AddOutputFilterByType DEFLATE text/xml
|
||||
AddOutputFilterByType DEFLATE text/css
|
||||
AddOutputFilterByType DEFLATE application/xml
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE application/rss+xml
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE application/x-javascript
|
||||
AddOutputFilterByType DEFLATE application/json
|
||||
AddOutputFilterByType DEFLATE image/svg+xml
|
||||
AddOutputFilterByType DEFLATE font/woff
|
||||
AddOutputFilterByType DEFLATE font/ttf
|
||||
</IfModule>
|
||||
|
||||
# ============================================
|
||||
# 4. MIME TYPES & SPECIAL FILE HANDLING
|
||||
# ============================================
|
||||
AddType application/javascript .js .mjs
|
||||
AddType application/wasm .wasm
|
||||
AddType font/woff2 .woff2
|
||||
AddType font/woff .woff
|
||||
AddType image/webp .webp
|
||||
|
||||
# Handle soffice.wasm.gz correctly
|
||||
<FilesMatch "soffice\.wasm\.gz$">
|
||||
ForceType application/wasm
|
||||
Header set Content-Encoding "gzip"
|
||||
Header set Cross-Origin-Resource-Policy "cross-origin"
|
||||
Header append Vary Accept-Encoding
|
||||
</FilesMatch>
|
||||
|
||||
# Handle data.gz
|
||||
<FilesMatch "soffice\.data\.gz$">
|
||||
ForceType application/octet-stream
|
||||
Header set Content-Encoding "gzip"
|
||||
Header append Vary Accept-Encoding
|
||||
</FilesMatch>
|
||||
|
||||
# ============================================
|
||||
# 5. REDIRECTS & ROUTING
|
||||
# ============================================
|
||||
# Canonical WWW (update domain as needed)
|
||||
RewriteCond %{HTTP_HOST} ^bentopdf\.com [NC]
|
||||
RewriteRule ^(.*)$ https://www.bentopdf.com/$1 [L,R=301]
|
||||
|
||||
# Force HTTPS
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# Remove trailing slash (except for language root directories)
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !^/(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/$
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [R=301,L]
|
||||
|
||||
# Existing files/dirs - serve directly
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# ============================================
|
||||
# 5.1. LANGUAGE ROUTES
|
||||
# ============================================
|
||||
# Supported languages: de, es, zh, zh-TW, vi, it, id, tr, fr, pt
|
||||
# English has no prefix - served from root
|
||||
|
||||
# English prefix redirects to root (for SEO consistency)
|
||||
RewriteRule ^en/?$ / [R=301,L]
|
||||
RewriteRule ^en/(.+)$ /$1 [R=301,L]
|
||||
|
||||
# Language prefix root (e.g., /de/ -> /de/index.html)
|
||||
RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L]
|
||||
|
||||
# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html)
|
||||
RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L]
|
||||
|
||||
# ============================================
|
||||
# 5.5. DOCS ROUTING (VitePress)
|
||||
# ============================================
|
||||
RewriteCond %{REQUEST_URI} ^/docs
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME}\.html -f
|
||||
RewriteRule ^(.*)$ $1.html [L]
|
||||
|
||||
# ============================================
|
||||
# 6. ADD .HTML EXTENSION IF FILE EXISTS (ROOT LEVEL ONLY)
|
||||
# ============================================
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME}.html -f
|
||||
RewriteRule ^([^/]+)$ $1.html [L]
|
||||
|
||||
# ============================================
|
||||
# 7. ERROR PAGES
|
||||
# ============================================
|
||||
ErrorDocument 404 /404.html
|
||||
```
|
||||
|
||||
## Alt Dizin .htaccess Örneği
|
||||
|
||||
`yourdomain.com/pdf-tools/` için şu satırları güncelleyin:
|
||||
|
||||
```apache
|
||||
RewriteBase /pdf-tools/
|
||||
|
||||
# ... (same content as above, but update paths) ...
|
||||
|
||||
# Language prefix root
|
||||
RewriteCond %{DOCUMENT_ROOT}/pdf-tools/$1/index.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /pdf-tools/$1/index.html [L]
|
||||
|
||||
# Language prefix with path
|
||||
RewriteCond %{DOCUMENT_ROOT}/pdf-tools/$1/$2.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /pdf-tools/$1/$2.html [L]
|
||||
|
||||
# Root level .html extension
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME}.html -f
|
||||
RewriteRule ^([^/]+)$ $1.html [L]
|
||||
|
||||
ErrorDocument 404 /pdf-tools/404.html
|
||||
```
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### WASM Dosyaları Yüklenmiyor
|
||||
|
||||
MIME türlerinin `.htaccess` içinde doğru ayarlandığından emin olun:
|
||||
|
||||
```apache
|
||||
AddType application/wasm .wasm
|
||||
```
|
||||
|
||||
### LibreOffice Araçları Çalışmıyor
|
||||
|
||||
Güvenlik başlıkları SharedArrayBuffer için kritiktir:
|
||||
|
||||
```apache
|
||||
Header always set Cross-Origin-Opener-Policy "same-origin"
|
||||
Header always set Cross-Origin-Embedder-Policy "require-corp"
|
||||
```
|
||||
|
||||
Başlıklar uygulanmıyorsa, `mod_headers` modülünü etkinleştirmek için Hostinger desteğiyle iletişime geçin.
|
||||
|
||||
### Sayfa Yenilemede 404 Hataları
|
||||
|
||||
`.html` uzantı kuralının ve dil yönlendirmelerinin doğru yapılandırıldığından emin olun. BentoPDF, SPA yönlendirmesi değil statik HTML dosyaları kullanır:
|
||||
|
||||
```apache
|
||||
# Language routes serve actual files from language directories
|
||||
RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f
|
||||
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L]
|
||||
|
||||
# Root level pages
|
||||
RewriteCond %{REQUEST_FILENAME}.html -f
|
||||
RewriteRule ^([^/]+)$ $1.html [L]
|
||||
```
|
||||
|
||||
### Dosya Yükleme Sınırları
|
||||
|
||||
Hostinger'ın dosya boyutu sınırları olabilir. Toplu yükleme başarısız olursa WASM dosyalarını ayrı yükleyin.
|
||||
@@ -0,0 +1,538 @@
|
||||
# Kendi Sunucunuzda Barındırma Kılavuzu
|
||||
|
||||
BentoPDF kendi altyapınızda barındırılabilir. Bu kılavuz çeşitli dağıtım seçeneklerini kapsar.
|
||||
|
||||
## Docker / Podman ile Hızlı Başlangıç
|
||||
|
||||
BentoPDF'i kendi sunucunuzda barındırmanın en hızlı yolu:
|
||||
|
||||
> [!TIP]
|
||||
> BentoPDF iki derleme halinde sunulur:
|
||||
>
|
||||
> - **Kendi Sunucunuzda Barındırma derlemesi**: `ghcr.io/alam00000/bentopdf-simple:latest`. Tanıtım arayüzü olmadan (kahraman bölümü, SSS, kullanıcı yorumları, alt bilgi yok) tüm PDF araçlarını içerir. Kurum içi/ekip/organizasyon dağıtımları için bunu kullanın. Özellikleri kısıtlanmış bir "lite" sürüm **değildir**.
|
||||
> - **Ticari derleme**: `ghcr.io/alam00000/bentopdf:latest`. Tanıtım sitesinin tamamını içerir; bentopdf.com'un kendisi ve herkese açık dağıtım yapan ticari lisans sahipleri tarafından kullanılır.
|
||||
>
|
||||
> Emin değilseniz: Kendi Sunucunuzda Barındırma derlemesini çekin.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Office dosyası dönüştürme `SharedArrayBuffer` gerektirir; bu da uygulamanın hem çapraz kaynak yalıtımlı olması hem de güvenli bir bağlamdan sunulması anlamına gelir. Resmi imaj gerekli COOP/COEP başlıklarını zaten gönderir, ancak tarayıcılar `http://192.168.x.x` gibi düz HTTP yerel ağ kaynaklarında `SharedArrayBuffer`'ı yine de devre dışı bırakır.
|
||||
>
|
||||
> `http://localhost` adresini yalnızca aynı cihazdaki testler için kullanın. Kullanıcılar BentoPDF'e bir yerel ağ IP'si veya ana bilgisayar adı üzerinden erişiyorsa, bağlantıyı HTTPS ile sonlandırın.
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker run -d -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Podman
|
||||
podman run -d -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
Veya Docker Compose / Podman Compose ile:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
bentopdf:
|
||||
image: ghcr.io/alam00000/bentopdf-simple:latest
|
||||
ports:
|
||||
- '3000:8080'
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
```bash
|
||||
# Docker Compose
|
||||
docker compose up -d
|
||||
|
||||
# Podman Compose
|
||||
podman-compose up -d
|
||||
```
|
||||
|
||||
## Podman Quadlet (Linux Systemd)
|
||||
|
||||
BentoPDF'i bir systemd hizmeti olarak çalıştırın. `~/.config/containers/systemd/bentopdf.container` dosyasını oluşturun:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
Image=ghcr.io/alam00000/bentopdf-simple: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
|
||||
```
|
||||
|
||||
Tam Quadlet belgeleri için [Docker dağıtım kılavuzuna](/tr/self-hosting/docker) bakın.
|
||||
|
||||
## Kaynaktan Derleme
|
||||
|
||||
```bash
|
||||
# Clone and build
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# The built files are in the `dist` folder
|
||||
```
|
||||
|
||||
## Yapılandırma Seçenekleri
|
||||
|
||||
### Kendi Sunucunuzda Barındırma derlemesi (Basit Mod)
|
||||
|
||||
Kendi Sunucunuzda Barındırma derlemesi (`bentopdf-simple` imajı, Basit Mod olarak da adlandırılır) Ticari derlemeyle **işlevsel olarak aynıdır**: her PDF aracı mevcuttur ve aynı şekilde davranır. Yalnızca bentopdf.com'da veya herkese açık bir ticari dağıtımda anlamlı olan tanıtım arayüzünü gizler. **Özellikleri kısıtlanmış veya "lite" bir sürüm değildir.**
|
||||
|
||||
**Kendi Sunucunuzda Barındırma derlemesinin gizledikleri** (yalnızca görünüm; hiçbir PDF özelliği kaldırılmaz):
|
||||
|
||||
- Gezinme çubuğu, kahraman bölümü, özellikler bölümü, SSS, kullanıcı yorumları, alt bilgi
|
||||
- Sayfa başlığını "PDF Araçları" olarak günceller
|
||||
|
||||
**Kendi Sunucunuzda Barındırma derlemesinin koruduğu** (gerçekten PDF işi yapan her şey):
|
||||
|
||||
- Her PDF aracı (birleştirme, bölme, düzenleme, imzalama, OCR, Office dönüştürme vb.)
|
||||
- Özel marka desteği, tüm derleme zamanı ve çalışma zamanı yapılandırması
|
||||
|
||||
Ticari derleme (`ghcr.io/alam00000/bentopdf:latest`) bentopdf.com'un kendisini çalıştıran ve herkese açık dağıtım yapan ticari lisans sahipleri tarafından kullanılan derlemedir; bir kurum içi araçta anlamlı olmayacak kahraman bölümü, SSS, kullanıcı yorumları ve alt bilgiyi ekler.
|
||||
|
||||
BentoPDF'i ekibiniz, kuruluşunuz veya kurum içi bir araç olarak kendi sunucunuzda barındırıyorsanız, Kendi Sunucunuzda Barındırma derlemesini çekin:
|
||||
|
||||
```bash
|
||||
# Use the pre-built image (recommended)
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
|
||||
|
||||
# Or build it yourself
|
||||
SIMPLE_MODE=true npm run build
|
||||
```
|
||||
|
||||
Tüm ayrıntılar için [SIMPLE_MODE.md](https://github.com/alam00000/bentopdf/blob/main/SIMPLE_MODE.md) dosyasına bakın.
|
||||
|
||||
### Ticari derleme (kendi markanızla herkese açık dağıtımlar)
|
||||
|
||||
Ticari derleme (`bentopdf` imajı, `-simple` soneki olmadan) bentopdf.com'un kendisini çalıştıran derlemedir. Her PDF aracının üzerine tanıtım sitesinin tamamını (kahraman bölümü, özellikler, SSS, kullanıcı yorumları, alt bilgi) ekler. **BentoPDF'i kendi markanız altında herkese açık bir PDF hizmeti olarak dağıtmak** istediğinizde bu derlemeyi kullanın, örneğin:
|
||||
|
||||
- BentoPDF'i kendi alan adınızda son kullanıcılar için barındırılan bir SaaS olarak çalıştırıyorsunuz
|
||||
- Yalnızca çıplak araç arayüzünü değil, açılış sayfası deneyimini (tanıtım bölümleri + araçlar) istiyorsunuz
|
||||
- BentoPDF'i ticari bir ürüne gömen bir ticari lisans sahibisiniz
|
||||
|
||||
**Olduğu gibi çalıştırın** (BentoPDF markası, derlemeyi önizlemek için yararlıdır):
|
||||
|
||||
```bash
|
||||
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
|
||||
```
|
||||
|
||||
**Kendi markanızla derleyin** (tipik ticari iş akışı):
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg VITE_BRAND_NAME="AcmePDF" \
|
||||
--build-arg VITE_BRAND_LOGO="images/acme-logo.svg" \
|
||||
--build-arg VITE_FOOTER_TEXT="© 2026 Acme Corp. All rights reserved." \
|
||||
-t acmepdf .
|
||||
|
||||
docker run -p 3000:8080 acmepdf
|
||||
```
|
||||
|
||||
Diğer tüm derleme zamanı seçenekleri (`BASE_URL`, `VITE_DEFAULT_LANGUAGE`, `DISABLE_TOOLS`, WASM URL geçersiz kılmaları vb.) Kendi Sunucunuzda Barındırma derlemesinde olduğu gibi çalışır.
|
||||
|
||||
::: warning Lisanslama
|
||||
Ticari derlemeyi çalıştırmaya BentoPDF'in iki lisans seçeneğinden biri altında izin verilir:
|
||||
|
||||
- **AGPL-3.0** (ücretsiz): dağıtımınız, marka değişiklikleri ve çevresindeki iş mantığı dahil tüm kaynak kodunu AGPL altında yayımlıyorsa izin verilir.
|
||||
- **Ticari lisans** ($79 ömür boyu): marka fork'unuzu veya iş kodunuzu açık kaynak yapmadığınız kapalı kaynaklı / tescilli dağıtımlar için gereklidir.
|
||||
|
||||
Tam karşılaştırma için [Lisanslama sayfasına](https://www.bentopdf.com/licensing) bakın. AGPL lisanslı WASM modülleri (PyMuPDF, Ghostscript, CoherentPDF) çalışma zamanında bir CDN'den yüklenir, bu nedenle imajınıza girmezler ve lisanslama durumunuzu değiştirmezler.
|
||||
:::
|
||||
|
||||
### Temel URL
|
||||
|
||||
Bir alt dizine dağıtın:
|
||||
|
||||
```bash
|
||||
BASE_URL=/pdf-tools/ npm run build
|
||||
```
|
||||
|
||||
### Özel Marka
|
||||
|
||||
Varsayılan BentoPDF logosunu, adını ve alt bilgi metnini derleme zamanında kendinizinkilerle değiştirin:
|
||||
|
||||
| Değişken | Açıklama | Varsayılan |
|
||||
| ------------------ | --------------------------------------- | --------------------------------------- |
|
||||
| `VITE_BRAND_NAME` | Üst ve alt bilgide gösterilen marka adı | `BentoPDF` |
|
||||
| `VITE_BRAND_LOGO` | `public/` dizinine göre logo yolu | `images/favicon-no-bg.svg` |
|
||||
| `VITE_FOOTER_TEXT` | Özel alt bilgi/telif hakkı metni | `© 2026 BentoPDF. All rights reserved.` |
|
||||
|
||||
```bash
|
||||
# Place your logo in public/, then build
|
||||
VITE_BRAND_NAME="AcmePDF" \
|
||||
VITE_BRAND_LOGO="images/acme-logo.svg" \
|
||||
VITE_FOOTER_TEXT="© 2026 Acme Corp. Internal use only." \
|
||||
npm run build
|
||||
```
|
||||
|
||||
Veya Docker ile:
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg VITE_BRAND_NAME="AcmePDF" \
|
||||
--build-arg VITE_BRAND_LOGO="images/acme-logo.svg" \
|
||||
--build-arg VITE_FOOTER_TEXT="© 2026 Acme Corp. Internal use only." \
|
||||
-t acmepdf .
|
||||
```
|
||||
|
||||
Marka özelleştirme hem tam modda hem de Basit Modda çalışır ve diğer tüm derleme zamanı seçenekleriyle (`BASE_URL`, `SIMPLE_MODE`, `VITE_DEFAULT_LANGUAGE`) birlikte kullanılabilir.
|
||||
|
||||
### Belirli Araçları Devre Dışı Bırakma
|
||||
|
||||
Uyumluluk veya güvenlik için tek tek araçları gizleyin. Devre dışı bırakılan araçlar ana sayfadan, aramadan, kısayollardan, iş akışı oluşturucudan ve doğrudan URL erişiminden kaldırılır.
|
||||
|
||||
Araç kimlikleri, `.html` olmadan sayfa URL'sidir: herhangi bir aracı açıp URL'ye bakın (örn. `edit-pdf`, `sign-pdf`, `encrypt-pdf`).
|
||||
|
||||
**Derleme zamanı** (pakete gömülür):
|
||||
|
||||
```bash
|
||||
DISABLE_TOOLS="edit-pdf,sign-pdf" npm run build
|
||||
```
|
||||
|
||||
**Çalışma zamanı** (yeniden derleme gerekmez, bir `config.json` bağlayın):
|
||||
|
||||
```json
|
||||
{
|
||||
"disabledTools": ["edit-pdf", "sign-pdf"]
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run -d -p 3000:8080 \
|
||||
-v ./config.json:/usr/share/nginx/html/config.json:ro \
|
||||
ghcr.io/alam00000/bentopdf-simple:latest
|
||||
```
|
||||
|
||||
Her iki yöntem birlikte kullanılabilir: listeler birleştirilir.
|
||||
|
||||
Ayrıca `config.json` dosyasına `editorDisabledCategories` ekleyerek, aracın tamamını devre dışı bırakmadan PDF Düzenleyici içindeki belirli özellikleri (örn. karartma) devre dışı bırakabilirsiniz. Kategorilerin tam listesi için [Docker kılavuzuna](/tr/self-hosting/docker#duzenleyici-ozelliklerini-devre-dısı-bırakma) bakın.
|
||||
|
||||
## Dağıtım Kılavuzları
|
||||
|
||||
Platformunuzu seçin:
|
||||
|
||||
- [Vercel](/tr/self-hosting/vercel)
|
||||
- [Netlify](/tr/self-hosting/netlify)
|
||||
- [Cloudflare Pages](/tr/self-hosting/cloudflare)
|
||||
- [AWS S3 + CloudFront](/tr/self-hosting/aws)
|
||||
- [Hostinger](/tr/self-hosting/hostinger)
|
||||
- [Nginx](/tr/self-hosting/nginx)
|
||||
- [Apache](/tr/self-hosting/apache)
|
||||
- [Docker](/tr/self-hosting/docker)
|
||||
- [Kubernetes](/tr/self-hosting/kubernetes)
|
||||
- [CORS Proxy](/tr/self-hosting/cors-proxy) - Dijital imzalar için gereklidir
|
||||
|
||||
## Sık Karşılaşılan Sorunlar
|
||||
|
||||
### Word / ODT / Excel / PowerPoint'ten PDF'ye Dönüştürme Takılıyor (SharedArrayBuffer Kullanılamıyor)
|
||||
|
||||
**Belirti**: LibreOffice tabanlı belge dönüştürmeleri (Word, ODT, Excel, PowerPoint'ten PDF'ye) yaklaşık %55'te takılır veya başlamaz. Tarayıcı konsolu şunu gösterebilir:
|
||||
|
||||
> `ReferenceError: SharedArrayBuffer is not defined`
|
||||
|
||||
...veya `window.crossOriginIsolated` değeri `false` döner ya da WASM derlemesi `expected magic word 00 61 73 6d, found 1f 8b 08 08` bildirir.
|
||||
|
||||
**Neden**: LibreOffice WASM, tarayıcının yalnızca sayfa **çapraz kaynak yalıtımlı** VE **güvenli bir bağlamdan** sunulduğunda etkinleştirdiği `SharedArrayBuffer`'a ihtiyaç duyar. Bunun için iki şeyin doğru olması gerekir:
|
||||
|
||||
1. Her yanıt her iki başlığı da içerir:
|
||||
- `Cross-Origin-Embedder-Policy: require-corp`
|
||||
- `Cross-Origin-Opener-Policy: same-origin`
|
||||
2. Sayfa `https://...` veya `http://localhost` üzerinden sunulur. Yerel ağ IP'sinde düz HTTP (örn. `http://192.168.x.x`) güvenli SAYILMAZ: tarayıcılar orada `SharedArrayBuffer`'ı devre dışı bırakır.
|
||||
|
||||
`00 61 73 6d / 1f 8b 08 08` uyuşmazlığı ayrı bir alt belirtidir: önceden sıkıştırılmış `.wasm.gz` / `.data.gz` dosyalarında `Content-Encoding: gzip` yanıt başlığı eksiktir, bu yüzden tarayıcı açılmış WASM yerine ham gzip baytlarını alır.
|
||||
|
||||
**Çözüm**: tam yapılandırma için platformunuza özel dağıtım kılavuzuna bakın:
|
||||
|
||||
- [Nginx →](/tr/self-hosting/nginx#word-odt-excel-den-pdf-ye-donusturme-calısmıyor)
|
||||
- [Apache →](/tr/self-hosting/apache#word-odt-excel-den-pdf-e-donusturme-calısmıyor)
|
||||
- [AWS S3 + CloudFront →](/tr/self-hosting/aws#adım-3b-response-headers-policy-libreoffice-wasm-icin-gerekli)
|
||||
- [Cloudflare Pages →](/tr/self-hosting/cloudflare#yapılandırma-dosyası) (`_headers` dosyası)
|
||||
- [Netlify →](/tr/self-hosting/netlify#word-odt-excel-den-pdf-ye-donusturme-55-te-takılıyor) (`netlify.toml`)
|
||||
- [Vercel →](/tr/self-hosting/vercel#word-odt-excel-den-pdf-ye-donusturme-calısmıyor) (`vercel.json`)
|
||||
- [Hostinger →](/tr/self-hosting/hostinger#libreoffice-aracları-calısmıyor) (`.htaccess`)
|
||||
- [Kubernetes →](/tr/self-hosting/kubernetes#sharedarraybuffer-baslıklarının-hala-calıstıgından-emin-olma-ingress-gateway)
|
||||
- **Docker**: birlikte gelen nginx yapılandırması tarafından otomatik olarak halledilir, işlem gerekmez.
|
||||
|
||||
**Doğrulama**: herhangi bir BentoPDF sayfasında DevTools Konsolu'nu açın ve şunu çalıştırın:
|
||||
|
||||
```js
|
||||
console.log(window.crossOriginIsolated); // should be true
|
||||
console.log(typeof SharedArrayBuffer); // should be "function"
|
||||
```
|
||||
|
||||
Sayfa HTTPS veya `http://localhost` ise VE her yanıtta hem COEP hem COOP başlıkları varsa, iki kontrol de geçer. `http://192.168.x.x` veya loopback olmayan başka bir HTTP kaynağındaysanız, bağlantıyı HTTPS ile sonlandırın: yalnızca başlıkla çözülebilecek bir çözüm yoktur.
|
||||
|
||||
### `.mjs` Dosyaları `application/octet-stream` Olarak Sunuluyor
|
||||
|
||||
**Belirti**: PDF İmzala / Form Doldurucu / bazı diğer araçlar boş bir görüntüleyici gösterir veya yüklenemez. Tarayıcı konsolu şunu bildirir:
|
||||
|
||||
> `Failed to load module script: The server responded with a non-JavaScript MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.`
|
||||
|
||||
**Neden**: Web sunucunuzda veya ters proxy'nizde `.mjs` dosyaları için bir MIME türü eşlemesi yok (birlikte gelen PDF görüntüleyici ES modüllerini bu uzantıyla sunar). Birçok standart sunucu yapılandırması tanınmayan uzantılar için varsayılan olarak `application/octet-stream` kullanır ve tarayıcılar bunu ES modülü olarak çalıştırmayı reddeder.
|
||||
|
||||
**Çözüm**: tam kod parçacığı için platformunuza özel dağıtım kılavuzuna bakın:
|
||||
|
||||
- [Nginx →](/tr/self-hosting/nginx#pdf-imzala-veya-form-doldurucu-bos-goruntuleyici-gosteriyor-mjs-mime-hatası)
|
||||
- [Apache →](/tr/self-hosting/apache#pdf-imzala-veya-form-doldurucu-bos-goruntuleyici-gosteriyor-mjs-mime-hatası)
|
||||
- [AWS S3 + CloudFront →](/tr/self-hosting/aws#adım-2-derleyin-ve-yukleyin) (`aws s3 cp ... --include "*.mjs"` bölümüne bakın)
|
||||
- [Kubernetes →](/tr/self-hosting/kubernetes#mjs-mime-turu-hataları-pdf-imzala-form-doldurucu-iframe-i-bos)
|
||||
- **Docker, Vercel, Netlify, Cloudflare Pages, Hostinger**: otomatik olarak halledilir, işlem gerekmez.
|
||||
|
||||
**Doğrulama**: DevTools → Network sekmesini açın, başarısız olan `.mjs` isteğini bulun ve `Content-Type` yanıt başlığını kontrol edin. `application/javascript` olmalıdır. Hâlâ `application/octet-stream` ise, dıştaki bir ters proxy veya CDN türü yeniden algılıyor olabilir: sunum zincirinizdeki her katmanı kontrol edin.
|
||||
|
||||
## WASM Yapılandırması (AGPL Bileşenleri)
|
||||
|
||||
BentoPDF, AGPL lisanslı işleme kütüphanelerini kaynak koduna **dahil etmez**, ancak tüm özelliklerin kutudan çıktığı gibi çalışması için **CDN URL'lerini önceden yapılandırır**; elle kurulum gerekmez.
|
||||
|
||||
::: tip Varsayılan Olarak Sıfır Yapılandırma
|
||||
v2.0.0 itibarıyla WASM modülleri, ortam değişkenleriyle jsDelivr CDN'den yüklenecek şekilde önceden yapılandırılmıştır. Tüm gelişmiş özellikler herhangi bir kullanıcı yapılandırması olmadan hemen çalışır.
|
||||
:::
|
||||
|
||||
| Bileşen | Lisans | Özellikler |
|
||||
| --------------- | -------- | -------------------------------------------------------------- |
|
||||
| **PyMuPDF** | AGPL-3.0 | EPUB/MOBI/FB2/XPS dönüştürme, görsel çıkarma, tablo çıkarma |
|
||||
| **Ghostscript** | AGPL-3.0 | PDF/A dönüştürme, sıkıştırma, eğrilik düzeltme, rasterleştirme |
|
||||
| **CoherentPDF** | AGPL-3.0 | İçindekiler, ekler, yer işaretleriyle PDF birleştirme |
|
||||
|
||||
### Varsayılan Ortam Değişkenleri
|
||||
|
||||
Bunlar `.env.production` dosyasında ayarlanır ve derlemeye gömülür:
|
||||
|
||||
```bash
|
||||
VITE_WASM_PYMUPDF_URL=https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm@0.11.16/
|
||||
VITE_WASM_GS_URL=https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm@0.1.1/assets/
|
||||
VITE_WASM_CPDF_URL=https://cdn.jsdelivr.net/npm/coherentpdf@2.5.5/dist/
|
||||
VITE_TESSERACT_WORKER_URL=
|
||||
VITE_TESSERACT_CORE_URL=
|
||||
VITE_TESSERACT_LANG_URL=
|
||||
VITE_TESSERACT_AVAILABLE_LANGUAGES=
|
||||
VITE_OCR_FONT_BASE_URL=
|
||||
```
|
||||
|
||||
### WASM URL'lerini Geçersiz Kılma
|
||||
|
||||
Özel dağıtımlar için varsayılanları derleme zamanında geçersiz kılabilirsiniz:
|
||||
|
||||
```bash
|
||||
# Via Docker build args
|
||||
docker build \
|
||||
--build-arg VITE_WASM_PYMUPDF_URL=https://your-server.com/pymupdf/ \
|
||||
--build-arg VITE_WASM_GS_URL=https://your-server.com/gs/ \
|
||||
--build-arg VITE_WASM_CPDF_URL=https://your-server.com/cpdf/ \
|
||||
--build-arg VITE_TESSERACT_WORKER_URL=https://your-server.com/ocr/worker.min.js \
|
||||
--build-arg VITE_TESSERACT_CORE_URL=https://your-server.com/ocr/core \
|
||||
--build-arg VITE_TESSERACT_LANG_URL=https://your-server.com/ocr/lang-data \
|
||||
--build-arg VITE_TESSERACT_AVAILABLE_LANGUAGES=eng,deu \
|
||||
--build-arg VITE_OCR_FONT_BASE_URL=https://your-server.com/ocr/fonts \
|
||||
-t bentopdf .
|
||||
|
||||
# Or via .env.production before building from source
|
||||
VITE_WASM_PYMUPDF_URL=https://your-server.com/pymupdf/ npm run build
|
||||
```
|
||||
|
||||
Bir modülü tamamen devre dışı bırakmak için (kullanıcının Gelişmiş Ayarlar üzerinden elle yapılandırmasını gerektirir), değişkenini boş bir dizeye ayarlayın.
|
||||
|
||||
OCR için ya tüm `VITE_TESSERACT_*` değişkenlerini boş bırakıp varsayılan çevrimiçi varlıkları kullanın ya da kendi sunucunuzda/çevrimdışı OCR için worker/core/lang URL'lerini birlikte ayarlayın. Yalnızca belirli OCR dillerini pakete dahil ederseniz, arayüzün yalnızca kurulu dilleri sunması ve desteklenmeyen seçimlerin açıklayıcı bir hatayla başarısız olması için `VITE_TESSERACT_AVAILABLE_LANGUAGES` değişkenini de aynı virgülle ayrılmış kodlara ayarlayın. Tam çevrimdışı aranabilir PDF çıktısı için ayrıca `VITE_OCR_FONT_BASE_URL` değişkenini, birlikte gelen OCR yazı tiplerini sunan dahili dizine ayarlayın.
|
||||
|
||||
Kullanıcılar ayrıca bu varsayılanları arayüzdeki **Gelişmiş Ayarlar** üzerinden istedikleri zaman geçersiz kılabilir: tarayıcıda saklanan kullanıcı geçersiz kılmaları ortam varsayılanlarına göre önceliklidir.
|
||||
|
||||
### Hava Boşluklu / Çevrimdışı Dağıtım
|
||||
|
||||
İnternet erişimi olmayan ağlar için (kamu, sağlık, finans vb.). WASM URL'leri JavaScript'e **derleme zamanında** gömülür; gerçek WASM dosyaları çalışma zamanında **kullanıcının tarayıcısı** tarafından indirilir. Bu nedenle her şeyi internet erişimi olan bir makinede hazırlayıp yalıtılmış ağa aktarmanız gerekir.
|
||||
|
||||
#### Otomatik Betik (Önerilen)
|
||||
|
||||
Birlikte gelen `prepare-airgap.sh` betiği tüm süreci otomatikleştirir: WASM paketlerini indirir, Docker imajını derler ve bir kurulum betiğiyle birlikte kendi kendine yeten bir paket üretir.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
|
||||
# Show supported OCR language codes (for --ocr-languages)
|
||||
bash scripts/prepare-airgap.sh --list-ocr-languages
|
||||
|
||||
# Search OCR language codes by name or abbreviation
|
||||
bash scripts/prepare-airgap.sh --search-ocr-language german
|
||||
|
||||
# Interactive mode — prompts for all options
|
||||
bash scripts/prepare-airgap.sh
|
||||
|
||||
# Or fully automated
|
||||
bash scripts/prepare-airgap.sh --wasm-base-url https://internal.example.com/wasm
|
||||
```
|
||||
|
||||
Bu, bir paket dizini üretir:
|
||||
|
||||
```
|
||||
bentopdf-airgap-bundle/
|
||||
bentopdf.tar # Docker image
|
||||
*.tgz # WASM packages (PyMuPDF, Ghostscript, CoherentPDF, Tesseract)
|
||||
tesseract-langdata/ # OCR traineddata files
|
||||
ocr-fonts/ # OCR text-layer font files
|
||||
setup.sh # Setup script for the air-gapped side
|
||||
README.md # Instructions
|
||||
```
|
||||
|
||||
Paketi USB, kurum içi yapıt deposu veya onaylı bir yöntemle hava boşluklu ağa aktarın. Ardından birlikte gelen kurulum betiğini çalıştırın:
|
||||
|
||||
```bash
|
||||
cd bentopdf-airgap-bundle
|
||||
bash setup.sh
|
||||
```
|
||||
|
||||
Kurulum betiği Docker imajını yükler, WASM dosyalarını çıkarır ve isteğe bağlı olarak kapsayıcıyı başlatır.
|
||||
|
||||
**Betik seçenekleri:**
|
||||
|
||||
| Bayrak | Açıklama | Varsayılan |
|
||||
| ------------------------------ | ----------------------------------------------------------------- | ---------------------------- |
|
||||
| `--wasm-base-url <url>` | WASM'lerin dahili olarak barındırılacağı yer | _(zorunlu, eksikse sorulur)_ |
|
||||
| `--image-name <name>` | Docker imaj etiketi | `bentopdf` |
|
||||
| `--output-dir <path>` | Çıktı paketi dizini | `./bentopdf-airgap-bundle` |
|
||||
| `--simple-mode` | Basit Modu etkinleştirir | kapalı |
|
||||
| `--base-url <path>` | Alt dizin temel URL'si (örn. `/pdf/`) | `/` |
|
||||
| `--language <code>` | Varsayılan arayüz dili (örn. `fr`, `de`) | _(yok)_ |
|
||||
| `--brand-name <name>` | Özel marka adı | _(yok)_ |
|
||||
| `--brand-logo <path>` | `public/` dizinine göre logo yolu | _(yok)_ |
|
||||
| `--footer-text <text>` | Özel alt bilgi metni | _(yok)_ |
|
||||
| `--ocr-languages <list>` | Pakete dahil edilecek virgülle ayrılmış OCR dilleri | `eng` |
|
||||
| `--list-ocr-languages` | Desteklenen OCR kodlarını ve adlarını yazdırır, sonra çıkar | kapalı |
|
||||
| `--search-ocr-language <term>` | OCR kodlarını ada veya kısaltmaya göre arar | kapalı |
|
||||
| `--dockerfile <path>` | Kullanılacak Dockerfile | `Dockerfile` |
|
||||
| `--skip-docker` | Docker derlemesini ve dışa aktarmayı atlar | kapalı |
|
||||
| `--skip-wasm` | WASM indirmeyi atlar (mevcut `.tgz` dosyalarını yeniden kullanır) | kapalı |
|
||||
|
||||
Etkileşimli istem ayrıca tam desteklenen Tesseract kod listesini yazdırmak için `list` ve `search german` veya `search chi` gibi eşleşmeleri bulmak için `search <term>` kabul eder.
|
||||
|
||||
::: warning Aynı Kaynak Gereksinimi
|
||||
WASM dosyaları BentoPDF uygulamasıyla **aynı kaynaktan** sunulmalıdır. Web Worker'lar, komut dosyalarını çapraz kaynaktan yükleyemeyen `importScripts()` kullanır. Örneğin BentoPDF `https://internal.example.com` adresinde çalışıyorsa, WASM temel URL'si de `https://internal.example.com/wasm` olmalıdır.
|
||||
:::
|
||||
|
||||
#### Elle Adımlar
|
||||
|
||||
<details>
|
||||
<summary>Betik olmadan elle yapmayı tercih ediyorsanız</summary>
|
||||
|
||||
**Adım 1: WASM ve OCR paketlerini indirin** (internet erişimi olan bir makinede)
|
||||
|
||||
```bash
|
||||
npm pack @bentopdf/pymupdf-wasm@0.11.14
|
||||
npm pack @bentopdf/gs-wasm
|
||||
npm pack coherentpdf
|
||||
npm pack tesseract.js@7.0.0
|
||||
npm pack tesseract.js-core@7.0.0
|
||||
mkdir -p tesseract-langdata
|
||||
curl -fsSL https://cdn.jsdelivr.net/npm/@tesseract.js-data/eng/4.0.0_best_int/eng.traineddata.gz -o tesseract-langdata/eng.traineddata.gz
|
||||
mkdir -p ocr-fonts
|
||||
curl -fsSL https://raw.githack.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSans/NotoSans-Regular.ttf -o ocr-fonts/NotoSans-Regular.ttf
|
||||
```
|
||||
|
||||
**Adım 2: Docker imajını dahili URL'lerle derleyin**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
|
||||
docker build \
|
||||
--build-arg VITE_WASM_PYMUPDF_URL=https://internal-server.example.com/wasm/pymupdf/ \
|
||||
--build-arg VITE_WASM_GS_URL=https://internal-server.example.com/wasm/gs/ \
|
||||
--build-arg VITE_WASM_CPDF_URL=https://internal-server.example.com/wasm/cpdf/ \
|
||||
--build-arg VITE_TESSERACT_WORKER_URL=https://internal-server.example.com/wasm/ocr/worker.min.js \
|
||||
--build-arg VITE_TESSERACT_CORE_URL=https://internal-server.example.com/wasm/ocr/core \
|
||||
--build-arg VITE_TESSERACT_LANG_URL=https://internal-server.example.com/wasm/ocr/lang-data \
|
||||
--build-arg VITE_OCR_FONT_BASE_URL=https://internal-server.example.com/wasm/ocr/fonts \
|
||||
-t bentopdf .
|
||||
```
|
||||
|
||||
**Adım 3: Docker imajını dışa aktarın**
|
||||
|
||||
```bash
|
||||
docker save bentopdf -o bentopdf.tar
|
||||
```
|
||||
|
||||
**Adım 4: Hava boşluklu ağa aktarın**
|
||||
|
||||
USB, kurum içi yapıt deposu veya onaylı aktarım yöntemiyle kopyalayın:
|
||||
|
||||
- `bentopdf.tar`: Docker imajı
|
||||
- Adım 1'deki beş `.tgz` WASM/OCR paketi
|
||||
- Adım 1'deki `tesseract-langdata/` dizini
|
||||
- Adım 1'deki `ocr-fonts/` dizini
|
||||
|
||||
**Adım 5: Hava boşluklu ağın içinde kurun**
|
||||
|
||||
```bash
|
||||
# Load the Docker image
|
||||
docker load -i bentopdf.tar
|
||||
|
||||
# Extract WASM packages
|
||||
mkdir -p ./wasm/pymupdf ./wasm/gs ./wasm/cpdf ./wasm/ocr/core ./wasm/ocr/lang-data ./wasm/ocr/fonts
|
||||
tar xzf bentopdf-pymupdf-wasm-0.11.14.tgz -C ./wasm/pymupdf --strip-components=1
|
||||
tar xzf bentopdf-gs-wasm-*.tgz -C ./wasm/gs --strip-components=1
|
||||
tar xzf coherentpdf-*.tgz -C ./wasm/cpdf --strip-components=1
|
||||
TEMP_TESS=$(mktemp -d)
|
||||
tar xzf tesseract.js-7.0.0.tgz -C "$TEMP_TESS"
|
||||
cp "$TEMP_TESS/package/dist/worker.min.js" ./wasm/ocr/worker.min.js
|
||||
rm -rf "$TEMP_TESS"
|
||||
tar xzf tesseract.js-core-7.0.0.tgz -C ./wasm/ocr/core --strip-components=1
|
||||
cp ./tesseract-langdata/*.traineddata.gz ./wasm/ocr/lang-data/
|
||||
cp ./ocr-fonts/* ./wasm/ocr/fonts/
|
||||
|
||||
# Run BentoPDF
|
||||
docker run -d -p 3000:8080 --restart unless-stopped bentopdf
|
||||
```
|
||||
|
||||
Dosyaların Adım 2'de yapılandırdığınız URL'lerde, yani `.../ocr/worker.min.js`, `.../ocr/core`, `.../ocr/lang-data` ve `.../ocr/fonts` dahil erişilebilir olduğundan emin olun.
|
||||
|
||||
</details>
|
||||
|
||||
::: info Docker yerine kaynaktan mı derliyorsunuz?
|
||||
`npm run build` çalıştırmadan önce değişkenleri `.env.production` dosyasında ayarlayın:
|
||||
|
||||
```bash
|
||||
VITE_WASM_PYMUPDF_URL=https://internal-server.example.com/wasm/pymupdf/
|
||||
VITE_WASM_GS_URL=https://internal-server.example.com/wasm/gs/
|
||||
VITE_WASM_CPDF_URL=https://internal-server.example.com/wasm/cpdf/
|
||||
VITE_TESSERACT_WORKER_URL=https://internal-server.example.com/wasm/ocr/worker.min.js
|
||||
VITE_TESSERACT_CORE_URL=https://internal-server.example.com/wasm/ocr/core
|
||||
VITE_TESSERACT_LANG_URL=https://internal-server.example.com/wasm/ocr/lang-data
|
||||
VITE_OCR_FONT_BASE_URL=https://internal-server.example.com/wasm/ocr/fonts
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Kendi WASM Proxy'nizi Barındırma
|
||||
|
||||
AGPL WASM dosyalarını uygun CORS başlıklarıyla sunmanız gerekiyorsa basit bir proxy dağıtabilirsiniz. Örnek bir uygulama için [Cloudflare WASM Proxy kılavuzuna](https://github.com/alam00000/bentopdf/blob/main/cloudflare/WASM-PROXY.md) bakın.
|
||||
|
||||
::: tip Neden Ayrı?
|
||||
Bu ayrım şunları sağlar:
|
||||
|
||||
- Ticari kullanıcılar için net yasal uyumluluk
|
||||
- BentoPDF çekirdeğinin ikili lisansı (AGPL-3.0 / Ticari) altında kalması
|
||||
- WASM dosyalarının kaynağa dahil edilmeden çalışma zamanında yüklenmesi
|
||||
:::
|
||||
|
||||
## Sistem Gereksinimleri
|
||||
|
||||
| Gereksinim | Asgari |
|
||||
| ---------- | ----------------------------------------- |
|
||||
| Depolama | ~100 MB (AGPL modülleri olmadan çekirdek) |
|
||||
| RAM | 512 MB |
|
||||
| CPU | Herhangi bir modern işlemci |
|
||||
|
||||
::: tip
|
||||
BentoPDF statik bir sitedir: veritabanı veya arka uç sunucusu gerekmez!
|
||||
:::
|
||||
@@ -0,0 +1,211 @@
|
||||
# Kubernetes ile Dağıtım
|
||||
|
||||
Kubernetes statik bir site için gereğinden fazla olabilir, ancak zaten Helm + GitOps standardını kullanıyorsanız çok iyi bir seçim olabilir.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Office Dosyası Dönüştürme için Gerekli Başlıklar**
|
||||
>
|
||||
> LibreOffice tabanlı araçlar (Word, Excel, PowerPoint dönüştürme) `SharedArrayBuffer` desteği için şu HTTP başlıklarını gerektirir:
|
||||
>
|
||||
> - `Cross-Origin-Opener-Policy: same-origin`
|
||||
> - `Cross-Origin-Embedder-Policy: require-corp`
|
||||
>
|
||||
> Resmi BentoPDF nginx imajları bu başlıkları içerir. Kubernetes'te **Ingress/Gateway denetleyicileri de birer ters proxy'dir**, bu nedenle bu başlıkların korunduğundan emin olun (veya uç katmanda ekleyin).
|
||||
|
||||
## Ön Koşullar
|
||||
|
||||
- Kubernetes kümesi
|
||||
- Helm v3
|
||||
- **8080 numaralı bağlantı noktasında** hizmet veren bir BentoPDF nginx imajı (örn. `ghcr.io/alam00000/bentopdf:<tag>`)
|
||||
|
||||
## Helm ile Dağıtım
|
||||
|
||||
### Bu depodan kurulum (yerel chart)
|
||||
|
||||
```bash
|
||||
kubectl create namespace bentopdf
|
||||
|
||||
helm upgrade --install bentopdf /path/to/bentopdf/chart \
|
||||
--namespace bentopdf \
|
||||
--set image.repository=ghcr.io/alam00000/bentopdf \
|
||||
--set image.tag=latest
|
||||
```
|
||||
|
||||
### GHCR'den kurulum (OCI chart)
|
||||
|
||||
Chart GHCR'de OCI yapıtı olarak yayımlanmışsa:
|
||||
|
||||
```bash
|
||||
export GHCR_USERNAME="<github-org-or-user>"
|
||||
|
||||
helm upgrade --install bentopdf oci://ghcr.io/$GHCR_USERNAME/charts/bentopdf \
|
||||
--namespace bentopdf \
|
||||
--create-namespace \
|
||||
--version 0.1.0 \
|
||||
--set image.repository=ghcr.io/alam00000/bentopdf \
|
||||
--set image.tag=latest
|
||||
```
|
||||
|
||||
## Erişime Açma
|
||||
|
||||
### Port-forward (hızlı test)
|
||||
|
||||
```bash
|
||||
kubectl -n bentopdf port-forward deploy/bentopdf 8080:8080
|
||||
```
|
||||
|
||||
### Ingress (isteğe bağlı)
|
||||
|
||||
Ingress'i etkinleştirin (nginx-ingress için örnek):
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
hosts:
|
||||
- host: pdf.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
```
|
||||
|
||||
### Gateway API (isteğe bağlı)
|
||||
|
||||
Bu chart, Gateway API `Gateway` + `HTTPRoute` yapılarını destekler.
|
||||
|
||||
Örnek (Cloudflare Gateway API operatörü):
|
||||
|
||||
```yaml
|
||||
gateway:
|
||||
enabled: true
|
||||
name: bento-tunnel
|
||||
namespace: bentopdf
|
||||
gatewayClassName: cloudflare
|
||||
|
||||
httpRoute:
|
||||
enabled: true
|
||||
parentRefs:
|
||||
- name: bento-tunnel
|
||||
namespace: bentopdf
|
||||
sectionName: http
|
||||
hostnames:
|
||||
- pdfs.example.com
|
||||
```
|
||||
|
||||
## SharedArrayBuffer Başlıklarının Hâlâ Çalıştığından Emin Olma (Ingress/Gateway)
|
||||
|
||||
### Ne olması "gerekir"
|
||||
|
||||
BentoPDF'in nginx yapılandırması gerekli yanıt başlıklarını ayarlar. Çoğu Ingress/Gateway denetleyicisi **üst akış yanıt başlıklarını değiştirmeden iletir**.
|
||||
|
||||
### Neyi bozabilir
|
||||
|
||||
- Yanıt başlıklarını **geçersiz kılan** veya **kaldıran** bir denetleyici/uç politikası
|
||||
- Farklı COOP/COEP değerleri ayarlayan bir "güvenlik başlıkları" ara katmanı
|
||||
|
||||
### Nasıl doğrulanır
|
||||
|
||||
Bunu herkese açık uç noktanıza karşı çalıştırın:
|
||||
|
||||
```bash
|
||||
curl -I https://pdf.example.com/ | egrep -i 'cross-origin-opener-policy|cross-origin-embedder-policy'
|
||||
```
|
||||
|
||||
Şunları görmelisiniz:
|
||||
|
||||
- `Cross-Origin-Opener-Policy: same-origin`
|
||||
- `Cross-Origin-Embedder-Policy: require-corp`
|
||||
|
||||
### Ingress denetleyiciniz bunları korumuyorsa
|
||||
|
||||
Başlıkları uç katmanda ekleyin (denetleyiciye özgüdür). **nginx-ingress** için örnek:
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
```
|
||||
|
||||
## `.mjs` MIME türü hataları (PDF İmzala / Form Doldurucu iframe'i boş)
|
||||
|
||||
Tarayıcı konsolunda bir `.mjs` isteğinde `Failed to load module script: ... non-JavaScript MIME type "application/octet-stream"` görüyorsanız, BentoPDF nginx'inin önündeki bir Ingress/Gateway denetleyicisi üst akıştaki `Content-Type` başlığını `application/octet-stream` ile değiştiriyor demektir.
|
||||
|
||||
BentoPDF imajındaki nginx `.mjs` dosyalarını zaten `application/javascript` olarak sunar. Çözüm, denetleyicinin bunu kaldırmasını/değiştirmesini engellemektir. nginx-ingress için:
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
location ~* \.mjs$ {
|
||||
types {} default_type application/javascript;
|
||||
}
|
||||
```
|
||||
|
||||
Veya Gateway API'de `.mjs` yolları için `Content-Type: application/javascript` ayarlamak üzere bir `ResponseHeaderModifier` filtresi kullanın. DevTools → Network sekmesiyle doğrulayın: başarısız olan `.mjs` isteği artık `content-type: application/javascript` göstermelidir.
|
||||
|
||||
### Gateway API kullanıyorsanız ve başlıkları zorla eklemek istiyorsanız
|
||||
|
||||
Gateway API bir `ResponseHeaderModifier` filtresi destekler. Bunu `httpRoute.rules[*].filters` içine ekleyebilirsiniz:
|
||||
|
||||
```yaml
|
||||
httpRoute:
|
||||
enabled: true
|
||||
hostnames: [pdf.example.com]
|
||||
parentRefs:
|
||||
- name: bento-tunnel
|
||||
namespace: misc
|
||||
sectionName: http
|
||||
rules:
|
||||
- matches:
|
||||
- path: { type: PathPrefix, value: / }
|
||||
filters:
|
||||
- type: ResponseHeaderModifier
|
||||
responseHeaderModifier:
|
||||
set:
|
||||
- name: Cross-Origin-Opener-Policy
|
||||
value: same-origin
|
||||
- name: Cross-Origin-Embedder-Policy
|
||||
value: require-corp
|
||||
```
|
||||
|
||||
Belirli filtrelerin desteği Gateway denetleyicinize bağlıdır; bir filtre yok sayılırsa başlıkları bunun yerine uç/denetleyici katmanında ekleyin.
|
||||
|
||||
## Belirli Araçları Devre Dışı Bırakma
|
||||
|
||||
İmajı yeniden derlemeden çalışma zamanında araçları devre dışı bırakmak için bir ConfigMap kullanın:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: bentopdf-config
|
||||
namespace: bentopdf
|
||||
data:
|
||||
config.json: |
|
||||
{
|
||||
"disabledTools": ["edit-pdf", "sign-pdf", "encrypt-pdf"]
|
||||
}
|
||||
```
|
||||
|
||||
Bunu sunulan dizine bağlayın:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: bentopdf
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /usr/share/nginx/html/config.json
|
||||
subPath: config.json
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: bentopdf-config
|
||||
```
|
||||
|
||||
Araç kimlikleri, `.html` olmadan sayfa URL'sidir: herhangi bir aracı açıp URL'ye bakın (örn. `edit-pdf`, `merge-pdf`, `compress-pdf`). Devre dışı bırakılan araçlar ana sayfadan, aramadan, kısayollardan, iş akışı oluşturucudan ve doğrudan URL erişiminden gizlenir. Seçeneklerin tam listesi için [Docker kılavuzuna](/tr/self-hosting/docker#belirli-aracları-devre-dısı-bırakma) bakın.
|
||||
@@ -0,0 +1,139 @@
|
||||
# Netlify'a Dağıtım
|
||||
|
||||
[Netlify](https://netlify.com), cömert bir ücretsiz katmanla mükemmel statik site barındırma sunar.
|
||||
|
||||
## Tek Tıkla Dağıtım
|
||||
|
||||
[](https://app.netlify.com/start/deploy?repository=https://github.com/alam00000/bentopdf)
|
||||
|
||||
## Elle Dağıtım
|
||||
|
||||
### Adım 1: Depoyu Bağlayın
|
||||
|
||||
1. [Netlify](https://app.netlify.com)'a giriş yapın
|
||||
2. "Add new site" → "Import an existing project" seçeneğine tıklayın
|
||||
3. GitHub hesabınızı bağlayın
|
||||
4. BentoPDF fork'unuzu seçin
|
||||
|
||||
### Adım 2: Derleme Ayarlarını Yapılandırın
|
||||
|
||||
| Ayar | Değer |
|
||||
| -------------- | --------------- |
|
||||
| Derleme komutu | `npm run build` |
|
||||
| Yayın dizini | `dist` |
|
||||
| Node sürümü | 18+ |
|
||||
|
||||
### Adım 3: Dağıtın
|
||||
|
||||
"Deploy site"a tıklayın ve derlemenin bitmesini bekleyin.
|
||||
|
||||
## Yapılandırma Dosyası
|
||||
|
||||
Proje kök dizininizde `netlify.toml` oluşturun:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
command = "npm run build"
|
||||
publish = "dist"
|
||||
|
||||
[build.environment]
|
||||
NODE_VERSION = "18"
|
||||
|
||||
# Required security headers for SharedArrayBuffer (used by LibreOffice WASM)
|
||||
[[headers]]
|
||||
for = "/*"
|
||||
[headers.values]
|
||||
Cross-Origin-Embedder-Policy = "require-corp"
|
||||
Cross-Origin-Opener-Policy = "same-origin"
|
||||
Cross-Origin-Resource-Policy = "cross-origin"
|
||||
|
||||
# Pre-compressed LibreOffice WASM binary - must be served with Content-Encoding
|
||||
[[headers]]
|
||||
for = "/libreoffice-wasm/soffice.wasm.gz"
|
||||
[headers.values]
|
||||
Content-Type = "application/wasm"
|
||||
Content-Encoding = "gzip"
|
||||
Cache-Control = "public, max-age=31536000, immutable"
|
||||
|
||||
# Pre-compressed LibreOffice WASM data - must be served with Content-Encoding
|
||||
[[headers]]
|
||||
for = "/libreoffice-wasm/soffice.data.gz"
|
||||
[headers.values]
|
||||
Content-Type = "application/octet-stream"
|
||||
Content-Encoding = "gzip"
|
||||
Cache-Control = "public, max-age=31536000, immutable"
|
||||
|
||||
# Cache other WASM files
|
||||
[[headers]]
|
||||
for = "*.wasm"
|
||||
[headers.values]
|
||||
Cache-Control = "public, max-age=31536000, immutable"
|
||||
Content-Type = "application/wasm"
|
||||
|
||||
# SPA routing
|
||||
[[redirects]]
|
||||
from = "/*"
|
||||
to = "/index.html"
|
||||
status = 200
|
||||
```
|
||||
|
||||
::: warning Önemli
|
||||
`Cross-Origin-Embedder-Policy` ve `Cross-Origin-Opener-Policy` başlıkları Word/ODT/Excel/PowerPoint'ten PDF'ye dönüştürmeler için gereklidir. Bunlar olmadan `SharedArrayBuffer` kullanılamaz ve LibreOffice WASM motoru başlatılamaz.
|
||||
|
||||
`.wasm.gz` ve `.data.gz` dosyalarındaki `Content-Encoding: gzip` başlıkları, tarayıcıya bunları otomatik olarak açmasını söyler. Bunlar olmadan tarayıcı ham gzip baytlarını alır ve WASM derlemesi başarısız olur.
|
||||
:::
|
||||
|
||||
## Ortam Değişkenleri
|
||||
|
||||
Bunları Site settings → Environment variables bölümünde ayarlayın:
|
||||
|
||||
| Değişken | Açıklama |
|
||||
| ----------------------- | ------------------------------------------------------------- |
|
||||
| `SIMPLE_MODE` | Asgari derleme için `true` yapın |
|
||||
| `VITE_BRAND_NAME` | Özel marka adı ("BentoPDF" yerine geçer) |
|
||||
| `VITE_BRAND_LOGO` | `public/` dizinine göre logo yolu (örn. `images/my-logo.svg`) |
|
||||
| `VITE_FOOTER_TEXT` | Özel alt bilgi/telif hakkı metni |
|
||||
| `VITE_DEFAULT_LANGUAGE` | Varsayılan arayüz dili (örn. `fr`, `de`, `es`) |
|
||||
|
||||
## Özel Alan Adı
|
||||
|
||||
1. Site settings → Domain management bölümüne gidin
|
||||
2. "Add custom domain"e tıklayın
|
||||
3. DNS yapılandırma yönergelerini izleyin
|
||||
|
||||
## Büyük Medya
|
||||
|
||||
Büyük WASM dosyaları için [Netlify Large Media](https://docs.netlify.com/large-media/overview/) özelliğini etkinleştirmeyi düşünebilirsiniz:
|
||||
|
||||
```bash
|
||||
netlify lm:setup
|
||||
git lfs track "*.wasm"
|
||||
```
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### Word/ODT/Excel'den PDF'ye Dönüştürme %55'te Takılıyor
|
||||
|
||||
Belge dönüştürmeleri %55'te takılırsa DevTools Konsolu'nu açıp şunları kontrol edin:
|
||||
|
||||
```js
|
||||
console.log(window.crossOriginIsolated); // should be true
|
||||
console.log(typeof SharedArrayBuffer); // should be "function"
|
||||
```
|
||||
|
||||
`crossOriginIsolated` değeri `false` ise, `netlify.toml` dosyanızdaki COEP/COOP başlıkları uygulanmıyor demektir. Dosyanın proje kök dizininizde olduğundan emin olun ve yeniden dağıtın.
|
||||
|
||||
Konsolda `expected magic word 00 61 73 6d, found 1f 8b 08 08` görüyorsanız, `.wasm.gz` dosyalarında `Content-Encoding: gzip` başlıkları eksiktir. `soffice.wasm.gz` ve `soffice.data.gz` için `[[headers]]` bloklarının `netlify.toml` dosyanızda olduğundan emin olun.
|
||||
|
||||
### Derleme Başarısız Oluyor
|
||||
|
||||
Node sürümü uyumluluğunu kontrol edin:
|
||||
|
||||
```toml
|
||||
[build.environment]
|
||||
NODE_VERSION = "20"
|
||||
```
|
||||
|
||||
### Yavaş İlk Yükleme
|
||||
|
||||
Site settings → Build & deploy → Asset optimization bölümünde varlık optimizasyonunu etkinleştirin.
|
||||
@@ -0,0 +1,232 @@
|
||||
# Nginx ile Dağıtım
|
||||
|
||||
BentoPDF'i Nginx kullanarak kendi sunucunuzda barındırın.
|
||||
|
||||
## Ön Koşullar
|
||||
|
||||
- Ubuntu/Debian sunucu
|
||||
- Kurulu Nginx
|
||||
- SSL sertifikası (önerilen: Let's Encrypt)
|
||||
|
||||
## Adım 1: Projeyi Derleyin
|
||||
|
||||
```bash
|
||||
git clone https://github.com/alam00000/bentopdf.git
|
||||
cd bentopdf
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Markayı özelleştirmek için derlemeden önce ortam değişkenlerini ayarlayın:
|
||||
|
||||
```bash
|
||||
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
|
||||
```
|
||||
|
||||
## Adım 2: Dosyaları Kopyalayın
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /var/www/bentopdf
|
||||
sudo cp -r dist/* /var/www/bentopdf/
|
||||
sudo chown -R www-data:www-data /var/www/bentopdf
|
||||
```
|
||||
|
||||
## Adım 3: Nginx Yapılandırması
|
||||
|
||||
`/etc/nginx/sites-available/bentopdf` dosyasını oluşturun:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your-domain.com;
|
||||
|
||||
# SSL Configuration
|
||||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||||
|
||||
root /var/www/bentopdf;
|
||||
index index.html;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/wasm;
|
||||
gzip_min_length 1000;
|
||||
|
||||
# WASM MIME type
|
||||
types {
|
||||
application/wasm wasm;
|
||||
}
|
||||
|
||||
# Required headers for SharedArrayBuffer (LibreOffice WASM)
|
||||
# These must be on every response - especially HTML pages
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
||||
|
||||
# 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;
|
||||
|
||||
# Pre-compressed LibreOffice WASM binary
|
||||
location ~* /libreoffice-wasm/soffice\.wasm\.gz$ {
|
||||
gzip off;
|
||||
types {} default_type application/wasm;
|
||||
add_header Content-Encoding gzip;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
}
|
||||
|
||||
# Pre-compressed LibreOffice WASM data
|
||||
location ~* /libreoffice-wasm/soffice\.data\.gz$ {
|
||||
gzip off;
|
||||
types {} default_type application/octet-stream;
|
||||
add_header Content-Encoding gzip;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
}
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|wasm)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
}
|
||||
|
||||
# SPA routing - serve index.html for all routes
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Adım 4: Siteyi Etkinleştirin
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## Adım 5: Let's Encrypt ile SSL
|
||||
|
||||
```bash
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d your-domain.com
|
||||
```
|
||||
|
||||
## Alt Dizinde Dağıtım
|
||||
|
||||
`/pdf/` altında barındırmak için:
|
||||
|
||||
```nginx
|
||||
location /pdf/ {
|
||||
alias /var/www/bentopdf/;
|
||||
try_files $uri $uri/ /pdf/index.html;
|
||||
}
|
||||
```
|
||||
|
||||
Şununla derleyin:
|
||||
|
||||
```bash
|
||||
BASE_URL=/pdf/ npm run build
|
||||
```
|
||||
|
||||
## Performans İyileştirme
|
||||
|
||||
`nginx.conf` dosyasına ekleyin:
|
||||
|
||||
```nginx
|
||||
http {
|
||||
# Enable sendfile
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
# Increase buffer sizes
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Worker connections
|
||||
worker_connections 2048;
|
||||
}
|
||||
```
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### WASM Yüklenmiyor
|
||||
|
||||
MIME türünün ayarlandığından emin olun:
|
||||
|
||||
```nginx
|
||||
types {
|
||||
application/wasm wasm;
|
||||
}
|
||||
```
|
||||
|
||||
### PDF İmzala veya Form Doldurucu Boş Görüntüleyici Gösteriyor (`.mjs` MIME hatası)
|
||||
|
||||
Tarayıcı konsolunda şunu görüyorsanız:
|
||||
|
||||
```
|
||||
Failed to load module script: The server responded with a non-JavaScript
|
||||
MIME type of "application/octet-stream". Strict MIME type checking is
|
||||
enforced for module scripts per HTML spec.
|
||||
```
|
||||
|
||||
...ve başarısız olan istek `.mjs` ile bitiyorsa, nginx'inizde `.mjs → application/javascript` eşlemesi eksiktir. Gömülü PDF görüntüleyici (PDF İmzala, Form Doldurucu ve birkaç başka araç tarafından kullanılır) `.mjs` uzantılı ES modül dosyaları içerir ve nginx'in standart `mime.types` dosyası bunları varsayılan olarak içermez.
|
||||
|
||||
Çözmek için `/etc/nginx/mime.types` içindeki mevcut `application/javascript` satırına `mjs` ekleyin:
|
||||
|
||||
```nginx
|
||||
application/javascript js mjs;
|
||||
```
|
||||
|
||||
> İkinci bir `application/javascript` satırı EKLEMEYİN: nginx `mime.types` dosyasını satır satır ayrıştırır ve yalnızca bir tür-uzantı eşlemesi geçerli olur, bu nedenle ikinci satır bazı sürümlerde sessizce yok sayılır. Mevcut satırı düzenleyip `js` yanına `mjs` ekleyin.
|
||||
|
||||
Veya server bloğunuzun içinde yerel olarak geçersiz kılın (genel dosyayı düzenlemeden):
|
||||
|
||||
```nginx
|
||||
types {
|
||||
application/javascript js mjs;
|
||||
application/wasm wasm;
|
||||
}
|
||||
```
|
||||
|
||||
Değişiklikten sonra nginx'i yeniden yükleyin:
|
||||
|
||||
```bash
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
Doğrulamak için tarayıcı DevTools → Network sekmesinde başarısız olan `.mjs` isteğini bulun ve `Content-Type` yanıt başlığını kontrol edin. Artık `application/octet-stream` değil, `application/javascript` olmalıdır.
|
||||
|
||||
### Word/ODT/Excel'den PDF'ye Dönüştürme Çalışmıyor
|
||||
|
||||
LibreOffice WASM, `Cross-Origin-Embedder-Policy` ve `Cross-Origin-Opener-Policy` başlıklarını gerektiren `SharedArrayBuffer`'a ihtiyaç duyar. Ayrıca güvenli bir bağlam gerekir; bu nedenle `http://localhost` yerel testlerde çalışır, ancak `http://192.168.x.x` gibi yerel ağ IP'leri genellikle HTTPS gerektirir. Bir `location` bloğundaki nginx `add_header` yönergelerinin, sunucu düzeyindeki `add_header` yönergelerini **geçersiz kıldığını**, birleştirmediğini unutmayın. Kendi `add_header` yönergesi olan her `location` bloğu COEP/COOP başlıklarını içermelidir.
|
||||
|
||||
Şununla doğrulayın:
|
||||
|
||||
```bash
|
||||
curl -I https://your-domain.com/ | grep -i cross-origin
|
||||
```
|
||||
|
||||
Nginx'in önünde bir ters proxy kullanıyorsanız, bu başlıkları korumasından emin olun.
|
||||
|
||||
### 502 Bad Gateway
|
||||
|
||||
Nginx hata günlüklerini kontrol edin:
|
||||
|
||||
```bash
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
```
|
||||
@@ -0,0 +1,122 @@
|
||||
# Vercel'e Dağıtım
|
||||
|
||||
[Vercel](https://vercel.com), statik siteler için en kolay dağıtım deneyimini sunar.
|
||||
|
||||
## Tek Tıkla Dağıtım
|
||||
|
||||
[](https://vercel.com/new/clone?repository-url=https://github.com/alam00000/bentopdf)
|
||||
|
||||
## Elle Dağıtım
|
||||
|
||||
### Adım 1: Depoyu Fork'layın
|
||||
|
||||
[bentopdf/bentopdf](https://github.com/alam00000/bentopdf) deposunu GitHub hesabınıza fork'layın.
|
||||
|
||||
### Adım 2: Vercel'e Aktarın
|
||||
|
||||
1. [vercel.com/new](https://vercel.com/new) adresine gidin
|
||||
2. Fork'ladığınız depoyu seçin
|
||||
3. Projeyi yapılandırın:
|
||||
|
||||
| Ayar | Değer |
|
||||
| ---------------- | --------------- |
|
||||
| Framework Preset | Vite |
|
||||
| Build Command | `npm run build` |
|
||||
| Output Directory | `dist` |
|
||||
| Install Command | `npm install` |
|
||||
|
||||
### Adım 3: Ortam Değişkenleri (İsteğe Bağlı)
|
||||
|
||||
Gerekirse bunları ekleyin:
|
||||
|
||||
| Değişken | Açıklama |
|
||||
| ----------------------- | ------------------------------------------------------------- |
|
||||
| `SIMPLE_MODE` | Asgari arayüz için `true` yapın |
|
||||
| `VITE_BRAND_NAME` | Özel marka adı ("BentoPDF" yerine geçer) |
|
||||
| `VITE_BRAND_LOGO` | `public/` dizinine göre logo yolu (örn. `images/my-logo.svg`) |
|
||||
| `VITE_FOOTER_TEXT` | Özel alt bilgi/telif hakkı metni |
|
||||
| `VITE_DEFAULT_LANGUAGE` | Varsayılan arayüz dili (örn. `fr`, `de`, `es`) |
|
||||
|
||||
### Adım 4: Dağıtın
|
||||
|
||||
"Deploy"a tıklayın ve derlemenin tamamlanmasını bekleyin.
|
||||
|
||||
## Özel Alan Adı
|
||||
|
||||
1. Proje ayarlarınıza gidin
|
||||
2. "Domains" bölümüne gidin
|
||||
3. Özel alan adınızı ekleyin
|
||||
4. DNS'i yönergelere göre yapılandırın
|
||||
|
||||
## Sınırlamalar
|
||||
|
||||
::: warning Büyük Dosyalar
|
||||
Vercel'in sunucusuz işlevlerinin 50MB sınırı vardır. BentoPDF statik bir site olduğu için bu sizi etkilememelidir, ancak WASM modülleri büyüktür (toplam ~100MB). Bunların `/public` klasöründen sunulduğundan emin olun.
|
||||
:::
|
||||
|
||||
## Sorun Giderme
|
||||
|
||||
### Derleme Zaman Aşımı
|
||||
|
||||
Derlemeler zaman aşımına uğruyorsa şunu deneyin:
|
||||
|
||||
```json
|
||||
// vercel.json
|
||||
{
|
||||
"buildCommand": "npm run build",
|
||||
"outputDirectory": "dist"
|
||||
}
|
||||
```
|
||||
|
||||
### Yenilemede 404
|
||||
|
||||
SPA yönlendirmesi için bir `vercel.json` ekleyin:
|
||||
|
||||
```json
|
||||
{
|
||||
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
|
||||
}
|
||||
```
|
||||
|
||||
### Word/ODT/Excel'den PDF'ye Dönüştürme Çalışmıyor
|
||||
|
||||
LibreOffice WASM dönüştürmeleri `SharedArrayBuffer` gerektirir; bunun için tüm sayfalarda şu yanıt başlıkları gerekir:
|
||||
|
||||
- `Cross-Origin-Embedder-Policy: require-corp`
|
||||
- `Cross-Origin-Opener-Policy: same-origin`
|
||||
|
||||
Önceden sıkıştırılmış `.wasm.gz` ve `.data.gz` dosyalarının da tarayıcının bunları açabilmesi için `Content-Encoding: gzip` başlığına ihtiyacı vardır.
|
||||
|
||||
Bunları `vercel.json` dosyanıza ekleyin:
|
||||
|
||||
```json
|
||||
{
|
||||
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }],
|
||||
"headers": [
|
||||
{
|
||||
"source": "/(.*)",
|
||||
"headers": [
|
||||
{ "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" },
|
||||
{ "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
|
||||
{ "key": "Cross-Origin-Resource-Policy", "value": "cross-origin" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/libreoffice-wasm/soffice.wasm.gz",
|
||||
"headers": [
|
||||
{ "key": "Content-Type", "value": "application/wasm" },
|
||||
{ "key": "Content-Encoding", "value": "gzip" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"source": "/libreoffice-wasm/soffice.data.gz",
|
||||
"headers": [
|
||||
{ "key": "Content-Type", "value": "application/octet-stream" },
|
||||
{ "key": "Content-Encoding", "value": "gzip" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Doğrulamak için DevTools Konsolu'nu açın ve `console.log(window.crossOriginIsolated)` komutunu çalıştırın: `true` döndürmelidir.
|
||||
Reference in new issue
Block a user