# Yapılandırma

> Tüm QueryProxy ortam değişkenleri — sorgu limitleri, çalıştırma, sonuç depolama, ters vekil güveni, uygulama veritabanı ve kuyruk.

- Dokümantasyon: Referans
- Güncelleme: 2026-10-18
- Kaynak: https://queryproxy.com/tr/docs/yapilandirma/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Tüm yapılandırma ortam değişkenleriyle yapılır (yerelde `.env`, Docker'da
konteyner ortamı). Depodaki `.env.example` tam seti belgeler; bu sayfa gerçekten
değiştireceğiniz olanları açıklar.

## QueryProxy ayarları

| Değişken | Varsayılan | Anlamı |
| :-- | :-- | :-- |
| `QUERYPROXY_SELECT_DEFAULT_LIMIT` | `1000` | LIMIT'siz SELECT'lere eklenen limit |
| `QUERYPROXY_SELECT_HARD_LIMIT` | `10000` | Daha büyük LIMIT'ler bu değere indirilir |
| `QUERYPROXY_EXECUTION_TIMEOUT` | `300` | Tek bir talebin işçide çalışabileceği en uzun süre (sn). Sıfırdan büyük tam sayı saniye olmalı; başka her değer (metin, boş, `0`, negatif, ondalık, birimli değer) `300`'e düşer. Üst sınır `86400` saniyedir (24 saat): bunu aşan geçerli bir değer hata vermez, `86400`'e kırpılır. Docker girişi değeri kırptığında `[entrypoint]` uyarısı basar |
| `QUERYPROXY_RESULT_DISK` | `local` | Sonuç dosyaları için Laravel disk adı (`s3` desteklenir; herkese açık görünürlükteki diskler reddedilir) |
| `QUERYPROXY_RESULT_TTL_DAYS` | `30` | `results:prune` sonuçları kaç gün sonra siler |
| `QUERYPROXY_SEED_DEMO` | `false` | Yalnızca Docker: ilk açılışta demo takımı oluştur (tek rastgele parola, loglara bir kez yazılır; `QUERYPROXY_SEED_DEMO_FORCE=true` olmadıkça `APP_ENV=production` iken reddedilir) |
| `QUERYPROXY_ADMIN_EMAIL` / `QUERYPROXY_ADMIN_PASSWORD` | — | Yalnızca Docker: kurulumda hiç kullanıcı yokken açılışta ilk sistem yöneticisini oluştur (parola en az 8 karakter); herhangi bir kullanıcı olduğu anda etkisizdir |
| `QUERYPROXY_ADMIN_NAME` | `Admin` | Yalnızca Docker: o ilk yöneticinin görünen adı |
| `QUERYPROXY_RUN_WORKER` | `true` | Yalnızca Docker: kuyruk işçisini konteyner içinde çalıştır; işçi kendi konteynerinde koşuyorsa `false` yapın |
| `QUERYPROXY_RUN_SCHEDULER` | `true` | Yalnızca Docker: zamanlayıcıyı (`schedule:work`) konteyner içinde çalıştır |
| `QUERYPROXY_WORKER_PROCESSES` | `1` | Yalnızca Docker: kuyruk işçisi süreç sayısı |
| `QUERYPROXY_KEY_FILE` | `/var/www/html/storage/app/.app_key` | Yalnızca Docker: `APP_KEY` verilmediğinde üretilen anahtarın saklandığı dosya. Değişken ayarlı değilse ve eski yolda (`/var/www/html/database/.app_key`) bir anahtar dosyası zaten varsa, entrypoint o dosyayı kullanmaya devam eder |
| `QUERYPROXY_REQUIRE_2FA` | `none` | TOTP iki adımlı doğrulamayı zorunlu kıl: `none`, `admins`, `dba` (yöneticiler + DBA rolü olan herkes) veya `all` |
| `QUERYPROXY_CHAT_WEBHOOK_ALLOWED_HOSTS` | — | Giden chat webhook'ları için ek izinli hostlar, virgülle ayrılmış ve `*` jokerli (SSRF koruması; `hooks.slack.com`, `*.webhook.office.com` ve `*.logic.azure.com` varsayılan olarak izinlidir) |
| `QUERYPROXY_CHAT_INCLUDE_SQL` | `true` | Chat bildirimlerine SQL önizlemesi göm |
| `QUERYPROXY_CONNECTION_HOST_DENYLIST` | — | Bağlantı hedefi olarak engellenen ek hostlar (virgülle ayrılmış) |
| `QUERYPROXY_SQLITE_ALLOWED_DIR` | — | SQLite bağlantı dosyalarını bu dizinle sınırla. Uygulama dizini içindeki dosyalar (QueryProxy'nin varsayılan SQLite veritabanı orada durur) bu ayar verilsin ya da verilmesin her zaman reddedilir |
| `QUERYPROXY_EXTRA_UNTRUSTED_LANGUAGES` | — | Guard'ın `CREATE EXTENSION`'da reddettiği ek prosedürel diller (virgülle ayrılmış); yerleşik listeyi genişletir. `DO`, `CREATE FUNCTION` ve `CREATE PROCEDURE` bu ayardan bağımsız olarak yalnızca `plpgsql` ve `sql` kabul eder |
| `QUERYPROXY_EXTRA_DANGEROUS_VARIABLES` | — | Guard'ın `SET` ile (MySQL / MariaDB'de kalıcı scope'lar, PostgreSQL'de her scope) ve `set_config` ile yazılmasını reddettiği ek sunucu değişkenleri (virgülle ayrılmış); yerleşik listeyi genişletir |
| `QUERYPROXY_EXTRA_BLOCKED_FUNCTIONS` | — | Guard'ın doğrudan reddettiği ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir |
| `QUERYPROXY_EXTRA_STATE_CHANGING_FUNCTIONS` | — | Bir ifadeyi yazma yapan ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir |
| `QUERYPROXY_EXTRA_RESOURCE_CONSUMING_FUNCTIONS` | — | Kaynak tuttukları için (uyku/sleep gibi) bir ifadeyi yazma yapan ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir |
| `QUERYPROXY_EXTRA_BLOCKED_PROCEDURES` | — | Guard'ın reddettiği ek SQL Server prosedürleri (virgülle ayrılmış); yerleşik listeyi genişletir |
| `QUERYPROXY_EXTRA_SQLITE_PRAGMAS` | — | Çıplak, okuma biçiminde izin verilen ek SQLite pragma'ları (virgülle ayrılmış); yerleşik listeyi genişletir |
| `TRUSTED_PROXIES` | — | `X-Forwarded-*` başlıklarını ayarlamasına izin verilen ters vekillerin IP'leri / CIDR'ları (virgülle ayrılmış) |
| `TRUSTED_HOSTS` | — | `APP_URL`'deki host'a ek olarak bu kurulumun yanıt verdiği hostname'ler (virgülle ayrılmış) |
| `DB_QUEUE_RETRY_AFTER` | `QUERYPROXY_EXECUTION_TIMEOUT` + 30 (`330`) | Rezerve edilmiş bir kuyruk job'unun kaç saniye sonra yeniden deneneceği. Ayarlanmamışsa çalıştırma zaman aşımından türetilir; açıkça verilen değer önceliklidir. `BEANSTALKD_QUEUE_RETRY_AFTER` ve `REDIS_QUEUE_RETRY_AFTER` aynı şekilde çalışır |

