SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-10-30

Actual Budget VPS uzerinde Docker ile nasil kurulur?

Actual Budget uygulamasini Docker Compose kullanarak VPS uzerinde barindirin. HTTPS gereksinimi, ilk butce dosyasi olusturma, banka verileri ve yedekleme adimlarini ogrenin.

Ne inşa ediyorsunuz

Actual Budget, self-hosted bir zarf usulü bütçeleme uygulamasıdır ve YNAB alternatifi arayanların kendi sunucularında barındırabilecekleri yaygın bir çözümdür. Sunucu tek bir container, tek bir veri birimi ve tek bir HTTPS adından oluşur. Normal bir bütçeleme uygulamasının ihtiyaç duyduğu her şey, kiralayabileceğiniz en küçük VPS üzerinde bile rahatlıkla çalışır; çünkü sunucu temel olarak dosyaları saklar ve senkronize eder.

Herhangi bir işlem yapmadan önce mimariyi anlamak faydalıdır. Bütçenin kendisi, tarayıcınızın ve her bir mobil uygulamanın içinde yaşayan bir SQLite veritabanıdır. Kuracağınız sunucu bir senkronizasyon uç noktasıdır; hesap listesini, bütçe dosyalarını ve bir telefon ile dizüstü bilgisayarın uyumlu çalışmasını sağlayan değişiklik günlüğünü tutar. Uygulamanın sunucu kapalıyken bile çalışmaya devam etmesinin ve en az bir istemcide kopyası bulunduğu sürece sunucunun kaybedilmesinin bütçenizi yok etmemesinin nedeni budur.

Sunucunun neden HTTPS'e ihtiyacı var

Actual, HTTPS gerektirir ve bu bir formalite değildir. Actual'ın çalışabilmesi için tarayıcıların SharedArrayBuffer adlı bir özelliğe ihtiyacı vardır; tarayıcılar bu özelliği yalnızca sayfa, teknik şartnamede güvenli bağlam (secure context) olarak adlandırılan şekilde çapraz kökenli (cross-origin) izole edildiğinde etkinleştirir. Güvenli bağlam, https:// veya http://localhost anlamına gelir. Uygulamayı başka bir makinedeki tarayıcıda http://203.0.113.10:5006 üzerinden yüklerseniz, tarayıcı bu özelliği sayfaya hiçbir zaman sağlamaz ve bu nedenle bütçe yüklenmez. Telefonlar için bir istisna yoktur. Actual'ın SSS bölümünde, resmi bir iOS uygulamasının beta testinde olduğu ve kendi sunucunuza bağlandığı, henüz resmi bir Android uygulaması bulunmadığı belirtilmektedir; bu nedenle çoğu telefonda aynı web uygulamasını ana ekrana Progressive Web App olarak yüklersiniz ve aynı güvenli bağlam kuralı burada da geçerlidir.

Bu durumda iki uygulanabilir kurulum yöntemi vardır. Bu kılavuzda yapıldığı gibi, container'ın önüne gerçek bir alan adı üzerinde gerçek bir sertifika koyun. Ya da projenin belgelerinde yer aldığı üzere, ACTUAL_HTTPS_KEY ve ACTUAL_HTTPS_CERT kullanarak sunucuya kendinden imzalı (self-signed) bir sertifika verin ve her cihazda bir tarayıcı uyarısını kabul edin. Let's Encrypt üzerinden ücretsiz bir sertifika almak beş dakika sürer, bu yüzden ilk seçeneği tercih edin.

Actual Budget uygulamasını Docker Compose ile kurma

Sunucu yeni kurulmuşsa önce Docker kurulmalıdır. Compose dosyası söz dizimi yeni öğreniliyorsa aşağıdaki alanları açıklayan VPS için Docker Compose temelleri kılavuzuna bakılabilir.

sudo install -d -m 755 /opt/actual
sudo install -d -m 700 /opt/actual/data

/opt/actual/docker-compose.yml dosyasını yazın:

services:
  actual:
    image: actualbudget/actual-server:latest
    container_name: actual
    restart: unless-stopped
    ports:
      - '127.0.0.1:5006:5006'
    volumes:
      - ./data:/data

Bu dosyada üç ayrıntı önemlidir.

