feat: translate all pages, UI messages and docs and fix SEO redirects and indexing

This commit is contained in:
alam00000 committed 2026-10-25 12:55:21 +05:30
1 parent 5e019de5ae
commit 4edb1718cc
3344 files changed
+415643 -4759

No files matched your search

+275
View File
@@ -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
```
+200
View File
@@ -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"
}
}
```
+154
View File
@@ -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.
+180
View File
@@ -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
+622
View File
@@ -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
```
+266
View File
@@ -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.
+538
View File
@@ -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!
:::
+211
View File
@@ -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.
+139
View File
@@ -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
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](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.
+232
View File
@@ -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
```
+122
View File
@@ -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
[![Deploy with Vercel](https://vercel.com/button)](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.