> `retry_after` türetilir: `DB_QUEUE_RETRY_AFTER`'ı (ya da Beanstalkd / Redis
> karşılığını) kendiniz ayarlamadıkça `QUERYPROXY_EXECUTION_TIMEOUT` + 30
> saniyedir (varsayılan `300` için `330`). Docker girişi (entrypoint), işçinin
> `--timeout` (çalıştırma zaman aşımı + 10) ve `stopwaitsecs` (çalıştırma zaman
> aşımı + 20) değerlerini de aynı ayardan türetir. `retry_after`'ı açıkça
> ayarlarsanız çalıştırma zaman aşımının üzerinde tutun, çünkü sorgu job'u o
> noktada durdurulur; varsayılan +30 bir pay bırakır. Ona eşit ya da altındaki
> bir değer, yavaş bir sorgunun hâlâ çalışırken yeniden rezerve edilmesine ve
> sonra başarısız işaretlenmesine yol açar — yazması commit olabilse bile — ve
> `queue:work` (daemon ya da `--once`) veya `queue:listen` başlarken bir uyarı
> loglar. 0.2.0 `.env.example`'ından kalma sabit bir `*_QUEUE_RETRY_AFTER=330`
> türetmeyi durdurur; bilerek ayarlamadıysanız kaldırın.

Kabul edilen bir `QUERYPROXY_REQUIRE_2FA` TOTP kodu **yakılır**, dolayısıyla
penceresinin kalanında yeniden kullanılamaz. Pratik bir sonucu: aynı 30
saniyelik adımda ikinci bir cihazdan giriş yapmak için bir sonraki kodu beklemek
gerekir.

`QUERYPROXY_EXTRA_UNTRUSTED_LANGUAGES` ve `QUERYPROXY_EXTRA_DANGEROUS_VARIABLES`,
[SQL korumalarının](/tr/docs/sql-korumalari/) `CREATE EXTENSION` ve `SET`'i
değerlendirdiği iki listeye ekleme yapar. Yalnızca **genişletebilirler**:
yerleşik girdiler tabandır, ortamın verdiği her şeyin üstüne yeniden
eklenir; dolayısıyla kısaltılmış bir liste guard'ı etkisiz kılamaz.

