Serwer pod agenta AI 24/7: czy wystarczy VPS za 20 zł
Agent AI na API modeli w chmurze działający całą dobę: co zużywa RAM i CPU, systemd albo Docker, klucz API poza zmiennymi, limity wydatków u dostawcy i logi.
Redakcja serwisu Dealownia · ceny i fakty ze stron dostawców, jak sprawdzamy
Zwykle tak. Agent, który myśli modelem w chmurze (przez API Anthropic, OpenAI albo innego dostawcy), sam niczego nie liczy – wysyła zapytanie, czeka na odpowiedź, wykonuje narzędzie i znowu czeka. Przez większość czasu proces stoi na połączeniu sieciowym, a procesor jest bezczynny. Najmniejszy VPS z 1–2 GB RAM uciągnie takiego agenta, dopóki agent nie zacznie uruchamiać ciężkich narzędzi: przeglądarki, kompilacji, lokalnych modeli. Rachunek za API zależy od liczby tokenów, a nie od serwera, i przy agencie pracującym bez nadzoru łatwo przerasta cenę VPS-a. Dlatego ważniejsze od rozmiaru planu są limity wydatków i to, żeby klucz API nie wyciekł.
Ten poradnik nie dotyczy lokalnego modelu – jeśli model ma działać na serwerze, wymagania są zupełnie inne i opisuje je poradnik Ollama na VPS bez GPU.
Co naprawdę zużywa zasoby
| Element | RAM | CPU | Uwagi |
|---|---|---|---|
| Sam proces agenta (Python, Node.js) z SDK dostawcy | mało | prawie zero w czasie czekania na API | rośnie z historią rozmów trzymaną w pamięci |
| Przeglądarka bez okna (Playwright, Chromium) | dużo, każda karta osobno | skoki przy renderowaniu stron | dokumentacja Playwrighta ostrzega, że Chromium w Dockerze bez --ipc=host może zabraknąć pamięci i się wysypać |
| Wykonywanie kodu, testów, kompilacji | zależy od projektu | wysokie w trakcie | najczęstszy powód, dla którego mały VPS przestaje wystarczać |
| Lokalna baza wektorowa, embeddingi liczone na serwerze | średnio do dużo | wysokie przy indeksowaniu | embeddingi z API przenoszą ten koszt do dostawcy |
| Kilka zadań naraz | mnoży wszystko powyżej | ogranicz współbieżność w kodzie | |
| Logi | – | – | zajmują dysk, jeśli nie ustawisz limitów (krok 5) |
Zamiast zgadywać, zmierz: uruchom agenta na najmniejszym planie i zostaw na dobę typowej pracy. systemctl status agent pokazuje zużycie pamięci usługi (w nowszych wersjach systemd także szczytowe), systemd-cgtop – wszystkie usługi naraz, docker stats – kontenery. Jeśli szczyt zbliża się do RAM-u serwera, weź większy plan albo przenieś ciężkie narzędzie gdzie indziej. Tanie plany porównasz w rankingu VPS do 20 zł i w pełnym rankingu VPS.
Krok 1. Osobny użytkownik i katalog
Zakładamy serwer przygotowany jak w poradniku od zera. Agent, który potrafi wykonywać polecenia albo pisać pliki, nie powinien działać jako Twój użytkownik z sudo – błąd w promptach albo złośliwa treść, którą agent przeczyta na stronie, może skłonić go do zrobienia czegoś, czego nie chciałeś. Ogranicz szkody z góry:
Kod należy do deploy, a agent go tylko czyta. Dane, które agent zapisuje, trafią do osobnego katalogu stanu (krok 3).
Krok 2. Klucz API w pliku poświadczeń, nie w zmiennej środowiskowej
Najczęstsza praktyka to klucz w pliku .env wczytywanym jako zmienne środowiskowe. Dokumentacja systemd ocenia to wprost: zmienne środowiskowe nie nadają się do przekazywania sekretów – te ustawione w jednostce są widoczne dla nieuprzywilejowanych klientów przez D-Bus, a wszystkie dziedziczą procesy potomne. Dla agenta, który uruchamia podprocesy (narzędzia, skrypty, przeglądarkę), to szczególnie ważne: każdy z nich dostaje klucz w swoim środowisku, a stamtąd łatwo trafia do logów, zrzutów błędów czy wyniku polecenia env. Zalecany mechanizm to poświadczenia systemd (LoadCredential=).
Uczciwie trzeba dodać, czego poświadczenia nie załatwiają: plik z kluczem jest czytelny dla użytkownika usługi, więc podproces działający jako agent może go odczytać, jeśli celowo go poszuka. Poświadczenia usuwają klucz ze środowiska i z przypadkowych wycieków, ale nie izolują go od kodu uruchamianego przez agenta. Przed tym chronią dopiero osobny klucz z niskim limitem wydatków (krok 4) albo uruchamianie narzędzi w osobnym kontenerze lub jako inny użytkownik.
Plik z kluczem, czytelny tylko dla roota (wpisz klucz w edytorze, nie przez echo, żeby nie został w historii powłoki):
W kodzie agent czyta klucz z katalogu, który systemd przekazuje w zmiennej $CREDENTIALS_DIRECTORY, i podaje go klientowi SDK jawnie. Przykład dla SDK Anthropic w Pythonie (domyślnie czyta ono klucz ze zmiennej ANTHROPIC_API_KEY, ale przyjmuje go też w parametrze api_key):
SDK innych dostawców mają analogiczny parametr klucza w konstruktorze klienta.
Dwie zasady niezależne od sposobu przechowywania:
- Osobny klucz dla serwera. Nie używaj tego samego klucza co na laptopie. Po wycieku unieważniasz jeden klucz i nic innego nie przestaje działać.
- Osobna przestrzeń rozliczeń. U Anthropic załóż dla agenta osobny workspace w Claude Console i wygeneruj w nim klucz – limity wydatków ustawisz wtedy tylko dla niego (krok 4). U OpenAI to samo robi osobny projekt.
Krok 3. Usługa systemd
Plik /etc/systemd/system/agent.service:
Co tu jest ważne:
LoadCredential=api_key:/etc/agent/api_key– systemd sam odczytuje plik roota i udostępnia go procesom usługi w katalogu z$CREDENTIALS_DIRECTORY(według dokumentacji dostęp ma tylko użytkownik usługi i root). Użytkownikagentnie musi mieć dostępu do/etc/agent.StateDirectory=agent– katalog/var/lib/agentz prawem zapisu dla agenta. PrzyProtectSystem=strictcały system plików jest tylko do odczytu, więc to jedyne miejsce, w którym agent może pisać (pliki robocze, baza SQLite, pamięć rozmów).MemoryMax=iMemoryHigh=– według dokumentacjiMemoryMaxto twardy limit (po jego przekroczeniu zadziała OOM killer wewnątrz usługi, a nie na całym serwerze), aMemoryHighto próg, powyżej którego procesy są mocno spowalniane. Wartości dobierz do planu – na serwerze z 1 GB RAM przykładowe zostawiają trochę pamięci dla systemu i SSH.CPUQuota=80%– najwyżej 80% jednego rdzenia. Pętla, która się zawiesi na liczeniu, nie zablokuje serwera.Restart=on-failurezRestartSec=30– agent wstaje po awarii, ale nie częściej niż co 30 sekund. Celowo niealways: agent, który poprawnie kończy pracę, nie powinien startować w pętli.- Gdy agent ma uruchamiać przeglądarkę albo kompilować kod, sprawdź, czy narzędzia działają przy
ProtectSystem=strict– mogą potrzebować dodatkowych katalogów zapisu (ReadWritePaths=).
Prostszą wersję tej samej usługi – z tokenem w pliku .env wczytywanym przez EnvironmentFile= – opisuje poradnik o bocie Discorda 24/7. Dla bota, który nie uruchamia cudzych poleceń ani podprocesów, to rozsądny kompromis; dla agenta, który je uruchamia, lepsze są poświadczenia.
Wariant w Dockerze
Jeśli agent działa w kontenerze, odpowiednikiem poświadczeń są sekrety Compose. Dokumentacja Dockera zwraca uwagę na ten sam problem co systemd: zmienne środowiskowe widzą wszystkie procesy w kontenerze i łatwo trafiają do logów. Plik /opt/apps/agent/compose.yaml:
Compose montuje plik w kontenerze jako /run/secrets/api_key – kod czyta go z tej ścieżki zamiast z $CREDENTIALS_DIRECTORY. Bez Docker Swarm sekret z pliku jest zwykłym zamontowanym plikiem z uprawnieniami takimi jak na hoście: jeśli proces w kontenerze nie działa jako root (a nie powinien), plik root:root z prawami 600 będzie dla niego nieczytelny. Nadaj plikowi na hoście właściciela o tym samym UID, którego używa kontener, i zostaw prawa 600. init: true zapobiega procesom zombie, co dokumentacja Playwrighta zaleca przy przeglądarce w kontenerze. Jeśli agent używa Chromium, dodaj też ipc: host. Kontener nie ma sekcji ports, bo agent łączy się tylko na zewnątrz.
Krok 4. Limity wydatków u dostawcy API
To najważniejszy krok. Agent działający całą dobę bez nadzoru może wpaść w pętlę: błąd narzędzia, ponowienie, ta sama odpowiedź, kolejne ponowienie – i każde z tych wywołań kosztuje. Limit na serwerze tego nie zatrzyma, limit u dostawcy tak.
Anthropic (Claude API). Według dokumentacji (stan na 12.11.2026):
- każdy poziom konta ma miesięczny limit wydatków organizacji (np. 500 USD na poziomie Start); własny, niższy limit ustawisz w Claude Console w Settings → Spend limits;
- można ustawić osobne limity wydatków i zapytań dla workspace’ów – z wyjątkiem domyślnego workspace’u, dlatego agent powinien mieć własny;
- po osiągnięciu limitu ustawionego przez Ciebie API zwraca błąd 400
invalid_request_errorz komunikatem o osiągniętym limicie, a po osiągnięciu limitu poziomu – 429 bez nagłówkaretry-after. W tym drugim przypadku ponawianie, także automatyczne ponowienia SDK, nie pomoże aż do początku kolejnego miesiąca (00:00 UTC pierwszego dnia) albo przejścia na wyższy poziom; w treści błędu jest kodenforced_spend_limit_reached.
OpenAI. Według dokumentacji limity ustawisz dla organizacji i dla projektu. Alerty wysyłają tylko powiadomienie i nie zatrzymują ruchu. Zatrzymuje go dopiero twardy limit (opcja „Enforce a hard limit”) – wtedy zapytania dostają błąd 429 z kodem project_spend_limit_exceeded albo organization_spend_limit_exceeded. Dokumentacja zastrzega, że egzekwowanie nie jest natychmiastowe, więc wydatki mogą nieznacznie przekroczyć limit.
W kodzie agenta dołóż własne bezpieczniki, bo limit miesięczny chroni przed katastrofą, a nie przed zmarnowaniem połowy budżetu w jedną noc:
- maksymalna liczba kroków (wywołań modelu) na jedno zadanie;
max_tokensw każdym zapytaniu;- przy błędzie limitu wydatków – zatrzymanie pracy i powiadomienie zamiast ponawiania;
- licznik tokenów z pola
usageodpowiedzi, zapisywany w logu przy każdym zadaniu.
Ile kosztują tokeny i jak policzyć miesięczny rachunek w złotych, pokazuje poradnik ile kosztuje API modeli AI. Jeśli agent ma służyć tylko Tobie do pracy na co dzień, porównaj też abonamenty w rankingu asystentów AI.
Krok 5. Logi, które nie zapchają dysku
Agent loguje dużo: zapytania, odpowiedzi, wyniki narzędzi. Na małym dysku to realny problem.
- journald. Według dokumentacji domyślny limit to 10% systemu plików (najwyżej 4 GB), a czasowe usuwanie wpisów jest domyślnie wyłączone. Na VPS-ie z 20 GB dysku ustaw limit jawnie w pliku
/etc/systemd/journald.conf.d/60-limit.conf:
Katalog nadpisań zwykle trzeba najpierw utworzyć: sudo mkdir -p /etc/systemd/journald.conf.d. Potem:
- Docker. Domyślny sterownik
json-filewedług dokumentacji nie rotuje logów. Sterowniklocal(jak w przykładzie wyżej) rotuje je domyślnie. - Czego nie logować. Klucza API (także w komunikatach wyjątków z konfiguracją klienta), pełnych treści dokumentów z danymi osobowymi i haseł, które agent mógł zobaczyć w trakcie pracy. Loguj identyfikator zadania, liczbę kroków, zużyte tokeny i błędy.
Krok 6. Sygnał, że agent żyje
Proces może działać, a agent i tak stać – np. zawieszony na zapytaniu bez limitu czasu albo zatrzymany przez limit wydatków. Niech agent po każdym udanym cyklu wywołuje adres monitora typu push w Uptime Kuma. Gdy wywołania ustaną, dostaniesz alert. Pozostałe zabezpieczenia serwera – SSH tylko z kluczem, zapora, aktualizacje – są w liście kontrolnej.
Najczęstsze problemy
KeyError: 'CREDENTIALS_DIRECTORY'. Proces uruchomiony poza systemd (np. ręcznie do testu) albo brakLoadCredential=w usłudze. Testuj przezsudo systemctl restart agentijournalctl -u agent -n 50, a nie uruchamiając skrypt ręcznie.- Usługa ginie, a w
journalctljest „oom-kill”. PrzekroczonyMemoryMax. Sprawdź, co rośnie – historia rozmowy w pamięci, przeglądarka, równoległe zadania – i albo to ogranicz, albo podnieś limit i plan. - Agent stoi, błędy 429. Rozróżnij limit zapytań (jest nagłówek
retry-after, wystarczy poczekać) od limitu wydatków (u Anthropic bezretry-after, u OpenAI kod…_spend_limit_exceeded). Na limit wydatków nie pomaga ponawianie. - Narzędzie nie może zapisać pliku: „Read-only file system”. Skutek
ProtectSystem=strict. Zapisuj w/var/lib/agentalbo dodaj katalog wReadWritePaths=. - Rachunek za API większy niż zakładany. Przejrzyj w logach liczbę kroków na zadanie. Najczęściej winna jest pętla ponowień albo zbyt długa historia wysyłana przy każdym kroku.
Źródła
Sprawdzone 12.11.2026:
- systemd.exec – zmienne środowiskowe a sekrety,
LoadCredential=,$CREDENTIALS_DIRECTORY,ProtectSystem=,NoNewPrivileges=: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html - systemd.resource-control –
MemoryMax=,MemoryHigh=,CPUQuota=: https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html - journald.conf –
SystemMaxUse=,MaxRetentionSec=, katalog nadpisań: https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html - Docker – sekrety w Compose: https://docs.docker.com/compose/how-tos/use-secrets/
- Docker – konfiguracja logowania (brak rotacji w
json-file, sterowniklocal): https://docs.docker.com/engine/logging/configure/ - Playwright – Docker (
--ipc=host,--init): https://playwright.dev/docs/docker - Anthropic – limity wydatków i zapytań, workspace’y, błędy po osiągnięciu limitu: https://platform.claude.com/docs/en/api/rate-limits
- OpenAI – limity wydatków (alerty, twardy limit, kody błędów): https://developers.openai.com/api/docs/guides/spend-limits