Skip to content
Yusuf Özdemir
Anvil: PHP, Node.js ve diğer diller için yerel geliştirme ortamı
ALL ARTICLES

Anvil: PHP, Node.js ve diğer diller için yerel geliştirme ortamı

9 MIN READ 1,713 WORDS
ALSO IN English

Anvil, PHP, Node.js, Python, Go, Rust ve .NET projeleri için yazdığım yerel bir geliştirme ortamı. Her projeyi shop.test gibi kendi adresinde, kendi dil sürümüyle ve kendi veritabanıyla çalıştırıyor. macOS, Windows ve Linux'ta hem masaüstü uygulaması hem de CLI olarak geliyor. Açık kaynak ve ücretsiz.

Yerelde birkaç proje birden yürütünce aynı sorunlar tekrar ediyor. Eski bir proje PHP 8.2 istiyor, yenisi 8.5. Bir Laravel projesinin yanında bir Next.js sitesi ve küçük bir Go servisi duruyor. Her birinin queue worker'ı, Vite'ı ya da dev server'ı ayrı bir terminal sekmesinde açık kalmak zorunda. Docker tabanlı kurulumlar bu ayrımı sağlıyor ama her projeye bir compose dosyası, macOS ve Windows'ta da sürekli çalışan bir sanal makine ekliyor. Anvil aynı ayrımı doğrudan makinenizde yapıyor. Bütün binary'ler ~/.anvil altında duruyor ve sistemdeki PHP'ye ya da Node.js'e dokunulmuyor.

Anvil tanıtım videosu (YouTube)

Anvil: uygulama listesi ve bir Laravel uygulamasının Overview sekmesi

Nasıl çalışıyor

Bir klasörü park ettiğinizde içindeki her proje bir adres alıyor. ~/Sites/shop klasörü shop.test oluyor. Laravel Valet ya da Herd kullandıysanız bu fikir tanıdık gelecek. Anvil aynı fikri PHP dışındaki dillere de taşıyor.

anvil php install 8.4   # izole bir PHP
anvil setup             # .test, 80/443 portları, PATH
anvil park ~/Sites      # ~/Sites içindeki her klasör <klasör>.test olur
anvil start

anvil setup bir kez şifre soruyor. .test sorgularını Anvil'in DNS'ine yönlendiriyor, 80 ve 443 portlarını Anvil'e iletiyor, yerel sertifikayı güvenilir yapıyor ve komutları shell'in PATH'ine ekliyor. anvil uninstall bunların hepsini önce listeliyor, sonra geri alıyor.

Projenin türü dosyalarından anlaşılıyor. artisan varsa Laravel, Cargo.toml varsa Rust, package.json içinde next varsa Next.js. Şu an on yedi tür tanınıyor ve projenize bir config dosyası eklemeniz gerekmiyor. Anvil projenin zaten kullandığı komutları çalıştırıyor.

Bir isteğin macOS'taki yolu şöyle:

flowchart LR
    B[Tarayıcı] --> D["Anvil DNS<br/>*.test → 127.0.0.1"]
    D --> C[Caddy]
    C --> F["PHP-FPM<br/>sürüm başına havuz"]
    C --> S[Statik dosyalar]
    C --> P["Dev server'lar<br/>Node.js, Go, Rust..."]

DNS sunucusu Anvil'in içinde. *.test altındaki her isme 127.0.0.1 cevabı veriyor, gerisini reddediyor. Web sunucusu olarak Caddy çalışıyor ve her uygulama için bir blok üretiliyor. PHP projeleri PHP-FPM'e gidiyor. Her PHP sürümü için ortak bir havuz var. Kendi php.ini değerleri olan bir uygulama ya da bir worktree ayrı bir havuz alıyor, böylece ayarlar birbirine karışmıyor. Node.js, Go, Rust, .NET ve Python uygulamaları kendi dev server'larını özel bir portta açıyor. Port $PORT ile veriliyor, Caddy de adresi o porta yönlendiriyor.

Proje başına sürüm

PHP 8.1'den 8.5'e kadar, 8.6 da önizleme olarak kurulabiliyor. Her uygulamaya ayrı bir sürüm sabitleyebiliyorsunuz. Terminaldeki php, composer ve node hangi klasörde olduğunuza bakıyor.