### MySQL / MariaDB hedefleri: `sql_mode`

Guard tırnakları ve ters eğik çizgileri varsayılan biçimde okur; bu yüzden oturum
`sql_mode`'u bunları farklı okuyacaksa talep reddedilir. QueryProxy, bir `mysql`
ya da `mariadb` bağlantısında SQL'i çalıştırmadan önce `@@SESSION.sql_mode`
değerini okur; `NO_BACKSLASH_ESCAPES` ya da `ANSI_QUOTES` içeriyorsa talep
başarısız olur ve hiçbir şey çalışmaz; mesaj ilgili bayrağı adıyla belirtir.
QueryProxy'nin kendisi bağlanırken, sunucunun varsayılanının yerine geçen katı bir
`sql_mode` ayarlar; bu yüzden denetim tetiklenirse bağlandıktan sonra modu neyin
değiştirdiğine bakın (aradaki bir vekil, değişmiş bir bağlantı ayarı). Bayrakları
sunucu ve bağlantı kullanıcısı varsayılanlarından uzak tutmak yine de yerindedir,
ama tek başına sorunu gidermez. `sql_mode`'u değiştiren bir `SET` göndermek
her driver'da reddedilir
(bkz. [SQL korumaları](/tr/docs/sql-korumalari/)).

## Uygulama anahtarı ve HTTPS

`APP_KEY`, saklanan bağlantı kimlik bilgilerinizi ve chat sırlarınızı şifreler.
**Üretimde açıkça belirleyin ve sabit tutun** — yeniden üretilen bir anahtar
(ör. konteyner yeniden oluşturulunca) saklanan tüm kimlik bilgilerini okunamaz
hale getirir. `php artisan key:generate --show` ile üretin ve döndürürken eski
anahtarı `APP_PREVIOUS_KEYS`'e (virgülle ayrılmış) taşıyın ki mevcut şifreli
veri hâlâ çözülebilsin.

HTTPS'i bir ters vekil arkasından sunarken `SESSION_SECURE_COOKIE=true` ayarlayın.

## Ters vekil arkasında

> **Kırıcı değişiklik — QueryProxy'nin önünde bir vekil varsa `TRUSTED_PROXIES`'i
> ayarlayın.** Önceki sürümler her vekile güveniyordu. Bu sürümden itibaren
> hiçbir vekile varsayılan olarak güvenilmez ve siz kendinizinkini yazana kadar
> uygulama bağlanan tarafı istemci olarak okur.

`TRUSTED_PROXIES`, `X-Forwarded-*` başlıklarını ayarlamasına izin verilen IP'lerin
ya da CIDR'ların virgülle ayrılmış listesini alır:

```dotenv
TRUSTED_PROXIES=10.0.0.0/8
```

Bu liste vekilinizin adını içermedikçe `X-Forwarded-Proto` yok sayılır — HTTPS
algılanmaz, dolayısıyla HSTS başlığı gönderilmez — ve denetim kayıtlarına
istemcinin değil vekilin adresi düşer.

**Asla `*` yazmayın.** Her vekile güvenmek, herhangi bir istemcinin kendi
`X-Forwarded-For` başlığını göndermesine izin verir; bu, denetim izindeki
istemci IP'sini sahteler ve sınırsız giriş ile 2FA denemesi hakkı verir, çünkü
iki throttle da IP başına anahtarlanır.

`X-Forwarded-Host`, listede ne yazarsa yazsın hiç dikkate alınmaz: sahte bir host
başlığı parola sıfırlama e-postasındaki bağlantıyı yeniden yazıyordu. İkinci bir
katman olarak istek host'u `APP_URL`'deki host'a (ve `www.` kardeşine)
sabitlenir; böylece mutlak URL'ler — imzalı route'lar, parola sıfırlama
e-postaları — her zaman kendi kurulumunuzu gösterir. `APP_URL`'i kullanıcıların
gerçekten eriştiği adrese ayarlayın.

Kurulum birden fazla ada yanıt veriyorsa diğerlerini `TRUSTED_HOSTS`'e yazın:

```dotenv
TRUSTED_HOSTS=queryproxy.internal,db.example.com
```

`X-Forwarded-Host` yok sayıldığına göre çok alan adlı bir dağıtımı çalıştırmanın
desteklenen yolu budur — listelemediğiniz bir hostname yine de bir parola
sıfırlama bağlantısını yeniden yazamaz. Adlar `APP_URL`'deki host'a (ve `www.`
kardeşine) eklenir, onun yerine geçmez. Hostname olarak okunamayan girdiler
sessizce atılır, böylece bir yazım hatası kurulumu çökertemez.