Görüntü, proje tarafından Docker Hub'da yayımlanan ve ghcr.io/actualbudget/actual adresinde yansısı bulunan actualbudget/actual-server:latest değeridir. Düşük güç tüketimli makineler için latest-alpine etiketi vardır.

Container, tüm verileri /data altında yazar. Container içinde, giriş ve oturum token'larını içeren account.sqlite dosyasının bulunduğu server-files ile bütçe dosyalarının kendisini içeren user-files bulunur. Bu yolu bağlayın. Aksi halde sonraki docker compose pull bütçenizi siler. ACTUAL_DATA_DIR bu yolu değiştirebilir, ancak varsayılan değer yeterlidir.

Port yalnızca 127.0.0.1 üzerinde yayımlanır. Yalın bir 5006:5006 tüm arayüzlerde yayımlama yapar. Docker kendi kurallarını ufw kurallarının önüne yazdığı için uygulama, tüm trafiği reddeden bir güvenlik duvarı olsa bile internete açık hale gelir. Bu beklenmeyen davranış Docker tarafından yayımlanan portların ufw kurallarını neden atlattığını açıklayan bölümde ele alınır. Loopback adresine bağlamak, yalnızca aynı sunucudaki reverse proxy'nin uygulamaya erişebilmesini sağlar.

Uygulamayı başlatın:

cd /opt/actual
docker compose up --detach
docker compose logs -f actual

Sunucu 5006 numaralı portu dinlediğini bildirdiğinde log sakinleşir. DNS ayarlarına dokunmadan önce yerel olarak kontrol edin:

curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5006/

200 çıktısı, uygulamanın istekleri yanıtladığını gösterir. curl: (7) Failed to connect çıktısı, 127.0.0.1:5006 üzerinde bağlantıyı kabul eden hiçbir sürecin bulunmadığını gösterir. docker compose ps --all komutunu çalıştırın. Çünkü düz docker compose ps yalnızca çalışan container'ları listeler. Container durdurulmuş görünüyorsa olağan neden, bağlı volume üzerindeki izin sorunudur. Bu sorun logda EACCES satırı olarak görülebilir.

Önüne sertifika ve gerçek bir ad koyun

VPS'ye bir A kaydı yönlendirin: budget.example.com. Kaydın çözülmesini bekleyin. Ardından nginx'i kurun ve sertifikayı alın. Ubuntu 24.04 üzerinde nginx ile Certbot kılavuzunda sertifika alma ve yenileme zamanlayıcısı ayrıntılı biçimde açıklanır.

Proxy bloğu:

server {
    listen 443 ssl;
    http2 on;
    server_name budget.example.com;

    ssl_certificate     /etc/letsencrypt/live/budget.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/budget.example.com/privkey.pem;

    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:5006;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

client_max_body_size, genellikle unutulan satırdır. Günlük senkronizasyon yalnızca yaptığınız değişiklikleri gönderir. Ancak bir bütçeyi sunucuya ilk kez kaydettiğinizde ve senkronizasyonu sıfırladığınızda bütçe dosyasının tamamı yüklenir. nginx varsayılan olarak istek gövdesini 1 MB ile sınırlar. Dosya bu boyutu aştığında tam dosya yüklemeleri başarısız olur. nginx erişim günlüğünde 413 Request Entity Too Large görülür. Uygulama ise yalnızca genel bir senkronizasyon hatası gösterir. Sunucunun ayrıca kendi sınırları vardır: ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB varsayılan olarak 20, ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB ise 50 değerini kullanır. Bu nedenle nginx sınırını, sizin için geçerli olan değerin üzerine ayarlayın.

Yapılandırmayı yeniden yükleyin ve test edin:

sudo nginx -t && sudo systemctl reload nginx
curl -fsS -o /dev/null -w '%{http_code}\n' https://budget.example.com/

İlk çalıştırma: parola ve ilk bütçe dosyanız

https://budget.example.com adresini bir tarayıcıda açın. İlk ekran sizden sunucu parolası belirlemenizi ister. Bu tek parola sunucunun tamamını korur. Bu nedenle uzun ve rastgele bir parola oluşturun. Parolayı, örneğin self-hosted Vaultwarden parola yöneticisi gibi daha sonra yeniden bulabileceğiniz güvenli bir yerde saklayın. Varsayılan kurulumda oluşturulacak kullanıcı hesabı yoktur. Sunucuda tek bir parola bulunur. Bu nedenle bir bütçeyi paylaşmak, bu parolayı paylaşmak anlamına gelir. Ayrı oturum açma seçenekleri yalnızca bir OpenID sağlayıcısı bağlandığında kullanılabilir. Actual, çok kullanıcılı kurulumlar için bunu destekler.

Ardından bir bütçe dosyası oluşturun. Actual, uçtan uca şifrelemeyi etkinleştirmek isteyip istemediğinizi sorar. Evet yanıtını verin. Böylece sunucu yalnızca şifreli metni saklar. Kiralanmış bir makinedeki finansal veriler için doğru tercih budur. Bunun gerçek bir maliyeti vardır: Şifreleme parolası sunucuya gönderilmez. Bu nedenle parolayı kaybederseniz dosya da kaybolur ve sıfırlama seçeneği bulunmaz. Bu ekrandan ilerlemeden önce parolayı not alın.

Başlangıç bakiyelerinizi yıllarca süren geçmişi içe aktarmak yerine bankanızdaki güncel tutarlara göre belirleyin. Zarf bütçeleme, elinizde bulunan mevcut parayla ileriye doğru çalışır. Bu nedenle geçmiş verilerin bulunmaması sorun oluşturmaz.

İşlemleri içeri aktarma

Bu noktada dürüstlük, hevesli olmaktan daha önemlidir; çünkü içeri aktarma süreci, insanların self-hosted bütçeleme araçlarını kullanmaktan vazgeçmelerinin temel nedenidir.

Elle giriş yapmak temel yöntemdir ve her zaman çalışır. Zarf yöntemi için bu, sürecin özü sayılabilecek bir noktadır; çünkü bir harcamayı elle yazmak, onu fark etmenizi sağlar.

Dosya ile içeri aktarma, büyük hacimli işlemler için kullanılır. Actual; CSV, QIF, OFX, QFX ve CAMT formatlarını okuyabilir ve her banka bu formatlardan en az birini dışa aktarma seçeneği sunar. İçeri aktarma işlemini hesap ekranından hesap bazlı olarak gerçekleştirin ve dosya CSV formatındaysa sütunları eşleştirin.

Otomatik banka senkronizasyonu mevcuttur ancak sunucu bankalarla doğrudan iletişim kuramadığı için üçüncü taraf bir servis gerektirir. Actual; Kuzey Amerika bankaları için SimpleFIN Bridge, Avrupa için Enable Banking, Yeni Zelanda için Akahu ve Brezilya için Pluggy.ai servislerini destekler. GoCardless hâlâ desteklenmektedir ancak yeni hesap kabul etmemektedir. Servis sağlayıcıya kendiniz kaydolmalı, kimlik bilgileri oluşturmalı ve bunları sunucuya eklemelisiniz. Ekim 2026 itibarıyla SimpleFIN Bridge, 25 kuruma kadar yıllık 15 ABD doları artı vergi ücret talep etmektedir; diğer servislerin fiyatlandırması ise farklıdır.

Bu yönteme güvenmeden önce kabul etmeniz gereken iki sınırlama vardır. API kimlik bilgileri sunucuda tutulur ve sunucunun bunları kullanması gerektiği için uçtan uca şifreleme kapsamında değildir. Ayrıca Actual kapalıyken hiçbir şey senkronize edilmez: otomatik senkronizasyon varsayılan olarak kapalıdır ve açtığınızda yalnızca uygulama açıkken çalışır; bu nedenle sunucu bankalarınızı kendi başına sorgulamaz.

Yedeklemeler, çünkü sadece dosyalardan ibaret

Önem verdiğiniz her şey /opt/actual/data dizini altındadır. Herhangi bir dışa aktarma adımı veya betiklenmesi gereken bir veritabanı dökümü yoktur.

Buradaki tek tuzak SQLite kullanımıdır. Sunucu yazma işlemi yaparken account.sqlite dosyasını kopyalamak, yarım kalmış bir işlemi yakalamanıza neden olabilir ve bunu ancak geri yükleme yapmaya çalıştığınızda fark edersiniz. Kopyalama işleminin sürdüğü birkaç saniye boyunca container'ı durdurun:

cd /opt/actual
docker compose stop
restic -r sftp:backup@backup.example.com:/srv/restic backup /opt/actual/data
docker compose start

Bunu, depo kurulumu, saklama politikaları ve geri yükleme tatbikatını kapsayan bir VPS üzerinde restic yedeklemeleri yaklaşımıyla bir zamanlamaya bağlayın. Geri yükleme tatbikatını mutlaka gerçekleştirin. Daha önce geri yüklemediğiniz bir yedekleme, sadece bir tahmindir.

Actual'ın kendi otomatik yedeklemeleri ayrı bir konudur ve bilinmesi faydalıdır, ancak bunlar yalnızca masaüstü uygulamasında mevcuttur. Bütçe dosyasının en son 10 kopyasını tutar ve File > Load Backup menüsünden erişilebilir; bu özellik, sunucuya hiç dokunmadan "yanlışlıkla bir kategori sildim" gibi durumları çözer. Tarayıcıdaki web uygulaması bu tür kopyaları tutmaz, bu nedenle evdeki herkes tarayıcıyı kullanıyorsa, yukarıda belirtilen sunucu yedeklemesi sahip olduğunuz tek yedeklemedir.

Sunucunun güncellenmesi

cd /opt/actual
docker compose pull
docker compose up --detach

Compose, yeni image üzerinden container'ı yeniden oluşturur ve aynı volume'u yeniden bağlar; bu nedenle veriler korunur. İstemciler de güncellenmelidir. Alınan verilerden daha eski bir istemci değişiklikleri uygulamayı durdurur ve Update Required mesajını gösterir. Büyük bir sürüm geçişinden önce yedek alınmalıdır; ilk başlatmada migration işlemleri çalışır ve downgrade yolu yoktur. Durumu dosyalardan oluşan bir dizin olduğu için Actual, kayan latest etiketiyle yapılan güncellemeleri tolere eder. Gerçek bir veritabanı kullanan uygulamalarda bu yaklaşım geçerli değildir. Chatwoot'u self-host etme başlığı, sabitlenen etiketleri ve bu işlem için gerekli yükseltme öncesi dump alma adımını açıklar.

Neler bozulur ve ne görürsünüz

Uygulama yükleniyor ancak eşitleme asla tamamlanmıyor. 413 için nginx erişim günlüğünü kontrol edin. Bu, client_max_body_size değerinin çok düşük ayarlandığı anlamına gelir. 502 hatası ise nginx'in upstream'den kullanılabilir bir yanıt alamadığını gösterir. Bu durum genellikle container'ın durmuş olmasından veya 5006 numaralı portu dinlemiyor olmasından kaynaklanır; bu nedenle başka bir işlem yapmadan önce docker compose ps --all komutunu ve container günlüğünü kontrol edin.

Uygulama başka bir cihazda yüklenmiyor veya SharedArrayBuffer eksik hatası veriyor. Sayfa güvenli bir bağlamda değil. Adres çubuğu, bir IP adresi veya localhost olmayan bir ana bilgisayar adı ile http:// uyarısını gösterecektir. Sorunu geçici çözümlerle aşmak yerine sertifikayı düzeltin.

Bütçe dosyasının bu sürümle uyumlu olmadığına dair bir mesaj. Dosya, şu an kullandığınız istemciden daha yeni bir Actual sürümünde açılmış. İstemciyi en az o sürüme güncelleyin veya dosya daha yeni sürüm tarafından işlenmeden önce alınan bir yedeği geri yükleyip sayfayı yeniden yükleyin.

Container sürekli yeniden başlatılıyor. docker compose logs actual dosyasını okuyun. /data üzerindeki bir izin hatası, mount edilen dizinin container kullanıcısı tarafından yazılabilir olmadığını gösterir. "Address-in-use" hatası ise başka bir sürecin loopback üzerinde 5006 numaralı portu halihazırda kullandığı anlamına gelir.

İlk yükleme yavaş hissettiriyor. Bütçe dosyasının tamamı, uygulamayı açtığınızda tarayıcıya indirilir. Bu tek bir büyük aktarımdır, sonrasında okuma işlemleri yerel olarak yapılır. Bu bir sunucu boyutlandırma sorunu değildir ve RAM eklemek durumu değiştirmeyecektir.

FAQ

Actual Budget'in çalışması için HTTPS gerekli mi?

Evet, pratikte gereklidir. Actual, tarayıcının SharedArrayBuffer özelliğine ihtiyaç duyar ve tarayıcılar bu özelliği yalnızca güvenli bağlamlarda, yani https:// veya http://localhost üzerinden erişildiğinde etkinleştirir. Başka bir makineden düz HTTP üzerinden bağlanıldığında uygulama yüklenmeyecektir. Resmi bir iOS uygulaması beta aşamasındadır ve henüz resmi bir Android uygulaması bulunmamaktadır; bu nedenle çoğu telefon aynı web uygulamasını kullanır ve aynı kurala tabidir. (FAQ) Gerçek bir alan adı üzerinde bir Let's Encrypt sertifikası kullanın veya her cihazda sertifika uyarısını kabul edebiliyorsanız ACTUAL_HTTPS_KEY ve ACTUAL_HTTPS_CERT ile kendi imzaladığınız bir sertifikayı tercih edin.

Actual banka işlemlerimi otomatik olarak içe aktarabilir mi?

Yalnızca kendi kaydolduğunuz üçüncü taraf bir servis aracılığıyla: Kuzey Amerika'da SimpleFIN Bridge, Avrupa'da Enable Banking, Yeni Zelanda'da Akahu veya Brezilya'da Pluggy.ai. GoCardless desteklenmektedir ancak yeni hesap kabul etmemektedir. Bu API kimlik bilgileri sunucunuzda tutulur ve uçtan uca şifreleme kapsamında değildir. Otomatik eşitleme varsayılan olarak kapalıdır ve etkinleştirildiğinde yalnızca Actual açıkken çalışır; bu nedenle sunucu tarafında arka planda herhangi bir sorgulama yapılmaz. CSV, QIF, OFX, QFX ve CAMT içe aktarma işlemleri için herhangi bir üçüncü tarafa ihtiyaç duyulmaz.

Tam olarak neleri yedeklemem gerekiyor?

Bu kılavuzda /opt/actual/data olarak belirtilen, mount edilmiş veri dizinini yedeklemelisiniz. Bu dizin, giriş bilgileri ve oturumları içeren server-files/account.sqlite dosyasını ve bütçe dosyalarını içeren user-files klasörünü barındırır. Kopyalama işleminden önce container'ı durdurun; çünkü çalışan bir SQLite veritabanını kopyalamak, veritabanının kısmi yazılmış bir kopyasını almanıza neden olabilir. Sunucuda durum bilgisi tutan başka hiçbir öğe yoktur.

Şifreleme şifresini kaybedersem ne olur?

Dosya kurtarılamaz. Şifre hiçbir zaman sunucuya ulaşmaz; uçtan uca şifrelemenin temel amacı budur, bu nedenle bir sıfırlama seçeneği veya destek yolu bulunmamaktadır. Dosyayı oluşturduğunuz anda şifreyi bir parola yöneticisine kaydedin ve bu sunucuya bağımlı olmayan bir yerde bir kopyasını saklayın.

Actual Budget ne kadar sunucu kaynağına ihtiyaç duyar?

Çok az. Container statik varlıkları ve dosyaları sunar, bütçe hesaplamaları ise tarayıcıda gerçekleşir. Bir adet paylaşımlı vCPU ve 1 GB RAM ile sorunsuz çalışır. Birkaç yıllık geçmişe sahip bir aile bütçesinin veri dizini, yalnızca onlarca megabayt yer kaplar. Disk üzerindeki yük, Actual'dan değil, yedeklerinizden ve diğer container'larınızdan kaynaklanır. Yanında daha fazla kaynak tüketen başka uygulamalar çalıştıracak bir sunucu planlıyorsanız, genellikle fotoğraf sunucuları sistem gereksinimlerini belirler; bu nedenle bir plan seçmeden önce PhotoPrism ve Immich'in gerçekte ne kadar RAM'e ihtiyaç duyduğuna göz atın. Aynı mantık medya yığınları için de geçerlidir: Transcoding işlemi planı belirlerken, Jellyfin kütüphanesini 90'ların gezilebilir bir video mağazasına dönüştüren Halcyon gibi bir tarayıcı arayüzü, Actual kadar az kaynak tüketir.

Bu yazı işinize yaradı mı?