cd ~/Sites/legacy && php -v   # 8.2
cd ~/Sites/shop && php -v     # 8.4

Bu komutlar Homebrew'daki PHP'ye geri düşmüyor. Anvil'de kurulu bir PHP yoksa sessizce başka bir binary çalıştırmak yerine hata verip duruyor. Hangi binary'nin çalışacağını anvil which php söylüyor. Node.js sürümü .anvil.toml, .nvmrc ya da .node-version dosyasından okunuyor. Python, Go, Rust ve .NET ise Anvil'in çalıştırdığı uygulamalar için izole, terminalde PATH'inizde ne varsa o kalıyor.

Servisler

MySQL, PostgreSQL, Redis, Mailpit ve S3 uyumlu depolama ekleyebiliyorsunuz. Her birinden istediğiniz kadar kurabiliyorsunuz, yani bir projede MySQL 8.0, diğerinde 8.4 aynı anda çalışabiliyor. Siz eklemeden hiçbiri çalışmıyor. Hepsi yalnızca 127.0.0.1'i dinliyor.

Bunların dışında bir Docker imajı ya da makinedeki mevcut bir container da servis olarak eklenebiliyor. Ağdaki başka bir MySQL, PostgreSQL ya da Redis sunucusunu da tanıtabiliyorsunuz. Bir servisin bağlantı bilgilerini, önce gösterdikten sonra uygulamanın .env dosyasına yazmak tek bir tık.

anvil service add --docker mongo:7 --port 27017:27017
anvil service add --external db.lan:3306 --kind mysql

Dev süreçleri

Dev sekmesi, bir projenin siz çalışırken açık kalması gereken programlarını arka planda yürütüyor: queue worker, php artisan pail, Vite, bir dokümantasyon sitesi. Her birinin canlı çıktısı görünüyor. Biri çökerse çıkış kodu yazılıyor, kenar çubuğundaki uygulama kırmızıya dönüyor ve bildirim geliyor.

Dev sekmesi: Laravel uygulamasının süreçleri ve canlı çıktısı

Süreçler projenin script'lerinden tespit ediliyor. Listeyi kendiniz belirlemek isterseniz projeye bir .anvil.toml ekliyorsunuz:

[processes]
queue = "php artisan queue:listen"
vite = "npm run dev"

Ne değildir

Anvil bir production sunucusu ya da deploy aracı değil. Her şey yalnızca 127.0.0.1'i dinliyor ve ağdaki başka bir makine projelerinize ulaşamıyor. Bir projeyi birine göstermek için geçici bir Cloudflare tüneli açılabiliyor, ama o da Ctrl-C'ye kadar yaşıyor.

Container tabanlı bir ortam da değil. PHP, Node.js ve servisler doğrudan makinenizde, kendi kullanıcınızla çalışıyor. Docker yalnızca bir Docker Compose projesi ya da Docker servisi eklediğinizde devreye giriyor. Anvil Docker'ı kurmuyor, makinedekini kullanıyor. Ekibin herkesinde birebir aynı ortamı garanti etmek istiyorsanız Sail ya da DDEV gibi Docker tabanlı araçlar bu iş için daha uygun.

Bitmiş bir ürün de değil. İlk public sürüm 21 Ekim 2026'da çıktı ve hâlâ beta. 1.0'a kadar minor sürümlerde kırıcı değişiklik olabilir. Platformlar arasında da fark var. Windows'ta Python ve Rust henüz yok. Linux'ta uygulamalar http://<isim>.localhost:8080 adresinde açılıyor. .test adresleri, 80/443 portları, HTTPS güveni ve PHP eklentileri Linux'a sonraki bir sürümde gelecek.

Neler yapılabilir

Branch'leri yan yana çalıştırmak

Bir uygulamanın her Git worktree'si yanında ayrı bir adresle açılıyor. shop uygulamasında feature/login branch'i için shop--feature-login.test adresi, kendi dev süreçleri ve shop_feature_login adında kendi veritabanı oluşuyor. Veritabanı boş başlayabiliyor ya da ana uygulamanınkinin kopyası olabiliyor. Redis ve cache anahtarları da ayrı bir prefix alıyor. Böylece main çalışmaya devam ederken yeni bir özelliği yanında deneyebiliyorsunuz.