İki değer de uygulama yapılandırması üzerinden okunur, bu yüzden `.env`'e yazmak
yeterlidir. Yapılandırmayı cache'liyorsanız değiştirdikten sonra
`php artisan config:cache`'i yeniden çalıştırın; Docker imajı her açılışta
yeniden cache'ler.

## Uygulama veritabanı

QueryProxy'nin kendi verisi (kullanıcılar, takımlar, talepler, denetim günlüğü)
varsayılan olarak SQLite'ta yaşar — sıfır yapılandırma. MySQL veya PostgreSQL
için standart Laravel değişkenlerini ayarlayın:

```dotenv
DB_CONNECTION=pgsql        # veya mysql
DB_HOST=db
DB_PORT=5432
DB_DATABASE=queryproxy
DB_USERNAME=queryproxy
DB_PASSWORD=degistir-beni
```

Bu, *uygulama* veritabanıdır — proxy'lediğiniz veritabanları arayüzde
**Connections** altında, takım bazında ve şifreli kimlik bilgileriyle tanımlanır.

## Kuyruk

Kuyruk varsayılan olarak veritabanı tabanlıdır (Redis gerekmez). Redis'e
taşımak için:

```dotenv
QUEUE_CONNECTION=redis
REDIS_HOST=redis
```

`REDIS_QUEUE_RETRY_AFTER` isteğe bağlıdır: ayarlanmamışsa
`QUERYPROXY_EXECUTION_TIMEOUT` + 30 saniyeden türetilir (bkz. ayar tablosunun
altındaki not). Yalnızca bu değeri geçersiz kılmak için ayarlayın ve çalıştırma
zaman aşımının üzerinde tutun.

İşçi komutu aynı kalır. `--timeout` değerini çalıştırma zaman aşımının biraz
üzerinde tutun (çalıştırma zaman aşımı + 10 saniye; `QUERYPROXY_EXECUTION_TIMEOUT`
varsayılan olarak `300`'dür, dolayısıyla `310`):

```bash
php artisan queue:work --queue=queries,default --tries=1 --timeout=310
```

Manuel kurulumda bu sayı sizin için türetilmez: `QUERYPROXY_EXECUTION_TIMEOUT`'u
değiştirirseniz `--timeout`'u da ona göre değiştirin (Docker girişi bunu kendisi
türetir).

Aynı uyarı (`retry_after`'ın çalıştırma zaman aşımına eşit ya da altında olması)
yalnızca daemon `queue:work` için değil, `queue:listen` ya da
`queue:work --once` başlarken de bir kez loglanır. `queue:listen`'ın başlattığı
kısa ömürlü `queue:work --once` süreçleri bunu tekrarlamaz.

Deponun `docker-compose.yml` dosyasındaki ayrı `worker` örneği artık
`--timeout=310` değerini sabit yazmaz: imaj girişinin
`QUERYPROXY_EXECUTION_TIMEOUT` + 10 olarak türettiği
`QUERYPROXY_WORKER_TIMEOUT`'u geçirir. O servis için
`QUERYPROXY_EXECUTION_TIMEOUT`'u ayarlayın, işçi onu izler. Bu, imajın varsayılan
girişini gerektirir; bu yüzden worker servisinde `entrypoint:`'i geçersiz
kılmayın.

## S3 üzerinde sonuç depolama

`QUERYPROXY_RESULT_DISK=s3` ve standart `AWS_*` değişkenlerini ayarlayın. Sonuç
dosyaları NDJSON olarak, akış hâlinde yazılır — bellek kullanımı sonuç boyutundan
bağımsız olarak sabit kalır.

Disk **özel** olmalıdır. Sonuç yolları tahmin edilebilirdir
(`results/{team_id}/{id}.ndjson`); bu yüzden herkese açık sunulan bir disk, indirme
yetkilendirmesini tümden atlayarak her takımın satırlarını doğrudan web kökünden
dağıtırdı. Bu nedenle `QUERYPROXY_RESULT_DISK` `public` diskini ya da
`visibility => public` ile yapılandırılmış herhangi bir diski gösteriyorsa
QueryProxy sonuç yazmayı reddeder ve talep bunun yerine açık bir mesajla
başarısız olur.

## SQL Server hedefleri

Varsayılan Docker imajı `pdo_pgsql`, `pdo_mysql` ve `pdo_sqlite` ile gelir.
Microsoft SQL Server veritabanlarını proxy'lemek için Dockerfile'ı Microsoft'un
ODBC sürücüsü ve `sqlsrv` / `pdo_sqlsrv` PECL eklentileriyle genişletin, ardından
`queryproxy/queryproxy` yerine kendi imajınızı derleyip çalıştırın. Onaylı
sorgular işçide çalıştığı için eklentilerin hem web sürecini hem kuyruk işçisini
çalıştıran PHP derlemesinde bulunması gerekir.