anvil worktree add feature/login --new --copy-db

Worktrees: her branch kendi adresinde

Worktree'yi silmek, commit edilmemiş ya da push edilmemiş değişiklik varsa reddediliyor. Kopyalanan veritabanları da ancak --drop-db verirseniz siliniyor.

Sıfırdan proje açmak

anvil new on altı şablondan biriyle yeni bir uygulama kuruyor: Laravel, Statamic, Symfony, WordPress, düz PHP, statik site, Next.js, Nuxt, Vite, Node.js, Rust, Go, .NET, Django, FastAPI ve Flask. Laravel için starter kit ve veritabanı da seçilebiliyor.

anvil new laravel shop --starter react --db sqlite

Proje oluşunca adresi hazır oluyor ve doğrudan tarayıcıda açılabiliyor.

İstekleri, mail'leri ve logları okumak

Requests sekmesi bir uygulamanın cevapladığı her isteği header'larıyla birlikte listeliyor. Logs sekmesi Laravel, Symfony ve PHP-FPM loglarını kayıt kayıt gösteriyor. Tekrar eden hatalar tek satıra katlanıyor, stack frame'e tıklayınca dosya editörünüzde o satırda açılıyor.

Requests sekmesi: bir uygulamanın cevapladığı istekler

Mail catcher açıkken her uygulamanın ayrı bir gelen kutusu oluyor. Anvil, uygulamanın süreçlerine ve web isteklerine MAIL_HOST gibi değişkenleri kendisi veriyor. Laravel ve Symfony'de bu değişkenler .env'in önüne geçtiği için projede hiçbir dosyayı değiştirmeniz gerekmiyor. Mail'ler saklanıyor ama hiçbir yere gönderilmiyor.

AI agent'lara erişim vermek

Anvil bir MCP sunucusu içeriyor. MCP, Claude Code gibi agent'ların dış araçları çağırmasını sağlayan bir protokol. Bu özellik varsayılan olarak kapalı, Settings › Features altından açılıyor.

claude mcp add anvil -- anvil mcp

Agent bulunduğu klasörün uygulaması üzerinde çalışıyor. Uygulamaları başlatıp durdurabiliyor, log'ları, istekleri, yakalanan mail'leri ve tarayıcıdaki JavaScript hatalarını okuyabiliyor. "Son baktığımdan beri ne bozuldu" diye sorabiliyor ve worktree ekleyip kaldırabiliyor. Geri alınamayacak hiçbir işlem açık değil. Veritabanı silmek, servis verisini temizlemek ya da uygulamayı kaldırmak agent'a kapalı. Başlatma komutlarını ve php.ini'yi de değiştiremiyor, yani Anvil'in neyi çalıştıracağına agent karar veremiyor. Log, istek ve mail metinleri güvenilmeyen içerik olarak işaretleniyor.

Uygulamayı dışarıya açmak

Settings › Features › Tunnel açıksa bir uygulamayı geçici bir public adreste paylaşabiliyorsunuz. Bunun için Cloudflare'in quick tunnel'ı kullanılıyor ve adres Ctrl-C'ye basana kadar açık kalıyor.

anvil app share blog

Bir webhook'u yerelde denemek ya da birine çalışan bir ekranı göstermek için yetiyor.

Mevcut durum

Anvil şu an 0.3.2 sürümünde ve beta. Rust ile yazıldı, masaüstü uygulaması Tauri üzerinde çalışıyor. Web sunucusu Caddy, macOS ve Linux'taki PHP build'leri de static-php-cli ile php.net'in sürümlerinden derleniyor. Yeni bir PHP patch sürümü bir gün içinde geliyor ve varsayılan olarak arka planda kendiliğinden kuruluyor. Lisansı GPL v3.

brew install --cask n1crack/anvil/anvil

macOS 12 ve üzerinde çalışıyor. Windows için 10 ya da 11, Linux için glibc 2.35 ve üzeri gerekiyor.

Deneyip takıldığınız bir yer olursa bana yazabilirsiniz.

More to read