<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[JSystems — IT, AI i automatyzacja]]></title><description><![CDATA[JSystems — IT, AI i automatyzacja]]></description><link>https://jsystems.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>JSystems — IT, AI i automatyzacja</title><link>https://jsystems.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 00:56:12 GMT</lastBuildDate><atom:link href="https://jsystems.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Ansible od podstaw - automatyzacja konfiguracji serwerow bez agenta (przyklad)]]></title><description><![CDATA[Rekami skonfigurowany serwer to serwer, ktorego nikt juz nie pamieta jak odtworzyc. Ansible rozwiazuje to deklaratywnie i bez agenta. Pokazujemy konkretny przyklad od zera.

Ansible w pigułce: jeden w]]></description><link>https://jsystems.hashnode.dev/czym-jest-ansible-automatyzacja-serwerow</link><guid isPermaLink="true">https://jsystems.hashnode.dev/czym-jest-ansible-automatyzacja-serwerow</guid><category><![CDATA[ansible]]></category><category><![CDATA[Devops]]></category><category><![CDATA[automation]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:04:30 GMT</pubDate><content:encoded><![CDATA[<p>Rekami skonfigurowany serwer to serwer, ktorego nikt juz nie pamieta jak odtworzyc. Ansible rozwiazuje to deklaratywnie i bez agenta. Pokazujemy konkretny przyklad od zera.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/hero_ansible.gif" alt="Animacja: Ansible z jednego węzła sterującego konfiguruje wiele serwerów przez SSH, bez agenta" /></p>
<p>Ansible w pigułce: jeden węzeł sterujący wypycha konfigurację na wiele serwerów naraz, a na tych serwerach nie instalujesz żadnego dodatkowego oprogramowania.</p>
<p>Wyobraź sobie, że masz postawić dziesięć identycznych serwerów WWW. Logujesz się przez SSH na pierwszy, instalujesz nginx, wgrywasz konfigurację, zakładasz konto, uruchamiasz usługę. Potem to samo na drugim. I na trzecim. Po piątym mylisz się w jednym poleceniu i nagle serwery przestają być identyczne. Właśnie ten problem rozwiązuje <strong>Ansible</strong>.</p>
<p>W tym artykule wyjaśnimy od zera, czym Ansible jest i jak działa. Nie na slajdach, tylko na <strong>działającym labie</strong>: postawiliśmy węzeł sterujący i cztery serwery, a wszystkie zrzuty poniżej to prawdziwe wyjścia poleceń z tego środowiska. Zobaczysz playbook w akcji, zrozumiesz idempotencję i dowiesz się, dlaczego model bez agenta zrobił z Ansible ulubione narzędzie administratorów.</p>
<p>Z tego artykułu dowiesz się</p>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#czym-jest">Czym jest Ansible i jaki problem rozwiązuje</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#agentless">Dlaczego działa bez agenta i czym różni się od Puppet i Chef</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#pierwszy-kontakt">Jak wygląda inventory i polecenia ad-hoc</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#playbook">Czym jest playbook i jak jednym plikiem konfigurujesz wiele serwerów</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#idempotencja">Co to jest idempotencja i czemu jest tak ważna</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/#zaawansowane">Fakty, szablony Jinja2, role i szyfrowanie sekretów (Vault)</a></li>
</ul>
<h2>Czym jest Ansible</h2>
<p>Ansible to narzędzie do <strong>automatyzacji konfiguracji serwerów</strong> i wdrożeń. Zamiast ręcznie klikać i wpisywać polecenia na każdej maszynie z osobna, opisujesz <strong>stan docelowy</strong> w czytelnym pliku tekstowym, a Ansible sam doprowadza do niego wszystkie wskazane serwery. Powiesz mu: „na tych dziesięciu hostach ma być zainstalowany nginx, ma działać i ma mieć taką konfigurację”, a on wykona to na wszystkich naraz.</p>
<p>Ansible powstał w 2012 roku, dziś rozwija go Red Hat i jest jednym z najpopularniejszych <a href="https://jsystems.pl/show_post/czym-jest-devops-narzedzia-i-zastosowania">narzędzi w świecie DevOps</a>. Jego siła bierze się z prostoty: konfigurację zapisujesz w formacie <strong>YAML</strong>, który czyta się niemal jak zwykłą listę kroków po polsku, a do działania nie potrzebujesz niczego poza SSH i Pythonem.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/architektura.png" alt="Infografika sześciu elementów Ansible: inventory, moduły, playbook, zmienne i Jinja2, role, Vault" /></p>
<p>Cały Ansible opiera się na kilku prostych pojęciach. Przejdziemy przez nie po kolei, pokazując każde na żywym przykładzie.</p>
<h3>Problem, który rozwiązuje</h3>
<p>Ręczna administracja nie skaluje się. Trzy serwery jeszcze ogarniesz, ale przy trzydziestu pojawiają się dwa problemy. Po pierwsze <strong>czas</strong>: ta sama czynność powtórzona trzydzieści razy to godziny pracy. Po drugie <strong>rozjazd konfiguracji</strong>: prędzej czy później któryś serwer dostanie inną wersję pakietu albo inny wpis w konfiguracji, i zaczyna zachowywać się inaczej niż reszta. Ansible zamyka opis serwera w pliku, który trzymasz w repozytorium razem z kodem - dzięki temu konfiguracja jest powtarzalna, wersjonowana i taka sama na każdej maszynie. Skoro konfiguracja żyje w repozytorium, warto znać podstawy kontroli wersji - jeśli dopiero zaczynasz, zajrzyj do przewodnika <a href="https://jsystems.pl/show_post/czym-jest-git-przewodnik-krok-po-kroku">czym jest Git i jak z niego korzystać</a>. Ansible często łączy się też z narzędziami do zarządzania infrastrukturą jako kodem, takimi jak Terraform, i z podejściem GitOps - pokazaliśmy taki tandem w artykule o <a href="https://jsystems.pl/show_post/ai-dla-devopsow-agent-terraform-gitops-proxmox">agencie AI, który stawia maszyny Terraformem i pilnuje GitOps</a>.</p>
<h2>Agentless, czyli bez agenta na serwerach</h2>
<p>Najważniejsza cecha Ansible kryje się w słowie <strong>agentless</strong> (bez agenta). Na zarządzanych serwerach nie instalujesz żadnego oprogramowania Ansible - żadnej usługi, żadnego demona działającego w tle. Ansible siedzi tylko na jednej maszynie, tak zwanym <strong>węźle sterującym</strong> (może nim być Twój laptop), i łączy się z serwerami przez zwykłe <strong>SSH</strong>. Wykorzystuje to, co i tak jest na każdym Linuksie: połączenie SSH i interpreter Pythona.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/agentless_vs_agent.png" alt="Porównanie Ansible (agentless, model push) z Puppet i Chef (agent na hoście, model pull)" /></p>
<p>Ansible wypycha konfigurację z węzła sterującego (model push). Starsze narzędzia, jak Puppet i Chef, wymagają agenta na każdym hoście, który sam odpytuje serwer centralny (model pull).</p>
<p>To ogromne uproszczenie. W modelu z agentem (jak w starszych Puppet czy Chef) na każdym serwerze musisz zainstalować i utrzymywać program, który cyklicznie pyta serwer centralny o konfigurację. To kolejna rzecz do zainstalowania, zabezpieczenia i naprawiania, gdy się zepsuje. Ansible tego nie potrzebuje: model <strong>push</strong> oznacza, że to węzeł sterujący sam wypycha zmiany na serwery wtedy, kiedy Ty o to poprosisz. Start jest banalny - o czym za chwilę.</p>
<h2>Pierwszy kontakt: instalacja, inventory i polecenia ad-hoc</h2>
<p>Instalacja sprowadza się do jednego polecenia. Ansible to paczka Pythona, więc instalujemy go menedżerem pakietów <code>pip</code>:</p>
<pre><code>python3 -m pip install ansible
ansible --version
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_version.png" alt="Zrzut terminala z wynikiem polecenia ansible --version pokazujący Ansible core w wersji 2.17" /></p>
<p>Po instalacji sprawdzamy wersję. To całe przygotowanie węzła sterującego - reszta to już praca.</p>
<h3>Inventory - lista serwerów</h3>
<p>Ansible musi wiedzieć, czym ma zarządzać. Tę listę nazywamy <strong>inventory</strong>. To zwykły plik tekstowy, w którym grupujemy serwery - na przykład osobno serwery WWW, osobno bazy danych. Grupy pozwalają potem powiedzieć „zrób to tylko na serwerach WWW”:</p>
<pre><code># inventory.ini - lista zarzadzanych hostow
[web]
web1
web2
web3

[db]
db1

[serwery:children]
web
db
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_inventory.png" alt="Zrzut terminala z drzewem inventory Ansible: grupa serwery z podgrupami web i db oraz hostami" /></p>
<p>Polecenie ansible-inventory --graph pokazuje inventory jako drzewo grup. Widać grupę serwery z podgrupami web (web1, web2, web3) i db (db1).</p>
<h3>Polecenia ad-hoc - szybkie zadania bez pliku</h3>
<p>Zanim napiszemy pełny scenariusz, możemy odpalać pojedyncze zadania jednym poleceniem. Nazywamy je <strong>ad-hoc</strong> (doraźnymi). Klasyczny pierwszy kontakt to <code>ping</code> - sprawdzenie, czy Ansible dogada się ze wszystkimi hostami:</p>
<pre><code>ansible serwery -m ping
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_ping.png" alt="Zrzut terminala z wynikiem ansible -m ping: wszystkie hosty odpowiadają SUCCESS i pong" /></p>
<p>Każdy host odpowiada zielonym SUCCESS i „pong”. To potwierdza, że węzeł sterujący ma połączenie SSH i Pythona na wszystkich serwerach.</p>
<p>Tak samo uruchomimy dowolne polecenie systemowe na całej grupie naraz. Tu pytamy serwery WWW o czas działania, a przy okazji sprawdzamy, że nginx jeszcze nie jest zainstalowany - zaraz to zmienimy playbookiem:</p>
<pre><code>ansible web -m command -a "uptime"
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_adhoc.png" alt="Zrzut terminala z poleceniami ad-hoc Ansible: uptime na serwerach web oraz nieudane nginx -v przed instalacją" /></p>
<p>Polecenia ad-hoc wykonują się na wszystkich serwerach WWW jednocześnie. Widać, że nginx jeszcze nie istnieje (błąd na czerwono) - to nasz punkt wyjścia.</p>
<p>Polecenia ad-hoc i inventory to dopiero rozgrzewka. Jeśli chcesz nauczyć się pisać kompletne playbooki, składać z nich role wielokrotnego użytku i wdrażać całe środowiska od zera, pokażemy Ci to na praktycznych warsztatach. <a href="https://jsystems.pl/szkolenia-devops-sysops;devops_ansible_full.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=link_srodtekst1_czym-jest-ansible">Szkolenie Ansible: automatyzacja zadań w praktyce</a> ma terminy gwarantowane.</p>
<h2>Playbook - serce Ansible</h2>
<p>Polecenia ad-hoc są wygodne do drobiazgów, ale prawdziwa moc Ansible to <strong>playbook</strong>: plik YAML, w którym opisujemy cały scenariusz konfiguracji. Playbook to lista <strong>zadań</strong> (tasks), wykonywanych po kolei na wskazanych hostach. Każde zadanie używa jakiegoś <strong>modułu</strong> - gotowego klocka, który wie, jak coś zrobić. Modułowi mówisz, jaki ma być efekt („nginx ma być zainstalowany”), a on martwi się, jak to osiągnąć na danym systemie.</p>
<p>Oto kompletny playbook, który stawia serwer WWW na wszystkich hostach z grupy web - instaluje nginx, zakłada konto, wgrywa stronę z szablonu, poprawia wpis w konfiguracji, uruchamia usługę i sprawdza, czy odpowiada:</p>
<pre><code>---
# site.yml - postaw serwer WWW nginx na wszystkich hostach z grupy [web]
- name: Konfiguracja serwerow WWW
  hosts: web
  gather_facts: true
  vars:
    powitanie: "Ta strona zostala postawiona przez Ansible"
    admin_user: deploy

  tasks:
    - name: Zainstaluj serwer nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

    - name: Zaloz konto administracyjne
      ansible.builtin.user:
        name: "{{ admin_user }}"
        groups: sudo
        shell: /bin/bash
        state: present

    - name: Wgraj strone startowa z szablonu Jinja2
      ansible.builtin.template:
        src: templates/index.html.j2
        dest: /var/www/html/index.html
        owner: www-data
        mode: "0644"

    - name: Ustaw liczbe procesow roboczych nginx
      ansible.builtin.lineinfile:
        path: /etc/nginx/nginx.conf
        regexp: "^worker_processes"
        line: "worker_processes auto;"

    - name: Uruchom serwer nginx
      ansible.builtin.command: nginx
      args:
        creates: /run/nginx.pid

    - name: Sprawdz odpowiedz serwera WWW
      ansible.builtin.uri:
        url: http://localhost
        return_content: false
      register: odpowiedz

    - name: Pokaz kod odpowiedzi HTTP
      ansible.builtin.debug:
        msg: "Serwer {{ inventory_hostname }} odpowiada kodem HTTP {{ odpowiedz.status }}"
</code></pre>
<p>Zwróć uwagę, jak czyta się ten plik: to niemal lista kroków po ludzku. <code>hosts: web</code> mówi „rób to na serwerach WWW”, a każdy <code>- name:</code> to jeden opisany krok. Uruchamiamy całość jednym poleceniem:</p>
<pre><code>ansible-playbook site.yml
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_playbook1.png" alt="Zrzut terminala z pierwszym uruchomieniem playbooka Ansible: zadania changed, PLAY RECAP z changed=4 na trzech serwerach" /></p>
<p>Playbook w akcji. Ansible wykonuje zadania na trzech serwerach jednocześnie. Na żółto zadania, które coś zmieniły (changed), na zielono te, które już były w porządku (ok). Na dole PLAY RECAP: changed=4 na każdym hoście.</p>
<p>W kolorach kryje się cała logika Ansible. Żółte „changed” to zadania, które faktycznie coś zmieniły na serwerze. Zielone „ok” oznacza, że stan już się zgadzał i nie trzeba było nic robić. Podsumowanie <strong>PLAY RECAP</strong> na dole zbiera statystyki z każdego hosta - ile zadań się wykonało i ile z nich coś zmieniło.</p>
<p>Efekt jest namacalny. Zadanie z modułem <code>template</code> wygenerowało stronę startową, podstawiając do szablonu prawdziwe dane każdego serwera (nazwę hosta, wersję systemu, adres IP). Podejrzyjmy gotowy plik prosto na serwerze web1 poleceniem <code>cat</code>:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_page.png" alt="Zrzut terminala z poleceniem cat na pliku index.html serwera web1 - HTML z podstawionymi przez szablon Jinja2 nazwą hosta web1, systemem Debian 12 i adresem IP" /></p>
<p>Gotowy plik index.html na serwerze web1, podejrzany poleceniem cat. Nazwa hosta, system i adres IP nie są wpisane na sztywno - szablon Jinja2 podstawił je automatycznie z faktów o serwerze.</p>
<p>Widziałeś, jak jeden plik konfiguruje całą flotę serwerów naraz - to codzienność administratora pracującego z Ansible. Chcesz opanować playbooki, zmienne i szablony na tyle, by automatyzować własną infrastrukturę bez zaglądania do dokumentacji co chwilę? <a href="https://jsystems.pl/szkolenia-devops-sysops;devops_ansible_full.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=link_srodtekst2_czym-jest-ansible">Szkolenie Ansible: automatyzacja infrastruktury dla administratorów</a> ma terminy gwarantowane.</p>
<h2>Idempotencja - uruchom raz albo sto razy</h2>
<p>Dochodzimy do pojęcia, które odróżnia Ansible od zwykłego skryptu. <strong>Idempotencja</strong> oznacza, że wielokrotne uruchomienie tego samego playbooka daje ten sam efekt co jedno uruchomienie. Ansible najpierw sprawdza stan serwera i zmienia tylko to, co odbiega od opisanego celu. Jeśli wszystko już się zgadza - nie robi nic.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/idempotencja.png" alt="Infografika idempotencji Ansible: pierwsze uruchomienie changed=4, drugie changed=0" /></p>
<p>Ta sama konfiguracja, dwa uruchomienia. Za pierwszym razem Ansible doprowadza serwer do stanu docelowego (changed=4). Za drugim nie ma już nic do zrobienia (changed=0).</p>
<p>Zobaczmy to na żywo. Uruchamiamy dokładnie to samo polecenie drugi raz, bez żadnych zmian:</p>
<pre><code>ansible-playbook site.yml     # to samo, drugi raz
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_playbook2.png" alt="Zrzut terminala z drugim uruchomieniem playbooka Ansible: wszystkie zadania ok, PLAY RECAP z changed=0" /></p>
<p>Drugie uruchomienie: wszystkie zadania na zielono (ok), PLAY RECAP pokazuje changed=0. Nginx jest już zainstalowany, strona wgrana, usługa działa - Ansible niczego nie rusza.</p>
<p>To potężna właściwość w praktyce. Playbook możesz odpalać bez obaw ile razy chcesz - jako sposób na sprawdzenie, czy serwery nadal są w prawidłowym stanie, albo po dodaniu jednego nowego zadania. Ansible dołoży tylko brakującą różnicę i nie zepsuje tego, co już działa. Zwykły skrypt shellowy tak nie potrafi - próba drugiej instalacji czy dopisania tej samej linijki zwykle kończy się błędem albo duplikatem.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/flow_ansible.gif" alt="Animacja ścieżki uruchomienia Ansible: inventory, playbook, moduły, SSH, serwery, PLAY RECAP" /></p>
<p>Co dzieje się przy jednym uruchomieniu: Ansible bierze inventory i playbook, moduły łączą się przez SSH z serwerami, doprowadzają je do stanu docelowego i zwracają raport zmian.</p>
<h2>Fakty, szablony, role i sekrety</h2>
<p>Powyższe wystarczy, żeby zrozumieć, czym jest Ansible. Warto jednak poznać jeszcze cztery pojęcia, które spotkasz od razu przy realnej pracy.</p>
<h3>Fakty (facts) - Ansible sam bada serwer</h3>
<p>Zanim wykona zadania, Ansible zbiera <strong>fakty</strong> o każdym serwerze: system operacyjny, adresy IP, ilość pamięci, zamontowane dyski i setki innych informacji. Możesz się do nich odwoływać w playbookach - na przykład zainstalować inny pakiet na Debianie, a inny na systemie z rodziny Red Hat. Podejrzyjmy fakty o dystrybucji jednego z serwerów:</p>
<pre><code>ansible web1 -m setup -a "filter=ansible_distribution*"
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_facts.png" alt="Zrzut terminala z faktami Ansible o hoście web1: dystrybucja Debian w wersji 12" /></p>
<p>Fakty o serwerze web1. Ansible sam wykrył, że to Debian 12. Tych danych używamy potem w playbookach i szablonach, żeby jedna konfiguracja działała na różnych systemach.</p>
<h3>Szablony Jinja2 - jedna konfiguracja, wiele serwerów</h3>
<p>Widziałeś już moduł <code>template</code> w playbooku. Korzysta on z <strong>Jinja2</strong> - systemu szablonów, w którym w plik konfiguracyjny wstawiasz miejsca do wypełnienia w podwójnych nawiasach klamrowych. Ansible podstawia tam wartości zmiennych i faktów osobno dla każdego serwera. Dzięki temu jeden szablon obsługuje całą flotę, a każdy host dostaje swoją, właściwą wersję pliku - jak strona z poprzedniego przykładu, gdzie nazwa hosta i adres IP były podstawione automatycznie.</p>
<p>Tak dokładnie wygląda szablon <code>index.html.j2</code>, który wgrywaliśmy w playbooku. Wszystko, co stoi w podwójnych nawiasach klamrowych (podświetlone), to miejsce do wypełnienia - Ansible wstawi tam realną wartość osobno dla każdego serwera:</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="pl"&gt;
&lt;head&gt;&lt;meta charset="utf-8"&gt;&lt;title&gt;{{ inventory_hostname }}&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;{{ powitanie }}&lt;/h1&gt;
  &lt;p&gt;Host: {{ inventory_hostname }}&lt;/p&gt;
  &lt;p&gt;System: {{ ansible_distribution }} {{ ansible_distribution_version }}&lt;/p&gt;
  &lt;p&gt;Adres IP: {{ ansible_default_ipv4.address | default('n/d') }}&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Widać to od razu, gdy zestawimy szablon z wynikiem z poprzedniej sekcji: <code>{{ inventory_hostname }}</code> zamieniło się w <code>web1</code>, a <code>{{ ansible_default_ipv4.address }}</code> w konkretny adres IP tego serwera. Najlepszy dowód, że dzieje się to osobno dla każdego hosta, to pobrać gotową stronę wprost z innego serwera. Odpytajmy przez HTTP maszynę web2:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_page_web2.png" alt="Zrzut terminala z pobraniem strony przez curl po HTTP z serwera web2 - HTML z hostem web2 i adresem IP 172.19.0.2 podstawionymi przez ten sam szablon Jinja2" /></p>
<p>Ta sama konfiguracja, inny serwer. Strona pobrana przez HTTP z web2 ma w treści web2 i jego własny adres IP (172.19.0.2) - a powstała z dokładnie tego samego szablonu Jinja2 co strona web1. To właśnie znaczy „jedna konfiguracja, wiele serwerów”.</p>
<h3>Role i Ansible Galaxy - porządek w większych projektach</h3>
<p>Gdy playbooków i zadań przybywa, jeden wielki plik YAML robi się nieczytelny. Wtedy dzielimy konfigurację na <strong>role</strong>. Rola to samodzielny, gotowy do wielokrotnego użytku kawałek automatyzacji - na przykład „postaw serwer WWW” albo „skonfiguruj bazę danych” - w którym zadania, szablony, pliki i zmienne leżą w z góry ustalonych katalogach. Dzięki tej stałej strukturze Ansible sam wie, gdzie czego szukać, a Ty raz napisaną rolę wpinasz potem do dowolnego playbooka jednym wpisem.</p>
<p>Roli nie musisz pisać od zera. Służy do tego osobne narzędzie <code>ansible-galaxy</code>, a stoi za nim <a href="https://galaxy.ansible.com/">Ansible Galaxy</a> - publiczny katalog ról i kolekcji współdzielonych przez społeczność. Tym samym poleceniem pobierzesz gotową rolę z internetu (<code>ansible-galaxy role install autor.nazwa_roli</code>) albo wygenerujesz pusty szkielet własnej:</p>
<pre><code>ansible-galaxy role init webserver
</code></pre>
<p>To polecenie <strong>niczego nie pobiera z sieci</strong> - tworzy lokalnie kompletny szkielet katalogów nowej roli o nazwie <code>webserver</code>, z pustymi plikami <code>main.yml</code> w każdym miejscu, którego Ansible się spodziewa. Zamiast ręcznie zakładać kilkanaście folderów, dostajesz je od razu gotowe do wypełnienia:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_galaxy.png" alt="Zrzut terminala z poleceniem ansible-galaxy role init webserver i wygenerowaną strukturą katalogów roli: tasks, handlers, templates, files, defaults, vars, meta oraz tests" /></p>
<p>Polecenie ansible-galaxy role init tworzy gotowy szkielet roli webserver - komplet standardowych katalogów, każdy z pustym plikiem main.yml do wypełnienia.</p>
<p>Każdy katalog w tym szkielecie ma z góry przypisane zadanie:</p>
<ul>
<li><code>tasks/main.yml</code> - główna lista zadań roli, ta sama, którą wcześniej wpisywaliśmy wprost w playbooku (tu trafiłyby zadania instalujące i konfigurujące nginx).</li>
<li><code>handlers/main.yml</code> - procedury (handlers) uruchamiane tylko wtedy, gdy coś faktycznie się zmieniło, na przykład „przeładuj nginx po zmianie konfiguracji”.</li>
<li><code>templates/</code> - szablony Jinja2 (pliki <code>.j2</code>), dokładnie takie jak nasz <code>index.html.j2</code>.</li>
<li><code>files/</code> - gotowe pliki statyczne kopiowane na serwery bez żadnych zmian.</li>
<li><code>defaults/main.yml</code> oraz <code>vars/main.yml</code> - zmienne roli. W <code>defaults</code> trzymasz wartości domyślne, łatwe do nadpisania, a w <code>vars</code> te ważniejsze, o wyższym priorytecie.</li>
<li><code>meta/main.yml</code> - metadane roli i lista innych ról, od których ona zależy.</li>
<li><code>tests/</code> oraz <code>README.md</code> - przykładowy playbook testowy z własnym inventory i miejsce na dokumentację roli.</li>
</ul>
<p>Gotową rolę wpinasz do playbooka jednym wpisem <code>roles:</code>, a Ansible sam sięgnie po jej <code>tasks/main.yml</code>:</p>
<pre><code>---
# site.yml - ten sam efekt co wczesniej, ale zadania siedza w roli
- name: Konfiguracja serwerow WWW
  hosts: web
  roles:
    - webserver
</code></pre>
<p>Odwrotny scenariusz jest jeszcze wygodniejszy: zamiast pisać rolę samodzielnie, pobierasz gotową i sprawdzoną z Ansible Galaxy. Weźmy popularną rolę <a href="https://github.com/geerlingguy/ansible-role-nginx">geerlingguy.nginx</a>, która potrafi postawić i skonfigurować nginx za nas. Pobieramy ją jednym poleceniem:</p>
<pre><code>ansible-galaxy role install geerlingguy.nginx
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_galaxy_install.png" alt="Zrzut terminala z pobraniem roli geerlingguy.nginx z Ansible Galaxy - rola ściągnięta z GitHuba i rozpakowana do katalogu ~/.ansible/roles" /></p>
<p>Ansible Galaxy pobiera rolę geerlingguy.nginx wprost z GitHuba i rozpakowuje ją lokalnie do ~/.ansible/roles. Od tej chwili możesz jej używać w swoich playbookach.</p>
<p>Teraz wystarczy krótki playbook, który stosuje pobraną rolę - bez pisania własnych zadań instalujących nginx:</p>
<pre><code>---
# nginx-galaxy.yml - uzyj gotowej roli pobranej z Ansible Galaxy
- name: Postaw serwer WWW rola z Galaxy
  hosts: web2
  become: true
  roles:
    - geerlingguy.nginx
</code></pre>
<p>Uruchamiamy go dokładnie tak samo jak każdy inny playbook:</p>
<pre><code>ansible-playbook nginx-galaxy.yml
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_galaxy_run.png" alt="Zrzut terminala z uruchomieniem playbooka wykorzystującego rolę geerlingguy.nginx - Ansible instaluje i konfiguruje nginx, PLAY RECAP pokazuje ok=11 changed=3 failed=0" /></p>
<p>Rola z Galaxy robi całą robotę: instaluje nginx, wgrywa konfigurację i uruchamia usługę. Część jej zadań dotyczy innych systemów niż Debian, więc Ansible je pomija - stąd liczba w polu skipped w podsumowaniu.</p>
<h3>Ansible Vault - sekrety w repozytorium</h3>
<p>Playbooki i pliki ze zmiennymi trzymasz w repozytorium Git razem z resztą kodu - i słusznie, bo masz wtedy pełną historię zmian. Kłopot w tym, że część danych to <strong>sekrety</strong>: hasła do baz, klucze API, tokeny. Gdyby leżały w repozytorium otwartym tekstem, zobaczyłby je każdy, kto ma do niego dostęp, a po wycieku repozytorium - praktycznie każdy. <strong>Ansible Vault</strong> rozwiązuje to, szyfrując sekrety algorytmem AES256 hasłem, które znasz tylko Ty (i Twój serwer automatyzacji). Zaszyfrowane dane spokojnie commitujesz, a Ansible odszyfruje je w pamięci dopiero w chwili uruchomienia playbooka. Przejdźmy przez to krok po kroku.</p>
<h4>Krok 1: zaszyfruj pojedynczą wartość</h4>
<p>Najczęstszy przypadek to jeden sekret, na przykład hasło do bazy. Zamieniasz go w zaszyfrowany blok poleceniem <code>encrypt_string</code>:</p>
<pre><code>ansible-vault encrypt_string --stdin-name db_password
</code></pre>
<p>Co oznaczają poszczególne części polecenia:</p>
<ul>
<li><code>encrypt_string</code> - tryb szyfrowania <strong>pojedynczej wartości</strong>, a nie całego pliku.</li>
<li><code>--stdin-name db_password</code> - nazwa zmiennej, pod jaką zapiszesz sekret. Samą wartość sekretu Ansible czyta ze standardowego wejścia - wpisujesz ją w terminalu i kończysz skrótem Ctrl+D.</li>
</ul>
<p>Po uruchomieniu Ansible poprosi najpierw o hasło Vaulta (dwa razy, drugi raz dla potwierdzenia), potem o samą wartość sekretu, a na końcu wypisze gotowy blok:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_vault_string.png?v=2" alt="Zrzut interaktywnej sesji ansible-vault encrypt_string: dwa pytania o hasło Vaulta (New Vault password i Confirm), wpisana wartość sekretu i wygenerowany zaszyfrowany blok !vault z nagłówkiem ANSIBLE_VAULT AES256" /></p>
<p>Ansible pyta dwa razy o hasło Vaulta (drugi raz dla potwierdzenia), prosi o wartość sekretu, a potem wypisuje blok !vault. Wklejasz go wprost do pliku ze zmiennymi jako wartość zmiennej db_password i spokojnie commitujesz - bez hasła Vaulta to bezużyteczny ciąg znaków.</p>
<h4>Krok 2: albo zaszyfruj cały plik</h4>
<p>Gdy sekretów jest więcej, wygodniej trzymać je w jednym pliku i zaszyfrować go w całości. Tworzysz zwykły plik YAML (na przykład <code>sekrety.yml</code> z kluczami <code>db_password</code> i <code>api_key</code>), a potem uruchamiasz:</p>
<pre><code>ansible-vault encrypt sekrety.yml
</code></pre>
<p>Polecenie <code>encrypt &lt;plik&gt;</code> szyfruje plik <strong>w miejscu</strong> - po podaniu hasła cała czytelna treść zamienia się w nagłówek <code>$ANSIBLE_VAULT;1.1;AES256</code> i blok szesnastkowy. Żeby zajrzeć do środka bez odszyfrowywania pliku na dysk, używasz <code>ansible-vault view</code>:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_vault_file.png" alt="Zrzut terminala z ansible-vault encrypt i view: zaszyfrowany plik sekrety.yml jako blok AES256 oraz jego odszyfrowany podgląd z db_password i api_key" /></p>
<p>U góry zaszyfrowany plik sekrety.yml (nieczytelny blok), a pod spodem podgląd poleceniem ansible-vault view - odszyfrowana treść pojawia się dopiero po podaniu hasła i tylko na ekranie.</p>
<h4>Krok 3: podglądaj, edytuj i zmieniaj hasło</h4>
<p>Na zaszyfrowanym pliku pracujesz kilkoma poleceniami, bez ręcznego odszyfrowywania go na dysk:</p>
<ul>
<li><code>ansible-vault view sekrety.yml</code> - pokazuje odszyfrowaną treść na ekranie (po podaniu hasła), nigdzie jej nie zapisując.</li>
<li><code>ansible-vault edit sekrety.yml</code> - otwiera plik w edytorze już odszyfrowany, a po zapisaniu automatycznie szyfruje go z powrotem.</li>
<li><code>ansible-vault rekey sekrety.yml</code> - zmienia hasło Vaulta, przydaje się przy rotacji haseł w zespole.</li>
<li><code>ansible-vault decrypt sekrety.yml</code> - trwale odszyfrowuje plik. Używaj wyjątkowo, bo zdejmuje ochronę.</li>
</ul>
<h4>Krok 4: użyj sekretu przy uruchomieniu playbooka</h4>
<p>To najważniejszy krok, bo sam zaszyfrowany plik nic nie robi, dopóki nie sięgniesz po niego w playbooku. Sekret podpinasz jak każdą inną zmienną - na przykład wpisem <code>vars_files: [sekrety.yml]</code> - i odwołujesz się do niego jako <code>{{ db_password }}</code>. Jedyna różnica jest przy uruchamianiu: musisz podać hasło Vaulta. Interaktywnie robisz to tak:</p>
<pre><code>ansible-playbook use-secret.yml --ask-vault-pass
</code></pre>
<p>A w automatyzacji (CI/CD) podajesz hasło z pliku, który trzymasz poza repozytorium:</p>
<pre><code>ansible-playbook use-secret.yml --vault-password-file ~/.vault_pass
</code></pre>
<p>Znaczenie parametrów:</p>
<ul>
<li><code>--ask-vault-pass</code> - Ansible zapyta o hasło interaktywnie, wygodne przy pracy z konsoli.</li>
<li><code>--vault-password-file &lt;plik&gt;</code> - hasło czytane z pliku, na potrzeby potoków CI/CD. Ten plik NIGDY nie trafia do repozytorium (trzymasz go w sekretach pipeline'u albo lokalnie, poza projektem).</li>
</ul>
<p>Jeśli uruchomisz playbook bez hasła, Ansible w ogóle nie wystartuje i zgłosi błąd. Dopiero z hasłem sekret zostaje odszyfrowany w pamięci na czas działania i nigdzie nie jest zapisywany:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/ansible/shot_vault_run.png" alt="Zrzut terminala: uruchomienie playbooka bez hasła Vaulta kończy się błędem, a z parametrem --vault-password-file sekret zostaje odszyfrowany i playbook wykonuje się poprawnie" /></p>
<p>Pierwsze uruchomienie bez hasła kończy się błędem „Attempting to decrypt but no vault secrets found”. Drugie, z parametrem --vault-password-file, odszyfrowuje sekret w pamięci i playbook wykonuje się poprawnie (PLAY RECAP: ok=1, failed=0).</p>
<p>Tak domyka się bezpieczny obieg sekretu: zaszyfrowany leży w repozytorium, a odszyfrowuje się wyłącznie w pamięci i wyłącznie w chwili, gdy jest naprawdę potrzebny.</p>
<h2>Podsumowanie</h2>
<p>Ansible to narzędzie, które zamienia ręczną, powtarzalną administrację w jeden opisany plik. Zapamiętaj kilka rzeczy:</p>
<ul>
<li><strong>Opisujesz stan docelowy</strong>, nie kolejne komendy - a Ansible sam doprowadza do niego serwery.</li>
<li><strong>Agentless</strong> - na serwerach nie instalujesz niczego, wystarczy SSH i Python.</li>
<li><strong>Playbook w YAML</strong> czyta się jak listę kroków i trzymasz go w repozytorium razem z kodem.</li>
<li><strong>Idempotencja</strong> pozwala uruchamiać playbook bez obaw, ile razy chcesz - zmienia się tylko to, co trzeba.</li>
<li><strong>Role, szablony i Vault</strong> dają porządek i bezpieczeństwo, gdy projekt rośnie.</li>
</ul>
<p>Dobry sposób na naukę to zrobić dokładnie to, co my w tym artykule: postawić kilka maszyn (choćby w kontenerach) i napisać własny, pierwszy playbook. Ansible odwdzięcza się szybko - już pierwszy scenariusz, który konfiguruje kilka serwerów naraz, pokazuje, ile czasu oszczędza.</p>
<p><a href="https://jsystems.pl/szkolenia-devops-sysops;devops_ansible_full.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=banner_czym-jest-ansible"><img src="https://jsystems.pl/new_page_resources/images/other/ansible.png" alt="Baner szkolenia Automatyzacja zadań z Ansible w JSystems z terminem gwarantowanym" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-devops-sysops;devops_ansible_full.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=link_czym-jest-ansible">Szkolenie Ansible --&gt;</a></p>
<p>Jeśli chcesz przejść od pierwszego playbooka do biegłej automatyzacji całej infrastruktury - ról, Vault, dynamicznego inventory i wdrożeń - nasze szkolenie <a href="https://jsystems.pl/szkolenia-devops-sysops;devops_ansible_full.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=link_czym-jest-ansible">Automatyzacja zadań z Ansible</a> prowadzi przez to krok po kroku, na praktycznych warsztatach. Kurs ma terminy gwarantowane.</p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post469&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/show_post/czym-jest-devops-narzedzia-i-zastosowania">Czym jest DevOps i jakich narzędzi używa (i do czego)</a></li>
<li><a href="https://jsystems.pl/show_post/kubernetes-vs-docker-roznice">Kubernetes vs Docker - czym się różnią i kiedy co wybrać</a></li>
<li><a href="https://jsystems.pl/show_post/ai-dla-devopsow-agent-terraform-gitops-proxmox">AI dla DevOpsów: agent stawia maszyny Terraformem i pilnuje GitOps</a></li>
<li><a href="https://jsystems.pl/show_post/czym-jest-git-przewodnik-krok-po-kroku">Czym jest Git i jak z niego korzystać? Przewodnik krok po kroku</a></li>
<li><a href="https://jsystems.pl/show_post/co_to_jest_prometheus_przewodnik_dla_poczatkujacych">Co to jest Prometheus? Kompletny przewodnik dla początkujących</a></li>
<li><a href="https://jsystems.pl/show_post/czym-jest-sre-site-reliability-engineering">Czym jest SRE (Site Reliability Engineering) i jakich narzędzi używa</a></li>
</ul>
<p>✕<img alt="" /></p>
]]></content:encoded></item><item><title><![CDATA[Claude Code kontra Codex - szczere porownanie dwoch narzedzi AI do kodu]]></title><description><![CDATA[Wybor miedzy Claude Code a Codex to nie kwestia mody, tylko realnych roznic w tym jak kazde z narzedzi prowadzi agentowa prace nad kodem. Rozkladamy to na konkrety.

Claude Code (Anthropic) i Codex (O]]></description><link>https://jsystems.hashnode.dev/claude-code-vs-codex-porownanie</link><guid isPermaLink="true">https://jsystems.hashnode.dev/claude-code-vs-codex-porownanie</guid><category><![CDATA[ClaudeCode]]></category><category><![CDATA[codex]]></category><category><![CDATA[AI]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:04:05 GMT</pubDate><content:encoded><![CDATA[<p>Wybor miedzy Claude Code a Codex to nie kwestia mody, tylko realnych roznic w tym jak kazde z narzedzi prowadzi agentowa prace nad kodem. Rozkladamy to na konkrety.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/hero_cc_vs_codex.png" alt="Porównanie Claude Code i Codex - to samo zadanie rozwiązane w dwóch agentach AI w terminalu, zrzuty obok siebie" /></p>
<p>Claude Code (Anthropic) i Codex (OpenAI) - dwaj najpopularniejsi agenci AI do kodowania w terminalu. Postawiliśmy przed nimi dokładnie to samo zadanie i nagraliśmy realny przebieg.</p>
<p>Jeszcze dwa lata temu asystent AI podpowiadał pojedyncze linie kodu w edytorze. Dziś pracujemy z <strong>agentami</strong> - programami, które samodzielnie czytają projekt, planują zmiany, edytują pliki, uruchamiają testy i poprawiają błędy, a my tylko opisujemy cel w zwykłym języku. Dwa najczęściej wybierane to <strong>Claude Code</strong> od Anthropic i <strong>Codex</strong> od OpenAI. W tym artykule porównamy je uczciwie: nie z folderu reklamowego, tylko na realnym zadaniu, które uruchomiliśmy w obu narzędziach.</p>
<p>Słowo wyjaśnienia na start. <strong><a href="https://jsystems.pl/blog/show_post/co_to_jest_agent_ai_przewodnik_2026/">Agent</a></strong> to model AI, któremu dano narzędzia (może czytać i zapisywać pliki, uruchamiać polecenia) oraz pętlę działania: dostaje cel, wykonuje krok, sprawdza wynik i powtarza, aż zadanie będzie gotowe. <strong>CLI</strong> (interfejs wiersza poleceń) to praca w czarnym oknie terminala, bez klikania. Oba narzędzia, które porównujemy, to właśnie agenci uruchamiani z terminala.</p>
<p>Porównujemy oba narzędzia pod każdym względem, który realnie waży przy wyborze: sposób pracy z kodem, modele AI pod spodem, bezpieczeństwo (uprawnienia i piaskownica), ekosystem (wtyczki do edytorów, tryb chmurowy, standard MCP, praca zespołowa agentów, otwartość kodu) oraz koszty i plany. Najważniejsze: <strong>to porównanie robimy na żywo, a nie w teorii</strong> - każdy wniosek opieramy na realnym przebiegu w terminalu i na prawdziwych zrzutach ekranu z obu narzędzi, a nie na tabelkach z materiałów producenta.</p>
<h3>Z tego artykułu dowiesz się</h3>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#czym-sa">Czym różni się Claude Code od Codeksa i skąd je wziąć</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#test">Jak oba narzędzia poradziły sobie z tym samym zadaniem (krok po kroku, z realnymi zrzutami)</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#modele">Na jakich modelach działają i jak wybrać mocniejszy albo tańszy</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#uprawnienia">Jak pilnują bezpieczeństwa - uprawnienia i piaskownica</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#funkcje">Pełna tabela funkcji: IDE, chmura, MCP, open source, praca zespołowa agentów</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#koszty">Ile to kosztuje i który plan wybrać</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude-code-vs-codex/#kiedy">Które narzędzie do czego lepiej pasuje</a></li>
</ul>
<h2>Czym są Claude Code i Codex</h2>
<p>Oba narzędzia działają tak samo od strony użytkownika: instalujesz jedno polecenie, wchodzisz do katalogu z projektem, uruchamiasz i piszesz po ludzku, co ma się stać. Reszta to już praca agenta. Różnice zaczynają się głębiej: kto je robi, na jakich modelach działają i na jakich zasadach.</p>
<h4>Claude Code</h4>
<ul>
<li>Tworzone przez <strong>Anthropic</strong> (twórcy modeli Claude).</li>
<li>Działa na rodzinie modeli Claude - od najszybszego po najmocniejszy do trudnych zadań.</li>
<li>Wliczone w plany <strong>Pro</strong> i <strong>Max</strong> (a także zespołowe), rozliczane z limitu subskrypcji.</li>
<li>Kod jest widoczny na GitHubie, ale narzędzie jest <strong>zamknięte licencyjnie</strong> (nie wolno go dowolnie kopiować ani hostować u siebie).</li>
</ul>
<h4>Codex</h4>
<ul>
<li>Tworzone przez <strong>OpenAI</strong> (twórcy modeli GPT).</li>
<li>Działa na rodzinie modeli GPT nastawionych na kodowanie.</li>
<li>Wliczone w plany <strong>Plus</strong>, <strong>Pro</strong> i <strong>Business</strong>, rozliczane z limitu subskrypcji.</li>
<li><strong>Otwarty kod (open source)</strong> na licencji Apache 2.0 - można go audytować, rozwijać i uruchamiać po swojemu.</li>
</ul>
<p>Każde z nich warto poznać osobno: podstawy Codeksa tłumaczymy w <a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/">osobnym przewodniku dla początkujących</a>, a całą pracę z Claude Code rozkładamy krok po kroku w <a href="https://jsystems.pl/blog/show_post/claude_code_kompletny_przewodnik_dla_programistow/">bezpłatnym kursie Claude Code</a>.</p>
<p>Tak wyglądają po uruchomieniu. Najpierw Claude Code z informacją o modelu i planie, pod spodem Codex z nazwą modelu i katalogiem roboczym. Oba czekają teraz na nasze polecenie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_ready.png" alt="Ekran startowy Claude Code w terminalu - nagłówek z wersją, modelem i planem Max oraz pole na polecenie" /></p>
<p>Claude Code po uruchomieniu: u góry model i plan konta, na dole pole, w które wpisujemy zadanie zwykłym językiem.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/codex_ready.png" alt="Ekran startowy Codex CLI w terminalu - nagłówek OpenAI Codex z nazwą modelu i katalogiem projektu" /></p>
<p>Codex po uruchomieniu w tym samym katalogu: nazwa narzędzia, aktywny model i podpowiedź, że możemy poprosić o cokolwiek.</p>
<h3>Instalacja przez npm</h3>
<p>Najprostsza droga to menedżer pakietów <strong>npm</strong> - jest on częścią środowiska Node.js (platformy do uruchamiania programów w języku JavaScript). Jeśli nie masz go jeszcze na komputerze, najpierw zainstaluj Node.js - npm dołączy się do niego automatycznie. Sprawdź w terminalu, czy już je masz:</p>
<p>Kopiuj</p>
<pre><code>node -v
npm -v
</code></pre>
<p>Jeśli w odpowiedzi zobaczysz numery wersji - masz wszystko, czego trzeba, przejdź od razu do instalacji niżej. Jeśli terminal odpowie, że nie zna takiego polecenia, zainstaluj Node.js w sposób pasujący do Twojego systemu:</p>
<ul>
<li><strong>Windows i macOS</strong> - pobierz instalator z oficjalnej strony <a href="https://nodejs.org/">nodejs.org</a> (wybierz wersję oznaczoną jako <strong>LTS</strong>, czyli stabilną i zalecaną) i przejdź przez kreator „dalej, dalej, zakończ". npm zainstaluje się razem z Node.js.</li>
<li><strong>macOS z Homebrew</strong> - wystarczy jedno polecenie: <code>brew install node</code>.</li>
<li><strong>Linux (Debian, Ubuntu)</strong> - <code>sudo apt install nodejs npm</code>.</li>
</ul>
<p>Po instalacji zamknij i otwórz terminal na nowo (żeby zobaczył nowe polecenia), a potem zainstaluj oba narzędzia - każde jednym poleceniem:</p>
<p>Kopiuj
Kopiuj</p>
<pre><code># Claude Code (Anthropic)
npm install -g @anthropic-ai/claude-code

# Codex (OpenAI)
npm install -g @openai/codex
</code></pre>
<h3>Logowanie i konto - w obu potrzebne płatne konto</h3>
<p>Po instalacji zostaje logowanie, i tu ważna rzecz: <strong>oba narzędzia wymagają płatnego konta</strong>. Darmowe plany (zwykły Claude.ai oraz darmowy ChatGPT) nie dają dostępu do agenta w terminalu. Wejściowy plan zaczyna się w obu przypadkach <strong>od około 20 USD miesięcznie</strong> - to Claude Pro oraz ChatGPT Plus; wyższe plany dają większe limity (szczegóły w sekcji o kosztach niżej).</p>
<p>Samo logowanie jest proste - uruchamiasz narzędzie w katalogu projektu, a ono otwiera przeglądarkę:</p>
<p>Kopiuj</p>
<pre><code># Claude Code - uruchom i zaloguj sie przez przegladarke (konto Pro/Max)
claude

# Codex - uruchom i wybierz "Sign in with ChatGPT" (konto Plus/Pro/Business)
codex
</code></pre>
<p><strong>Claude Code</strong> przy pierwszym uruchomieniu prosi o wybór sposobu logowania. Wybieramy pierwszą pozycję - <strong>Claude account with subscription</strong> (konto z subskrypcją Pro, Max, Team lub Enterprise), a nie rozliczenie po API.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_login_method.png" alt="Ekran Claude Code z wyborem sposobu logowania - podswietlona pozycja Claude account with subscription" /></p>
<p>Claude Code, wybór sposobu logowania: pierwsza opcja to konto z subskrypcją (Pro/Max), druga to rozliczenie po API.</p>
<p>Zaraz potem Claude Code otwiera przeglądarkę na stronie logowania Anthropic. Jeśli okno nie otworzy się samo, w terminalu pojawia się pełny adres do skopiowania i wklejenia ręcznie. Po zalogowaniu w przeglądarce wracamy do terminala - narzędzie jest gotowe.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_login_browser.png" alt="Claude Code pokazuje adres logowania do wklejenia w przegladarce, gdy okno nie otworzy sie automatycznie" /></p>
<p>Gdy przeglądarka nie otworzy się sama, Claude Code wyświetla pełny adres logowania do skopiowania.</p>
<p><strong>Codex</strong> po starcie pokazuje własny ekran wyboru logowania. Wybieramy <strong>Sign in with ChatGPT</strong> - to logowanie kontem OpenAI (Plus, Pro lub Business). Dwie pozostałe opcje to logowanie kodem urządzenia oraz własny klucz API.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cx_login_menu.png" alt="Ekran startowy Codex z wyborem sposobu logowania - podswietlona pozycja Sign in with ChatGPT" /></p>
<p>Codex, wybór logowania: „Sign in with ChatGPT" korzysta z Twojego planu (Plus/Pro/Business), bez osobnej opłaty za API.</p>
<p>Dalej jest tak samo jak w Claude Code: Codex otwiera przeglądarkę, a gdy tego nie zrobi - podaje adres do wklejenia. Logujemy się kontem ChatGPT i wracamy do terminala.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cx_login_browser.png" alt="Codex prosi o dokonczenie logowania w przegladarce i podaje adres logowania OpenAI" /></p>
<p>Codex kończy logowanie w przeglądarce; na maszynie bez okna graficznego można przełączyć się na logowanie kodem urządzenia.</p>
<p>Od tej pory w obu narzędziach pracujesz w ramach limitów swojego planu, bez osobnych opłat za samo narzędzie.</p>
<h2>Test praktyczny: to samo zadanie w obu narzędziach</h2>
<p>Żeby porównanie miało sens, przygotowaliśmy mały, czysty projekt w Pythonie - prosty koszyk sklepu z listą kursów i metodą liczącą sumę. Możesz pobrać go i powtórzyć ten sam test u siebie:</p>
<p><a href="https://jsystems.pl/new_page_resources/images/cc_vs_codex/pliki/sklep-demo.zip">Pobierz projekt demo (ZIP)</a></p>
<p>Do obu narzędzi wpisaliśmy <strong>identyczne polecenie</strong>:</p>
<p>Kopiuj</p>
<pre><code>Dodaj do klasy Koszyk metodę zastosuj_kod(kod): dla kodu RABAT10 obniża
sumę o 10 procent, a inne kody zgłaszają ValueError. Napisz testy w pytest
w pliku test_sklep.py i uruchom je.
</code></pre>
<p>Projekt zawierał też plik z instrukcjami dla asystenta (o tym pliku za chwilę). Oba narzędzia działały na dokładnie tym samym stanie kodu - między jednym a drugim testem cofaliśmy projekt do punktu wyjścia. Zobaczmy, co się stało.</p>
<h3>Claude Code - najpierw pyta o zgodę</h3>
<p>Claude Code przeczytał plik, zaplanował zmianę i pokazał nam gotową <strong>różnicę (diff)</strong> - to znaczy podgląd tego, co chce dopisać, z zielonym oznaczeniem nowych linii. Zanim jednak cokolwiek zapisał na dysku, zatrzymał się i zapytał o zgodę.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_permission.png" alt="Claude Code pokazuje kolorową różnicę kodu z nową metodą zastosuj_kod i pyta o zgodę na edycję pliku sklep.py" /></p>
<p>Claude Code pokazuje planowaną zmianę (zielone linie) i pyta: czy zapisać tę edycję w pliku? Nic nie dzieje się bez naszej akceptacji.</p>
<p>Po akceptacji dopisał metodę, stworzył plik z testami, uruchomił pytest i sam sprawdził wynik. Na koniec streścił po polsku, co zrobił.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_done.png" alt="Claude Code po ukończeniu zadania - uruchomiony pytest, komunikat że wszystkie cztery testy przechodzą i podsumowanie zmian" /></p>
<p>Efekt Claude Code: cztery napisane testy, wszystkie przechodzą, a niżej czytelne podsumowanie tego, co powstało. Zwróćmy uwagę - metoda liczy rabat "w locie", bez zmiany stanu koszyka.</p>
<h3>Codex - planuje i tłumaczy swoje decyzje</h3>
<p>Codex podszedł do tego samego zadania inaczej. Najpierw krótko opisał plan ("sprawdzę implementację i testy, potem dodam metodę zgodnie ze stylem"), zajrzał do kodu i wyjaśnił swoją decyzję projektową. Następnie zrobił zmianę, uruchomił testy i sprawdził stan repozytorium.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/codex_work.png" alt="Codex w trakcie pracy - plan działania po polsku, kolorowa różnica kodu z polem rabat_procent i uruchomiony pytest" /></p>
<p>Codex podczas pracy: tłumaczy, że doda do koszyka pole z rabatem i przerobi metodę liczącą sumę. Widać różnicę kodu i uruchomiony test.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/codex_done.png" alt="Codex po ukończeniu zadania - edycja dwóch plików, dwa testy pytest przechodzą, podsumowanie po polsku" /></p>
<p>Efekt Codeksa: przerobione dwa pliki, testy przechodzą, podsumowanie po polsku. Tu rozwiązanie jest inne - Codex dodał do koszyka pole rabat_procent i przebudował metodę sumy.</p>
<p>I to jest najciekawsze w całym teście. <strong>Oba narzędzia wykonały zadanie poprawnie, ale zupełnie inaczej.</strong> Claude Code dodał osobną metodę, która liczy rabat bez ruszania stanu koszyka, i obudował ją czterema testami. Codex wolał zapisać rabat jako pole obiektu i przebudować metodę liczącą sumę, dodając dwa testy. Żadne z podejść nie jest "błędne" - to dwie różne, sensowne decyzje projektowe, dokładnie tak, jak zrobiliby to dwaj różni programiści.</p>
<p>Wspólny mianownik jest ważniejszy niż różnice. Oba narzędzia: przeczytały nasz plik z instrukcjami, pokazały kolorową różnicę przed zapisem, same uruchomiły testy i potwierdziły, że przechodzą. To jest właśnie pętla agenta w akcji:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/anim_petla_agenta.gif" alt="Animacja pętli agenta AI - kolejno zapalane kroki: cel, plan, edycja plików, test, poprawa, i powrót do początku, aż testy przechodzą" /></p>
<p>Pętla agenta w akcji: cel, plan, edycja plików, uruchomienie testów i poprawki - a potem od nowa, aż wszystko przechodzi. Dokładnie tak pracują Claude Code i Codex.</p>
<h2>Na jakich modelach działają</h2>
<p>Siła każdego agenta to model pod spodem. Oba narzędzia pozwalają przełączać model w trakcie pracy - mocniejszy do trudnych zadań, tańszy i szybszy do prostych. W Claude Code robi to komenda wyboru modelu:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_model.png" alt="Lista modeli w Claude Code - Opus jako domyślny, Fable do najtrudniejszych zadań, Sonnet do rutyny i Haiku do szybkich odpowiedzi" /></p>
<p>Wybór modelu w Claude Code. Domyślny jest model do codziennej, złożonej pracy; osobno mamy najmocniejszy do najtrudniejszych zadań, wydajny do rutyny i najszybszy do prostych pytań.</p>
<p>Podobnie u Codeksa - lista modeli od najmocniejszego po tanie i szybkie warianty, plus starsze wersje dostępne na żądanie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/codex_model.png" alt="Lista modeli w Codex - wariant flagowy Sol, zbalansowany Terra i szybki tani Luna oraz starsze modele" /></p>
<p>Wybór modelu w Codeksie: wariant flagowy do najcięższej pracy, zbalansowany do codziennych zadań i najtańszy do prostych. Starsze modele wciąż są dostępne.</p>
<h4>Rodzina Claude (Claude Code)</h4>
<ul>
<li><strong>Opus</strong> - domyślny, do codziennej i złożonej pracy, z ogromnym oknem kontekstu.</li>
<li><strong>Fable</strong> - najmocniejszy, do najtrudniejszych i najdłuższych zadań.</li>
<li><strong>Sonnet</strong> - wydajny, do rutynowych zmian.</li>
<li><strong>Haiku</strong> - najszybszy, do prostych odpowiedzi.</li>
</ul>
<h4>Rodzina GPT (Codex)</h4>
<ul>
<li><strong>Sol</strong> - wariant flagowy, do najcięższego kodowania i pracy agentowej.</li>
<li><strong>Terra</strong> - zbalansowany, do codziennych zadań.</li>
<li><strong>Luna</strong> - najszybszy i najtańszy, do prostych zmian.</li>
<li>plus starsze modele dostępne na żądanie.</li>
</ul>
<p><strong>Kontekst</strong> to ilość tekstu (kodu, dokumentacji, historii rozmowy), którą model widzi naraz - im większy, tym większe fragmenty projektu agent może ogarnąć bez gubienia wątku. Claude Code udostępnia w praktyce bardzo duże okno kontekstu; Codex w wersji terminalowej pracuje na nieco mniejszym wycinku, mimo że sam model potrafi więcej. Przy ogromnych repozytoriach to realna różnica.</p>
<h2>Bezpieczeństwo: uprawnienia i piaskownica</h2>
<p>Agent, który sam uruchamia polecenia w Twoim systemie, brzmi groźniej niż jest - oba narzędzia mają mocne hamulce. Widzieliśmy je już wyżej: Claude Code zapytał o zgodę przed zapisem pliku. To domyślne zachowanie - każda edycja i każde polecenie wymaga akceptacji, chyba że świadomie włączymy tryb bardziej samodzielny.</p>
<p>Codex trzyma to samo od innej strony: pracuje w <strong>piaskownicy</strong> (po angielsku sandbox - odizolowane środowisko, w którym agent ma dostęp tylko do tego, na co pozwolisz) i pyta o zgodę przy wyjściu poza wyznaczony obszar. W panelu stanu widać aktualny tryb uprawnień. Panel otwieramy komendą <code>/status</code> wpisaną w oknie agenta - działa tak samo w Codeksie i w Claude Code.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/codex_status.png" alt="Panel stanu Codex - model gpt-5.6-sol, tryb uprawnień z pytaniem o zgodę, plik AGENTS.md, plan Plus oraz limity pięciogodzinny i tygodniowy" /></p>
<p>Panel stanu Codeksa: aktywny model, tryb uprawnień "pytaj o zgodę", odczytany plik z instrukcjami oraz zużycie limitów - pięciogodzinnego i tygodniowego. Adres konta zamaskowaliśmy.</p>
<p>Oba narzędzia mają kilka poziomów swobody - od "tylko do odczytu", przez "może pisać w katalogu projektu za zgodą", po pełną samodzielność dla tych, którzy wiedzą, co robią. Pod spodem korzystają z mechanizmów izolacji wbudowanych w system operacyjny, więc agent nie wychodzi tam, gdzie nie powinien.</p>
<h4>Claude Code</h4>
<ul>
<li>Domyślnie pyta o zgodę przed edycją i uruchomieniem polecenia.</li>
<li>Tryby: zwykły, automatyczna akceptacja edycji, tryb planowania, pełna samodzielność.</li>
<li>Izolacja poleceń powłoki na poziomie systemu.</li>
</ul>
<h4>Codex</h4>
<ul>
<li>Praca w piaskownicy: tylko odczyt, zapis w katalogu projektu albo pełny dostęp.</li>
<li>Pyta o zgodę przy wyjściu poza obszar roboczy.</li>
<li>Izolacja na poziomie systemu, a w chmurze - w osobnych kontenerach.</li>
</ul>
<h2>Pełne porównanie funkcji</h2>
<p>Poza samym kodowaniem oba narzędzia dorobiły się sporego ekosystemu: wtyczek do edytorów, trybu chmurowego, współpracy wielu agentów naraz i standardu MCP. Zebraliśmy to w jednej tabeli.</p>
<p><strong>MCP</strong> (Model Context Protocol) to otwarty standard, dzięki któremu agent może podłączyć się do zewnętrznych narzędzi i źródeł danych - bazy danych, systemu zgłoszeń, dokumentacji firmy - i korzystać z nich w trakcie pracy. Oba narzędzia go obsługują. W panelu stanu Claude Code widać, że ma podłączone serwery MCP:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/cc_vs_codex/cc_status.png" alt="Panel stanu Claude Code - wersja, logowanie kontem Max, domyślny model oraz informacja o dwóch podłączonych serwerach MCP" /></p>
<p>Panel stanu Claude Code: sposób logowania, model i podłączone serwery MCP. Adres konta zamaskowaliśmy.</p>
<table>
<thead>
<tr>
<th>Cecha</th>
<th>Claude Code</th>
<th>Codex</th>
</tr>
</thead>
<tbody><tr>
<td>Praca w terminalu (CLI)</td>
<td>Tak</td>
<td>Tak</td>
</tr>
<tr>
<td>Wtyczka do edytora (VS Code, JetBrains)</td>
<td>Tak</td>
<td>Tak</td>
</tr>
<tr>
<td>Tryb chmurowy i praca w tle</td>
<td>Tak (agenci w tle, zadania cykliczne)</td>
<td>Tak (Codex Cloud w kontenerach)</td>
</tr>
<tr>
<td>Wersja przeglądarkowa i mobilna</td>
<td>Tak</td>
<td>Tak</td>
</tr>
<tr>
<td>Tryb bez interfejsu (do skryptów i CI)</td>
<td>Tak (<code>-p</code>)</td>
<td>Tak (<code>codex exec</code>)</td>
</tr>
<tr>
<td>Obsługa MCP (podłączanie narzędzi)</td>
<td>Tak</td>
<td>Tak (jako klient i serwer)</td>
</tr>
<tr>
<td>Plik z instrukcjami dla projektu</td>
<td><code>CLAUDE.md</code></td>
<td><code>AGENTS.md</code></td>
</tr>
<tr>
<td>Wielu agentów naraz</td>
<td>Tak - zespoły ze wspólną listą zadań</td>
<td>Tak - równolegli agenci w piaskownicach</td>
</tr>
<tr>
<td>Otwarty kod (open source)</td>
<td>Nie - kod widoczny, licencja zamknięta</td>
<td>Tak - Apache 2.0</td>
</tr>
<tr>
<td>Rozliczenie</td>
<td>subskrypcja lub klucz API</td>
<td>subskrypcja lub klucz API</td>
</tr>
</tbody></table>
<p>Warto zatrzymać się przy dwóch wierszach. Pierwszy to <strong>plik z instrukcjami</strong>. Oba narzędzia czytają na starcie specjalny plik w katalogu projektu - <code>CLAUDE.md</code> u jednego, <code>AGENTS.md</code> u drugiego - w którym opisujemy zasady: styl kodu, czego używać, czego unikać. W naszym teście oba faktycznie zastosowały się do tych zasad. Drugi wiersz to <strong>open source</strong>. Codex można pobrać, przejrzeć jego kod i uruchomić po swojemu - to ważne dla firm, które muszą audytować narzędzia. Claude Code ma kod widoczny na GitHubie, ale zamkniętą licencję.</p>
<h2>Ile to kosztuje</h2>
<p>Najważniejsza wiadomość: <strong>w obu przypadkach narzędzie w terminalu jest wliczone w subskrypcję czatu</strong>, którą być może już masz. Nie płaci się osobno za sam program. Płaci się za zużycie, które rozlicza się z limitów planu. Widać to na panelach stanu - jest limit odnawiany co kilka godzin i limit tygodniowy.</p>
<p>A jednostką, w której mierzy się to zużycie - i za którą naliczana jest opłata przy rozliczeniu za faktyczne użycie - jest <strong>token</strong>. To od liczby tokenów zależy, jak szybko topnieją limity planu i ile zapłacisz przy rozliczeniu przez klucz API.</p>
<p><strong>Co to jest token?</strong> Token to najmniejszy kawałek tekstu, którym operuje model - zwykle fragment słowa. W języku polskim jeden token to mniej więcej dwa do czterech znaków: krótkie „kod" to jeden token, a dłuższa „refaktoryzacja" rozpada się na kilka. Liczą się tokeny w obie strony - to, co wysyłasz (Twoje polecenie plus pliki, które agent czyta), oraz to, co model generuje w odpowiedzi (kod, testy, wyjaśnienia). Im większy kontekst wrzucasz i im dłuższą odpowiedź dostajesz, tym więcej tokenów zużywasz.</p>
<p>Ile tokenów dostajesz w danym planie? Tu jest niespodzianka: <strong>plany subskrypcyjne nie dają stałej puli tokenów na miesiąc</strong>. Rozliczają zużycie w oknach czasowych - jest limit odnawiany co kilka godzin oraz limit tygodniowy - a wyższy plan po prostu podnosi te limity (u Anthropic plan Max to 5x lub 20x tego, co Pro; u OpenAI podobnie Pro względem Plus). Ile dokładnie się w nich zmieści, zależy od modelu, długości rozmowy i liczby plików, które agent czyta - dlatego żaden z dostawców nie podaje jednej stałej liczby „tokenów na miesiąc". Codex liczy zużycie okna wprost w tokenach (cięższe zadania wyczerpują je szybciej), a Claude Code pokazuje to raczej jako liczbę zapytań i czas pracy modelu. Ile zostało w bieżącym oknie, sprawdzisz w panelu stanu komendą <code>/status</code>.</p>
<p>Claude Code (Anthropic)</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>Pro plan indywidualny, lżejsza praca</td>
<td>20 USD/mies</td>
</tr>
<tr>
<td>Max większe limity, 5x lub 20x</td>
<td>od 100 USD/mies</td>
</tr>
<tr>
<td>Zespołowy / Enterprise konta firmowe, administracja</td>
<td>od 20 USD/os.</td>
</tr>
<tr>
<td>Klucz API rozliczenie za tokeny</td>
<td>za zużycie</td>
</tr>
</tbody></table>
<p>Codex (OpenAI)</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td>Plus plan indywidualny, lżejsza praca</td>
<td>20 USD/mies</td>
</tr>
<tr>
<td>Pro duże limity dla intensywnej pracy</td>
<td>200 USD/mies</td>
</tr>
<tr>
<td>Business konta firmowe, administracja, Codex w cenie</td>
<td>od 25 USD/os.</td>
</tr>
<tr>
<td>Klucz API rozliczenie za tokeny</td>
<td>za zużycie</td>
</tr>
</tbody></table>
<p>Jedyny tryb, w którym płacisz dosłownie za każdy token, to <strong>klucz API</strong> (rozliczenie za zużycie). Cennik podaje wtedy stawkę za milion tokenów - osobno, taniej, za tokeny wejściowe i drożej za wyjściowe. Nie ma tu limitu z góry ani okna czasowego: masz pełną kontrolę nad kosztem, ale płacisz od faktycznego zużycia, a nie ryczałtem jak w subskrypcji. To rozwiązanie raczej dla automatyzacji i zespołów niż dla codziennej pracy przy jednym komputerze.</p>
<p>Ceny podajemy orientacyjnie - to rynek, który zmienia cenniki co kilka tygodni, a oba narzędzia potrafią dostać nowe modele i limity z miesiąca na miesiąc. Przed decyzją sprawdź aktualny cennik u źródła: <a href="https://claude.com/pricing">cennik Anthropic</a> oraz <a href="https://openai.com/chatgpt/pricing">cennik OpenAI</a>. Sama mechanika jest jednak stabilna: wejściowy plan za około 20 USD u obu, wyższe plany dla intensywnej pracy oraz opcja rozliczenia za tokeny przez klucz API, gdy potrzebujesz pełnej kontroli nad kosztem.</p>
<p>Praktyczny wniosek: jeśli masz już subskrypcję jednego z tych ekosystemów, zacznij od narzędzia, które w niej dostajesz - nie dopłacasz nic więcej. Dopiero przy naprawdę intensywnej, codziennej pracy warto rozważyć wyższe plany albo rozliczenie za tokeny.</p>
<h2>Które wybrać?</h2>
<p>Po tym teście nie ogłosimy jednego zwycięzcy, bo go nie ma. Oba narzędzia są dojrzałe i oba zrobiły zadanie poprawnie. A wielu doświadczonych programistów po prostu <strong>używa obu naprzemiennie</strong> - w zależności od zadania.</p>
<h4>Claude Code sprawdzi się, gdy:</h4>
<ul>
<li>Duże, powiązane refaktory, gdzie liczy się ogarnięcie całego projektu naraz (bardzo duże okno kontekstu).</li>
<li>Praca zespołu agentów ze wspólną listą zadań.</li>
<li>Jesteś już w ekosystemie Anthropic albo cenisz mocne domyślne hamulce bezpieczeństwa.</li>
</ul>
<h4>Codex sprawdzi się, gdy:</h4>
<ul>
<li>Potrzebujesz <strong>otwartego kodu</strong> - do audytu, własnych zmian albo uruchomienia u siebie.</li>
<li>Wiele niezależnych zadań uruchamianych równolegle w piaskownicach.</li>
<li>Jesteś już w ekosystemie OpenAI albo zależy Ci na oszczędnym zużyciu tokenów.</li>
</ul>
<p>Najlepsza rada jest banalna, ale prawdziwa: <strong>spróbuj obu na własnym, realnym zadaniu</strong>. Oba instalujesz jednym poleceniem, oba dostajesz w ramach subskrypcji za około 20 USD, a różnice w podejściu - takie jak te, które pokazaliśmy wyżej - najlepiej poczujesz na swoim kodzie, nie na cudzym przykładzie.</p>
<h2>Podsumowanie</h2>
<p>Claude Code i Codex to dwie bardzo dobre odpowiedzi na to samo pytanie: jak oddać agentowi AI nudną, powtarzalną część programowania, zachowując kontrolę nad tym, co dzieje się z kodem. Oba czytają projekt, planują, edytują pliki za naszą zgodą i same uruchamiają testy. Różnią się filozofią (zamknięte kontra otwarte), rodziną modeli, wielkością kontekstu i drobnymi decyzjami, które widać dopiero w praktyce. Wybór sprowadza się do tego, w którym ekosystemie już jesteś, czy potrzebujesz otwartego kodu i jak wyglądają Twoje zadania. A najrozsądniej - miej pod ręką oba i wybieraj w zależności od zadania.</p>
<p>Jeśli chcesz wejść w agentowe kodowanie na poważnie i nauczyć się wyciskać z tych narzędzi maksimum - od uprawnień i plików instrukcji, przez MCP, po pracę zespołu agentów - prowadzimy praktyczne szkolenia z obu:</p>
<p><a href="https://jsystems.pl/szkolenia-ai;claude_code.szczegoly?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472"><img src="https://jsystems.pl/page2026/images/banners/claude_code_FB.jpg" alt="Baner szkolenia Claude Code - od zera do zespołu agentów AI, JSystems, z terminami gwarantowanymi" /></a>
<a href="https://jsystems.pl/szkolenia-ai;claude_code.szczegoly?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472">Szkolenie Claude Code - od zera do zespołu agentów AI --&gt;</a></p>
<p>To szkolenie może być dofinansowane dla Ciebie z <a href="https://jsystems.pl/dofinansowania?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472">KFS lub BUR</a> - nawet do 100% kosztów.</p>
<p>★★★★★ Średnia ocena naszych szkoleń w Google: 5/5</p>
<p><a href="https://jsystems.pl/szkolenia-ai;codex.szczegoly?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472"><img src="https://jsystems.pl/page2026/images/banners/codex_FB.jpg" alt="Baner szkolenia Codex - od zera do zespołu agentów AI, JSystems, z terminami gwarantowanymi" /></a>
<a href="https://jsystems.pl/szkolenia-ai;codex.szczegoly?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472">Szkolenie Codex - od zera do zespołu agentów AI --&gt;</a></p>
<p>To szkolenie może być dofinansowane dla Ciebie z <a href="https://jsystems.pl/dofinansowania?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=post472">KFS lub BUR</a> - nawet do 100% kosztów.</p>
<p>★★★★★ Średnia ocena naszych szkoleń w Google: 5/5</p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/claude_na_produkcji_bezpieczenstwo_monitoring_i_optymalizacja_kosztow">Kurs Claude Code: Claude na produkcji</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/ux_aplikacji_z_claude_jak_projektowac_interfejsy_ai_ktore_dzialaja_i_buduja_zauf">Kurs Claude Code: UX aplikacji z Claude</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/claude_w_cicd_automatyzacja_pipelineu_i_code_review_z_ai">Kurs Claude Code: automatyzacja CI/CD</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/claude_code_jak_zaczac_i_co_potrafic_w_2026">Kurs Claude Code: jak zacząć i co potrafić w 2026</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/prompt_engineering_dla_claude_jak_pisac_prompty_ktore_daja_powtarzalne_wyniki">Kurs Claude Code: prompt engineering dla Claude</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/claude_umiejetnosci_i_mozliwosci_co_potrafi_i_czym_rozni_sie_od_chatgpt">Kurs Claude Code: umiejętności i możliwości Claude</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[OpenAI Codex od zera - co to jest i jak zaczac z tym narzedziem w 2026]]></title><description><![CDATA[Nazwa Codex wraca w rozmowach o AI do kodowania, ale rzadko ktos tlumaczy co dokladnie robi. Ten przewodnik startuje od podstaw - definicja, instalacja, pierwsze uzycie.

Tak w skrócie pracuje Codex: ]]></description><link>https://jsystems.hashnode.dev/czym-jest-codex-przewodnik-dla-poczatkujacych</link><guid isPermaLink="true">https://jsystems.hashnode.dev/czym-jest-codex-przewodnik-dla-poczatkujacych</guid><category><![CDATA[openai]]></category><category><![CDATA[codex]]></category><category><![CDATA[AI]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:03:39 GMT</pubDate><content:encoded><![CDATA[<p>Nazwa Codex wraca w rozmowach o AI do kodowania, ale rzadko ktos tlumaczy co dokladnie robi. Ten przewodnik startuje od podstaw - definicja, instalacja, pierwsze uzycie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_hero_loop.gif" alt="Animacja pętli agenta Codex: piszesz polecenie, agent czyta pliki i planuje, proponuje zmiany w kodzie, uruchamia je w piaskownicy i pyta Cię o zgodę" /></p>
<p>Tak w skrócie pracuje Codex: od Twojego polecenia zapisanego zwykłym językiem, przez czytanie kodu i propozycję zmian, po uruchomienie i prośbę o zatwierdzenie. Poniżej rozkładamy każdy z tych kroków na czynniki pierwsze - na prawdziwych zrzutach z naszej sesji.</p>
<p>Coraz częściej słyszysz, że „AI samo pisze kod", a obok nazwy ChatGPT pojawia się słowo <strong>Codex</strong>. Jeśli dopiero zaczynasz, łatwo się w tym pogubić: czy to osobny program, model, wtyczka, a może wszystko naraz? W tym przewodniku wyjaśnimy prosto i bez żargonu, czym jest Codex, jak działa i jak zrobić z nim pierwszy realny krok. Żeby nie zostać na poziomie teorii, uruchomiliśmy Codeksa na czystej maszynie i przeszliśmy całą drogę sami - wszystkie zrzuty terminala poniżej pochodzą z tej właśnie sesji.</p>
<p>Codex to <strong>agent kodujący</strong> (po angielsku <em>coding agent</em>) stworzony przez OpenAI - firmę, która robi też ChatGPT. „Agent" to kluczowe słowo, do którego jeszcze wrócimy: chodzi o program, który nie tylko doradza, ale sam wykonuje pracę w Twoim projekcie. Jeśli chcesz najpierw zrozumieć samo pojęcie agenta w szerszym kontekście, zacznij od naszego wpisu <a href="https://jsystems.pl/blog/show_post/co_to_jest_agent_ai_przewodnik_2026">Co to jest agent AI - przewodnik dla firm</a>; tutaj skupiamy się na jednym, konkretnym agencie dla programistów.</p>
<h3>Z tego artykułu dowiesz się</h3>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#czym-jest">Czym właściwie jest Codex</a> i czym różni się od zwykłego czatu z AI</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#gdzie-dziala">Gdzie Codex działa</a>: w terminalu, w edytorze kodu i w chmurze</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#instalacja">Jak go zainstalować i zalogować się</a> przez konto ChatGPT oraz którego planu (i za ile) potrzebujesz</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#pierwsze-zadanie">Jak wygląda pierwsze zadanie krok po kroku</a> - na prawdziwym przykładzie</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#bezpieczenstwo">Jak działa piaskownica i zatwierdzanie</a>, czyli jak zachować kontrolę nad agentem</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#automatyzacja">Jak uruchomić Codeksa bez pytań</a> w skrypcie i automatyzacji</li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-codex-przewodnik-dla-poczatkujacych/#kiedy">Kiedy Codex się przydaje</a> i na co warto uważać na starcie</li>
</ul>
<h2>Czym właściwie jest Codex (i czym różni się od czatu)</h2>
<p>Najprościej: <strong>Codex to sztuczna inteligencja, która pracuje w Twoim kodzie tak, jak zrobiłby to programista siedzący obok Ciebie</strong>. Nie ogranicza się do rozmowy w oknie czatu. Codex potrafi otworzyć pliki Twojego projektu, przeczytać je, samodzielnie wprowadzić zmiany w wielu miejscach naraz, uruchomić polecenia (na przykład testy) i pokazać Ci efekt do akceptacji.</p>
<p>To właśnie oznacza słowo <strong>agent</strong>. Zwykły asystent w czacie odpowiada tekstem: podpowiada linijkę, którą musisz sam skopiować i wkleić, a poza tym, co mu wkleisz, nie wie nic o Twoim projekcie. Agent działa inaczej - dostaje dostęp do Twojego kodu i sam wykonuje w nim zadanie. Różnicę najlepiej widać na jednym obrazku.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_agent_vs_chat.png" alt="Porównanie: zwykły asystent w czacie tylko podpowiada tekstem, a agent Codex czyta całe repozytorium, sam edytuje pliki, uruchamia testy i pokazuje różnice przed zapisem" /></p>
<p>Zwykły asystent doradza w oknie czatu; agent Codex wykonuje pracę bezpośrednio w projekcie i pokazuje efekt do zatwierdzenia. To ta różnica sprawia, że mówimy o „agencie", a nie o zwykłym podpowiadaczu.</p>
<p>Dwa pojęcia, które będą się przewijać w całym artykule, warto od razu wyjaśnić po polsku:</p>
<ul>
<li><strong>Repozytorium</strong> - to po prostu katalog z Twoim projektem, zwykle prowadzony pod kontrolą systemu Git (jeśli nie wiesz, czym jest Git, mamy osobny <a href="https://jsystems.pl/blog/show_post/czym-jest-git-przewodnik-krok-po-kroku">przewodnik po Git krok po kroku</a>). Codex czyta ten katalog i to w nim wprowadza zmiany.</li>
<li><strong>Piaskownica</strong> (po angielsku <em>sandbox</em>) - odizolowane, „ogrodzone" środowisko, w którym Codex uruchamia polecenia tak, żeby nie mógł przypadkiem namieszać w reszcie komputera. Do piaskownicy wrócimy w części o bezpieczeństwie.</li>
</ul>
<p>Ważne, żeby nie mylić Codeksa z samym modelem językowym. Model to „mózg", który generuje tekst i kod; wyjaśnialiśmy to w artykule <a href="https://jsystems.pl/blog/show_post/jak-dziala-llm">Jak działa LLM</a>. Codex to warstwa wyżej - to całe narzędzie zbudowane wokół takiego modelu, które potrafi realnie działać na plikach i uruchamiać polecenia. Model odpowiada; agent wykonuje.</p>
<h2>Gdzie działa Codex: terminal, edytor i chmura</h2>
<p>Codex to nie jeden program, lecz <strong>rodzina powierzchni</strong> - kilka sposobów korzystania z tego samego agenta. Wszystkie łączy jedno konto ChatGPT i ten sam model, więc możesz zacząć w jednym miejscu, a dokończyć w innym bez utraty kontekstu.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_surfaces.png" alt="Cztery powierzchnie Codeksa: narzędzie CLI w terminalu, rozszerzenie do edytora IDE, Codex w ChatGPT w chmurze oraz aplikacja na komputer - wszystkie na jednym koncie ChatGPT" /></p>
<p>Ten sam agent w czterech odsłonach. Dla początkującego najprostszym punktem wejścia jest wiersz poleceń (CLI) - i na nim skupimy się w tym przewodniku.</p>
<h3>Codex CLI - agent w terminalu</h3>
<p>To wersja konsolowa: instalujesz jedno polecenie, wpisujesz <code>codex</code> w terminalu i rozmawiasz z agentem wprost w oknie tekstowym. Nie wymaga żadnego dodatkowego programu, dlatego jest najlepszym startem, gdy chcesz zrozumieć, jak Codex myśli i działa. Właśnie tę wersję pokazujemy na kolejnych zrzutach.</p>
<h3>Rozszerzenie do edytora (IDE)</h3>
<p>Jeśli pracujesz w edytorze kodu takim jak Visual Studio Code, Cursor czy Windsurf, możesz dodać Codeksa jako panel obok kodu. Rozszerzenie jest darmowe i oficjalne - wydawcą jest OpenAI.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/web_ide.png" alt="Oficjalne rozszerzenie Codex - OpenAI's coding agent w sklepie Visual Studio Code Marketplace, z liczbą pobrań i przyciskiem Install" /></p>
<p>Rozszerzenie Codeksa do Visual Studio Code w oficjalnym sklepie. Instalujesz je jak każdą inną wtyczkę do edytora, a logujesz się tym samym kontem ChatGPT co w terminalu.</p>
<h3>Codex w ChatGPT (chmura)</h3>
<p>Możesz też zlecić zadanie w przeglądarce, a agent wykona je w tle na Twoim repozytorium - nawet gdy nie ma Cię przy komputerze. Ta wersja przydaje się do dłuższych zadań i pracy zespołowej, ale wymaga podłączenia repozytorium z serwisu GitHub, dlatego dla pierwszych kroków zostawiamy ją na później.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/web_cloud.png" alt="Panel startowy Codex w chmurze w ChatGPT: wybór sposobu pracy - narzędzie CLI, aplikacja, rozszerzenie do edytora oraz podłączenie repozytorium z GitHub" /></p>
<p>Panel startowy Codeksa w chmurze. Widać w nim wszystkie drogi wejścia oraz przycisk podłączenia repozytorium z GitHub, potrzebny do zadań uruchamianych w tle.</p>
<p>Jest jeszcze osobna aplikacja na komputer, która pozwala prowadzić kilku agentów naraz. Cokolwiek wybierzesz, płacisz raz - Codex korzysta z Twojego planu ChatGPT, o czym za chwilę.</p>
<h2>Instalacja i logowanie: Sign in with ChatGPT</h2>
<p>Cała droga od zera do pierwszego zadania sprowadza się do trzech kroków: instalacja, logowanie i pierwsze polecenie. Zajmuje to kilka minut.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_install_steps.gif" alt="Trzy kroki startu z Codeksem: instalacja poleceniem npm, zaloguj się kontem ChatGPT i pierwsze zadanie zapisane zwykłym językiem" /></p>
<p>Trzy kroki startu. Poniżej rozpisujemy każdy z nich, z prawdziwymi zrzutami z terminala.</p>
<h3>Krok 1. Instalacja</h3>
<p>Najprostsza droga to menedżer pakietów o nazwie <strong>npm</strong>. Jest on częścią środowiska <strong>Node.js</strong> (popularnej platformy do uruchamiania programów napisanych w języku JavaScript), więc jeśli nie masz go jeszcze na komputerze, najpierw zainstaluj Node.js - npm dołączany jest do niego automatycznie. Możesz sprawdzić, czy już go masz, wpisując w terminalu:</p>
<p>Kopiuj</p>
<pre><code>node -v
npm -v
</code></pre>
<p>Jeśli w odpowiedzi zobaczysz numery wersji, masz wszystko, czego trzeba - przejdź od razu do polecenia instalującego Codeksa niżej. Jeśli terminal odpowie, że nie zna takiego polecenia, zainstaluj Node.js w sposób pasujący do Twojego systemu:</p>
<ul>
<li><strong>Windows i macOS</strong> - pobierz instalator z oficjalnej strony <a href="https://nodejs.org/">nodejs.org</a> (wybierz wersję oznaczoną jako LTS, czyli stabilną i zalecaną) i przejdź przez kreator „dalej, dalej, zakończ". npm zainstaluje się razem z Node.js.</li>
<li><strong>macOS z menedżerem Homebrew</strong> - wystarczy jedno polecenie: <code>brew install node</code>.</li>
<li><strong>Linux (Debian, Ubuntu)</strong> - <code>sudo apt install nodejs npm</code>.</li>
</ul>
<p>Po instalacji zamknij i otwórz terminal na nowo, a potem sprawdź wersje jeszcze raz - powinny się już pokazać. Gdy masz gotowe Node.js, instalacja samego Codeksa to jedno polecenie:</p>
<p>Kopiuj</p>
<pre><code>npm install -g @openai/codex
</code></pre>
<p>Jeśli wolisz w ogóle pominąć instalację Node.js, Codex ma też instalator dla systemu macOS (przez menedżer Homebrew) oraz gotowe skrypty instalacyjne, które nie wymagają npm:</p>
<p>Kopiuj</p>
<pre><code># macOS (Homebrew)
brew install --cask codex

# Linux / macOS - skrypt instalacyjny
curl -fsSL https://chatgpt.com/codex/install.sh | sh
</code></pre>
<p>Kopiuj</p>
<p>Po instalacji możemy sprawdzić, czy wszystko się udało, prostym poleceniem z wersją:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_install.png" alt="Terminal po instalacji Codeksa: polecenie npm install -g @openai/codex zakończone sukcesem oraz codex --version zwracające numer wersji narzędzia" /></p>
<p>Instalacja zakończona sukcesem. Polecenie z flagą wersji potwierdza, że Codex jest gotowy do pracy.</p>
<h3>Krok 2. Logowanie kontem ChatGPT</h3>
<p>Codeksa uruchamiasz poleceniem <code>codex</code>. Przy pierwszym starcie wybierasz opcję <strong>Sign in with ChatGPT</strong> („zaloguj się przez ChatGPT"). To wygodne dla początkujących: <strong>nie musisz zakładać osobnego konta dla programistów ani generować klucza API</strong> - logujesz się swoim zwykłym kontem ChatGPT, a Codex korzysta z limitów Twojego planu. O tym, czy plan musi być płatny i ile to kosztuje, piszemy zaraz niżej.</p>
<p>Zanim Codex zacznie pracę w danym katalogu, zapyta, czy ufasz jego zawartości. To celowy bezpiecznik: agent będzie czytał pliki z tego folderu, a w nieznanym kodzie mogłyby się kryć ukryte instrukcje próbujące nim pokierować - dlatego Codex upewnia się, że świadomie otwierasz właśnie ten katalog.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_trust.png" alt="Ekran startowy Codeksa w terminalu z pytaniem, czy ufasz zawartości katalogu, oraz opcjami: tak kontynuuj albo nie wychodzę" /></p>
<p>Zanim ruszy do pracy, Codex pyta o zaufanie do katalogu. To pierwszy z kilku momentów, w których to Ty masz ostatnie słowo.</p>
<p>Po potwierdzeniu zobaczysz ekran startowy: nazwę i wersję narzędzia, wybrany model, katalog roboczy oraz pole, w które wpisujesz polecenie. Od tej chwili możesz „rozmawiać" z agentem po polsku.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_start.png" alt="Ekran startowy Codex CLI: nazwa OpenAI Codex z numerem wersji, wybrany model, katalog roboczy oraz pole tekstowe z zachętą do wpisania polecenia" /></p>
<p>Ekran startowy Codeksa. W dole widać pole „Ask Codex to do anything" - czyli miejsce, w którym zlecasz zadanie.</p>
<h3>Czy potrzebujesz płatnego konta ChatGPT (i ile to kosztuje)</h3>
<p>Tak - Codex działa z <strong>płatnym planem ChatGPT</strong>; darmowe konto nie wystarczy. Dobra wiadomość jest taka, że nie płacisz osobno za samego Codeksa - korzystasz z limitów planu, który już masz albo dopiero wykupisz. Do wyboru jest kilka planów (ceny podajemy orientacyjnie, bo bywają aktualizowane - najświeższe znajdziesz na <a href="https://openai.com/chatgpt/pricing/">oficjalnej stronie z cennikiem</a>):</p>
<ul>
<li><strong>Plus</strong> - plan dla osób prywatnych, orientacyjnie około 23 € miesięcznie. To najczęstszy wybór na start i w zupełności wystarcza, żeby poznać Codeksa.</li>
<li><strong>Pro</strong> - większe limity dla osób, które pracują z AI codziennie i intensywnie, orientacyjnie od około 103 € miesięcznie.</li>
<li><strong>Business</strong> - plan dla zespołów (od dwóch stanowisk, rozliczany rocznie), orientacyjnie około 21 € za użytkownika miesięcznie, z panelem administratora i wspólnym kontem firmowym.</li>
</ul>
<p>Codex działa też z planami Edu oraz Enterprise. Jeśli dopiero zaczynasz, wybierz Plus - w każdej chwili możesz zmienić plan na wyższy.</p>
<p><strong>Jak założyć konto i włączyć plan:</strong></p>
<ol>
<li>Wejdź na stronę <a href="https://chatgpt.com/">chatgpt.com</a> i załóż konto - adresem e-mail albo przez logowanie kontem Google.</li>
<li>W ustawieniach konta kliknij „Ulepsz plan" (po angielsku <em>Upgrade</em>) i wykup Plus. Na tym etapie podajesz dane karty płatniczej.</li>
<li>Gotowe. Tym samym kontem logujesz się w Codeksie przez „Sign in with ChatGPT" - nie musisz nic dodatkowo konfigurować.</li>
</ol>
<p>A jak wygląda samo logowanie krok po kroku? Zajmuje kilkanaście sekund. W terminalu wpisujesz <code>codex</code> i wybierasz „Sign in with ChatGPT" - Codex uruchamia logowanie i podaje adres, który otwiera się w przeglądarce.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_login_cli.png" alt="Terminal po komendzie codex login: uruchomienie lokalnego serwera do uwierzytelnienia, adres do autoryzacji oraz potwierdzenie Successfully logged in" /></p>
<p>Logowanie startuje jednym poleceniem. Codex sam otwiera przeglądarkę (a jeśli tego nie zrobi, podaje adres do wklejenia) i na końcu potwierdza „Successfully logged in".</p>
<p>W przeglądarce wybierasz konto ChatGPT, którego chcesz użyć:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/login_choose.png" alt="Ekran wyboru konta ChatGPT w trakcie uwierzytelniania Codeksa, dane konta celowo zasłonięte" /></p>
<p>Krok 1 w przeglądarce: wybór konta ChatGPT. Dane konta zasłoniliśmy.</p>
<p>Następnie potwierdzasz dostęp dla Codeksa. Jeśli Twoje konto ma kilka obszarów roboczych (na przykład firmowy i prywatny), tutaj wskazujesz właściwy:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/login_consent.png" alt="Ekran zgody Sign in to Codex z wyborem obszaru roboczego i przyciskiem Kontynuuj, adres e-mail zasłonięty" /></p>
<p>Krok 2: potwierdzenie dostępu przyciskiem „Kontynuuj". Adres e-mail konta zasłoniliśmy.</p>
<p>Gotowe - pojawia się potwierdzenie, a w terminalu Codex jest już zalogowany:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/login_success.png" alt="Ekran potwierdzenia Signed in to Codex z informacją, że można zamknąć stronę przeglądarki" /></p>
<p>Krok 3: „Signed in to Codex". Zamykasz kartę i wracasz do terminala - od tej chwili możesz zlecać zadania.</p>
<p>Jest jeszcze druga droga, raczej dla zaawansowanych: zamiast planu ChatGPT można zalogować Codeksa <strong>kluczem API</strong> z platformy dla programistów OpenAI i płacić za faktyczne zużycie. Bywa taniej przy sporadycznym korzystaniu, ale wymaga osobnego konta rozliczeniowego - dla początkującego prostszy jest zwykły plan ChatGPT.</p>
<h2>Twoje pierwsze zadanie krok po kroku</h2>
<p>Teoria za nami - czas na praktykę. Przygotowaliśmy maleńki projekt: skrypt w Pythonie, który liczy statystyki sprzedaży z pliku CSV, ale ma celowo wprowadzony błąd (średnią liczy przez złą liczbę elementów). Możesz pobrać dokładnie ten sam projekt i przejść całe ćwiczenie razem z nami:</p>
<p><a href="https://jsystems.pl/new_page_resources/files/codex/codex_demo.zip">Pobierz projekt demo (ZIP)</a></p>
<p>W środku znajdziesz skrypt <code>stats.py</code>, plik <code>sprzedaz.csv</code> z przykładowymi danymi oraz krótki opis. Poprosimy teraz Codeksa, żeby ten błąd znalazł, poprawił i sprawdził wynik. Polecenie wpisujemy zwykłym językiem, po polsku:</p>
<p>Kopiuj
Popraw błąd w obliczaniu średniej w pliku stats.py (trzeba dzielić przez liczbę elementów). Potem uruchom skrypt i pokaż wynik.</p>
<p>Zauważ, że nie musimy używać żadnych specjalnych komend - piszemy po ludzku, co ma się stać. Wpisane polecenie wygląda w oknie Codeksa tak:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_prompt.png" alt="Codex CLI z wpisanym po polsku poleceniem, żeby poprawił błąd w obliczaniu średniej w pliku stats.py, uruchomił skrypt i pokazał wynik" /></p>
<p>Polecenie zapisane zwykłym językiem. Tak samo napisalibyśmy je do kolegi z zespołu.</p>
<p>Po zatwierdzeniu Codex najpierw <strong>przygląda się projektowi</strong>: streszcza, co zamierza zrobić, i otwiera plik, żeby zrozumieć kod. Widać to na pasku „Explored" z zapisem odczytania pliku. Agent nie zgaduje - czyta źródło, zanim cokolwiek zmieni.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_plan.png" alt="Codex planuje zadanie: streszcza po polsku, że sprawdzi plik stats.py i poprawi mianownik, oraz pokazuje krok odczytania pliku i status pracy" /></p>
<p>Codex zapowiada plan i czyta plik, zanim wprowadzi zmianę. To dobry nawyk, którego oczekiwalibyśmy od człowieka.</p>
<p>Najciekawsze dzieje się w kolejnym kroku. Codex <strong>proponuje konkretną zmianę i od razu pokazuje różnicę</strong> - po angielsku nazywa się to <em>diff</em>: linia usuwana jest oznaczona na czerwono, a wstawiana na zielono. Następnie sam <strong>uruchamia skrypt</strong> i pokazuje jego wynik, a na końcu krótko podsumowuje, co zrobił.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_diff_run.png" alt="Codex pokazuje różnicę w pliku stats.py: usuwa dzielenie przez liczbę elementów minus jeden, wstawia poprawne dzielenie, po czym uruchamia skrypt i wypisuje poprawioną średnią 162 złote" /></p>
<p>Pełny cykl w jednym miejscu: różnica (diff) z poprawką, uruchomienie skryptu i poprawny wynik - średnia 162,00 zł zamiast błędnej wartości. To jest ta „magia", o którą chodzi w agentach: od polecenia do sprawdzonej zmiany.</p>
<p>W kilkanaście sekund agent zrobił to, co człowiek: zrozumiał kod, znalazł błąd, poprawił go w jednym miejscu i potwierdził uruchomieniem, że wynik jest już prawidłowy. I - co istotne - cały czas widzieliśmy, co robi.</p>
<h2>Piaskownica i zatwierdzanie: jak zachować kontrolę</h2>
<p>Skoro agent może zmieniać pliki i uruchamiać polecenia, naturalne pytanie brzmi: co go powstrzymuje przed narobieniem szkód? Codex ma na to <strong>dwie niezależne dźwignie</strong>, którymi to Ty ustawiasz poziom swobody agenta: piaskownicę (co agent może w ogóle dotknąć) oraz zatwierdzanie (kiedy pyta Cię o zgodę).</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_modes.png" alt="Dwie dźwignie bezpieczeństwa Codeksa: piaskownica z trybami tylko odczyt, zapis w projekcie i pełny dostęp, oraz zatwierdzanie z trybami pyta o zgodę, zatwierdza sam i nigdy nie pyta" /></p>
<p>Piaskownica i zatwierdzanie to dwie osobne dźwignie. Ustawiasz je zależnie od tego, jak bardzo ufasz zadaniu i środowisku.</p>
<p>W praktyce, gdy uruchamiasz Codeksa domyślnie, pracuje on w trybie <strong>zapisu w katalogu roboczym z pytaniem o zgodę przy ważniejszych krokach</strong>. Możesz to sprawdzić w każdej chwili poleceniem <code>/status</code>, które pokazuje między innymi wybrany model, uprawnienia oraz zużycie planu (limit na kilka godzin i tygodniowy).</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_status.png" alt="Panel /status w Codeksie: model, katalog roboczy, uprawnienia ustawione na zapis w projekcie z pytaniem o zgodę, plan konta oraz zużycie limitów na kilka godzin i tydzień" /></p>
<p>Panel <code>/status</code>. Wiersz „Permissions" pokazuje aktualny tryb (tu: zapis w projekcie z pytaniem o zgodę), a niżej widać zużycie limitów planu. Adres e-mail konta zasłoniliśmy.</p>
<p>Tryby możesz zmieniać wprost w trakcie sesji - służą do tego wbudowane komendy. Komenda <code>/permissions</code> otwiera wybór trybu pracy: od pytania o zgodę, przez automatyczne zatwierdzanie, po pełny dostęp.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_permissions.png" alt="Wybór trybu uprawnień w Codeksie po komendzie /permissions: opcje pytaj o zgodę, zatwierdzaj automatycznie oraz pełny dostęp" /></p>
<p>Komenda <code>/permissions</code> pozwala przełączyć tryb pracy bez wychodzenia z sesji. Trzy gotowe zestawy odpowiadają dźwigniom z grafiki wyżej; dłuższe opisy po prawej stronie skraca szerokość okna terminala.</p>
<p>Z kolei komenda <code>/model</code> przełącza model i poziom „wysiłku", z jakim agent podchodzi do zadania:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/cli_model.png" alt="Wybór modelu w Codeksie po komendzie /model: lista dostępnych modeli z krótkim opisem, aktualnie używany oznaczony jako current" /></p>
<p>Komenda <code>/model</code> przełącza model używany w sesji. Aktualnie wybrany jest oznaczony jako „current".</p>
<p>Te same ustawienia możesz zapisać z góry w pliku konfiguracyjnym <code>~/.codex/config.toml</code>. Prosty przykład:</p>
<p>Kopiuj</p>
<pre><code># ~/.codex/config.toml
approval_policy = "on-request"      # pytaj o zgodę przy ważnych krokach
sandbox_mode = "workspace-write"   # pozwól zapisywać w katalogu projektu
</code></pre>
<p>Kopiuj</p>
<p>Zasada dla początkującego jest prosta: <strong>zaczynaj od trybów ostrożnych</strong>. Tryb tylko do odczytu jest świetny do poznawania cudzego kodu, a zapis w projekcie z pytaniem o zgodę wystarcza do większości codziennych zadań. Pełny dostęp (bez pytań, także poza projektem) zostaw na później i tylko dla zaufanych, odizolowanych środowisk.</p>
<h2>Codex w skrypcie: tryb bez pytań</h2>
<p>Interaktywne okno to nie jedyny sposób pracy. Codex ma też tryb <strong>nieinteraktywny</strong>, uruchamiany jednym poleceniem <code>codex exec</code>. Agent wykonuje wtedy zadanie od razu, bez pełnego interfejsu i bez zatrzymywania się na pytania - idealnie do skryptów, potoków ciągłej integracji (po angielsku <em>CI</em>, czyli automatycznego budowania i testowania kodu) oraz powtarzalnych czynności.</p>
<p>Kopiuj</p>
<pre><code>codex exec -s read-only "Wyjaśnij w dwóch zdaniach, co robi skrypt stats.py."
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/codex/c_exec_render.png" alt="Codex w trybie nieinteraktywnym codex exec: nagłówek z katalogiem roboczym, trybem tylko do odczytu, polecenie użytkownika i zwięzła odpowiedź agenta po polsku" /></p>
<p>Ten sam agent uruchomiony jednym poleceniem, bez interfejsu. Odpowiedź trafia prosto na wyjście - można ją zapisać do pliku albo przekazać dalej w skrypcie.</p>
<p>W tym przykładzie użyliśmy flagi trybu tylko do odczytu, więc mamy pewność, że Codex niczego nie zmieni - jedynie przeczyta kod i odpowie. To wygodny, bezpieczny sposób, żeby na przykład automatycznie streszczać zmiany albo generować krótkie opisy do zgłoszeń.</p>
<p>To jednak dopiero połowa obrazka. Jeśli nadasz trybowi wyższe uprawnienia - na przykład zapis w projekcie - możesz zlecić Codeksowi <strong>realną zmianę i od razu zapisanie jej w repozytorium Gita</strong>. Jednym poleceniem agent wprowadzi poprawkę, utworzy commit i wypchnie go (polecenie <code>git push</code>) na wskazaną gałąź:</p>
<p>Kopiuj</p>
<pre><code>codex exec -s workspace-write "Popraw literówki w pliku README, zrób commit i wypchnij zmianę na gałąź main."
</code></pre>
<p>Właśnie tak buduje się drobne automatyzacje, w których agent samodzielnie realizuje zadanie i zapisuje wynik - na przykład w potoku CI, który po każdej zmianie porządkuje kod albo aktualizuje dokumentację. Pamiętaj tylko, że w trybie <code>exec</code> Codex nie zatrzymuje się, żeby zapytać o zgodę, więc takie polecenia uruchamiaj świadomie i w zaufanym, odizolowanym środowisku.</p>
<h2>Kiedy Codex się przydaje (i na co uważać)</h2>
<p>Codex nie zastępuje programisty - jest narzędziem, które oszczędza mu kilka godzin dziennie na powtarzalnej robocie. Sprawdza się szczególnie tam, gdzie trzeba zrozumieć kod i wprowadzić w nim konkretne, weryfikowalne zmiany:</p>
<ul>
<li><strong>Poprawianie błędów</strong> - opisujesz objaw, agent znajduje przyczynę i proponuje poprawkę (dokładnie jak w naszym przykładzie).</li>
<li><strong>Dodawanie funkcji i refaktoryzacja</strong> - drobne przebudowy kodu w wielu plikach naraz, z podglądem różnic przed zapisem.</li>
<li><strong>Pisanie testów</strong> - agent potrafi dopisać testy i od razu je uruchomić.</li>
<li><strong>Poznawanie nowego projektu</strong> - w trybie tylko do odczytu wypytujesz o to, jak działa nieznana baza kodu.</li>
</ul>
<p>Są też rzeczy, o których na starcie warto pamiętać. Zawsze <strong>przeglądaj różnice, zanim je zatwierdzisz</strong> - agent bywa pewny siebie, a to Ty odpowiadasz za kod. Trzymaj się <strong>trybów ostrożnych</strong>, dopóki nie nabierzesz zaufania, i nie uruchamiaj pełnego dostępu na produkcyjnym środowisku „w ciemno". I nie traktuj wyniku jak wyroczni: Codex, jak każde narzędzie AI, potrafi się pomylić, dlatego uruchomienie kodu i testy są tu najlepszym sprawdzianem. Więcej o tym, jak zmienia się rola programisty w czasach takich narzędzi, piszemy w artykule <a href="https://jsystems.pl/blog/show_post/jak-przetrwac-w-branzy-it-senior-w-czasach-ai">Doświadczony programista w czasach AI</a>.</p>
<h2>Od czego zacząć</h2>
<p>Codex to agent kodujący od OpenAI, który realnie pracuje w Twoim projekcie - czyta pliki, proponuje zmiany, uruchamia je w piaskownicy i pyta Cię o zgodę. Dostępny jest w terminalu, w edytorze i w chmurze, a płacisz za niego swoim planem ChatGPT. Jeśli chcesz go dziś wypróbować, wystarczą trzy ruchy: zainstaluj narzędzie poleceniem <code>npm install -g @openai/codex</code>, uruchom <code>codex</code> i zaloguj się przez ChatGPT, a potem daj mu małe, konkretne zadanie w istniejącym projekcie i przejrzyj proponowane różnice. Zacznij od trybu tylko do odczytu albo zapisu z pytaniem o zgodę - tak najszybciej i najbezpieczniej złapiesz, jak Codex myśli.</p>
<p>Jeśli interesuje Cię pokrewne narzędzie tej klasy, mamy też obszerny, bezpłatny <a href="https://jsystems.pl/blog/show_post/claude_code_kompletny_przewodnik_dla_programistow">kurs Claude Code dla programistów</a>. A gdy zechcesz przejść od pierwszych kroków do świadomej, zespołowej pracy z Codeksem - od trybów i integracji po budowanie współpracujących agentów - najszybszą drogą jest przejście przez to z trenerem na naszym szkoleniu.</p>
<p><a href="https://jsystems.pl/szkolenia-ai;codex.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post471&amp;utm_content=banner_codex"><img src="https://jsystems.pl/page2026/images/banners/codex_FB.jpg" alt="Baner szkolenia Codex - od zera do zespołu agentów AI prowadzonego przez JSystems, z terminami gwarantowanymi" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-ai;codex.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post471&amp;utm_content=link_codex">Szkolenie Codex - od zera do zespołu agentów AI --&gt;</a></p>
<p><strong>To szkolenie ma terminy gwarantowane.</strong></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post471&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/co_to_jest_agent_ai_przewodnik_2026">Co to jest agent AI w 2026 - kompletny przewodnik</a></li>
<li><a href="https://jsystems.pl/blog/show_post/claude_code_kompletny_przewodnik_dla_programistow">Bezpłatny kurs Claude Code - przewodnik dla programistów</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-git-przewodnik-krok-po-kroku">Czym jest Git i jak z niego korzystać? Przewodnik krok po kroku</a></li>
<li><a href="https://jsystems.pl/blog/show_post/ai-dla-devopsow-agent-terraform-gitops-proxmox">AI dla DevOpsów: agent stawia maszyny i pilnuje GitOps</a></li>
<li><a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">MCP - czym jest Model Context Protocol i dlaczego zmienia AI w firmach</a></li>
</ul>
<p><img alt="Powiększony zrzut z artykułu o Codeksie" /></p>
]]></content:encoded></item><item><title><![CDATA[Snowflake od podstaw - czym jest chmurowa hurtownia danych i kiedy jej uzyc]]></title><description><![CDATA[Coraz wiecej firm przenosi analitykie danych do Snowflake zamiast wlasnych serwerowni. Ten tekst tlumaczy architekture, ceny i typowe zastosowania bez zargonu marketingowego.

Tak w praktyce wygląda p]]></description><link>https://jsystems.hashnode.dev/co-to-jest-snowflake-chmurowa-hurtownia-danych</link><guid isPermaLink="true">https://jsystems.hashnode.dev/co-to-jest-snowflake-chmurowa-hurtownia-danych</guid><category><![CDATA[snowflake]]></category><category><![CDATA[database]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[dataengineering]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:03:14 GMT</pubDate><content:encoded><![CDATA[<p>Coraz wiecej firm przenosi analitykie danych do Snowflake zamiast wlasnych serwerowni. Ten tekst tlumaczy architekture, ceny i typowe zastosowania bez zargonu marketingowego.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_02_worksheet.png" alt="Arkusz roboczy Snowsight w Snowflake z zapytaniem SQL i tabelą wyników - 35 wierszy przychodów wg roku i segmentu policzonych w 1,6 sekundy" /></p>
<p>Tak w praktyce wygląda praca w Snowflake: piszemy zwykłe zapytanie SQL, klikamy uruchom i po chwili mamy wynik. Tutaj policzyliśmy roczne przychody wg segmentu rynku na zbiorze około 1,5 miliona zamówień. Wynik, 35 wierszy, pojawił się w 1,6 sekundy. To prawdziwy zrzut z konta, które założyliśmy na potrzeby tego artykułu.</p>
<p>Snowflake to jedno z tych pojęć, które w ogłoszeniach o pracę i na konferencjach pojawia się coraz częściej, a mimo to wiele osób nie potrafi krótko powiedzieć, czym właściwie jest. Baza danych? Hurtownia? Kolejna chmura? W tym przewodniku wyjaśnimy to po kolei, bez żargonu i na prawdziwych przykładach. Wszystkie zrzuty pochodzą z żywego konta Snowflake, na którym naprawdę uruchamialiśmy zapytania, więc widzisz autentyczne wyniki.</p>
<p>Z tego artykułu dowiesz się:</p>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#czym-jest">Czym jest Snowflake i dlaczego mówi się o nim „hurtownia danych w chmurze jako usługa"</a></li>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#architektura">Jak zbudowana jest jego architektura z trzech rozdzielonych warstw i co to praktycznie daje</a></li>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#magazyny">Czym są wirtualne magazyny i na czym polega rozdzielenie mocy obliczeniowej od składowania danych</a></li>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#szybkosc">Dlaczego zapytania w Snowflake są szybkie, mimo że nie zakładamy żadnych indeksów</a></li>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#funkcje">Jak działają Time Travel, współdzielenie danych i model rozliczeń w kredytach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake/#kiedy">Kiedy Snowflake ma sens, a kiedy lepiej sięgnąć po coś innego</a></li>
</ul>
<h2>Czym właściwie jest Snowflake</h2>
<p><strong>Snowflake to hurtownia danych działająca w chmurze i dostarczana jako usługa (ang. Software as a Service, w skrócie SaaS, czyli gotowe oprogramowanie, z którego korzystasz przez przeglądarkę, bez instalowania i utrzymywania go u siebie).</strong> Mówiąc prościej: to miejsce, w którym firma trzyma duże ilości danych i zadaje im pytania językiem SQL, a całą maszynerię pod spodem, czyli serwery, dyski, aktualizacje i kopie zapasowe, utrzymuje dostawca. Ty logujesz się do przeglądarki i pracujesz z danymi.</p>
<p>Hurtownia danych (ang. data warehouse) to wyspecjalizowana baza, w której gromadzi się dane z wielu systemów firmy po to, żeby je analizować: liczyć raporty, budować pulpity, szukać wzorców. Różni się od zwykłej bazy aplikacyjnej tym, że jest zoptymalizowana pod ciężkie zapytania analityczne przechodzące przez miliony wierszy, a nie pod pojedyncze, szybkie operacje typu „dodaj zamówienie". Snowflake jest właśnie taką hurtownią, tyle że w całości w chmurze.</p>
<p>Warto od razu rozwiać trzy nieporozumienia. Snowflake <strong>nie jest programem, który się instaluje</strong> na własnym serwerze, bo działa wyłącznie w chmurze. Snowflake <strong>nie jest przywiązany do jednej chmury</strong>: to samo konto możesz założyć na infrastrukturze Amazona (AWS), Microsoftu (Azure) albo Google (GCP), a sposób pracy jest identyczny. I wreszcie Snowflake <strong>nie jest kolejnym silnikiem, który trzeba stroić</strong> ręcznie: nie zakładasz w nim indeksów, nie planujesz partycji, nie dobierasz parametrów serwera. Większość tej pracy platforma bierze na siebie, a Ty skupiasz się na danych i na pytaniach, które chcesz im zadać.</p>
<p>Darmowe konto próbne z zapasem kredytów założysz w kilka minut na <a href="https://signup.snowflake.com/">signup.snowflake.com</a>, bez podawania karty płatniczej. Pierwsze, co widzimy po zalogowaniu, to Snowsight, czyli przeglądarkowy interfejs Snowflake. To z niego pisze się zapytania, przegląda dane, buduje pulpity i zarządza kontem. Poniżej jego strona główna zaraz po założeniu darmowego konta próbnego:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_01_home.png" alt="Strona główna Snowsight w Snowflake - lewe menu z sekcjami Projects, Ingestion, Monitoring, kafelki szybkich akcji oraz licznik 400 dolarów kredytu na koncie próbnym" /></p>
<p>Strona główna Snowsight, czyli przeglądarkowego interfejsu Snowflake, na świeżo założonym koncie próbnym. Po lewej menu (praca z danymi, katalog, zarządzanie), na środku szybkie akcje, a w rogu licznik darmowych kredytów. Cała praca odbywa się tutaj, bez instalowania czegokolwiek.</p>
<p>Skąd w ogóle wziął się Snowflake? Powstał z prostego spostrzeżenia: <a href="https://jsystems.pl/blog/show_post/wspolczesne-rozwiazania-big-data-2026">klasyczne hurtownie danych łączyły</a> na sztywno moc obliczeniową z dyskami. Jeśli chciałeś liczyć szybciej, musiałeś dokupić większy serwer razem z dyskami, nawet jeśli danych wcale nie przybyło. A gdy dwa zespoły odpytywały hurtownię naraz, wchodziły sobie w drogę i czekały w kolejce. Snowflake rozwiązał to, rozdzielając te dwie rzeczy od siebie. To jest sedno całej platformy i właśnie od architektury zaczniemy.</p>
<h2>Architektura: trzy rozdzielone warstwy</h2>
<p>Snowflake jest zbudowany z trzech niezależnych warstw. To nie jest szczegół dla inżynierów, tylko klucz do zrozumienia, dlaczego platforma działa tak, jak działa. Każda warstwa skaluje się osobno i odpowiada za inną część pracy.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_arch.png" alt="Infografika architektury Snowflake - trzy rozdzielone warstwy: usług chmurowych (mózg), obliczeniowa (mięśnie) i składowania danych (magazyn)" /></p>
<p>Trzy warstwy Snowflake. Warstwa usług koordynuje pracę (to mózg), warstwa obliczeniowa liczy zapytania (mięśnie), a warstwa składowania trzyma dane (magazyn). Kluczowe jest to, że każda z nich skaluje się niezależnie od pozostałych.</p>
<h3>Warstwa składowania danych</h3>
<p>Na samym dole są dane. Snowflake trzyma je w chmurze obiektowej, czyli w usłudze do przechowywania plików w chmurze (na przykład Amazon S3), i sam zajmuje się ich organizacją. Zapisuje je w formacie kolumnowym, mocno je kompresuje i dzieli na małe fragmenty zwane micro-partycjami, o których opowiemy dokładniej przy okazji wydajności. Ważne jest jedno: tych danych nie widzisz jako plików i nie musisz nimi zarządzać. Dla Ciebie to po prostu tabele, do których piszesz SQL.</p>
<h3>Warstwa obliczeniowa</h3>
<p>Nad danymi jest moc obliczeniowa (ang. compute), która wykonuje zapytania. W Snowflake dostarczają jej wirtualne magazyny (ang. warehouses), czyli klastry serwerów uruchamiane na żądanie. To one czytają dane, łączą tabele, liczą sumy i zwracają wynik. Magazynów może działać wiele naraz i, co najważniejsze, są od siebie niezależne. Za chwilę poświęcimy im osobną sekcję, bo to najczęściej mylona część Snowflake.</p>
<h3>Warstwa usług chmurowych</h3>
<p>Na górze jest warstwa, która spina całość. To ona przyjmuje Twoje logowanie, pilnuje uprawnień, przechowuje informacje o tym, jakie masz tabele i co w nich jest (tak zwane metadane, czyli dane o danych), planuje i optymalizuje zapytania oraz dba o spójność transakcji. Nazywamy ją mózgiem, bo sama nic nie liczy, ale steruje tym, co robią pozostałe warstwy. Działa w tle i zwykle w ogóle o niej nie myślisz, a to dobrze, bo to znak, że robi swoje.</p>
<p>Dlaczego ten podział jest tak istotny? Bo pozwala skalować każdą warstwę osobno. Masz dużo danych, ale liczysz rzadko? Płacisz głównie za składowanie, a moc włączasz na chwilę. Masz mało danych, ale liczysz je intensywnie i przez wielu użytkowników naraz? Dokładasz mocy obliczeniowej, nie ruszając składowania. W klasycznej hurtowni jedno ciągnęło drugie. Tutaj są rozłączone.</p>
<h2>Wirtualne magazyny: moc obliczeniowa na żądanie</h2>
<p><strong>Do czego służą:</strong> wirtualne magazyny to moc obliczeniowa Snowflake. Każdy magazyn to osobny klaster, który wykonuje Twoje zapytania. Włączasz go, gdy potrzebujesz liczyć, powiększasz, gdy pracy jest dużo, i wyłączasz, gdy skończysz. Płacisz tylko za czas, w którym pracował.</p>
<p>To jest pojęcie, które najłatwiej zrozumieć na przykładzie, więc spójrzmy na listę magazynów na naszym koncie. Widać na niej trzy magazyny w rozmiarze X-Small. Jeden ma status <strong>Started</strong>, bo przed chwilą liczyliśmy na nim zapytanie z początku artykułu, a dwa pozostałe są <strong>Suspended</strong>, czyli uśpione, i nie generują żadnego kosztu.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_04_warehouses.png" alt="Lista wirtualnych magazynów w Snowflake - trzy magazyny w rozmiarze X-Small, jeden uruchomiony (Started), dwa uśpione (Suspended)" /></p>
<p>Lista wirtualnych magazynów. Każdy to osobna moc obliczeniowa o zadanym rozmiarze (tutaj X-Small). Magazyn COMPUTE_WH jest uruchomiony, bo przed chwilą na nim liczyliśmy, a dwa pozostałe są uśpione i nic nie kosztują. Uśpienie i wybudzanie dzieje się automatycznie.</p>
<p>Rozmiar magazynu decyduje o jego mocy. Zaczyna się od X-Small, a kolejne rozmiary, Small, Medium, Large i dalej, to za każdym razem mniej więcej podwojenie mocy obliczeniowej. Zmiana rozmiaru to jedno kliknięcie, bez przenoszenia danych i bez przerwy w pracy:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_05_wh_sizes.png" alt="Okno tworzenia nowego magazynu w Snowflake z rozwiniętą listą rozmiarów od X-Small do 4X-Large - ilustracja skalowania mocy obliczeniowej" /></p>
<p>Tworzenie magazynu i wybór rozmiaru. Od X-Small po 4X-Large (i dalej), a każdy krok w górę to około dwa razy więcej mocy. Ciężkie zapytanie na większym magazynie policzy się szybciej, ale zużyje w tym czasie więcej kredytów.</p>
<p>Najciekawsze jest to, jak magazyny się włączają i wyłączają. Możesz ustawić, żeby magazyn sam się usypiał po chwili bezczynności (auto-suspend) i sam wybudzał przy pierwszym zapytaniu (auto-resume). Dzięki temu nie płacisz za moc, której nikt nie używa. Poniższa animacja pokazuje ten cykl: powiększamy magazyn na czas ciężkiej pracy, a gdy nikt nie odpytuje, magazyn gaśnie i koszt obliczeń spada do zera.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_scale.gif" alt="Animacja skalowania wirtualnego magazynu Snowflake - moc rośnie od X-Small do Large wraz z obciążeniem, a przy braku zapytań magazyn usypia się i koszt spada do zera" /></p>
<p>Elastyczna moc obliczeniowa w Snowflake. Magazyn powiększamy na czas ciężkich zapytań, a gdy praca się kończy, sam się usypia i przestaje generować koszt. To jest istota modelu „płacisz za użycie".</p>
<p>Definicję magazynu zapisuje się zwykłym poleceniem SQL, więc całą tę logikę możesz mieć opisaną w kodzie i wersjonowaną razem z projektem:</p>
<pre><code>-- Magazyn, ktory sam sie usypia po minucie bezczynnosci
CREATE WAREHOUSE analityka
  WAREHOUSE_SIZE = 'X-SMALL'
  AUTO_SUSPEND  = 60     -- uspij po 60 sekundach ciszy
  AUTO_RESUME   = TRUE;  -- wznow sam przy pierwszym zapytaniu
</code></pre>
<h2>Jedna kopia danych, wiele zespołów naraz</h2>
<p>Skoro moc obliczeniowa jest oddzielona od danych, wynika z tego coś bardzo praktycznego: kilka zespołów może pracować na tych samych danych jednocześnie, każdy na własnym magazynie, nie wchodząc sobie w drogę. W klasycznej hurtowni ciężki raport potrafił spowolnić pracę wszystkich, bo wszyscy dzielili tę samą moc. W Snowflake każdy zespół dostaje osobne mięśnie, a dane pozostają jedną, wspólną kopią.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_sep.gif" alt="Animacja rozdzielenia obliczeń i danych w Snowflake - trzy zespoły (ETL, analitycy BI, Data Science) pracują równocześnie na jednej kopii danych, każdy na własnym wirtualnym magazynie" /></p>
<p>Rozdzielenie obliczeń i danych w praktyce. Zespół ładujący dane, analitycy raportujący i zespół uczenia maszynowego korzystają z jednej kopii danych, ale każdy na własnym magazynie. Nikt nie czeka w kolejce za cudzym zapytaniem.</p>
<p>To rozwiązuje jeden z najstarszych bólów hurtowni danych: konflikt między tymi, którzy dane ładują, a tymi, którzy je analizują. Nocny proces ładowania może działać na swoim magazynie, analitycy na swoim, a zespół uczenia maszynowego na jeszcze innym. Jeśli któryś z magazynów okaże się za mały, powiększasz tylko jego, nie ruszając reszty. Dane cały czas są jedne i te same, więc nie ma mowy o rozjeżdżających się kopiach.</p>
<h2>Jak wygląda codzienna praca w Snowflake</h2>
<p>Od strony użytkownika Snowflake to przede wszystkim pisanie SQL w przeglądarce. Zapytanie z początku artykułu policzyło roczne przychody wg segmentu rynku na zbiorze przykładowym, który Snowflake udostępnia każdemu nowemu kontu. Oto dokładnie to zapytanie, gotowe do skopiowania:</p>
<pre><code>-- Roczne przychody wg segmentu rynku (dane przykladowe TPC-H, ~1,5 mln zamowien)
SELECT YEAR(o_orderdate)                    AS rok,
       c_mktsegment                         AS segment,
       ROUND(SUM(o_totalprice)/1000000, 1)  AS przychod_mln_usd,
       COUNT(*)                             AS liczba_zamowien
FROM snowflake_sample_data.tpch_sf1.orders o
JOIN snowflake_sample_data.tpch_sf1.customer c
     ON c.c_custkey = o.o_custkey
GROUP BY rok, segment
ORDER BY rok, segment;
</code></pre>
<p>Zwróć uwagę, że to zwykły, standardowy SQL. Nie ma tu niczego specyficznego dla Snowflake poza nazwą zbioru danych. Ktokolwiek zna SQL z innej bazy, odnajdzie się tu od pierwszej minuty, i to jedna z głównych przyczyn popularności platformy.</p>
<p>Jeśli chcesz przejść od pierwszych zapytań do sprawnego przetwarzania danych w Snowflake, <a href="https://jsystems.pl/szkolenia-big-data;snowflake.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post465&amp;utm_content=link_snowflake">Szkolenie Snowflake</a> ma terminy gwarantowane.</p>
<p>Wynik nie musi zostać suchą tabelą. W Snowsight ten sam rezultat jednym kliknięciem zamieniamy na wykres, bez eksportowania danych do innego narzędzia. Poniżej ten sam zestaw przychodów pokazany jako wykres słupkowy wg segmentu:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_03_chart.png" alt="Wynik zapytania SQL zamieniony na wykres słupkowy w Snowsight - przychody wg segmentu rynku, z panelem konfiguracji osi po lewej stronie" /></p>
<p>Ten sam wynik co w tabeli, pokazany jako wykres. W panelu po lewej wybieramy typ wykresu oraz to, co ma trafić na osie. Prosta wizualizacja powstaje bez opuszczania Snowflake i bez eksportu danych na zewnątrz.</p>
<p>Dane w Snowflake są zorganizowane w bazy i schematy, czyli foldery na tabele. Wbudowany eksplorator pokazuje tę strukturę i pozwala przeglądać zawartość konta. Na naszym zrzucie widać rozwinięty zbiór przykładowy z kilkoma schematami w różnych rozmiarach:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_06_catalog.png" alt="Eksplorator baz danych w Snowflake z rozwiniętym zbiorem przykładowym SNOWFLAKE_SAMPLE_DATA i szczegółami źródła danych udostępnionego przez Snowflake" /></p>
<p>Eksplorator baz danych. Po lewej drzewo baz i schematów, po prawej szczegóły. Zbiór przykładowy nie jest tu skopiowany, tylko udostępniony przez Snowflake (widoczne pole „Shared by"), o czym więcej przy okazji współdzielenia danych.</p>
<h2>Dlaczego zapytania są szybkie: micro-partycje i wgląd w wykonanie</h2>
<p>Wróćmy do pytania, które zadaje sobie każdy, kto przesiada się na Snowflake z klasycznej bazy: skoro nie zakładam indeksów ani nie planuję partycji, to skąd bierze się szybkość? Odpowiedzią są micro-partycje.</p>
<p>Snowflake sam, bez Twojego udziału, dzieli każdą tabelę na wiele małych, skompresowanych fragmentów zwanych micro-partycjami. Dla każdego z nich zapamiętuje, jakie wartości się w nim znajdują, na przykład najmniejszą i największą datę czy kwotę. Dzięki temu, gdy pytasz o konkretny zakres, silnik od razu wie, które fragmenty w ogóle mogą zawierać wynik, a resztę pomija. Zamiast czytać całą tabelę, czyta jej ułamek.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_micropart.png" alt="Infografika micro-partycji w Snowflake - zapytanie o lata 2024 i nowsze czyta tylko pasujące micro-partycje, a starsze pomija" /></p>
<p>Micro-partycje w akcji. Zapytanie o lata 2024 i nowsze każe silnikowi sięgnąć tylko po pasujące fragmenty danych, a te ze starszymi latami całkowicie pominąć. Mniej odczytanych danych to krótszy czas i mniejszy koszt, a wszystko dzieje się automatycznie.</p>
<p>To dlatego w Snowflake zwykle nie zakłada się indeksów. Ten mechanizm działa z automatu na każdej tabeli i w większości przypadków wystarcza. Efekt widać na liczbach. Nasze zapytanie łączące półtora miliona zamówień z bazą klientów policzyło się poniżej dwóch sekund, a gdy zajrzymy w jego szczegóły, zobaczymy dokładnie, ile trwało i na jakim magazynie:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_08_querydetail.png" alt="Szczegóły wykonanego zapytania w Snowflake - status Success, czas trwania 1,6 sekundy, rozmiar magazynu X-Small" /></p>
<p>Szczegóły wykonanego zapytania. Snowflake zapisuje o każdym zapytaniu komplet informacji: status, czas trwania (tutaj 1,6 sekundy), rozmiar użytego magazynu i znaczniki czasu. To punkt wyjścia, gdy chcemy zrozumieć, co zadecydowało o czasie wykonania zapytania.</p>
<p>Jeśli zapytanie działa wolno, Snowflake pokazuje jego profil wykonania, czyli rozbicie na kolejne kroki (odczyt tabel, łączenie, grupowanie) wraz z udziałem każdego z nich w czasie. To pierwsze miejsce, do którego zagląda się przy optymalizacji:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_09_profile.png" alt="Profil wykonania zapytania w Snowflake - drzewo operatorów (odczyt tabel, złączenie, grupowanie) z udziałem procentowym i podsumowaniem czasu wykonania" /></p>
<p>Profil wykonania zapytania. Snowflake rozkłada zapytanie na kroki i pokazuje, który z nich zajął najwięcej czasu. Tutaj najdroższy jest odczyt tabel, a całość policzyła się w niecałą sekundę czystego przetwarzania. Taki obraz zastępuje zgadywanie konkretną wiedzą, co poprawić.</p>
<p>Wszystkie zapytania, które kiedykolwiek uruchomiono na koncie, trafiają do historii. Można je filtrować, przeszukiwać i wracać do nich później, co jest bezcenne przy rozliczaniu kosztów i szukaniu tego jednego zapytania, które zamula system:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_07_history.png" alt="Historia zapytań w Snowflake z listą wykonanych zapytań, ich identyfikatorami i filtrami po statusie, użytkowniku i czasie" /></p>
<p>Historia zapytań. Każde uruchomione zapytanie zostaje zapisane wraz z czasem, statusem i tym, kto je uruchomił. To wbudowany dziennik pracy całego konta, przydatny zarówno do rozliczeń, jak i do diagnozy.</p>
<h2>Funkcje, które lubią zespoły danych</h2>
<p>Poza samym liczeniem SQL Snowflake ma kilka funkcji, które w codziennej pracy robią dużą różnicę. Nie sposób omówić tu wszystkich, więc wybraliśmy te, o które najczęściej pytają uczestnicy <a href="https://jsystems.pl/szkolenia-big-data;snowflake.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_co_to_jest_snowflake&amp;utm_content=inline_co_to_jest_snowflake">naszego szkolenia z Snowflake</a>.</p>
<h3>Time Travel, czyli podróż w czasie po danych</h3>
<p>Snowflake przez zadany czas pamięta wcześniejsze wersje danych. Możesz odpytać tabelę taką, jaka była godzinę czy dzień temu, a nawet przywrócić tabelę skasowaną przez pomyłkę. Pomyłkowy UPDATE albo DROP przestaje być katastrofą, bo do stanu sprzed błędu wracasz jednym zapytaniem.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_timetravel.png" alt="Infografika funkcji Time Travel w Snowflake - oś czasu ze stanem aktualnym, sprzed godziny, sprzed dnia oraz przywracaniem usuniętej tabeli poleceniem UNDROP" /></p>
<p>Time Travel pozwala patrzeć na dane wstecz. Odpytasz tabelę sprzed godziny, porównasz ją z obecną albo cofniesz przypadkowe skasowanie. Jak długo sięga pamięć wstecz, zależy od wybranej wersji Snowflake.</p>
<p>W praktyce wygląda to tak jak niżej. Pierwsze zapytanie pokazuje dane sprzed godziny, drugie przywraca właśnie usuniętą tabelę:</p>
<pre><code>-- Tabela taka, jaka byla godzine temu
SELECT * FROM zamowienia AT(OFFSET =&gt; -3600);

-- Ups, skasowalismy tabele. Przywracamy ja jednym poleceniem
UNDROP TABLE zamowienia;
</code></pre>
<h3>Współdzielenie danych bez kopiowania</h3>
<p>Snowflake pozwala udostępnić dane innej firmie lub innemu kontu bez wysyłania plików i bez robienia kopii. Odbiorca widzi u siebie zawsze aktualne dane, a Ty zachowujesz nad nimi kontrolę. Dokładnie tak działa zbiór przykładowy, który odpytywaliśmy: nie został skopiowany na nasze konto, tylko udostępniony przez Snowflake, co widać w jego szczegółach jako pole „Shared by" na jednym z wcześniejszych zrzutów. Wokół tego mechanizmu wyrósł <a href="https://www.snowflake.com/en/data-cloud/marketplace/">Snowflake Marketplace</a>, czyli miejsce, gdzie firmy wymieniają się gotowymi zbiorami danych.</p>
<h3>Dane półstrukturalne i język Python</h3>
<p>Snowflake radzi sobie nie tylko z klasycznymi tabelami. Dane półstrukturalne, na przykład w formacie JSON (popularny sposób zapisu danych, w którym wartości opisane są nazwami), można wczytać do specjalnej kolumny i odpytywać SQL-em bez wcześniejszego rozkładania ich na kolumny:</p>
<pre><code>-- 'dane' to kolumna typu VARIANT, w ktorej siedzi cale JSON
SELECT dane:klient.miasto::string AS miasto,
       dane:kwota::number        AS kwota
FROM zdarzenia;
</code></pre>
<p>Kto woli programować, może pracować z danymi w Pythonie przy pomocy biblioteki <a href="https://www.snowflake.com/en/data-cloud/snowpark/">Snowpark</a>, w której zapytania pisze się w kodzie, a wykonują się po stronie Snowflake, blisko danych. Do tego dochodzi warstwa funkcji sztucznej inteligencji (<a href="https://www.snowflake.com/en/product/features/cortex/">Snowflake Cortex</a>), która pozwala wołać gotowe modeli językowe wprost z SQL. To już temat na osobny artykuł, ale warto wiedzieć, że platforma daleko wyszła poza samo raportowanie.</p>
<h2>Za co się płaci: model kredytów</h2>
<p>Rozliczenia w Snowflake bywają źródłem nieporozumień, więc uprośćmy je do dwóch niezależnych osi. Płacisz osobno za moc obliczeniową i osobno za składowanie danych.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/SNOWFLAKE/sf_credits.png" alt="Infografika modelu rozliczeń w Snowflake - obliczenia rozliczane w kredytach naliczanych co sekundę pracy magazynu, składowanie płatne osobno za terabajt miesięcznie" /></p>
<p>Dwie niezależne osie rozliczeń. Za obliczenia płacisz w kredytach naliczanych co sekundę pracy magazynu (uśpiony magazyn nie kosztuje nic), a za składowanie osobno, ryczałtem za terabajt miesięcznie. To dlatego można trzymać dużo danych tanio, a dopłacać dopiero za realne liczenie.</p>
<p>Moc obliczeniową rozlicza się w kredytach. Magazyn zużywa je tylko wtedy, gdy pracuje, a naliczanie idzie co sekundę. Większy magazyn zużywa więcej kredytów na godzinę, ale ciężkie zapytanie kończy na nim szybciej, więc bywa, że większy rozmiar wychodzi podobnie kosztowo, za to daje wynik wcześniej. Kluczowe jest to, że uśpiony magazyn nie kosztuje nic, dlatego auto-suspend jest tak ważny.</p>
<p>Składowanie danych to zupełnie osobna opłata, liczona ryczałtem za terabajt miesięcznie, podobnie jak za dysk w chmurze. Ponieważ Snowflake mocno kompresuje dane, w praktyce zajmują one mniej miejsca niż w zwykłej bazie. Dzięki rozdzieleniu tych dwóch osi możesz trzymać ogromne ilości danych stosunkowo tanio i płacić więcej tylko wtedy, gdy naprawdę je przeliczasz.</p>
<p><strong>O czym warto pamiętać:</strong> elastyczność bywa mieczem obosiecznym. Skoro powiększenie magazynu to jedno kliknięcie, równie łatwo zostawić włączoną dużą moc albo puścić nieoptymalne zapytanie po całej tabeli. Dlatego w Snowflake tak ważne są nawyki: auto-suspend, świadome dobieranie rozmiaru magazynu i zaglądanie w historię oraz profil zapytań. Tego właśnie uczymy na szkoleniu.</p>
<h2>Kiedy Snowflake ma sens, a kiedy niekoniecznie</h2>
<p>Snowflake nie jest odpowiedzią na każdy problem z danymi, więc warto wiedzieć, do czego pasuje, a do czego lepiej wziąć coś innego.</p>
<p><strong>Sprawdzi się</strong>, gdy masz dużo danych z wielu systemów i chcesz je wspólnie analizować, gdy zależy Ci na tym, by nie utrzymywać serwerów samodzielnie, gdy wiele zespołów potrzebuje pracować na tych samych danych naraz, oraz gdy obciążenie jest nierówne, raz spokojnie, raz skokowo, bo wtedy model płatności za użycie naprawdę się opłaca.</p>
<p><strong>Będzie gorszym wyborem</strong> jako baza pod aplikację obsługującą tysiące drobnych, pojedynczych zapytań na sekundę, bo do tego służą <a href="https://jsystems.pl/blog/show_post/SQL_vs_NoSQL_wielkie_porownanie_baz_danych_kiedy_wybrac_relacyjna_a_kiedy_nierelacyjna">bazy operacyjne takie jak PostgreSQL</a>. Nie jest też darmowy, więc przy małych, prostych zbiorach danych zwykła baza często wystarczy taniej. I choć upraszcza bardzo wiele, nie zwalnia z myślenia o kosztach, bo łatwość skalowania działa w obie strony.</p>
<h2>Jak zacząć z Snowflake</h2>
<p>Najlepszą wiadomością jest to, że próg wejścia jest niski. Snowflake udostępnia bezpłatne konto próbne z zapasem kredytów, a wszystkie zrzuty w tym artykule powstały właśnie na takim koncie. Zakładasz je w kilka minut, dostajesz gotowy zbiór przykładowy i możesz od razu pisać zapytania w przeglądarce, bez instalowania czegokolwiek.</p>
<p>Sensowna kolejność nauki wygląda tak. Najpierw dobrze opanuj SQL, bo to fundament pracy w Snowflake. Potem zrozum architekturę trzech warstw i wirtualne magazyny, bo bez tego trudno panować nad wydajnością i kosztami. Następnie naucz się ładować własne dane i modelować je w tabele. Na koniec zajmij się rzeczami, które odróżniają Snowflake od zwykłej bazy: Time Travel, współdzieleniem, danymi półstrukturalnymi i bezpieczeństwem. Najszybciej przechodzi się tę drogę na żywym koncie, pod okiem kogoś, kto pokaże także pułapki, których na własnej skórze wolałbyś uniknąć.</p>
<h2>Podsumowanie</h2>
<p>Snowflake to hurtownia danych w chmurze dostarczana jako usługa, której siła bierze się z jednego pomysłu: rozdzielenia mocy obliczeniowej od składowania danych. Dane leżą w jednej, wspólnej warstwie, a liczą je niezależne wirtualne magazyny, które włączasz, powiększasz i usypiasz zależnie od potrzeb, płacąc tylko za czas realnej pracy. Nad tym wszystkim czuwa warstwa usług, która planuje zapytania, pilnuje uprawnień i spójności. Zapytania są szybkie dzięki automatycznym micro-partycjom, a nie ręcznemu strojeniu, a funkcje takie jak Time Travel czy współdzielenie danych rozwiązują problemy, z którymi klasyczne hurtownie radziły sobie z trudem. Dla firmy oznacza to mniej utrzymania infrastruktury i elastyczne koszty, a dla osoby pracującej z danymi znajomy SQL w przeglądarce i platformę, która skaluje się razem z ambicjami. To właśnie jest Snowflake i do tego służy.</p>
<p><a href="https://jsystems.pl/szkolenia-big-data;snowflake.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_co_to_jest_snowflake&amp;utm_content=banner_co_to_jest_snowflake"><img src="https://jsystems.pl/new_page_resources/images/other/snowflake.jpg" alt="Baner szkolenia Przetwarzanie danych z użyciem Snowflake w JSystems z terminami gwarantowanymi" /></a></p>
<p>Przetwarzanie danych z użyciem Snowflake - szkolenie z praktykiem
Od architektury i wirtualnych magazynów, przez ładowanie i modelowanie danych, po wydajność, Time Travel i rozliczenia. Wszystko na żywym koncie Snowflake, dokładnie na tych mechanizmach, które pokazaliśmy w artykule. Szkolenie ma terminy gwarantowane.
<a href="https://jsystems.pl/szkolenia-big-data;snowflake.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_co_to_jest_snowflake&amp;utm_content=link_co_to_jest_snowflake">Przyjdź na szkolenie Snowflake --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post465&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/power-query-krok-po-kroku">Power Query krok po kroku: import, czyszczenie i łączenie danych w Excelu i Power</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/SQL_vs_NoSQL_wielkie_porownanie_baz_danych_kiedy_wybrac_relacyjna_a_kiedy_nierelacyjna">SQL vs. NoSQL - wielkie porównanie baz danych</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/co-to-jest-knime-przewodnik">Co to jest KNIME? Tutorial krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/wspolczesne-rozwiazania-big-data-2026">Współczesne rozwiązania Big Data 2026</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/czym-jest-power-bi">Czym jest Power BI, Power Query i DAX?</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[ChatGPT Plus vs Business vs Enterprise - ktory plan wybrac dla firmy]]></title><description><![CDATA[Wybor planu ChatGPT dla firmy to nie tylko kwestia budzetu - to tez bezpieczenstwo danych i administracja kontami. Ten przewodnik porownuje Plus, Business i Enterprise wprost.

Trzy plany ChatGPT, mię]]></description><link>https://jsystems.hashnode.dev/chatgpt-w-firmie-plus-business-enterprise</link><guid isPermaLink="true">https://jsystems.hashnode.dev/chatgpt-w-firmie-plus-business-enterprise</guid><category><![CDATA[chatgpt]]></category><category><![CDATA[AI]]></category><category><![CDATA[business]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:02:48 GMT</pubDate><content:encoded><![CDATA[<p>Wybor planu ChatGPT dla firmy to nie tylko kwestia budzetu - to tez bezpieczenstwo danych i administracja kontami. Ten przewodnik porownuje Plus, Business i Enterprise wprost.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/hero_porownanie.png" alt="Porównanie trzech planów ChatGPT dla firm: Plus za 23 euro, Business od 21 euro za stanowisko jako najczęstszy wybór firm oraz Enterprise z wyceną indywidualną" /></p>
<p>Trzy plany ChatGPT, między którymi realnie wybiera firma: Plus dla jednej osoby, Business dla zespołu oraz Enterprise dla dużej organizacji. Ten artykuł rozkłada każdy z nich na czynniki - z cenami i prawdziwymi zrzutami z konta Business.</p>
<p>Decyzja o wprowadzeniu ChatGPT w firmie sprowadza się zwykle do dwóch pytań: który plan kupić i ile to kosztuje. Odpowiedź nie jest oczywista, bo OpenAI ma dziś kilka poziomów licencji, a nazwy potrafią mylić. W tym artykule porównamy trzy plany, które w praktyce bierze pod uwagę firma - <strong>Plus</strong>, <strong>Business</strong> i <strong>Enterprise</strong> - pokażemy ich realne ceny i wytłumaczymy, do kogo pasuje który. Żeby nie zostać na poziomie teorii, uruchomiliśmy prawdziwy plan ChatGPT Business i część zrzutów poniżej pochodzi wprost z jego panelu administratora.</p>
<p>Na start jedna uwaga porządkowa dla szukających planu <strong>ChatGPT Team</strong>: OpenAI zmieniło jego nazwę na <strong>ChatGPT Business</strong>. To ten sam poziom „dla zespołu", tylko dziś nazywa się Business i ma dwa typy stanowisk, o czym za chwilę.</p>
<p>Ten artykuł skupia się na <strong>wyborze planu i kosztach</strong>. Jeśli szukasz samego wdrożenia krok po kroku - konfiguracji panelu administratora, bezpieczeństwa danych i RODO, gotowego regulaminu korzystania z AI oraz budowania firmowych agentów - mamy o tym osobny, praktyczny przewodnik: <a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business - wdrożenie w firmie</a>. Świetnie uzupełnia to, o czym piszemy poniżej.</p>
<h3>Z tego artykułu dowiesz się</h3>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#poziomy">Jakie poziomy licencji ma ChatGPT</a> - od konta darmowego po Enterprise</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#cennik">Ile realnie kosztują</a> plany Plus, Business i Enterprise</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#plus">Kiedy wystarczy ChatGPT Plus</a> i dlaczego to jeszcze nie jest rozwiązanie firmowe</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#business">Co daje ChatGPT Business</a> - prawdziwy panel administratora krok po kroku</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#enterprise">Kiedy firma dojrzewa do Enterprise</a> i za co się wtedy płaci</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#wybor">Który plan wybrać</a> - prosta decyzja w trzech krokach</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-w-firmie-plus-business-enterprise/#bezpieczenstwo">Jak wygląda bezpieczeństwo danych i RODO</a> w planach firmowych</li>
</ul>
<h2>Cztery poziomy: od konta prywatnego do Enterprise</h2>
<p>ChatGPT sprzedawany jest w dwóch światach. Pierwszy to plany <strong>indywidualne</strong>, kupowane przez jedną osobę na własną kartę: darmowy, tani plan Go, popularny Plus i wydajny Pro. Drugi to plany <strong>firmowe</strong>, które tworzą wspólną, zarządzaną przestrzeń dla całego zespołu: Business i Enterprise. Poniżej realny cennik planów indywidualnych - to punkt odniesienia, zanim przejdziemy do wersji dla firm.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/cennik_indywidualny.png" alt="Cennik indywidualnych planów ChatGPT: Free za 0 euro, Go za 8,50 euro, Plus za 23 euro i Pro od 103 euro miesięcznie" /></p>
<p>Cztery plany indywidualne ChatGPT: darmowy Free, tani Go, najczęściej wybierany Plus (23 euro) oraz wydajny Pro (od 103 euro). Wszystkie to licencje dla jednej osoby, bez panelu firmy.</p>
<p>A tak wygląda część firmowa cennika - plany Business i Enterprise:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/cennik_firmowy.png" alt="Cennik firmowy ChatGPT: plan Business ze stanowiskiem Standard za 21 euro i Premium za 105 euro miesięcznie oraz plan Enterprise z wyceną indywidualną" /></p>
<p>Część firmowa cennika ChatGPT. Business ma dwa typy stanowisk - Standard (21 euro miesięcznie przy rozliczeniu rocznym) i Premium z pięciokrotnie wyższymi limitami. Enterprise wyceniany jest indywidualnie w rozmowie z działem handlowym OpenAI.</p>
<p>Dla firmy kluczowa jest jedna granica. Plany indywidualne kupuje pracownik dla siebie i nikt tego nie kontroluje - ani dział IT, ani dział prawny. Plany firmowe odwracają tę sytuację: powstaje jedna <strong>przestrzeń robocza</strong> (po angielsku „workspace"), do której zapraszasz ludzi na adresy służbowe, a nad całością czuwa administrator. W dalszej części porównujemy więc trzy plany: <strong>Plus</strong> jako punkt odniesienia dla pojedynczej osoby oraz dwa plany firmowe - <strong>Business</strong> i <strong>Enterprise</strong>.</p>
<h2>Ile to kosztuje: realne ceny planów</h2>
<p>Zacznijmy od liczb, bo to zwykle one przesądzają. Ceny podajemy w euro, zgodnie z <a href="https://chatgpt.com/pricing">oficjalnym cennikiem ChatGPT</a> (stan na 2026 rok - warto je zweryfikować u źródła przed zakupem, bo dostawca je aktualizuje).</p>
<p>W części firmowej najważniejsza nowość względem starego planu Team to <strong>dwa typy stanowisk</strong> w planie Business (widać je na firmowym cenniku wyżej):</p>
<ul>
<li><strong>Stanowisko Standard</strong> - 21 euro miesięcznie przy rozliczeniu rocznym (26 euro przy rozliczeniu miesięcznym). To wariant do codziennej pracy biurowej.</li>
<li><strong>Stanowisko Premium</strong> - 105 euro miesięcznie przy rozliczeniu rocznym (130 euro przy miesięcznym). Ma pięciokrotnie wyższe limity i zdejmuje część ograniczeń intensywnego użycia.</li>
</ul>
<p>Wygodne jest to, że oba typy stanowisk mogą istnieć w jednej firmie obok siebie. Większość zespołu dostaje Standard, a osoby, które pracują z AI naprawdę intensywnie, dostają Premium. Tak wygląda nasze prawdziwe rozliczenie w planie Business - dwa stanowiska Standard, płatność miesięczna.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/panel_platnosci.png" alt="Panel Płatności w koncie ChatGPT Business JSystems: plan Business, dwa stanowiska standardowe za łącznie 52 euro miesięcznie, domyślny typ stanowiska Standard" /></p>
<p>Prawdziwy panel rozliczeń naszego konta ChatGPT Business. Dwa stanowiska Standard po 26 euro dają 52 euro miesięcznie. Widać też przełącznik na rozliczenie roczne (tańsze o 19 procent) oraz domyślny typ stanowiska ustawiony na Standard.</p>
<p>Plus na tym tle kosztuje 23 euro miesięcznie za jedno konto, a Enterprise nie ma sztywnej ceny - jest wyceniany indywidualnie, bo dochodzą do niego negocjowane limity, wsparcie i warunki umowy. Całość różnic najłatwiej ogarnąć w jednej tabeli.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/g_cennik_porownanie.png" alt="Tabela porównawcza planów ChatGPT Plus, Business i Enterprise: koszt, panel administratora, trenowanie na danych, umowa DPA i RODO, jednokrotne uwierzytelnianie SSO, Custom GPT, konektory, Codex oraz wsparcie" /></p>
<p>Plus, Business i Enterprise w jednej tabeli. Kolumna Business jest wyróżniona, bo to plan, do którego dojrzewa większość firm wdrażających ChatGPT u wszystkich pracowników.</p>
<h2>ChatGPT Plus - dla jednej osoby</h2>
<p><strong>ChatGPT Plus</strong> to plan dla pojedynczego użytkownika. Za 23 euro miesięcznie dostajesz dostęp do zaawansowanych modeli i trybów myślenia, wyższe limity niż w wersji darmowej oraz komplet funkcji do codziennej pracy: analizę plików, generowanie obrazów, tworzenie edytowalnych dokumentów, przeszukiwanie internetu, a także agenta do kodu Codex (w niższych limitach niż w planach firmowych). Sam Codex jest zresztą dostępny w każdym planie ChatGPT, od Free po Enterprise - plany różnią się nie tym, czy go mają, tylko limitami jego użycia. Dla freelancera albo jednej osoby w firmie, która chce po prostu przyspieszyć swoją pracę, to często w zupełności wystarcza.</p>
<p>Problem zaczyna się wtedy, gdy z narzędzia korzysta cały zespół. Na kontach Plus każdy pracownik ma osobne, prywatne konto: firma nie wie, kto z narzędzia korzysta, jakie dane do niego trafiają ani co się z nimi dzieje, gdy pracownik odchodzi. Nie ma panelu administratora, nie ma firmowej umowy powierzenia danych, nie ma wspólnych agentów. Innymi słowy, Plus świetnie sprawdza się jako <strong>narzędzie osobiste</strong>, ale nie jako firmowe wdrożenie. Jeśli dopiero poznajesz możliwości narzędzia na koncie prywatnym, dobrym punktem wyjścia jest nasz przewodnik <a href="https://jsystems.pl/blog/show_post/jak-wycisnac-100-procent-z-chatgpt">jak wycisnąć 100% z ChatGPT</a>, gdzie pokazujemy tryby, projekty i budowanie własnych agentów.</p>
<h2>ChatGPT Business - firmowe środowisko z panelem administratora</h2>
<p><strong>ChatGPT Business</strong> to moment, w którym korzystanie z AI przenosi się z szarej strefy prywatnych kont do środowiska, które da się rozliczyć, skonfigurować i objąć polityką bezpieczeństwa. Powstaje jedna firmowa przestrzeń robocza, do której zapraszasz pracowników, a najważniejsza różnica dotyczy danych: w planie firmowym rozmowy domyślnie nie są wykorzystywane do trenowania modeli. Sercem tego planu jest <strong>panel administratora</strong> (konsola zarządzania organizacją). Poniżej jego prawdziwy widok w naszej przestrzeni.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/panel_ogolne.png" alt="Panel administratora ChatGPT Business, zakładka Ogólne, z nazwą przestrzeni roboczej i pełną nawigacją: członkowie, uprawnienia, płatności, modele, wtyczki, analityka, tożsamość, Codex i agenty" /></p>
<p>Panel administratora ChatGPT Business, zakładka Ogólne. Po lewej cała mapa zarządzania firmowym wdrożeniem AI. Identyfikatory organizacji i przestrzeni roboczej zamazaliśmy.</p>
<p>To, co widzisz po lewej stronie, w świecie kont prywatnych po prostu nie istnieje. Przejdźmy przez najważniejsze sekcje. Pierwsza to <strong>członkowie</strong> - tu administrator zaprasza i usuwa użytkowników, więc dostęp do narzędzia gaśnie razem z odejściem pracownika. Widać też, ile stanowisk jest wykupionych, ile przypisanych i kto ma jaką rolę.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/r_panel_czlonkowie.png" alt="Zarządzanie członkami i stanowiskami w panelu ChatGPT Business: dwa przypisane stanowiska, role właściciel i członek, standardowy typ stanowiska" /></p>
<p>Zarządzanie członkami. Widać przypisane stanowiska, role (właściciel i członek), typ stanowiska oraz zakładki oczekujących zaproszeń i próśb o dołączenie. Dane osób zamazaliśmy.</p>
<p>Druga sekcja to <strong>uprawnienia i role</strong>. Da się je kontrolować bardzo drobiazgowo - w naszej przestrzeni panel wylicza kilkadziesiąt przełączników: od tego, czy pracownicy mogą tworzyć osobiste tokeny dostępowe, przez lokalny dostęp do narzędzi programistycznych, po nagrywanie i transkrypcję spotkań. To jest różnica między <strong>rolą</strong> (kim jesteś w organizacji) a <strong>uprawnieniem</strong> (co konkretnie wolno Ci zrobić).</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/r_panel_uprawnienia.png" alt="Uprawnienia i role w ChatGPT Business: długa lista przełączników, w tym tokeny dostępowe oraz lokalny dostęp do narzędzi w wierszu poleceń" /></p>
<p>Uprawnienia i role - kilkadziesiąt przełączników. Tu administrator decyduje między innymi o tokenach dostępowych i o lokalnym dostępie do narzędzi programistycznych.</p>
<p>Trzecia rzecz, o którą zawsze pyta dział bezpieczeństwa, to <strong>tożsamość i dostęp</strong>. W tej sekcji firma weryfikuje własne domeny, konfiguruje <strong>logowanie jednokrotne</strong> (po angielsku „SSO" - jedno firmowe logowanie do wielu narzędzi) i decyduje o automatycznym zakładaniu kont dla osób z zaufanej domeny. To domena działu IT, ale warto wiedzieć, że w planie Business takie mechanizmy w ogóle są.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/r_panel_tozsamosc.png" alt="Panel Tożsamość i dostęp w ChatGPT Business: zweryfikowane domeny firmowe, jednokrotne uwierzytelnianie SSO oraz automatyczne zakładanie kont użytkowników" /></p>
<p>Tożsamość i dostęp: zweryfikowane domeny, logowanie jednokrotne (SSO) oraz automatyczne tworzenie kont dla osób z firmowej domeny. Tego na kontach prywatnych po prostu nie ma.</p>
<p>Całe firmowe wdrożenie ChatGPT - od panelu administratora, przez dobór modeli, po własne agenty - przechodzimy krok po kroku na warsztacie <a href="https://jsystems.pl/szkolenia-ai;chatgpt_business.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post473&amp;utm_content=link_inline_chatgpt_business">Szkolenie ChatGPT Business - wdrożenie w firmie</a>.</p>
<p>Business daje też coś, czego indywidualny użytkownik nie ma: administrator ustala <strong>domyślny model i wysiłek myślenia dla całej organizacji</strong>, osobno dla zwykłego czatu i osobno dla trybu pracy z kodem. Dzięki temu pracownicy nie muszą się zastanawiać, a firma pilnuje rozsądnego balansu między jakością a kosztem.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/r_panel_modele.png" alt="Panel Modele w ChatGPT Business: administrator ustawia domyślny model i wysiłek myślenia osobno dla czatu oraz dla trybu pracy z kodem" /></p>
<p>Panel Modele. Administrator ustawia domyślny model, wysiłek myślenia i szybkość - osobno dla zwykłego czatu i osobno dla trybu pracy z kodem.</p>
<p>Wreszcie <strong>konektory</strong> (wtyczki łączące ChatGPT z systemami firmy). To one odblokowują prawdziwą wartość, bo asystent sięga po dokumenty i sprawy tam, gdzie one naprawdę żyją. Coraz częściej odbywa się to przez <strong>MCP</strong> (Model Context Protocol - wspólny standard łączenia AI z danymi i narzędziami), który rozłożyliśmy na części w artykule o tym, <a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">czym jest protokół MCP i dlaczego zmieni AI w firmach</a>.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/r_panel_konektory.png" alt="Wtyczki i konektory w panelu ChatGPT Business: Gmail, GitHub, Google Drive, Google Calendar, Slack, Notion, Outlook i Canva z osobnym statusem dostępności" /></p>
<p>Konektory w panelu administratora: Gmail, GitHub, Google Drive, Google Calendar, Slack, Notion, Outlook, Canva. Każdy z osobnym statusem i regułą instalacji, którą ustawia administrator.</p>
<p>Jeśli chcesz zobaczyć te wszystkie elementy w kontekście pełnego wdrożenia - z regulaminem AI, Custom GPT i budowaniem agentów dla działów - opisaliśmy to osobno w tekście <a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business - wdrożenie w firmie</a>. Tu chodzi nam przede wszystkim o to, żebyś wiedział, za co konkretnie płacisz, wybierając Business.</p>
<h2>ChatGPT Enterprise - dla dużej organizacji</h2>
<p><strong>ChatGPT Enterprise</strong> to plan dla dużych organizacji, w których dochodzą wymagania niemieszczące się już w Business. Zawiera wszystko, co Business, i dokłada do tego przede wszystkim skalę oraz kontrolę: najwyższe limity użycia, rozbudowane logowanie firmowe wraz z automatyczną aprowizacją i usuwaniem kont, dłuższe i konfigurowalne zasady przechowywania danych, dedykowane wsparcie oraz umowę o gwarantowanym poziomie usługi (po angielsku „SLA").</p>
<p>Enterprise nie ma sztywnej ceny widocznej w cenniku - kupuje się go w rozmowie z działem handlowym OpenAI, a wycena zależy od liczby stanowisk i negocjowanych warunków. W praktyce to plan dla organizacji, które mają osobny dział IT i compliance oraz twarde wymagania bezpieczeństwa. Dla znakomitej większości firm, które chcą po prostu bezpiecznie dać ChatGPT wszystkim pracownikom, plan Business jest w zupełności wystarczający - i wielokrotnie tańszy w uruchomieniu.</p>
<h2>Który plan wybrać</h2>
<p>Decyzję można sprowadzić do jednego pytania na starcie: <strong>ile osób będzie korzystać i jak wrażliwe dane będą wchodzić w grę?</strong> Reszta układa się niemal sama.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_plany/g_decyzja.gif" alt="Animacja decyzji, który plan ChatGPT wybrać: jedna osoba prowadzi do planu Plus, zespół i firma do planu Business, duża organizacja do planu Enterprise" /></p>
<p>Prosta decyzja w trzech krokach. Jedna osoba i dane niewrażliwe to Plus. Zespół i dane firmowe to Business. Duża organizacja z działem IT i compliance to Enterprise.</p>
<ul>
<li><strong>Jedna osoba</strong>, prywatna produktywność, brak potrzeby kontroli firmy - wybierz <strong>Plus</strong>.</li>
<li><strong>Zespół albo cała firma</strong>, wspólne dane, potrzeba panelu administratora i zgodności z RODO, a do tego chęć tworzenia własnych agentów (Custom GPT) i udostępniania ich całej organizacji - wybierz <strong>Business</strong>. To najczęstszy wybór i punkt, do którego dojrzewa większość firm.</li>
<li><strong>Duża organizacja</strong> z osobnym działem IT, wymaganiami compliance i potrzebą najwyższych limitów - rozważ <strong>Enterprise</strong>.</li>
</ul>
<p>Najczęstszy błąd to nie wybór złego planu, tylko kupienie licencji bez pomysłu na konkretne zastosowania i bez zasad, jakie dane wolno wprowadzać. Zanim więc zdecydujesz o planie, warto mieć listę realnych zadań dla AI w firmie - pomysłami dzielimy się w przeglądzie <a href="https://jsystems.pl/blog/show_post/10-zastosowan-agentow-ai-w-polskich-firmach">10 zastosowań agentów AI w polskich firmach</a>, gdzie przy każdym z dziesięciu zastosowań linkujemy do osobnego tutoriala krok po kroku, jak zbudować takiego agenta.</p>
<h2>Bezpieczeństwo danych i RODO w skrócie</h2>
<p>Zanim firma wpuści swoje dane do ChatGPT, pojawia się pytanie: czy to, co wpiszemy, posłuży do trenowania modelu i gdzie te dane trafiają. W planach firmowych (Business i Enterprise) odpowiedź jest korzystna i opiera się na kilku filarach, które warto znać przed rozmową z działem prawnym.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/g_bezpieczenstwo_rodo.gif" alt="Animacja pięciu filarów bezpieczeństwa danych w ChatGPT Business: brak trenowania na danych firmowych, szyfrowanie, umowa DPA i klauzule SCC, przetwarzanie w Europejskim Obszarze Gospodarczym oraz kontrola dostępu" /></p>
<p>Pięć filarów ochrony danych firmowych w planach ChatGPT dla firm. Część gwarantuje dostawca, część konfiguruje administrator po stronie firmy.</p>
<p>W skrócie: dane z ChatGPT Business i Enterprise domyślnie nie trenują modeli, OpenAI udostępnia umowę powierzenia przetwarzania danych oraz standardowe klauzule umowne, a dla klientów z Europejskiego Obszaru Gospodarczego stroną umowy jest OpenAI Ireland. Dane są szyfrowane, a infrastruktura ma uznane certyfikaty bezpieczeństwa. Ostatni filar, kontrola dostępu, dzieje się już w panelu administratora, który pokazaliśmy wyżej.</p>
<h2>Od czego zacząć</h2>
<p>Sensowna kolejność jest taka: najpierw ustal, do czego w ogóle chcecie używać AI, potem policz, ile osób będzie z niej korzystać (i czy któraś potrzebuje stanowiska Premium), a na końcu wybierz plan. Dla większości firm będzie to Business ze stanowiskami Standard, z pojedynczymi stanowiskami Premium dla osób pracujących z AI najintensywniej. Zacznij od pilotażu na małej grupie i jednego realnego zastosowania, a dopiero potem skaluj licencję na całą organizację.</p>
<p>Dobrze poprowadzone wdrożenie zamienia rozproszone eksperymenty pojedynczych osób w spójne, bezpieczne narzędzie, z którego korzysta cała firma i które oszczędza pracownikom sporo czasu każdego dnia. Jeśli chcesz przejść tę drogę z przewodnikiem, zapraszamy na nasze szkolenie.</p>
<p><a href="https://jsystems.pl/szkolenia-ai;chatgpt_business.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post473&amp;utm_content=banner_chatgpt_business"><img src="https://jsystems.pl/new_page_resources/images/chatgpt_business/g_cta_banner.png" alt="Baner szkolenia ChatGPT Business - wdrożenie w firmie: bezpieczeństwo, administracja i agenci AI, szkolenie online na żywo prowadzone przez JSystems" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-ai;chatgpt_business.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post473&amp;utm_content=link_end_chatgpt_business">Szkolenie ChatGPT Business - wdrożenie w firmie --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post473&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business - wdrożenie w firmie: panel administratora, RODO i agenci AI</a></li>
<li><a href="https://jsystems.pl/blog/show_post/jak-wycisnac-100-procent-z-chatgpt">Jak wycisnąć 100% z ChatGPT - tryby, projekty, własne GPT i agenci AI</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czy-warto-wdrozyc-microsoft-copilot">Czy warto wdrażać Microsoft Copilot - najczęstsze wątpliwości managementu</a></li>
<li><a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">MCP (Model Context Protocol) - czym jest i dlaczego zmieni AI w firmach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/10-zastosowan-agentow-ai-w-polskich-firmach">10 zastosowań agentów AI w polskich firmach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/jak-dziala-llm">Jak działa LLM - duży model językowy wytłumaczony po ludzku</a></li>
</ul>
<p><img alt="Powiększony zrzut z artykułu o planach ChatGPT dla firm" /></p>
]]></content:encoded></item><item><title><![CDATA[Jak zbudowac wlasnego GPT-a dla firmy bez kodowania (asystent na wiedzy firmowej)]]></title><description><![CDATA[Zamiast szukac w setkach plikow, mozna zapytac wlasnego GPT-a wytrenowanego na wiedzy firmowej. Ten tekst prowadzi przez cala konfiguracje - bez programowania, w ChatGPT Plus/Business.

Cel tego porad]]></description><link>https://jsystems.hashnode.dev/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej</link><guid isPermaLink="true">https://jsystems.hashnode.dev/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej</guid><category><![CDATA[chatgpt]]></category><category><![CDATA[AI]]></category><category><![CDATA[business]]></category><category><![CDATA[automation]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Mon, 07 Sep 2026 07:02:24 GMT</pubDate><content:encoded><![CDATA[<p>Zamiast szukac w setkach plikow, mozna zapytac wlasnego GPT-a wytrenowanego na wiedzy firmowej. Ten tekst prowadzi przez cala konfiguracje - bez programowania, w ChatGPT Plus/Business.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_hero.png" alt="Gotowy własny GPT dla firmy odpowiada pracownikowi na pytanie o cennik na podstawie wgranych dokumentów, w oknie ChatGPT Business" /></p>
<p>Cel tego poradnika: własny GPT, który odpowiada pracownikom na podstawie dokumentów firmy - oferty, procedur i najczęstszych pytań. Zbudujemy go od zera, bez pisania kodu.</p>
<p>W każdej firmie te same pytania krążą w kółko. Ile trwa realizacja zamówienia, jak wygląda procedura reklamacji, co jest w cenniku, kto odpowiada za dany temat. Odpowiedzi są w dokumentach, ale nikt nie chce ich za każdym razem przeszukiwać, więc pytania lądują na Slacku albo u jednej przeciążonej osoby. W tym poradniku pokażemy, jak w kilkanaście minut zbudować <strong>własnego GPT</strong> (konfigurowalnego asystenta na bazie ChatGPT), który zna dokumenty Twojej firmy i odpowiada na ich podstawie. Taki asystent nie tylko odpowie pracownikowi w kilka sekund - potrafi też przygotować <strong>wstępną odpowiedź na maila, który trafił do biura obsługi klienta</strong>, gotową do sprawdzenia i wysłania. Bez programowania, bez zewnętrznych narzędzi, w całości w oknie przeglądarki.</p>
<p>Dobra wiadomość na start: <strong>zbudujesz go zarówno w ChatGPT Plus, jak i w ChatGPT Business</strong>. Kreator jest w obu planach identyczny, więc każdy krok z tego poradnika wygląda tak samo niezależnie od tego, który masz. Różnica pojawia się dopiero przy <strong>udostępnianiu asystenta i ochronie danych</strong> - i to ona decyduje, który plan lepiej pasuje do wiedzy firmowej. Rozłożyliśmy to poniżej.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_plus_business.png" alt="Tabela porównawcza własnego GPT w ChatGPT Plus i Business: budowa asystenta i wgranie wiedzy identyczne w obu planach, różnice w udostępnianiu zespołowi, trenowaniu na danych, umowie powierzenia DPA i panelu administratora" /></p>
<p>Sam kreator działa tak samo w Plusie i w Business. Business dokłada to, co ważne przy danych firmowych: brak trenowania na Twoich danych, umowę powierzenia i udostępnianie w obrębie firmy.</p>
<p>W tym poradniku zrzuty robimy w <strong>ChatGPT Business</strong>, ale jeśli masz Plusa, przejdziesz dokładnie te same kroki - Twój asystent będzie po prostu widoczny dla Ciebie i osób, które zaprosisz, zamiast publikowany w firmowej przestrzeni. Jeśli interesuje Cię szerszy obraz całego wdrożenia firmowego, opisaliśmy je w artykule <a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business - wdrożenie w firmie</a>, gdzie pokazujemy prawdziwy panel administratora i zasady bezpieczeństwa. Tutaj skupiamy się na jednej rzeczy: zbudowaniu asystenta wiedzy firmowej krok po kroku.</p>
<h3>Z tego poradnika dowiesz się</h3>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#po-co">Czym jest własny GPT</a> i kiedy naprawdę warto go firmie zbudować</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#przygotowanie">Czy wystarczy ChatGPT Plus, czy lepszy Business</a> oraz co przygotować przed startem</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#krok1">Jak otworzyć kreator</a> własnego GPT w oknie przeglądarki</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#krok3">Jak napisać instrukcje</a>, żeby asystent nie zmyślał i mówił „nie wiem”</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#krok4">Jak wgrać wiedzę firmową</a> i jak asystent z niej korzysta</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#krok6">Jak przetestować asystenta</a>, zanim udostępnisz go innym</li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej/#krok7">Jak udostępnić asystenta</a> - sobie, zaproszonym osobom albo całej firmie - i o czym pamiętać</li>
</ul>
<h2>Czym jest własny GPT i po co go budować</h2>
<p>Własny GPT to zwykły ChatGPT, któremu raz opisujesz, kim ma być i z jakiej wiedzy korzystać, a on od tej pory zachowuje się tak samo dla każdego, kto z niego korzysta. Nie jest to osobny program ani integracja wymagająca informatyka. To raczej formularz: wypełniasz kilka pól i masz gotowego asystenta. Najlepiej widać to, gdy rozłożymy go na części.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_anatomia_gpt.png" alt="Infografika: z czego składa się własny GPT - nazwa i opis, instrukcje, wiedza firmowa, rozpoczęcia rozmowy, funkcje i widoczność (tylko Ty, link lub cała firma)" /></p>
<p>Własny GPT to sześć pól do wypełnienia. Najważniejsze z nich to instrukcje (charakter i zasady asystenta) oraz wiedza firmowa (wgrane dokumenty).</p>
<p>Naturalne pytanie brzmi: po co to robić, skoro można po prostu zapytać ChatGPT. Do jednorazowego pytania rzeczywiście wystarczy zwykła rozmowa. Własny GPT zaczyna się opłacać tam, gdzie te same pytania wracają, gdzie liczy się spójność odpowiedzi w zespole i gdzie asystent ma znać konkretne dokumenty Twojej firmy, a nie ogólną wiedzę z internetu. Poniższe zestawienie pokazuje tę różnicę wprost.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_kiedy_gpt.png" alt="Tabela porównawcza: zwykły czat kontra własny GPT z wiedzą firmy - wiedza o firmie, powtarzalne zadania, gdy pyta kilka osób, dostęp dla innych i nakład na start" /></p>
<p>Kiedy warto zbudować własnego GPT. Do jednorazowego pytania wystarczy czat, ale gdy pytania wracają i liczy się wiedza z Twoich dokumentów, wygrywa dedykowany asystent.</p>
<p>Jeśli chcesz najpierw dobrze opanować sam ChatGPT i jego tryby pracy, zebraliśmy to w artykule <a href="https://jsystems.pl/blog/show_post/jak-wycisnac-100-procent-z-chatgpt">Jak wycisnąć 100% z ChatGPT</a>. Tutaj zakładamy, że podstawy masz już za sobą, i przechodzimy prosto do budowy asystenta. Cały proces sprowadza się do pięciu kroków, które przejdziemy po kolei.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_pipeline_budowy.gif" alt="Animacja pięciu kroków budowy własnego GPT: nazwa i cel, instrukcje, wgranie wiedzy firmowej, test w podglądzie, udostępnienie (sobie albo zaproszonym osobom)" /></p>
<p>Pięć kroków od pomysłu do gotowego asystenta. Cały proces przechodzisz w oknie przeglądarki, bez pisania kodu.</p>
<h2>Zanim zaczniesz: konto i materiały</h2>
<p>Do zbudowania własnego GPT wystarczy konto <strong>ChatGPT Plus</strong> albo <strong>Business</strong> - w obu kreator jest dokładnie taki sam. Jeśli robisz asystenta na własny użytek albo dla nauki, Plus w zupełności wystarczy. Jeśli natomiast wgrywasz realne dokumenty firmy i chcesz udostępnić asystenta zespołowi, wybierz <strong>Business</strong>: dane z rozmów domyślnie nie trenują tam modelu, jest umowa powierzenia danych, a administrator decyduje, kto może publikować asystentów i komu są widoczne. Prościej mówiąc, wrażliwą wiedzę firmową bezpieczniej trzymać na koncie firmowym niż na prywatnym.</p>
<p>Druga rzecz to materiały, czyli <strong>wiedza</strong>, na której asystent ma się opierać. Najlepiej sprawdzają się dokumenty, które i tak już masz: oferta i cennik, procedury obsługi, najczęstsze pytania klientów, standardy komunikacji, regulaminy. Nie muszą być idealne. Wystarczy, że są aktualne i zawierają odpowiedzi, których oczekujesz od asystenta.</p>
<p>Na potrzeby tego poradnika zbudujemy asystenta obsługi klienta dla <strong>przykładowej firmy Ziarnovia</strong> - fikcyjnego dostawcy kawy, ekspresów i serwisu do biur. Przygotowaliśmy dla niej cztery krótkie dokumenty. Możesz je pobrać i przejść całe demo dokładnie tak, jak my, albo podmienić na własne pliki.</p>
<ul>
<li><a href="https://jsystems.pl/new_page_resources/images/wlasny_gpt/pliki/ziarnovia-oferta-i-cennik.pdf">Pobierz PDF</a>Ziarnovia - oferta i cennik (ekspresy, kawa, serwis)</li>
<li><a href="https://jsystems.pl/new_page_resources/images/wlasny_gpt/pliki/ziarnovia-procedury-obslugi.pdf">Pobierz PDF</a>Ziarnovia - procedury obsługi klienta (dostawa, serwis, reklamacje)</li>
<li><a href="https://jsystems.pl/new_page_resources/images/wlasny_gpt/pliki/ziarnovia-faq-klienci.pdf">Pobierz PDF</a>Ziarnovia - najczęstsze pytania klientów</li>
<li><a href="https://jsystems.pl/new_page_resources/images/wlasny_gpt/pliki/ziarnovia-standardy-komunikacji.pdf">Pobierz PDF</a>Ziarnovia - standardy komunikacji z klientem</li>
</ul>
<p><strong>Dobra praktyka:</strong> zanim wgrasz dokumenty, przejrzyj je pod kątem danych, których asystent nie powinien znać (na przykład dane osobowe czy wewnętrzne notatki). Asystent potraktuje wszystko, co wgrasz, jako wiarygodne źródło - dlatego wiedza powinna być czysta i aktualna.</p>
<h2>Krok 1. Otwórz kreator własnego GPT</h2>
<p>W bocznym menu ChatGPT otwieramy pozycję <strong>Modele GPT</strong> - to tu zbierają się wszystkie własne asystenty. Na stronie „Moje modele GPT” klikamy <strong>Utwórz model GPT</strong>. To jedno kliknięcie otwiera cały kreator, nie trzeba niczego instalować.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_menu_gpt.png" alt="Boczne menu ChatGPT z pozycją Modele GPT oraz strona Moje modele GPT z przyciskiem Utwórz model GPT do zbudowania własnego asystenta" /></p>
<p>Wejście do kreatora: w bocznym menu otwieramy „Modele GPT”, a na stronie „Moje modele GPT” klikamy „Utwórz model GPT”.</p>
<p>Kreator ma dwie zakładki u góry oraz podgląd na żywo po prawej stronie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_gpts_menu.png" alt="Kreator własnego GPT w ChatGPT Business z zakładkami Utwórz i Skonfiguruj oraz podglądem asystenta po prawej stronie" /></p>
<p>Kreator własnego GPT tuż po otwarciu. U góry przełączasz się między zakładką Utwórz (opisujesz asystenta rozmową) a Skonfiguruj (ustawiasz wszystko ręcznie), a po prawej masz podgląd na żywo.</p>
<p>Zakładka <strong>Utwórz</strong> prowadzi rozmowę, w której opisujesz asystenta zwykłym językiem, a ChatGPT sam wypełnia za Ciebie pola. Zakładka <strong>Skonfiguruj</strong> pokazuje wszystkie ustawienia wprost, do ręcznej edycji. W tym poradniku pracujemy na zakładce Skonfiguruj, bo daje pełną kontrolę i dokładnie widać, co gdzie wpisujemy. Po prawej stronie przez cały czas mamy <strong>podgląd</strong> - żywe okno rozmowy, w którym można od razu przetestować asystenta.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_builder_configure.png" alt="Kreator własnego GPT w ChatGPT Business, zakładka Skonfiguruj z pustymi polami nazwy, opisu, instrukcji, rozpoczęć konwersacji i wiedzy oraz podglądem po prawej stronie" /></p>
<p>Kreator własnego GPT, zakładka Skonfiguruj. Po lewej pola do wypełnienia (nazwa, opis, instrukcje, wiedza), po prawej podgląd na żywo. Na start wszystko jest puste.</p>
<h2>Krok 2. Nazwa, opis i charakter asystenta</h2>
<p>Zaczynamy od rzeczy najprostszych. <strong>Nazwa</strong> to sposób, w jaki pracownicy zobaczą asystenta na liście, więc powinna od razu mówić, do czego służy. „Asystent obsługi Ziarnovia” jest lepszy niż „Pomocnik”. <strong>Opis</strong> to jedno zdanie widoczne pod nazwą, które doprecyzowuje rolę. Te dwa pola nie wpływają na jakość odpowiedzi, ale porządkują asystentów, gdy w firmie zrobi się ich kilka.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_nazwa_opis.png" alt="Wypełnione pola nazwy i opisu własnego GPT w kreatorze: Asystent obsługi Ziarnovia oraz opis roli asystenta wiedzy firmowej" /></p>
<p>Nazwa i opis asystenta. To pierwsze, co widzą pracownicy, dlatego warto, żeby od razu mówiły, do czego służy asystent.</p>
<h2>Krok 3. Instrukcje - serce asystenta</h2>
<p>To najważniejszy krok w całym procesie. <strong>Instrukcje</strong> to opis zachowania asystenta zwykłym językiem - jego charakter, zasady i granice. To tu decydujesz, na jakiej podstawie ma odpowiadać, czego mu nie wolno i jakim tonem ma mówić. Dobre instrukcje zamieniają ogólny model w konkretnego, przewidywalnego pracownika. Oto instrukcje, których użyliśmy dla asystenta Ziarnovia. Możesz je skopiować i dopasować do własnej firmy.</p>
<p>Kopiuj
Jesteś asystentem obsługi klienta przykładowej firmy Ziarnovia, która dostarcza kawę, ekspresy i serwis do biur. Odpowiadasz wyłącznie na podstawie wgranych dokumentów: oferty i cennika, procedur obsługi, najczęstszych pytań oraz standardów komunikacji.
Zasady:</p>
<ol>
<li>Podawaj tylko ceny, terminy i warunki, które znajdziesz w dokumentach. Nie zmyślaj i nie podawaj cen spoza cennika.</li>
<li>Jeśli w materiałach nie ma odpowiedzi, powiedz to wprost i skieruj rozmówcę do biura obsługi, zamiast zgadywać.</li>
<li>Odpowiadaj po polsku, krótko, rzeczowo i uprzejmie, zwracając się do rozmówcy per Państwo.</li>
<li>Gdy pytanie jest niejasne, dopytaj o szczegóły, zanim odpowiesz.</li>
</ol>
<p>Zwróć uwagę na dwie rzeczy, które są kluczowe dla firmowego zastosowania. Po pierwsze, wyraźne <strong>ograniczenie odpowiedzi do wgranych dokumentów</strong>, dzięki czemu asystent nie wymyśla informacji. Po drugie, jawne pozwolenie na powiedzenie <strong>„nie wiem”</strong>. W obsłudze klienta pewna, ale błędna odpowiedź bywa groźniejsza niż uczciwe odesłanie do człowieka. Te dwa zdania w instrukcji robią większą różnicę niż cała reszta konfiguracji.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_instrukcje.png" alt="Pole Instrukcje w kreatorze własnego GPT z wklejoną instrukcją systemową asystenta obsługi Ziarnovia, opisującą zasady i granice odpowiedzi" /></p>
<p>Instrukcje wklejone w kreatorze. To one nadają asystentowi charakter: na czym się opiera, czego mu nie wolno i jak ma się zwracać do rozmówcy.</p>
<p>Nad samą treścią instrukcji naprawdę warto się pochylić, bo to od niej zależy jakość asystenta. Jeśli chcesz nauczyć się formułować takie polecenia skuteczniej, zebraliśmy techniki w artykule <a href="https://jsystems.pl/blog/show_post/prompt-engineering-techniki-2026">prompt engineering krok po kroku</a>.</p>
<p>Chcesz opanować pisanie skutecznych poleceń i instrukcji dla ChatGPT w praktyce? <a href="https://jsystems.pl/szkolenia-ai;mistrz_promptow_chatgpt.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post475&amp;utm_content=link_mistrz_promptow">Szkolenie Mistrz promptów - intensywne warsztaty z ChatGPT</a> ma terminy gwarantowane.</p>
<h2>Krok 4. Wgraj wiedzę firmową</h2>
<p>Instrukcje mówią asystentowi, <em>jak</em> ma się zachowywać. Teraz damy mu to, <em>na czym</em> ma pracować. W sekcji <strong>Wiedza</strong> dołączamy pliki, które asystent będzie traktował jako źródło prawdy. Wgrywamy tu nasze cztery dokumenty firmy Ziarnovia. Obsługiwane są typowe formaty biurowe, między innymi PDF, dokumenty tekstowe i arkusze, więc zwykle nie trzeba niczego konwertować.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_wiedza_upload.png" alt="Sekcja Wiedza w kreatorze własnego GPT z czterema wgranymi plikami PDF firmy Ziarnovia: oferta i cennik, procedury, najczęstsze pytania i standardy komunikacji" /></p>
<p>Cztery dokumenty firmy wgrane do sekcji Wiedza. Od tej chwili asystent odpowiada, sięgając do ich treści.</p>
<p>Warto rozumieć, co dzieje się pod spodem, bo to tłumaczy zarówno siłę, jak i granice takiego asystenta. Gdy pracownik zadaje pytanie, asystent najpierw przeszukuje wgrane dokumenty w poszukiwaniu pasujących fragmentów, a dopiero potem układa z nich odpowiedź. Nie „uczy się” dokumentów na pamięć - za każdym razem do nich zagląda. Dzięki temu odpowiada konkretem z Twoich materiałów, a nie ogólną wiedzą modelu.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_jak_dziala_wiedza.gif" alt="Animacja: jak własny GPT odpowiada z wiedzy firmowej - pytanie pracownika, przeszukanie wgranych dokumentów, trafienie w cenniku i odpowiedź z konkretną ceną" /></p>
<p>Od pytania do odpowiedzi. Asystent przeszukuje wgrane dokumenty i odpowiada zgodnie z ich treścią. Gdy odpowiedzi nie ma w materiałach, dobrze poinstruowany asystent mówi o tym wprost.</p>
<p>To podejście - odpowiadanie na podstawie własnych dokumentów, a nie samej wiedzy modelu - ma swoją nazwę i swoje głębsze, techniczne warianty. Jeśli chcesz zobaczyć, jak to samo można zbudować na większą skalę, opisaliśmy kilka dróg w artykule <a href="https://jsystems.pl/blog/show_post/wlasny-rag-bez-kodowania-4-sposoby-dla-nietech">własny asystent AI z wiedzą firmy bez kodowania</a>.</p>
<h2>Krok 5. Funkcje i rozpoczęcia rozmowy</h2>
<p>Zostały dwa ustawienia, które dopracowują asystenta. Sekcja <strong>Funkcje</strong> to przełączniki dodatkowych możliwości: wyszukiwania w sieci, generowania obrazów oraz interpretera kodu i analizy danych. Dla asystenta wiedzy firmowej zwykle chcemy, żeby trzymał się wgranych dokumentów, więc te funkcje wyłączamy - inaczej asystent mógłby mieszać firmowe procedury z przypadkowymi treściami z sieci. Wyszukiwanie w sieci włączamy świadomie tylko wtedy, gdy asystent naprawdę potrzebuje aktualnych danych z zewnątrz.</p>
<p><strong>Rozpoczęcia konwersacji</strong> to gotowe przykłady pytań, które pojawiają się pod oknem czatu jako klikalne podpowiedzi. Dobrze dobrane, od razu pokazują pracownikowi, do czego asystent służy i jak z nim rozmawiać. Wpisaliśmy tu cztery typowe pytania klienta firmy Ziarnovia.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_mozliwosci.png" alt="Sekcja Funkcje z wyłączonymi przełącznikami w kreatorze własnego GPT oraz podgląd asystenta Ziarnovia z czterema pytaniami startowymi jako klikalnymi kartami" /></p>
<p>Sekcja Funkcje z wyłączonymi przełącznikami (asystent trzyma się dokumentów), a po prawej podgląd z czterema rozpoczęciami konwersacji jako klikalnymi kartami.</p>
<h2>Krok 6. Przetestuj asystenta</h2>
<p>Zanim udostępnimy asystenta komukolwiek, sprawdzamy go w <strong>podglądzie</strong> po prawej stronie kreatora. To najważniejszy moment kontroli jakości. Zadajemy pytanie, na które odpowiedź jest w dokumentach - i patrzymy, czy asystent podaje właściwy konkret. Pytamy o cenę jednorazowego przeglądu ekspresu, która w cenniku Ziarnovia wynosi 180 zł netto.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_test_wiedza.png" alt="Podgląd własnego GPT: asystent Ziarnovia na pytanie o koszt przeglądu ekspresu poza abonamentem odpowiada 180 zł netto, zgodnie z wgranym cennikiem" /></p>
<p>Test odpowiedzi z wiedzy. Na pytanie o koszt przeglądu asystent podaje 180 zł netto - dokładnie tę wartość, która jest w cenniku. To znak, że korzysta z dokumentów, a nie zgaduje.</p>
<p>Równie ważny jest test odwrotny. Zadajemy pytanie, na które <strong>celowo nie ma odpowiedzi</strong> w dokumentach - na przykład o produkt, którego firma nie ma w ofercie. Dobrze poinstruowany asystent nie powinien niczego wymyślać. Zamiast tego przyznaje, że nie ma takiej informacji, i kieruje do biura obsługi. To właśnie działanie zasady „nie wiem” z instrukcji.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_test_niewiem.png" alt="Podgląd własnego GPT: na pytanie o produkt spoza oferty asystent Ziarnovia przyznaje, że nie ma takiej informacji w materiałach i kieruje do biura obsługi" /></p>
<p>Test granicy wiedzy. Pytanie o produkt spoza oferty - asystent nie zmyśla, tylko mówi wprost, że nie ma takiej informacji, i odsyła do biura obsługi. Dokładnie tego chcemy.</p>
<p>Jeśli w którymś teście asystent zmyśla albo pomija oczywistą informację z dokumentów, wracamy do instrukcji i je doprecyzowujemy, po czym testujemy ponownie. Ta pętla - popraw instrukcję, sprawdź w podglądzie - to normalna część budowy. Zwykle wystarczą dwie, trzy rundy, żeby asystent zachowywał się dokładnie tak, jak chcemy.</p>
<p>Chcesz, żeby Twój zespół samodzielnie budował takich asystentów i agentów AI? <a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post475&amp;utm_content=link_agenci_ai_tresc">Szkolenie Tworzenie agentów AI - Twoi wirtualni asystenci</a> ma terminy gwarantowane.</p>
<h2>Krok 7. Udostępnij asystenta</h2>
<p>Asystent działa, więc czas dać go innym. Zapisujemy go przyciskiem <strong>Utwórz</strong> w prawym górnym rogu, a w oknie <strong>Udostępnianie modelu GPT</strong> ustawiamy, kto ma dostęp. Jedyny możliwy zakres to <strong>Tylko zaproszeni</strong> - publiczne udostępnianie GPT zostało wyłączone w całym ChatGPT, więc asystent nie trafia do internetu, tylko do wskazanych przez Ciebie osób. To akurat zaleta: wiedza firmowa zostaje w firmie.</p>
<p>Zapraszanie jest proste. W polu <strong>Dodaj osoby ze swojego obszaru roboczego</strong> u góry okna wpisujesz imię lub adres e-mail współpracownika, wybierasz go z podpowiedzi i potwierdzasz. Od tej chwili widzi on asystenta na swojej liście modeli GPT i może z niego korzystać. Kolejne osoby dodajesz tak samo, a dostęp w każdej chwili odbierzesz, usuwając kogoś z listy.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_zapraszanie.png" alt="Okno Udostępnianie modelu GPT w ChatGPT z zakresem Tylko zaproszeni oraz polem Dodaj osoby ze swojego obszaru roboczego, w które wpisujemy współpracownika" /></p>
<p>Okno udostępniania. Zakres to „Tylko zaproszeni”, a osoby dodajesz w polu u góry, wpisując imię lub adres e-mail. Dane osoby udostępniającej zasłoniliśmy.</p>
<p>Zasady udostępniania zależą od planu. W <strong>Business</strong> nad całością czuwa administrator - w panelu firmowym decyduje, kto może publikować własne GPT i komu wolno je udostępniać, dzięki czemu z pomysłu jednej osoby robi się kontrolowane narzędzie całej firmy. Na koncie <strong>Plus</strong> nie ma administratora ani firmowej przestrzeni, więc o dostępie decydujesz samodzielnie, zapraszając pojedyncze osoby.</p>
<p>Po zapisaniu asystent jest gotowy do pracy - otwiera się z własnym ekranem powitalnym, opisem i podpowiadanymi pytaniami.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/z_gotowy.png" alt="Gotowy własny GPT Asystent obsługi Ziarnovia otwarty w ChatGPT z opisem i czterema pytaniami startowymi, gotowy do rozmowy" /></p>
<p>Gotowy asystent - z nazwą, opisem i podpowiadanymi pytaniami. Otwierasz go jednym kliknięciem i pytasz jak zwykłego kolegę z działu, a w firmie robi to każda zaproszona osoba. Dane autora zasłoniliśmy.</p>
<h2>O czym pamiętać: granice i dobre praktyki</h2>
<p>Własny GPT jest szybki i tani w budowie, ale ma swoje granice. Warto je znać, żeby nie budować oczekiwań, których nie spełni. Zebraliśmy cztery zasady, które oddzielają dobrą praktykę od rozczarowania.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/wlasny_gpt/g_granice_praktyki.png" alt="Infografika czterech dobrych praktyk przy własnym GPT: dane na koncie firmowym, wiedza jest statyczna, to nie połączenie na żywo, testuj granice odpowiedzi" /></p>
<p>Cztery rzeczy, o których warto pamiętać. Najczęstsze rozczarowanie bierze się z traktowania wgranej wiedzy jak połączenia z systemem firmy na żywo.</p>
<p>Najważniejsza z nich dotyczy aktualności. Wgrana wiedza jest <strong>statyczna</strong> - to zdjęcie dokumentów z chwili wgrania. Gdy zmienisz cennik albo procedurę, musisz podmienić plik w bazie wiedzy, bo asystent nie zaktualizuje się sam. Jeśli potrzebujesz połączenia z systemami firmy na żywo, to już zadanie dla konektorów i protokołu <strong>MCP</strong> (wspólnego standardu łączenia AI z danymi firmy), o którym piszemy w artykule <a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">czym jest Model Context Protocol</a>. Własny GPT z wgranymi plikami to inne, prostsze narzędzie - i do wielu zastosowań w zupełności wystarczające.</p>
<h2>Podsumowanie: asystent w kilkanaście minut</h2>
<p>Zbudowanie własnego GPT nie wymaga programisty ani budżetu na wdrożenie. Wystarczy konto Plus lub firmowe, kilka dokumentów i kilkanaście minut. Przeszliśmy całą drogę: od nazwy i instrukcji, przez wgranie wiedzy firmowej, po test i udostępnienie gotowego asystenta. Efektem jest asystent, który odpowiada na podstawie dokumentów Twojej firmy i uczciwie przyznaje, gdy czegoś nie wie.</p>
<p>Najlepszy pierwszy asystent to ten, który rozwiązuje jedno konkretne, powtarzalne zadanie w jednym dziale - odpowiadanie na typowe pytania obsługi, przygotowanie oferty według firmowych standardów czy tłumaczenie regulaminów pracownikom. Gdy zobaczysz, ile czasu oszczędza, kolejne asystenty dla innych działów zbudujesz już w kwadrans. A jeśli chcesz przejść tę drogę pod okiem praktyków i z gotowymi wzorcami dla różnych działów, zapraszamy na nasze warsztaty.</p>
<p><a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post475&amp;utm_content=banner_agenci_ai"><img src="https://jsystems.pl/new_page_resources/images/other/agenci_ai.jpg" alt="Baner szkolenia Tworzenie agentów AI - Twoi wirtualni asystenci, warsztaty JSystems z terminami gwarantowanymi" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post475&amp;utm_content=link_agenci_ai">Szkolenie Tworzenie agentów AI - Twoi wirtualni asystenci →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post475&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business w firmie: panel administratora, RODO i agenci AI</a></li>
<li><a href="https://jsystems.pl/blog/show_post/jak-wycisnac-100-procent-z-chatgpt">Jak wycisnąć 100% z ChatGPT - tryby, projekty, własne GPT i agenci AI</a></li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-rag-bez-kodowania-4-sposoby-dla-nietech">Własny RAG bez kodowania - asystent AI z wiedzą firmy</a></li>
<li><a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">MCP (Model Context Protocol) - czym jest i dlaczego zmieni AI w firmach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/10-zastosowan-agentow-ai-w-polskich-firmach">Jak stworzyć agenta AI - 10 przykładów dla firm z tutorialami krok po kroku</a></li>
</ul>
<p><img alt="Powiększony zrzut z poradnika o własnym GPT dla firmy" /></p>
]]></content:encoded></item><item><title><![CDATA[Pierwsza analiza danych w Pandas — od instalacji do wyników]]></title><description><![CDATA[Instalacja, wczytanie danych, pierwsze przekształcenia — pokazuję Pandas na realnym przykładzie, od zera.

Efekt kilkunastu linii kodu w pandas: przychód według kategorii i miesięczny trend sprzedaży.]]></description><link>https://jsystems.hashnode.dev/pierwsza-analiza-danych-w-pandas</link><guid isPermaLink="true">https://jsystems.hashnode.dev/pierwsza-analiza-danych-w-pandas</guid><category><![CDATA[Python]]></category><category><![CDATA[pandas]]></category><category><![CDATA[Dataanalysis]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 09:24:52 GMT</pubDate><content:encoded><![CDATA[<p>Instalacja, wczytanie danych, pierwsze przekształcenia — pokazuję Pandas na realnym przykładzie, od zera.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/hero_dashboard.png" alt="Wykres słupkowy przychodu według kategorii i wykres liniowy miesięcznego przychodu zbudowane w pandas i matplotlib" /></p>
<p>Efekt kilkunastu linii kodu w pandas: przychód według kategorii i miesięczny trend sprzedaży. Do tego dojdziemy w tym artykule, pracując na jednym pliku CSV.</p>
<p>Pandas to najpopularniejsza biblioteka Pythona do pracy z danymi w formie tabel. Wczytuje pliki CSV, Excela czy dane z bazy, pozwala je filtrować, grupować i liczyć, a na końcu narysować wykres - wszystko w kilku czytelnych liniach. W tym artykule zainstalujemy pandas od zera, a potem na prawdziwym zbiorze sprzedaży sklepu internetowego przejdziemy przez całą ścieżkę: od wczytania danych, przez filtrowanie i grupowanie, aż po gotowy wykres do raportu. Ten sam plik i ten sam kod odtworzysz u siebie w kilka minut - dane są do pobrania niżej.</p>
<p>Jeśli Pythona dopiero zaczynasz, warto najpierw zajrzeć do naszego <a href="https://jsystems.pl/blog/show_post/Bezp%C5%82atny_kurs_Python_od_podstaw/">bezpłatnego kursu Python od podstaw</a>, a potem wrócić tutaj. Do przejścia przez ten artykuł wystarczy jednak podstawowa znajomość języka.</p>
<p>Z tego artykułu dowiesz się:</p>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#instalacja">jak zainstalować pandas</a> przez pip i sprawdzić, że działa</li>
<li>czym jest <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#dataframe">DataFrame</a> i jak wczytać dane z pliku CSV</li>
<li>jak <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#wybieranie">filtrować</a>, <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#grupowanie">grupować</a> i liczyć na prawdziwych danych sprzedaży</li>
<li>jak zamienić wynik w <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#wykres">wykres</a>, który trafi do raportu</li>
<li>czym jest <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/#anaconda">Anaconda</a> i kiedy wybrać ją zamiast pip</li>
</ul>
<p><strong>Pobierz dane do ćwiczeń</strong>Plik <code>sprzedaz_sklep_internetowy.csv</code> - 4300 zamówień sklepu z lat 2024-2025 (kategoria, produkt, miasto, ilość, cena). Dokładnie ten sam plik widzisz na wszystkich zrzutach poniżej. Zapisz go w folderze, z którego będziesz uruchamiać Pythona.</p>
<p><a href="https://jsystems.pl/new_page_resources/images/pandas/sprzedaz_sklep_internetowy.csv">Pobierz plik CSV</a></p>
<h2>Czym jest pandas i najważniejsze pojęcie: DataFrame</h2>
<p>Pandas dodaje do Pythona jeden kluczowy obiekt: <strong>DataFrame</strong>, czyli dwuwymiarową tabelę z nazwanymi kolumnami i ponumerowanymi wierszami - tak jak arkusz w Excelu, tylko sterowany kodem. Pojedyncza kolumna DataFrame to obiekt <strong>Series</strong>. Każda kolumna ma swój typ danych, po angielsku <em>dtype</em> (skrót od data type): liczby całkowite, liczby z przecinkiem, tekst albo daty. Ten typ decyduje o tym, co można z kolumną zrobić - na liczbach policzysz średnią, a z daty wyciągniesz miesiąc.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/ig_dataframe.png" alt="Infografika anatomii obiektu DataFrame w pandas: indeks, kolumny, typy danych dtype oraz różnica między DataFrame a Series" /></p>
<p>Anatomia DataFrame: kolumny mają nazwy i typy (dtype), wiersze mają indeks (etykiety 0, 1, 2...). Jedna kolumna to obiekt Series.</p>
<p>Cała reszta pandas sprowadza się do operacji na tym obiekcie: wybierz kolumny, odfiltruj wiersze, pogrupuj, policz, narysuj. Zobaczmy to na żywym przykładzie, ale najpierw zainstalujmy bibliotekę.</p>
<h2>Instalacja pandas przez pip</h2>
<p>Zakładamy, że masz zainstalowanego Pythona w wersji 3.9 lub nowszej. Jeśli jeszcze nie, przeprowadzi Cię przez to nasz wpis <a href="https://jsystems.pl/blog/show_post/Instalacja_Pythona_i_Pycharma/">Instalacja Pythona i PyCharma</a>. Mając Pythona, pandas instalujesz jednym poleceniem w terminalu (w Windowsie to Wiersz polecenia lub PowerShell, na macOS i Linuksie - Terminal):</p>
<p>Kopiuj</p>
<pre><code>pip install pandas
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/t_pip_install.png" alt="Terminal z instalacją pandas przez pip: pobieranie pakietów pandas i numpy oraz komunikat Successfully installed" /></p>
<p>Instalacja pandas przez pip. Menedżer pakietów sam dociąga zależności (m.in. numpy) i kończy komunikatem Successfully installed.</p>
<p>Na macOS i Linuksie polecenie brzmi często <code>pip3 install pandas</code>, bo samo <code>pip</code> może wskazywać na starego Pythona 2. Dobrym nawykiem jest tworzenie osobnego <strong>środowiska wirtualnego</strong> (po angielsku <em>virtual environment</em>) dla każdego projektu. To odizolowany katalog z własnym kompletem bibliotek, dzięki któremu projekty nie mieszają sobie wersji pakietów:</p>
<p>Kopiuj</p>
<pre><code>python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS / Linux:
source .venv/bin/activate
pip install pandas
</code></pre>
<p>Kopiuj</p>
<p>Po instalacji warto sprawdzić, czy wszystko działa. Uruchamiamy Pythona i importujemy pandas. Przyjęło się skracać nazwę do <code>pd</code> - zobaczysz ten zapis w każdym przykładzie w sieci:</p>
<p>Kopiuj</p>
<pre><code>python -c "import pandas as pd; print(pd.__version__)"
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/t_verify.png" alt="Terminal z weryfikacją instalacji pandas: import pandas as pd oraz wypisana wersja biblioteki" /></p>
<p>Sprawdzenie, że pandas działa: import biblioteki i odczyt numeru wersji. Jeśli nie widzisz błędu, możemy zaczynać analizę.</p>
<h2>Wczytanie danych - pierwszy DataFrame</h2>
<p>Pracujemy na pliku <code>sprzedaz_sklep_internetowy.csv</code> (jeśli jeszcze go nie masz, <a href="https://jsystems.pl/new_page_resources/images/pandas/sprzedaz_sklep_internetowy.csv">pobierz go tutaj</a>). To 4300 zamówień fikcyjnego sklepu z elektroniką: data zamówienia, kategoria, produkt, miasto, kanał sprzedaży, ilość i cena jednostkowa. Wczytujemy plik funkcją <code>read_csv</code> i od razu oglądamy pierwsze wiersze metodą <code>head</code>. Parametr <code>parse_dates</code> mówi pandas, żeby kolumnę z datą potraktował jako datę, a nie zwykły tekst:</p>
<p>Kopiuj</p>
<pre><code>import pandas as pd

df = pd.read_csv("sprzedaz_sklep_internetowy.csv", parse_dates=["data"])
df.head()
</code></pre>
<p>Kopiuj</p>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_read_head.png" alt="Notatnik Jupyter: wczytanie pliku CSV do pandas metodą read_csv i podgląd pierwszych pięciu wierszy tabeli metodą head" /></p>
<p>Metoda head() pokazuje pierwsze pięć wierszy. Widać wszystkie kolumny i pierwsze zamówienia - dane wczytały się poprawnie.</p>
<p>Kod uruchamiamy w notatniku Jupyter, dlatego ostatnia linia komórki od razu wyświetla ładnie sformatowaną tabelę. W zwykłym skrypcie dopisałbyś <code>print(df.head())</code>. O Jupyterze więcej w części o Anacondzie.</p>
<p>Ile w ogóle mamy danych? Atrybut <code>shape</code> zwraca liczbę wierszy i kolumn:</p>
<p>Kopiuj</p>
<pre><code>df.shape
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_shape.png" alt="Notatnik Jupyter: atrybut shape zwraca liczbę wierszy i kolumn DataFrame - cztery tysiące trzysta wierszy i osiem kolumn" /></p>
<p>shape zwraca parę liczb: 4300 wierszy i 8 kolumn. Pierwsza liczba to zawsze liczba wierszy.</p>
<p>Zanim cokolwiek policzymy, warto poznać strukturę tabeli. Metoda <code>info</code> wypisuje listę kolumn, liczbę niepustych wartości i typ danych każdej kolumny:</p>
<p>Kopiuj</p>
<pre><code>df.info()
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_info.png" alt="Notatnik Jupyter: metoda info wypisuje kolumny DataFrame, liczbę niepustych wartości i typy danych dtype każdej kolumny" /></p>
<p>info() to pierwszy raport o danych: nazwy kolumn, brak braków (4300 wartości wszędzie) oraz typy - liczby, tekst (str) i data (datetime64).</p>
<p>Zwróć uwagę na typy danych: <code>data</code> jest typu <code>datetime64</code> (dzięki <code>parse_dates</code>), ceny to <code>float64</code> (liczby z przecinkiem), a nazwy to <code>str</code> (tekst). Gdyby data była zwykłym tekstem, nie moglibyśmy wyciągnąć z niej miesiąca ani zrobić wykresu w czasie.</p>
<h2>Szybkie podsumowanie liczb metodą describe</h2>
<p>Jedno polecenie daje komplet statystyk dla wszystkich kolumn liczbowych: średnią, odchylenie standardowe, wartości minimalną i maksymalną oraz kwartyle. Metoda <code>round</code> zaokrągla wynik dla czytelności:</p>
<p>Kopiuj</p>
<pre><code>df.describe().round(2)
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_describe.png" alt="Notatnik Jupyter: metoda describe pokazuje statystyki opisowe kolumn liczbowych pandas - średnia, minimum, maksimum i kwartyle" /></p>
<p>describe() liczy statystyki jednym poleceniem. Widać między innymi średnią cenę jednostkową i najdroższe zamówienie w całym zbiorze.</p>
<p>To bezcenne przy pierwszym kontakcie z danymi. Od razu widać zakres cen, typową ilość w zamówieniu i to, czy nie ma podejrzanych wartości, na przykład ujemnych. Wiersz <code>50%</code> to mediana, czyli wartość środkowa - odporniejsza na pojedyncze bardzo drogie zamówienia niż zwykła średnia.</p>
<h2>Wybieranie kolumn i filtrowanie wierszy</h2>
<p>Pojedynczą kolumnę wybierasz przez <code>df["nazwa"]</code>, a kilka kolumn naraz przez listę nazw w podwójnych nawiasach kwadratowych:</p>
<p>Kopiuj</p>
<pre><code>df[["produkt", "cena_jedn"]].head()
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_select.png" alt="Notatnik Jupyter: wybieranie dwóch kolumn z DataFrame w pandas przez listę nazw w nawiasach kwadratowych" /></p>
<p>Wybranie dwóch kolumn: produkt i cena jednostkowa. Podwójne nawiasy kwadratowe oznaczają listę kolumn do pokazania.</p>
<p>Najczęstsza operacja to jednak <strong>filtrowanie wierszy</strong> po warunku. Zapis w środku nawiasu (<code>df["cena_jedn"] &gt; 5000</code>) tworzy tak zwaną <em>maskę logiczną</em>, czyli kolumnę wartości prawda albo fałsz dla każdego wiersza. Pandas zwraca tylko te wiersze, dla których warunek jest prawdziwy:</p>
<p>Kopiuj</p>
<pre><code>df[df["cena_jedn"] &gt; 5000].head()
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_filter.png" alt="Notatnik Jupyter: filtrowanie wierszy DataFrame w pandas po warunku - zamówienia z ceną jednostkową powyżej 5000 złotych" /></p>
<p>Filtr po warunku: tylko zamówienia droższe niż 5000 zł za sztukę. To najczęściej używana operacja w codziennej analizie danych.</p>
<p>Warunki można łączyć operatorami <code>&amp;</code> (i) oraz <code>|</code> (lub), pamiętając o nawiasach wokół każdego z nich, na przykład <code>df[(df["kategoria"] == "Laptopy") &amp; (df["ilosc"] &gt; 1)]</code>. Do precyzyjnego wskazywania wierszy i kolumn służą też <code>df.loc</code> (po etykietach) oraz <code>df.iloc</code> (po numerach pozycji).</p>
<h2>Tworzenie nowej kolumny - przychód</h2>
<p>W danych mamy ilość i cenę jednostkową, ale nie ma przychodu. Policzmy go. W pandas nie potrzeba do tego pętli - mnożymy dwie kolumny naraz, a wynik trafia do nowej kolumny. To tak zwana <strong>wektoryzacja</strong>: operacja wykonuje się od razu na całej kolumnie, dzięki czemu zapis jest krótki, a obliczenie bardzo szybkie. Do podglądu wybieramy zamówienia z ilością większą niż 1, żeby od razu było widać efekt mnożenia:</p>
<p>Kopiuj</p>
<pre><code>df["przychod"] = df["ilosc"] * df["cena_jedn"]
df[df["ilosc"] &gt; 1][["produkt", "ilosc", "cena_jedn", "przychod"]].head()
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_newcol.png" alt="Notatnik Jupyter: tworzenie nowej kolumny przychód w pandas przez pomnożenie kolumn ilość i cena jednostkowa" /></p>
<p>Nowa kolumna przychód powstaje z pomnożenia dwóch istniejących kolumn. Na zamówieniach z ilością większą niż 1 wyraźnie widać, że przychód to ilość razy cena jednostkowa.</p>
<h2>Sortowanie i największe zamówienia</h2>
<p>Które zamówienia były największe? Metoda <code>nlargest</code> zwraca wiersze o najwyższej wartości wskazanej kolumny, tutaj dziesięć zamówień o najwyższym przychodzie. Na końcu wybieramy kilka kolumn, żeby wynik był czytelny:</p>
<p>Kopiuj</p>
<pre><code>df.nlargest(10, "przychod")[["data", "produkt", "ilosc", "cena_jedn", "przychod"]]
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_nlargest.png" alt="Notatnik Jupyter: metoda nlargest w pandas zwraca dziesięć zamówień o najwyższym przychodzie posortowanych malejąco" /></p>
<p>Dziesięć największych zamówień według przychodu. Na szczycie drogie laptopy kupowane po dwie sztuki. Ogólne sortowanie robi metoda sort_values.</p>
<h2>Grupowanie - serce analizy (groupby)</h2>
<p>Najciekawsze pytania dotyczą grup: która kategoria zarabia najwięcej, które miasto kupuje najchętniej. Służy do tego <code>groupby</code>, które działa według schematu <strong>podziel, policz, połącz</strong> (po angielsku <em>split-apply-combine</em>): pandas dzieli dane na grupy według wskazanej kolumny, w każdej grupie wykonuje obliczenie (tu sumę przychodu), a potem składa wyniki w jedną tabelę. Na koniec sortujemy malejąco:</p>
<p>Kopiuj</p>
<pre><code>przychod_kat = df.groupby("kategoria")["przychod"].sum().sort_values(ascending=False)
przychod_kat
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_groupby.png" alt="Notatnik Jupyter: grupowanie danych w pandas metodą groupby - suma przychodu według kategorii posortowana malejąco" /></p>
<p>groupby sumuje przychód w każdej kategorii. Widać od razu, że Laptopy i Smartfony odpowiadają za większą część obrotu.</p>
<p>Liczby robią wrażenie, ale wykres przekonuje szybciej. Pandas ma wbudowane rysowanie - metoda <code>plot</code> na naszym wyniku tworzy gotowy wykres słupkowy. Parametr <code>kind="barh"</code> to słupki poziome, a <code>color</code> ustawia ich kolor:</p>
<h2>Pierwszy wykres wprost z danych</h2>
<p>Kopiuj</p>
<pre><code>przychod_kat.sort_values().plot(kind="barh", color="#E02D33",
                                title="Przychód wg kategorii", xlabel="przychód [zł]");
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_barchart.png" alt="Notatnik Jupyter: poziomy wykres słupkowy przychodu według kategorii narysowany w pandas metodą plot z biblioteką matplotlib" /></p>
<p>Ten sam wynik jako wykres słupkowy - kilka słów w wywołaniu plot() i mamy gotowy obraz do raportu. Laptopy na czele.</p>
<p>Średnik na końcu linii to drobiazg z notatnika Jupyter - ukrywa techniczny komunikat o obiekcie wykresu. W zwykłym skrypcie dopisz na górze <code>import matplotlib.pyplot as plt</code>, a na dole <code>plt.show()</code>, żeby okno z wykresem się pojawiło. Pandas rysuje przy pomocy biblioteki <strong>matplotlib</strong>, którą instaluje się tak samo prosto: <code>pip install matplotlib</code>.</p>
<p>Chcesz przejść od pojedynczych analiz do sprawnej, codziennej pracy z danymi w Pythonie pod okiem praktyka? <a href="https://jsystems.pl/szkolenia-python;analiza_danych_w_jezyku_python.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_pandas&amp;utm_content=link_analiza_python">Szkolenie Analiza danych w języku Python</a> ma terminy gwarantowane.</p>
<h2>Ile zamówień w każdej kategorii - value_counts</h2>
<p>Uwaga na pułapkę: największy przychód nie znaczy najwięcej zamówień. Metoda <code>value_counts</code> zlicza, ile razy występuje każda wartość w kolumnie:</p>
<p>Kopiuj</p>
<pre><code>df["kategoria"].value_counts()
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_valuecounts.png" alt="Notatnik Jupyter: metoda value_counts w pandas zlicza liczbę zamówień w każdej kategorii produktów" /></p>
<p>value_counts liczy zamówienia w kategoriach. Akcesoria mają ich najwięcej, choć w przychodzie były na ostatnim miejscu.</p>
<p>To jest właśnie ten moment, dla którego robi się analizę danych. <strong>Akcesoria</strong> to najczęstsze zamówienia, ale najniższy przychód - dużo tanich transakcji. Z <strong>laptopami</strong> jest odwrotnie: mało zamówień, ale każde wysokie. Bez zestawienia tych dwóch liczb łatwo o złą decyzję, na przykład o promowaniu nie tej kategorii, co trzeba.</p>
<h2>Tabela przestawna - pivot_table</h2>
<p>Jeśli znasz tabele przestawne z Excela, poczujesz się jak w domu. <code>pivot_table</code> rozkłada jedną wartość na dwa wymiary. Sprawdźmy przychód w układzie kategoria (wiersze) wobec kanału sprzedaży (kolumny). Parametr <code>margins=True</code> dodaje wiersz i kolumnę z sumami:</p>
<p>Kopiuj</p>
<pre><code>pd.pivot_table(df, values="przychod", index="kategoria",
               columns="kanal", aggfunc="sum", margins=True).round(0)
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_pivot.png" alt="Notatnik Jupyter: tabela przestawna pivot_table w pandas - przychód według kategorii i kanału sprzedaży z podsumowaniem" /></p>
<p>Tabela przestawna: kategoria wobec kanału sprzedaży. Kolumna All to suma dla każdej kategorii, a wiersz All - dla każdego kanału.</p>
<h2>Analiza w czasie - trend miesięczny (resample)</h2>
<p>Skoro kolumna z datą ma typ daty, możemy łatwo agregować po czasie. Ustawiamy datę jako indeks, a metoda <code>resample</code> grupuje dane w równe przedziały czasu. Tutaj <code>"ME"</code> oznacza końce kolejnych miesięcy (od angielskiego <em>month end</em>). Sumujemy przychód i od razu rysujemy:</p>
<p>Kopiuj</p>
<pre><code>miesiecznie = df.set_index("data").resample("ME")["przychod"].sum()
miesiecznie.plot(marker="o", color="#E02D33",
                 title="Miesięczny przychód", xlabel="", ylabel="przychód [zł]");
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/j_resample.png" alt="Notatnik Jupyter: wykres liniowy miesięcznego przychodu w pandas po grupowaniu czasu metodą resample z widocznymi szczytami sprzedaży" /></p>
<p>Miesięczny przychód na wykresie liniowym. Najwyższe słupki wypadają na przełomie roku (Black Friday i sezon świąteczny), a zaraz po nich, w styczniu i lutym, przychód gwałtownie spada.</p>
<p>Jednym spojrzeniem widać sezonowość: pod koniec roku sprzedaż wystrzeliwuje w górę - najwyższy słupek na całym wykresie to grudzień, a zaraz po nim, w styczniu i lutym, przychód gwałtownie spada. Taka informacja jest warta realnych pieniędzy - podpowiada, kiedy zwiększyć zapasy i budżet reklamowy. A wyciągnęliśmy ją z surowego pliku CSV w kilku liniach kodu.</p>
<h2>Anaconda - gdy chcesz wszystko w jednym pakiecie</h2>
<p>Do tej pory instalowaliśmy pandas przez pip. Jest jednak druga popularna droga: <strong>Anaconda</strong>. To gotowa dystrybucja Pythona przeznaczona do analizy danych i pracy naukowej. W jednym instalatorze dostajesz Pythona oraz komplet bibliotek - pandas, numpy, matplotlib - a także notatnik Jupyter i własny menedżer pakietów o nazwie <strong>conda</strong>. Nie musisz nic dobierać ręcznie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/ig_pip_vs_conda.png" alt="Infografika porównania pip i Anacondy do instalacji pandas w Pythonie - kiedy wybrać które narzędzie" /></p>
<p>pip i Anaconda prowadzą do tego samego pandas. pip jest lżejszy i standardowy, Anaconda daje komplet narzędzi od razu.</p>
<p>Różnica w praktyce sprowadza się do menedżera pakietów. Zamiast <code>pip install</code> używasz <code>conda install</code>, a osobne środowiska tworzysz poleceniem <code>conda create</code>. Conda potrafi sprawnie rozwiązać trudne zależności bibliotek kompilowanych, co bywa kłopotliwe przy czystym pip na Windowsie. Tak wygląda założenie nowego środowiska z pandas i Jupyterem oraz sprawdzenie wersji:</p>
<p>Kopiuj</p>
<pre><code>conda create -n analiza_danych python=3.12 pandas jupyter
conda activate analiza_danych
conda list pandas
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/t_conda.png" alt="Anaconda Prompt: tworzenie środowiska conda z pandas i Jupyterem oraz lista zainstalowanych pakietów" /></p>
<p>conda create zakłada izolowane środowisko i sam dobiera zgodne wersje pakietów. conda list pokazuje, że pandas jest gotowy do pracy.</p>
<p>Z Anacondą dostajesz też <strong>Jupyter Notebook</strong> - interaktywne środowisko, w którym kod pisze się w komórkach uruchamianych po kolei, a wynik (tabela albo wykres) pojawia się od razu pod komórką. To dlatego wszystkie zrzuty w tym artykule wyglądają tak, a nie jak wydruk z terminala. Jupyter uruchomisz z poziomu Anaconda Navigator (graficznego menu dystrybucji) albo poleceniem <code>jupyter notebook</code>:</p>
<p><img src="https://jsystems.pl/new_page_resources/images/pandas/jup_app_top.png" alt="Aplikacja Jupyter Notebook z otwartym notatnikiem analizy sprzedaży w pandas - pasek narzędzi, komórki kodu i tabela wyników" /></p>
<p>Notatnik Jupyter w akcji: po lewej kod, pod nim od razu wynik. Każdą komórkę uruchamiasz osobno, budując analizę krok po kroku.</p>
<p>Które podejście wybrać? Jeśli dopiero zaczynasz i chcesz tylko pobawić się danymi, <code>pip install pandas</code> w zupełności wystarczy. Jeśli planujesz poważniej wejść w analizę danych i uczenie maszynowe, Anaconda oszczędzi Ci sporo instalowania i konfiguracji. Jednej zasady warto pilnować: w obrębie jednego środowiska nie mieszaj pip i conda, bo łatwo wtedy o konflikt wersji.</p>
<h2>Co dalej</h2>
<p>Masz już komplet podstaw: instalacja, wczytywanie danych, filtrowanie, grupowanie, tabele przestawne i wykresy. To fundament, na którym stoi cała analiza danych i uczenie maszynowe w Pythonie. Kolejne naturalne kroki to numpy (obliczenia na tablicach liczb), ładniejsze wykresy w matplotlib i seaborn, a potem scikit-learn - biblioteka do budowania modeli uczenia maszynowego, która dane wejściowe przyjmuje właśnie jako DataFrame z pandas. Gdy dane przestaną mieścić się na jednym komputerze, w grę wchodzą <a href="https://jsystems.pl/blog/show_post/wspolczesne-rozwiazania-big-data-2026/">współczesne rozwiązania big data</a>, w których składnia pandas wraca w narzędziach rozproszonych.</p>
<p>Najlepszy sposób na naukę to własne ćwiczenia. Pobierz plik z danymi, otwórz notatnik i spróbuj odpowiedzieć na własne pytania: które miasto kupuje najdrożej, jak wypada sprzedaż w poszczególnych kanałach, który produkt ma największy udział w swojej kategorii. Każda z tych odpowiedzi to jedno albo dwa polecenia, które już znasz.</p>
<h2>Chcesz przejść od pandas do uczenia maszynowego z trenerem</h2>
<p>Jeśli wolisz uczyć się w uporządkowany sposób i pracować na realnych projektach, prowadzimy szkolenie, które przechodzi całą tę ścieżkę: od podstaw Pythona, przez analizę danych w pandas, aż po pierwsze modele uczenia maszynowego. Kurs ma terminy gwarantowane, więc masz pewność, że grupa się odbędzie.</p>
<p><a href="https://jsystems.pl/szkolenia-python;python_from_zero_do_machine_learning.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post477&amp;utm_content=banner_python_ml"><img src="https://jsystems.pl/new_page_resources/images/other/python_od_a_do_ml.jpg" alt="Baner szkolenia Python od podstaw przez analizę danych do machine learning w JSystems z terminami gwarantowanymi" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-python;python_from_zero_do_machine_learning.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post477&amp;utm_content=link_python_ml">Szkolenie Python od podstaw do machine learning --&gt;</a></p>
<p>NEWSLETTER</p>
<p>Nowe artykuły o Pythonie i danych prosto na maila</p>
<p>Co tydzień wysyłamy świeże poradniki z bloga JSystems. Bez spamu, wypisujesz się jednym kliknięciem.</p>
<p><a href="https://blog.jsystems.pl/subscribe2newsletter/">Zapisz się do newslettera --&gt;</a></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/Bezp%C5%82atny_kurs_Python_od_podstaw/">Bezpłatny kurs Python od podstaw</a></li>
<li><a href="https://jsystems.pl/blog/show_post/Instalacja_Pythona_i_Pycharma/">Instalacja Pythona i PyCharma - konfiguracja środowiska krok po kroku</a></li>
<li><a href="https://jsystems.pl/blog/show_post/langchain_rag_tutorial_python/">LangChain RAG tutorial w Pythonie - krok po kroku</a></li>
<li><a href="https://jsystems.pl/blog/show_post/wspolczesne-rozwiazania-big-data-2026/">Współczesne rozwiązania Big Data 2026 - Spark, lakehouse i streaming</a></li>
<li><a href="https://jsystems.pl/blog/show_post/SQL_vs_NoSQL_wielkie_porownanie_baz_danych_kiedy_wybrac_relacyjna_a_kiedy_nierelacyjna/">SQL vs. NoSQL - wielkie porównanie baz danych</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czy-ai-zastapi-programistow/">Czy AI zastąpi programistów? Oddzielamy dane od marketingu</a></li>
</ul>
<p><img alt="Powiększony zrzut ekranu z artykułu o pandas" /></p>
<hr />
<p><strong>Chcesz pogłębić temat na żywym szkoleniu z trenerem?</strong> Zobacz kurs <a href="https://jsystems.pl/szkolenia-python;python_from_zero_do_machine_learning.szczegoly">Python from zero do Machine Learning</a> w JSystems — termin gwarantowany.</p>
<p>Więcej zrzutów ekranu i przykładów: <a href="https://jsystems.pl/blog/show_post/pandas-python-instalacja-i-analiza-danych/">blog.jsystems.pl</a></p>
]]></content:encoded></item><item><title><![CDATA[ChatGPT Business czy Microsoft Copilot — który wybrać w 2026]]></title><description><![CDATA[Dwa dominujące asystenty AI dla firm, dwie różne filozofie. Zestawiam ChatGPT Business i Microsoft Copilot na realnych kryteriach wyboru.

To samo zadanie w obu narzędziach: gotowy plan biznesowy w ta]]></description><link>https://jsystems.hashnode.dev/chatgpt-business-czy-microsoft-copilot-2026</link><guid isPermaLink="true">https://jsystems.hashnode.dev/chatgpt-business-czy-microsoft-copilot-2026</guid><category><![CDATA[chatgpt]]></category><category><![CDATA[copilot]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 09:24:37 GMT</pubDate><content:encoded><![CDATA[<p>Dwa dominujące asystenty AI dla firm, dwie różne filozofie. Zestawiam ChatGPT Business i Microsoft Copilot na realnych kryteriach wyboru.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_hero.png" alt="Porównanie ChatGPT Business i Microsoft 365 Copilot na dwóch realnych zrzutach: oba narzędzia AI przygotowują gotowy plan biznesowy w formie tabeli" /></p>
<p>To samo zadanie w obu narzędziach: gotowy plan biznesowy w tabeli. Po lewej ChatGPT Business, po prawej Microsoft 365 Copilot. Wszystkie zrzuty w tym artykule pochodzą z naszych firmowych licencji obu narzędzi.</p>
<p>Coraz więcej firm zadaje to samo pytanie: skoro wprowadzamy AI dla całego zespołu, to które narzędzie wybrać - <strong>ChatGPT Business</strong> czy <strong>Microsoft 365 Copilot</strong>. Odpowiedź „to zależy" jest prawdziwa, ale bezużyteczna. Dlatego zamiast powtarzać hasła marketingowe, wykupiliśmy obie licencje firmowe i puściliśmy przez nie te same, typowo biurowe zadania. W tym artykule pokazujemy na realnych zrzutach z obu narzędzi, jak wygląda codzienna praca, praca na dokumentach i danych, sięganie po firmowe pliki, budowanie własnych agentów oraz administracja. Na końcu podpowiadamy, w jakiej firmie który wybór ma więcej sensu.</p>
<p>Jeśli dopiero zaczynasz i chcesz najpierw zrozumieć samo narzędzie od strony firmowej, warto zajrzeć do artykułu <a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">jak wdrożyć ChatGPT Business w firmie</a> oraz do zestawienia najczęstszych obaw przy <a href="https://jsystems.pl/blog/show_post/czy-warto-wdrozyc-microsoft-copilot">wdrożeniu Microsoft Copilot z perspektywy managementu</a>. Tutaj skupiamy się na jednym: bezpośrednim porównaniu obu narzędzi obok siebie.</p>
<h3>Z tego artykułu dowiesz się</h3>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#podejscia">Czym różnią się oba narzędzia</a> u samych podstaw i dla kogo są zaprojektowane</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#czat">Jak wygląda codzienna rozmowa</a> z AI w trybie firmowym po obu stronach</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#dokument">Jak każde z narzędzi tworzy dokument</a> i gdzie ten dokument powstaje</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#office">Jak radzą sobie z arkuszami, Outlookiem i resztą pakietu Office</a></li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#firmowe">Jak sięgają po dane Twojej firmy</a> i czym różnią się te dwa modele</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#agenci">Jak zbudować własnego agenta AI</a> w każdym z narzędzi</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#admin">Jak wygląda administracja, bezpieczeństwo i zgodność z RODO</a></li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#koszty">Ile to kosztuje</a> i dlaczego model rozliczenia jest ważniejszy od samej kwoty</li>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/#decyzja">Co wybrać do swojej firmy</a> w trzech typowych scenariuszach</li>
</ul>
<h2>Dwa różne podejścia do AI w firmie</h2>
<p>Najważniejsze, co trzeba zrozumieć przed jakimkolwiek porównaniem funkcji: to nie są dwa warianty tego samego produktu. To dwie różne filozofie. <strong>ChatGPT Business</strong> to uniwersalny asystent AI, który działa w przeglądarce i aplikacji, niezależnie od tego, z jakich programów korzysta Twoja firma. <strong>Microsoft 365 Copilot</strong> to z kolei asystent wbudowany w pakiet Microsoft 365, czyli w Worda, Excela, Outlooka, Teams i PowerPointa, i to właśnie w środku tych aplikacji jest najsilniejszy.</p>
<p>Z tej jednej różnicy wynika prawie wszystko inne: sposób sięgania po firmowe dane, model licencji, a nawet to, gdzie w ogóle uruchamiasz AI. Dlatego zamiast pytać „które jest lepsze", lepiej pytać „które pasuje do sposobu, w jaki pracuje mój zespół".</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_dwa_podejscia.png" alt="Infografika porównująca dwa podejścia do AI w firmie: ChatGPT Business jako uniwersalny asystent i Microsoft 365 Copilot wbudowany w pakiet Office" /></p>
<p>Dwa różne podejścia: uniwersalny asystent działający wszędzie kontra AI wbudowany w pakiet Microsoft 365.</p>
<p>Zanim wejdziemy w szczegóły, poniższa tabela zbiera najważniejsze różnice w jednym miejscu. Do każdego z tych punktów wrócimy dalej z konkretnym zrzutem z działania.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_matryca.png" alt="Tabela porównawcza ChatGPT Business kontra Microsoft 365 Copilot: gdzie działa, licencja, praca w Office, dane firmowe, agenci, administracja, trenowanie danych i mocne strony" /></p>
<p>Najważniejsze różnice ChatGPT Business i Microsoft 365 Copilot w jednej tabeli. Oba plany domyślnie nie wykorzystują firmowych rozmów do trenowania modeli.</p>
<h2>Codzienna rozmowa: gotowy materiał z jednego polecenia</h2>
<p>Najczęstszy sposób korzystania z AI w firmie to zwykła rozmowa: wpisujesz polecenie, dostajesz gotowy materiał. Oba narzędzia pokazujemy w wersji firmowej - ChatGPT Business oraz licencjonowany Microsoft 365 Copilot - w której rozmowy są objęte firmowymi zasadami i domyślnie nie służą do trenowania modeli. Na razie zostajemy przy zwykłym poleceniu, które nie sięga jeszcze po żadne firmowe pliki.</p>
<p>Postawiliśmy przed jednym i drugim narzędziem to samo zadanie: przygotuj gotowy plan wdrożenia dla zespołu handlowego, w formie tabeli, z etapami, osobami odpowiedzialnymi i ryzykami. Efekt jest w obu przypadkach bardzo podobny - czytelna tabela, którą można od razu wkleić do dokumentu.</p>
<p>ChatGPT Business
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/01_plan_wdrozenia.png" alt="ChatGPT Business przygotowuje tabelaryczny plan wdrożenia z kolumnami etap, działanie, osoba odpowiedzialna i ryzyko" /></p>
<p>ChatGPT Business: gotowy, wieloetapowy plan wdrożenia w tabeli, z osobą odpowiedzialną i ryzykiem przy każdym etapie.</p>
<p>Microsoft 365 Copilot
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/copilot-chat-plan-crm.png" alt="Microsoft 365 Copilot przygotowuje plan wdrożenia systemu CRM w formie tabeli z etapami i osobami odpowiedzialnymi" /></p>
<p>Microsoft 365 Copilot: to samo zadanie i bardzo zbliżony efekt - plan podzielony na etapy z celem i osobą odpowiedzialną.</p>
<p>Jeśli chcesz odtworzyć ten przykład u siebie, to jest dokładne polecenie, które wpisaliśmy w obu narzędziach:</p>
<p>Kopiuj
Jesteś asystentem menedżera sprzedaży. Przygotuj plan wdrożenia nowego systemu CRM w 6-osobowym zespole handlowym: podziel na 5 etapów, dla każdego podaj cel, osobę odpowiedzialną, czas trwania i główne ryzyko. Ujmij to w przejrzystą tabelę, a pod tabelą dodaj 3 rekomendacje na start.</p>
<p>Dla tak ogólnego polecenia różnica między narzędziami jest niewielka - oba dają dobry, gotowy materiał. Prawdziwe różnice zaczynają się dopiero wtedy, gdy przestajesz pisać „z głowy", a zaczynasz pracować na konkretnych dokumentach, danych i firmowych plikach. I właśnie od tego zaczynamy w kolejnych sekcjach.</p>
<h2>Praca nad dokumentem</h2>
<p>Tu zaczyna się pierwsza wyraźna różnica. Oba narzędzia potrafią napisać gotowy dokument, ale robią to w innym miejscu. W ChatGPT Business dokument powstaje w <strong>edytowalnym bloku tekstowym</strong> wewnątrz rozmowy - piszesz polecenie, a obok pojawia się sformatowany tekst, który możesz dalej dopracowywać.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/04_dokument_regulamin.png" alt="ChatGPT Business tworzy w edytowalnym bloku tekstowym gotowy regulamin korzystania z AI w firmie z ponumerowanymi zasadami" /></p>
<p>ChatGPT Business: gotowy regulamin powstaje w edytowalnym bloku obok rozmowy, gotowy do dalszej edycji.</p>
<p>Microsoft 365 Copilot idzie inną drogą. Ten sam dokument powstaje od razu <strong>w Wordzie</strong>, czyli w programie, w którym i tak trafiłby do obiegu w firmie. W praktyce sprowadza się to do jednego pytania: gdzie ten tekst i tak wyląduje. Jeśli finalny dokument będzie w Wordzie, Copilot oszczędza kopiowania i wklejania. Jeśli treść dopiero powstaje albo trafi w wiele różnych miejsc, elastyczny edytor ChatGPT sprawdza się równie dobrze.</p>
<h2>Arkusze, poczta i reszta pakietu Office</h2>
<p>To jest obszar, w którym najmocniej widać, na czym polega przewaga Copilota. Ponieważ jest wbudowany w cały pakiet Microsoft 365, ta sama pomoc AI jest dostępna nie tylko w czacie, ale wprost w Excelu, Outlooku czy PowerPoincie, czyli tam, gdzie zespół i tak pracuje.</p>
<p>Zacznijmy od danych. W arkuszu Copilot policzy wskaźniki, wskaże największe wzrosty albo anomalie i zwróci gotową tabelę z wnioskami, pracując bezpośrednio na danych w Excelu. ChatGPT Business zrobi dokładnie to samo, ale dane trzeba mu najpierw dostarczyć - wgrać plik albo wkleić tabelę do rozmowy. Tu jest sedno różnicy. Copilot ma przewagę, gdy dane już siedzą w firmowym Excelu, a ChatGPT sprawdza się, gdy leżą w różnych formatach i miejscach, bo jest w tym bardzo elastyczny.</p>
<p>Podobnie jest z pocztą. Copilot napisze gotową wiadomość follow-up po spotkaniu, od razu w kilku wariantach tonu do wyboru. Tę samą pomoc masz też bezpośrednio przy pisaniu maila w Outlooku, a przy budowaniu slajdów w PowerPoincie.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/copilot-outlook-followup.png" alt="Microsoft 365 Copilot pisze gotową wiadomość follow-up po spotkaniu sprzedażowym w dwóch wariantach: konkretnym sprzedażowym i bardziej partnerskim" /></p>
<p>Copilot pisze gotową wiadomość follow-up po spotkaniu, od razu w dwóch wariantach tonu do wyboru.</p>
<p>ChatGPT Business też napisze maila i przygotuje strukturę prezentacji - i zrobi to bardzo dobrze - ale wynik dostajesz w oknie rozmowy i musisz go przenieść do Outlooka czy PowerPointa. Różnica nie jest w jakości tekstu, tylko w liczbie kroków. Jeśli Twój zespół cały dzień pracuje w pakiecie Office, oszczędność tych kroków w skali miesiąca robi się odczuwalna.</p>
<p>Jeśli chcesz, żeby zespół realnie wyciskał z tego pakietu maksimum, sprawdź nasze <a href="https://jsystems.pl/szkolenia-ai;copilot365.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=link_copilot365">Szkolenie Copilot w Office 365: praca z AI w Wordzie, Excelu, Outlooku i Teams</a>. Ma terminy gwarantowane.</p>
<h2>Sięganie po dane Twojej firmy</h2>
<p>Sama rozmowa z AI to jedno, ale prawdziwą wartość w firmie daje dopiero odpowiadanie na podstawie <strong>firmowych dokumentów</strong>, a nie ogólnej wiedzy z internetu. Chodzi o podpięcie asystenta pod realne źródła firmy: pliki, pocztę, systemy (po angielsku nazywa się to grounding). I tu oba narzędzia idą zupełnie inną drogą.</p>
<p>Microsoft 365 Copilot ma tę przewagę, że firmowe dane już w nim są. Ten tryb pracy nazywa się w Copilocie <strong>Work IQ</strong>. Gdy jest włączony, asystent sięga po firmowe pliki, pocztę i spotkania z Microsoft 365 obok wiedzy z sieci. Gdy jest wyłączony, odpowiada wyłącznie na podstawie internetu. Skoro dokumenty leżą na SharePoincie i OneDrive, a rozmowy w Teams i w poczcie, Copilot z włączonym Work IQ po prostu po nie sięga, z zachowaniem uprawnień danego pracownika. W praktyce wpisujesz w rozmowie znak ukośnika i wybierasz konkretne źródło: plik, spotkanie, osobę.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/copilot-grounding-odwolania.png" alt="W Microsoft 365 Copilot znak ukośnika otwiera listę firmowych źródeł: pliki, kontakty, spotkania, adresy e-mail, czaty, kanały i witryny" /></p>
<p>W Copilocie wpisanie ukośnika otwiera firmowe źródła: pliki, kontakty, spotkania, pocztę czy witryny. Asystent widzi tylko to, do czego dany pracownik ma dostęp.</p>
<p>ChatGPT Business dochodzi do tego samego inną drogą. Nie zakłada, że firma siedzi w jednym ekosystemie, więc źródła podpinasz przez <strong>konektory</strong>, czyli gotowe wtyczki do popularnych systemów (dysków, poczty, CRM), a bardziej zaawansowane integracje przez wspólny standard łączenia AI z danymi. Administrator decyduje, które konektory są włączone. Dzięki temu ChatGPT sprawdza się także w firmach, które nie stoją na Microsofcie. Więcej o samym mechanizmie łączenia AI z firmowymi systemami piszemy w artykule o tym, <a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">czym jest protokół MCP i dlaczego zmienia AI w firmach</a>.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_grounding.gif" alt="Animacja pokazująca dwa modele sięgania po dane firmy: Copilot przez pakiet Microsoft 365 z uprawnieniami, ChatGPT przez konektory włączane przez administratora" /></p>
<p>Dwa modele docierania do firmowych dokumentów: Copilot idzie przez pakiet Microsoft 365 i uprawnienia, ChatGPT przez konektory włączane przez administratora.</p>
<h2>Własne agenty AI</h2>
<p>Oba narzędzia pozwalają zbudować własnego <strong>agenta AI</strong>, czyli asystenta o wąskiej specjalizacji: takiego, który zna procedury firmy, trzyma się ustalonego tonu i odpowiada tylko na podstawie wgranych materiałów. W ChatGPT Business robisz to jako <strong>Custom GPT</strong>: nadajesz nazwę, opis, instrukcje i wgrywasz wiedzę, a potem publikujesz go dla całej organizacji. Cały ten proces krok po kroku, bez pisania kodu, rozkładamy na części w osobnym artykule o <a href="https://jsystems.pl/blog/show_post/wlasny-gpt-dla-firmy-asystent-wiedzy-firmowej">budowie własnego GPT jako asystenta wiedzy firmowej</a>.</p>
<p>ChatGPT Business
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/05_custom_gpt.png" alt="Kreator Custom GPT w ChatGPT Business: pola nazwa, opis, instrukcje, przykładowe pytania startowe i miejsce na wgranie firmowej wiedzy" /></p>
<p>ChatGPT Business: własny asystent (Custom GPT) składasz z instrukcji i firmowej wiedzy, bez pisania kodu, i publikujesz dla zespołu.</p>
<p>Microsoft 365 Copilot
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/copilot-agenci-sklep.png" alt="Sklep z agentami w Microsoft 365 Copilot: lista własnych agentów firmy oraz gotowe agenty przygotowane przez Microsoft" /></p>
<p>Microsoft 365 Copilot: agentów tworzysz i uruchamiasz w ramach pakietu, obok gotowych agentów Microsoftu, blisko firmowych danych i Teams.</p>
<p>Różnica jest znów w tym, gdzie ten agent potem żyje. Custom GPT działa wszędzie tam, gdzie ChatGPT, czyli w przeglądarce, niezależnie od reszty narzędzi. Agent zbudowany po stronie Microsoftu naturalnie wpina się w Teams i w firmowe dane w pakiecie 365. Jeśli chcesz zrozumieć, ile taki asystent realnie zmienia w codziennej pracy, zebraliśmy <a href="https://jsystems.pl/blog/show_post/10-zastosowan-agentow-ai-w-polskich-firmach">konkretne zastosowania agentów AI w polskich firmach</a>. Do każdego rodzaju agenta prowadzi tam osobny tutorial krok po kroku, od pomysłu do wdrożenia.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_agenci.png" alt="Infografika porównująca budowanie agentów AI: Custom GPT w ChatGPT Business kontra Copilot Studio w Microsoft 365" /></p>
<p>Custom GPT kontra Copilot Studio: dwie drogi do własnego agenta. Główna różnica to miejsce, w którym agent potem działa.</p>
<p>Jeśli chcesz nauczyć zespół budować takich asystentów samodzielnie, poprowadzi Was przez to nasze <a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=link_agenci_ai">Szkolenie Tworzenie agentów AI: Twoi wirtualni asystenci</a>. Ma terminy gwarantowane.</p>
<h2>Administracja, bezpieczeństwo i RODO</h2>
<p>Dla firmy to często najważniejsza część, bo decyduje o tym, czy w ogóle wolno wpuścić narzędzie do organizacji. Dobra wiadomość jest taka, że w planach firmowych obu narzędzi obowiązuje ta sama, kluczowa zasada: <strong>rozmowy firmowe domyślnie nie służą do trenowania modeli</strong>. To fundamentalna różnica względem darmowych, prywatnych kont.</p>
<p>Po stronie ChatGPT Business dostajesz osobny panel administratora: zarządzasz członkami, rolami, dostępem i widzisz analitykę korzystania. To jedno miejsce, w którym firma ustala, kto i na jakich zasadach korzysta z AI.</p>
<p>ChatGPT Business
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/r_panel_uprawnienia.png" alt="Panel administratora ChatGPT Business z listą uprawnień, którymi firma steruje dostępem do funkcji dla pracowników" /></p>
<p>ChatGPT Business: panel administratora z rolami i uprawnieniami. Firma sama decyduje, kto ma dostęp do których funkcji.</p>
<p>Microsoft 365 Copilot
<img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/12-admin-licencje-br.png" alt="Panel licencji w centrum administracyjnym Microsoft 365: przypisane licencje Microsoft 365 Copilot i Microsoft 365 Business Standard w organizacji" /></p>
<p>Microsoft 365 Copilot: dostępem firma zarządza w centrum administracyjnym Microsoft 365 - tu widać przypisane licencje Copilota obok reszty pakietu Office.</p>
<p>Największa różnica dotyczy tego, skąd bierze się zgodność i bezpieczeństwo. Copilot <strong>dziedziczy</strong> zabezpieczenia i ustawienia zgodności całego środowiska Microsoft 365, które firma zwykle ma już wdrożone. ChatGPT Business wnosi <strong>własną</strong> umowę powierzenia danych i własne ustawienia prywatności, niezależne od pakietu Office. Obie drogi prowadzą do celu, ale w pierwszej opierasz się na tym, co już masz, a w drugiej dokładasz osobny, samodzielny element.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_bezpieczenstwo.png" alt="Infografika bezpieczeństwa i zgodności z RODO dla ChatGPT Business i Microsoft 365 Copilot: brak trenowania na danych, szyfrowanie, umowa powierzenia, kontrola dostępu i logi" /></p>
<p>Wspólne gwarancje obu narzędzi i kluczowa różnica: Copilot dziedziczy zgodność z pakietu Microsoft 365, ChatGPT Business wnosi własną.</p>
<h2>Ile to kosztuje i za co płacisz</h2>
<p>Przy kosztach najważniejsza jest nie sama kwota, tylko model rozliczenia. <strong>ChatGPT Business</strong> to samodzielna licencja, którą kupujesz za stanowisko, od dwóch stanowisk w górę, i która nie wymaga żadnej innej subskrypcji. <strong>Microsoft 365 Copilot</strong> jest natomiast dodatkiem, czyli dopłatą doliczaną za stanowisko do licencji Microsoft 365, którą firma już musi mieć.</p>
<p>W praktyce oznacza to jedno: żeby uczciwie porównać koszty, po stronie Copilota trzeba doliczyć to, co i tak płacisz za pakiet Office. Jeśli firma już od lat siedzi na Microsoft 365, ta baza jest kosztem, który i tak ponosisz, więc realna różnica robi się mniejsza. Jeśli nie korzystasz z pakietu Microsoftu, ChatGPT Business bywa prostszym i tańszym wejściem, bo nie ciągnie za sobą całej subskrypcji.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_cennik.png" alt="Infografika modelu licencjonowania: ChatGPT Business jako samodzielna licencja za stanowisko kontra Microsoft 365 Copilot jako dodatek do pakietu Office" /></p>
<p>Samodzielna licencja kontra dodatek do pakietu. Ceny podajemy orientacyjnie - zawsze warto sprawdzić aktualny cennik u producenta.</p>
<h2>Co wybrać do swojej firmy</h2>
<p>Po przejściu przez wszystkie te obszary odpowiedź robi się dużo konkretniejsza niż „to zależy". Najprostsze pytanie, od którego warto zacząć, brzmi: czy cały zespół pracuje na co dzień w Microsoft 365. Jeśli tak, Copilot ma naturalną przewagę, bo wchodzi tam, gdzie ludzie już są. Jeśli nie, ChatGPT Business daje większą swobodę i mniej zależności.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/biz_vs_copilot/g_decyzja.png" alt="Infografika decyzyjna: kiedy wybrać ChatGPT Business, kiedy Microsoft 365 Copilot, a kiedy warto rozważyć oba narzędzia naraz" /></p>
<p>Trzy typowe scenariusze i to, który wybór ma w nich najwięcej sensu. Coraz częściej najlepszą odpowiedzią okazuje się rozsądna mieszanka obu.</p>
<p>Warto też pamiętać, że to nie musi być wybór „albo-albo". Wiele firm decyduje się na oba narzędzia naraz i dzieli je według potrzeb działów: Copilot do codziennej produktywności w pakiecie Office, a ChatGPT do specjalistycznej pracy, researchu i budowania agentów. Jeśli budżet na to pozwala, taka mieszanka często daje najwięcej, bo gra mocnymi stronami każdego z narzędzi zamiast na siłę wciskać wszystko w jedno.</p>
<p>Niezależnie od tego, które narzędzie wybierzesz, największą różnicę i tak robi nie sama licencja, tylko to, czy ludzie potrafią z niej korzystać. Dobrze poprowadzone szkolenie zwraca się tu szybciej niż jakakolwiek dopłata do planu, bo zamienia „mamy AI w firmie" w realną oszczędność kilku godzin dziennie na osobę.</p>
<p><a href="https://jsystems.pl/szkolenia-ai;copilot365.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=banner_copilot365"><img src="https://jsystems.pl/new_page_resources/images/other/copilot365.jpg" alt="Baner szkolenia Copilot w Office 365 w JSystems z terminami gwarantowanymi" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-ai;copilot365.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=link_copilot365">Szkolenie Copilot w Office 365 --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<p><a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=banner_agenci_ai"><img src="https://jsystems.pl/new_page_resources/images/other/agenci_ai.jpg" alt="Baner szkolenia Tworzenie agentów AI w JSystems z terminami gwarantowanymi" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-ai;agenci_ai.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=link_agenci_ai">Szkolenie Tworzenie agentów AI --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post_chatgpt_business_vs_copilot&amp;utm_content=dofinansowanie2">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/chatgpt-business-wdrozenie-w-firmie">ChatGPT Business w firmie: wdrożenie, panel administratora i agenci AI</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czy-warto-wdrozyc-microsoft-copilot">Czy warto wdrażać Microsoft Copilot - najczęstsze wątpliwości managementu</a></li>
<li><a href="https://jsystems.pl/blog/show_post/jak-wycisnac-100-procent-z-chatgpt">Jak wycisnąć 100% z ChatGPT - tryby, projekty, własne GPT i agenci</a></li>
<li><a href="https://jsystems.pl/blog/show_post/10-zastosowan-agentow-ai-w-polskich-firmach">10 zastosowań agentów AI w polskich firmach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/mcp-model-context-protocol-ai">MCP (Model Context Protocol) - czym jest i dlaczego zmienia AI w firmach</a></li>
<li><a href="https://jsystems.pl/blog/show_post/wlasny-rag-bez-kodowania-4-sposoby-dla-nietech">Własny RAG bez kodowania - asystent AI z wiedzą Twojej firmy</a></li>
</ul>
<p><img alt="Powiększony zrzut z artykułu o ChatGPT Business i Microsoft Copilot" /></p>
<hr />
<p><strong>Chcesz pogłębić temat na żywym szkoleniu z trenerem?</strong> Zobacz kurs <a href="https://jsystems.pl/szkolenia-ai;ai_w_codziennej_pracy.szczegoly">Sztuczna inteligencja w codziennej pracy</a> w JSystems — termin gwarantowany.</p>
<p>Więcej zrzutów ekranu i przykładów: <a href="https://jsystems.pl/blog/show_post/chatgpt-business-vs-microsoft-copilot/">blog.jsystems.pl</a></p>
]]></content:encoded></item><item><title><![CDATA[Docker od podstaw — jak działa i jak zacząć go używać]]></title><description><![CDATA[Kontenery, obrazy, Dockerfile — sporo pojęć na start. Rozkładam Dockera na czynniki pierwsze, na konkretnych przykładach.

obraz zbudowany raz
Laptop programisty
to samo działa
Serwer / produkcja
to s]]></description><link>https://jsystems.hashnode.dev/docker-od-podstaw-jak-dziala-jak-zaczac</link><guid isPermaLink="true">https://jsystems.hashnode.dev/docker-od-podstaw-jak-dziala-jak-zaczac</guid><category><![CDATA[Docker]]></category><category><![CDATA[Devops]]></category><category><![CDATA[containers]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 09:19:35 GMT</pubDate><content:encoded><![CDATA[<p>Kontenery, obrazy, Dockerfile — sporo pojęć na start. Rozkładam Dockera na czynniki pierwsze, na konkretnych przykładach.</p>
<p><img src="https://jsystems.pl/static/images/logo-colored.svg" alt="JSystems" /></p>
<p>obraz zbudowany raz</p>
<p>Laptop programisty
to samo działa</p>
<p>Serwer / produkcja
to samo działa</p>
<p>Chmura
to samo działa</p>
<p>Zbuduj raz, uruchom wszędzie: ten sam obraz działa identycznie na każdym środowisku.</p>
<p>Sedno Dockera w jednym obrazku. Aplikację pakujemy w jeden obraz, a potem uruchamiamy go bez zmian na laptopie, na serwerze i w chmurze. Koniec z tłumaczeniem, że „u mnie działało".</p>
<p>Docker to jedno z tych pojęć, które pada na każdej rozmowie o nowoczesnym wytwarzaniu oprogramowania, a mimo to wielu osobom trudno powiedzieć wprost, czym właściwie jest. W tym przewodniku wyjaśnimy to od podstaw: czym jest konteneryzacja, czym kontener różni się od maszyny wirtualnej, a potem krok po kroku uruchomimy pierwszy kontener, zbudujemy własny obraz i połączymy kilka usług w jedną aplikację. Wszystkie przykłady uruchomiliśmy naprawdę, więc na zrzutach widzisz autentyczne wyniki z terminala i z przeglądarki, a nie rysunki poglądowe.</p>
<p>Z tego artykułu dowiesz się:</p>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#czym-jest">Czym jest Docker i konteneryzacja oraz jaki problem realnie rozwiązują</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#czym-jest">Czym kontener różni się od maszyny wirtualnej i dlaczego jest tak lekki</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#pojecia">Co znaczą słowa obraz, kontener, rejestr, Dockerfile i wolumen</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#instalacja">Jak uruchomić pierwszy kontener i gotową aplikację jedną komendą</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#wlasny-obraz">Jak zbudować własny obraz z pliku Dockerfile i połączyć usługi przez Docker Compose</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/#komendy">Jakie polecenia wystarczą na co dzień i jakich błędów początkujących unikać</a></li>
</ul>
<h2>Czym właściwie jest Docker</h2>
<p><strong>Docker to narzędzie do konteneryzacji, czyli pakowania aplikacji razem ze wszystkim, czego potrzebuje do działania (kodem, bibliotekami, ustawieniami), w jeden przenośny obraz, który uruchamia się identycznie na każdym komputerze.</strong> Taki zapakowany, działający pakiet nazywamy kontenerem (ang. container). Zamiast instalować aplikację i ręcznie doinstalowywać dziesiątki zależności na każdym serwerze, budujemy obraz raz i uruchamiamy go wszędzie tak samo.</p>
<p>Najprostsza analogia to kontener transportowy. Zanim upowszechniły się stalowe kontenery, każdy towar pakowano i przeładowywano inaczej, a połowa pracy w porcie polegała na kombinowaniu, jak to wszystko poukładać. Znormalizowany kontener zmienił zasady: nie ma znaczenia, co jest w środku, bo z zewnątrz każdy wygląda tak samo i pasuje na każdy statek, ciężarówkę i dźwig. Docker robi dokładnie to samo z oprogramowaniem. Twoja aplikacja może być w Pythonie, Javie czy Node.js, ale opakowana w kontener wygląda z zewnątrz identycznie i uruchamia się tak samo na laptopie, na serwerze i w chmurze.</p>
<p>Żeby zrozumieć, dlaczego to takie przełomowe, trzeba zobaczyć, czym kontener różni się od maszyny wirtualnej (ang. virtual machine), bo to z nią najczęściej się go myli.</p>
<p><img src="https://jsystems.pl/static/images/logo-colored.svg" alt="JSystems" /></p>
<h4>Maszyna wirtualna</h4>
<p>App Abiblioteki</p>
<p>App Bbiblioteki</p>
<p>App Cbiblioteki</p>
<p>System gościa</p>
<p>System gościa</p>
<p>System gościa</p>
<p>Hypervisor</p>
<p>System gospodarza</p>
<p>Sprzęt (serwer)</p>
<p>Każda aplikacja niesie własny, pełny system operacyjny. Stąd gigabajty miejsca i start liczony w minutach.</p>
<h4>Kontenery (Docker)</h4>
<p>App Abiblioteki</p>
<p>App Bbiblioteki</p>
<p>App Cbiblioteki</p>
<p>Docker Engine (silnik)</p>
<p>Jedno wspólne jądro systemu gospodarza</p>
<p>Sprzęt (serwer)</p>
<p>Kontenery współdzielą jądro gospodarza i niosą tylko aplikację z zależnościami. Stąd megabajty miejsca i start w sekundy.</p>
<p>Maszyna wirtualna emuluje cały komputer, więc każda z nich dźwiga własny system operacyjny. Kontenery współdzielą jądro (ang. kernel, rdzeń systemu) gospodarza, dlatego są znacznie lżejsze i szybsze. To jedna z głównych przyczyn popularności Dockera.</p>
<p>Różnica jest fundamentalna. Maszyna wirtualna udaje cały, osobny komputer razem z własnym systemem operacyjnym, więc typowo waży kilka gigabajtów i uruchamia się w minuty. Kontener nie udaje komputera. Współdzieli jądro systemu gospodarza i dokłada tylko to, co odróżnia jedną aplikację od drugiej, dlatego waży zwykle megabajty i startuje w sekundy. Za chwilę zobaczymy to na prawdziwych liczbach: uruchomione przez nas kontenery zajmowały pojedyncze dziesiątki megabajtów pamięci.</p>
<p>Warto od razu rozwiać jedno nieporozumienie. Docker <strong>nie jest maszyną wirtualną</strong> i <strong>nie jest wirtualizacją w klasycznym sensie</strong>. To mechanizm izolacji procesów wbudowany w system: kontener to zwykły proces działający na gospodarzu, tyle że odgrodzony od reszty tak, że widzi tylko swój własny, mały świat. Dodajmy jeszcze, że Docker to nie to samo co Kubernetes, o którym zapewne słyszałeś. Docker uruchamia pojedyncze kontenery, a Kubernetes zarządza tysiącami kontenerów na wielu serwerach naraz. Docker jest fundamentem, Kubernetes nadbudową. Naukę zaczyna się od Dockera, a różnice między nimi i moment, w którym warto sięgnąć po orkiestrację, rozwijamy w osobnym porównaniu <a href="https://jsystems.pl/blog/show_post/kubernetes-vs-docker-roznice/">Kubernetes vs Docker - czym się różnią i kiedy co wybrać</a>.</p>
<h2>Problem, który Docker rozwiązuje: koniec z „u mnie działa"</h2>
<p>Najłatwiej docenić Dockera, przypominając sobie ból, który usuwa. Prawie każdy, kto pisał lub wdrażał oprogramowanie, zna zdanie „przecież u mnie działa". Aplikacja chodzi bez zarzutu na komputerze programisty, ale po przeniesieniu na serwer testowy albo produkcyjny nagle przestaje. Powód jest zawsze podobny: gdzieś indziej jest inna wersja języka, brakuje jakiejś biblioteki systemowej, inny jest plik konfiguracyjny albo zmienna środowiskowa. Im więcej takich drobnych różnic, tym więcej godzin schodzi na szukanie, dlaczego „to samo" zachowuje się inaczej.</p>
<p><img src="https://jsystems.pl/static/images/logo-colored.svg" alt="JSystems" /></p>
<h4>Bez Dockera</h4>
<p>Laptop: Python 3.12, wszystkie biblioteki na miejscu działa</p>
<p>Serwer testowy: Python 3.9, brakuje biblioteki nie startuje</p>
<p>Produkcja: inna konfiguracja, inna zmienna błąd na wdrożeniu</p>
<p>Każde środowisko trochę inne. „U mnie działa" kontra „na serwerze nie". Godziny na diagnozę.</p>
<h4>Z Dockerem</h4>
<p>Laptop: ten sam obraz działa</p>
<p>Serwer testowy: ten sam obraz działa</p>
<p>Produkcja: ten sam obraz działa</p>
<p>Środowisko podróżuje razem z aplikacją w obrazie. Wszędzie identyczne, bo to dosłownie ten sam pakiet.</p>
<p>Docker likwiduje różnice między środowiskami u samego źródła. Zamiast konfigurować każdy serwer osobno, zamykamy aplikację i jej otoczenie w jednym obrazie, który wszędzie zachowuje się tak samo.</p>
<p>Docker rozwiązuje ten problem w najprostszy możliwy sposób: skoro kłopotem są różnice w środowisku, to pakujemy środowisko razem z aplikacją. Obraz zawiera nie tylko nasz kod, ale też konkretną wersję języka, dokładnie te biblioteki, których używamy, i całą konfigurację. Kiedy uruchamiamy go na serwerze, dostajemy dokładnie to samo, co działało na laptopie. Nie „prawie to samo", tylko dosłownie ten sam pakiet.</p>
<h2>Podstawowe pojęcia: obraz, kontener, rejestr, Dockerfile</h2>
<p>Zanim przejdziemy do praktyki, uporządkujmy pięć słów, które będą wracać w każdej komendzie. Bez nich dokumentacja Dockera wygląda jak żargon, a z nimi wszystko układa się w logiczną całość.</p>
<p><img src="https://jsystems.pl/static/images/logo-colored.svg" alt="JSystems" /></p>
<p>Obraz (image)</p>
<p>Niezmienny szablon aplikacji, coś jak plik instalacyjny. Zawiera kod, biblioteki i konfigurację. Sam z siebie nic nie robi, dopóki go nie uruchomimy.</p>
<p>Kontener (container)</p>
<p>Działająca instancja obrazu, czyli obraz „ożywiony" i uruchomiony. Z jednego obrazu można odpalić wiele kontenerów, tak jak z jednego pliku instalacyjnego wiele kopii programu.</p>
<p>Rejestr (registry)</p>
<p>Magazyn gotowych obrazów w sieci. Najpopularniejszy to Docker Hub. Stamtąd pobieramy obrazy poleceniem pull i tam publikujemy własne poleceniem push.</p>
<p>Dockerfile</p>
<p>Przepis na zbudowanie obrazu, zapisany jako zwykły plik tekstowy z listą kroków. To on sprawia, że obraz jest powtarzalny: każdy zbuduje z niego dokładnie to samo.</p>
<p>Wolumen (volume)</p>
<p>Miejsce na dane, które ma przetrwać dłużej niż kontener. Kontenery są ulotne, więc wszystko, co ma zostać (baza danych, pliki), trzymamy w wolumenie.</p>
<p>Demon (Docker daemon)</p>
<p>Usługa działająca w tle, która faktycznie buduje obrazy i uruchamia kontenery. My wydajemy jej polecenia komendą docker, a ona wykonuje całą pracę.</p>
<p>Sześć pojęć, które wystarczą, żeby swobodnie czytać dokumentację Dockera. Cała reszta to warianty tych podstaw. Zapamiętaj zwłaszcza różnicę obraz kontra kontener, bo to najczęstsze źródło nieporozumień.</p>
<p>Zależność między nimi jest prosta i warto ją zapamiętać jako jedno zdanie: z <strong>Dockerfile</strong> budujemy <strong>obraz</strong>, obraz przechowujemy w <strong>rejestrze</strong>, a po uruchomieniu obrazu powstaje <strong>kontener</strong>, który swoje trwałe dane trzyma w <strong>wolumenie</strong>. Mając te pojęcia w głowie, możemy wreszcie coś uruchomić.</p>
<h2>Instalacja i pierwszy kontener</h2>
<p>Na komputer osobisty najprościej zainstalować <a href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a>, dostępny na Windows, macOS i Linux. To jeden instalator, który dokłada wszystko, czego potrzeba: silnik Dockera, narzędzia wiersza poleceń i prosty panel graficzny. Na serwerze zwykle instaluje się sam silnik (ang. Docker Engine) z repozytorium systemu. Po instalacji sprawdzamy, czy wszystko gra, pytając Dockera o wersję, a potem uruchamiamy tradycyjny pierwszy kontener testowy o nazwie <code>hello-world</code>.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_hello.png" alt="Terminal: docker --version pokazuje Docker 29.2.1, a docker run hello-world pobiera obraz i wypisuje Hello from Docker" /></p>
<p>Pierwszy kontener w akcji. Ponieważ obrazu hello-world nie było jeszcze na dysku, Docker sam pobrał go z Docker Hub (linie „Pulling", „Pull complete"), utworzył z niego kontener i uruchomił. Wypisany komunikat to dowód, że cała maszyneria Dockera działa poprawnie.</p>
<p>To pozornie błahe polecenie pokazuje w miniaturze cały mechanizm Dockera. Napisaliśmy tylko <code>docker run hello-world</code>, a silnik po kolei: sprawdził, czy ma obraz lokalnie, a gdy go nie znalazł, pobrał go z rejestru, następnie utworzył z niego kontener i wykonał zaszytą w nim komendę. Dokładnie ten sam schemat zadziała za chwilę dla prawdziwego serwera WWW, tyle że zamiast wypisać tekst, kontener zacznie obsługiwać ruch sieciowy.</p>
<p><strong>Zapamiętaj wzorzec:</strong> <code>docker run &lt;nazwa-obrazu&gt;</code> to najważniejsze polecenie Dockera. Jeśli obrazu nie ma lokalnie, Docker sam go pobierze. Cała reszta to dokładanie do tego opcji, na przykład numeru portu albo nazwy.</p>
<h2>Obrazy i kontenery w praktyce</h2>
<p>Uruchommy teraz coś użytecznego: serwer WWW nginx, jeden z najpopularniejszych obrazów na świecie. Najpierw obejrzymy, jakie obrazy mamy już na dysku, a potem uruchomimy nginx tak, żeby był dostępny w przeglądarce. Kluczowe będą dwie opcje polecenia <code>run</code>: <code>-d</code> uruchamia kontener w tle (ang. detached), a <code>-p</code> łączy port na naszym komputerze z portem wewnątrz kontenera.</p>
<pre><code># Uruchom nginx w tle; port 8088 na naszym komputerze -&gt; port 80 w kontenerze
PS C:\demo&gt; docker run -d -p 8088:80 --name web nginx:alpine
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_images.png" alt="Terminal: docker images pokazuje obrazy nginx, redis i hello-world, docker run uruchamia nginx, a docker ps pokazuje działający kontener web na porcie 8088" /></p>
<p>Trzy najczęściej używane polecenia w jednym miejscu. <code>docker images</code> pokazuje obrazy na dysku (zwróć uwagę, jak lekki jest nginx w wariancie alpine), <code>docker run</code> uruchamia kontener, a <code>docker ps</code> wypisuje to, co aktualnie działa, wraz z mapowaniem portów.</p>
<p>Warto zwrócić uwagę na dwie rzeczy. Po pierwsze, dopisek <code>:alpine</code> po nazwie obrazu to tag, czyli wskazanie konkretnego wariantu. Wariant alpine jest zbudowany na wyjątkowo lekkiej dystrybucji Linuksa i dlatego zajmuje kilkadziesiąt megabajtów zamiast kilkuset. Po drugie, <code>docker ps</code> pokazał kolumnę z portami w postaci <code>0.0.0.0:8088-&gt;80</code>. To właśnie efekt opcji <code>-p</code>: cokolwiek wejdzie na port 8088 naszego komputera, trafi na port 80 wewnątrz kontenera, gdzie nasłuchuje nginx. Sprawdźmy to w przeglądarce.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/web_nginx.png" alt="Przeglądarka pod adresem localhost:8088 pokazuje stronę powitalną Welcome to nginx serwowaną przez kontener" /></p>
<p>Pod adresem localhost:8088 odpowiada nginx uruchomiony w kontenerze. Nie instalowaliśmy żadnego serwera WWW na swoim komputerze, nie konfigurowaliśmy niczego ręcznie. Jedno polecenie i działający serwer, który równie łatwo usuniemy, nie zostawiając po sobie śladu.</p>
<h3>Zaglądanie do środka i sprzątanie</h3>
<p>Skoro kontener działa, możemy zajrzeć do jego wnętrza, nie zatrzymując go. Polecenie <code>docker logs</code> pokazuje, co kontener wypisał, a <code>docker exec</code> pozwala uruchomić polecenie w środku działającego kontenera, na przykład sprawdzić wersję nginx albo podejrzeć, jaki system jest w środku. Jeśli praca w wierszu poleceń to dla Ciebie świeży temat, warto najpierw oswoić sam terminal - pokazujemy to w artykule <a href="https://jsystems.pl/blog/show_post/Linux_w_codziennej_pracy_programisty_dlaczego_warto_znac_terminal_Bash/">Linux w codziennej pracy programisty - dlaczego warto znać terminal</a>.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_exec.png" alt="Terminal: docker logs pokazuje logi nginx z wpisem GET 200, docker exec sprawdza wersję nginx i zawartość pliku os-release w kontenerze" /></p>
<p>Zaglądamy do działającego kontenera. <code>docker logs</code> wyświetla jego dziennik (widać wpis z naszej wizyty w przeglądarce, kod 200), a <code>docker exec</code> uruchamia polecenia w jego wnętrzu. Kontener okazuje się miniaturowym Linuksem (Alpine) z jednym zadaniem: obsłużyć nginx.</p>
<p>Gdy skończymy, kontener zatrzymujemy poleceniem <code>docker stop web</code> i usuwamy przez <code>docker rm web</code> (albo od razu <code>docker rm -f web</code>). Po usunięciu nie zostaje żaden ślad: żadnych rozsianych po systemie plików, wpisów w rejestrze usług czy zależności. To jedna z najbardziej wyzwalających cech Dockera. Można próbować, psuć i zaczynać od nowa bez obawy, że zaśmiecimy sobie komputer.</p>
<h2>Budowanie własnego obrazu z pliku Dockerfile</h2>
<p>Uruchamianie cudzych obrazów to dopiero połowa Dockera. Prawdziwa moc pojawia się, gdy pakujemy w obraz własną aplikację. Zrobimy to na malutkiej aplikacji webowej w Pythonie (framework Flask), która wyświetla powitanie i pokazuje, w jakim kontenerze działa. Najpierw sam kod aplikacji:</p>
<pre><code>import os, platform
from flask import Flask

app = Flask(__name__)

@app.route("/")
def strona_glowna():
    return f"""
      &lt;h1&gt;Witaj z wnetrza kontenera Docker!&lt;/h1&gt;
      &lt;p&gt;Nazwa hosta (kontenera): {os.uname().nodename}&lt;/p&gt;
      &lt;p&gt;Python w kontenerze: {platform.python_version()}&lt;/p&gt;
    """

if __name__ == "__main__":
    # 0.0.0.0 - nasluchuj na wszystkich interfejsach, inaczej port
    # nie bedzie widoczny spoza kontenera
    app.run(host="0.0.0.0", port=5000)
</code></pre>
<p>Aplikacja korzysta tylko z frameworka Flask, więc plik <code>requirements.txt</code> ma dosłownie jedną linię. Przypięta wersja (<code>==3.0.3</code>) sprawia, że obraz za każdym razem zbuduje się identycznie:</p>
<pre><code>flask==3.0.3
</code></pre>
<p>Teraz najważniejsze: <strong>Dockerfile</strong>, czyli przepis, według którego Docker zbuduje obraz z naszą aplikacją. Każda linia to jeden krok. Kolejność nie jest przypadkowa i za chwilę wyjaśnimy, dlaczego zależności instalujemy przed skopiowaniem kodu.</p>
<pre><code># 1. Obraz bazowy - lekki Python. Na nim budujemy nasz wlasny obraz.
FROM python:3.12-slim

# 2. Katalog roboczy wewnatrz kontenera. Kolejne kroki dzialaja wzgledem niego.
WORKDIR /app

# 3. Najpierw sama lista zaleznosci. Docker zapamieta ten krok w cache
#    i nie bedzie instalowal pakietow od nowa przy kazdej zmianie kodu.
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. Dopiero teraz kopiujemy kod aplikacji.
COPY app.py .

# 5. Informujemy, ze aplikacja w kontenerze nasluchuje na porcie 5000.
EXPOSE 5000

# 6. Polecenie uruchamiane przy starcie kontenera.
CMD ["python", "app.py"]
</code></pre>
<p>Te trzy pliki muszą leżeć <strong>obok siebie w jednym katalogu</strong> projektu (u nas nazwaliśmy go <code>moja-apka</code>). To dokładnie wszystko, czego Docker potrzebuje, żeby zbudować obraz:</p>
<p>moja-apka/</p>
<p>├─app.pykod aplikacji (Flask)</p>
<p>├─requirements.txtlista zależności (flask==3.0.3)</p>
<p>└─Dockerfileprzepis na obraz, nazwa pliku bez rozszerzenia</p>
<p>Nazwy plików muszą być dokładnie takie: <code>Dockerfile</code> pisany wielką literą i bez żadnego rozszerzenia, a <code>requirements.txt</code> to ta sama nazwa, którą podaliśmy w instrukcji <code>COPY</code>. Teraz w terminalu wchodzimy do katalogu <code>moja-apka</code> i stamtąd budujemy obraz jednym poleceniem. Kropka na końcu oznacza „buduj z bieżącego katalogu" (dlatego musimy stać wewnątrz <code>moja-apka</code>), a opcja <code>-t</code> nadaje obrazowi czytelną nazwę i wersję.</p>
<pre><code># jesteśmy w katalogu moja-apka, tym samym, w którym leży Dockerfile
PS C:\moja-apka&gt; docker build -t moja-apka:1.0 .
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_build.png" alt="Terminal: docker build wykonuje kolejno kroki 1 do 5 z Dockerfile, każdy zakończony statusem DONE, i tworzy obraz moja-apka:1.0" /></p>
<p>Budowanie obrazu krok po kroku. Docker wykonuje kolejne instrukcje z Dockerfile (numery 1 do 5), a każdą kończy statusem DONE wraz z czasem. Efektem jest gotowy, nazwany obraz moja-apka:1.0, który możemy teraz uruchomić albo wysłać na inny serwer.</p>
<h3>Warstwy obrazu i pamięć podręczna</h3>
<p>Podczas budowania Docker nie tworzy jednego wielkiego pliku. Buduje obraz <strong>warstwa po warstwie</strong>, gdzie każda instrukcja z Dockerfile dokłada jedną warstwę na poprzednią. To nie szczegół techniczny, tylko powód, dla którego kolejność w Dockerfile ma znaczenie.</p>
<p><img src="https://jsystems.pl/static/images/logo-colored.svg" alt="JSystems" /></p>
<p>CMDuruchom python app.py (warstwa startowa)</p>
<p>COPY app.pynasz kod aplikacji, zmienia się najczęściej</p>
<p>RUN pip installzainstalowane biblioteki, zmieniają się rzadko</p>
<p>COPY requirementslista zależności</p>
<p>WORKDIR /appkatalog roboczy</p>
<p>FROM pythonobraz bazowy: system i Python</p>
<p>Obraz to stos warstw, budowany od dołu do góry. Docker zapamiętuje każdą warstwę i przy kolejnym budowaniu używa gotowych, jeśli nic się w nich nie zmieniło. Dlatego zależności (rzadko zmieniane) kopiujemy przed kodem (często zmienianym): dzięki temu zmiana jednej linijki kodu nie wymusza ponownej instalacji wszystkich bibliotek.</p>
<p>Ta pozornie drobna sztuczka z kolejnością potrafi skrócić budowanie z minut do sekund. Przy pierwszym budowaniu Docker wykonuje wszystkie kroki, ale przy kolejnych, jeśli zmieniliśmy tylko <code>app.py</code>, ponownie użyje zapamiętanej warstwy z bibliotekami i przebuduje jedynie ostatnie kroki. To jeden z tych detali, które odróżniają osobę „klikającą w Dockerze" od kogoś, kto rozumie, co się dzieje pod spodem.</p>
<p>Zbudowany obraz uruchamiamy tak samo jak wcześniej nginx, tyle że podajemy nazwę naszego obrazu. Sprawdźmy efekt najpierw w terminalu, a potem w przeglądarce.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_runapp.png" alt="Terminal: docker run uruchamia obraz moja-apka na porcie 5000, docker ps potwierdza działanie, a curl zwraca stronę z nazwą hosta kontenera i wersją Pythona" /></p>
<p>Nasz własny obraz działa. Kontener wystartował na porcie 5000, a zapytanie poleceniem curl zwróciło stronę wygenerowaną w środku kontenera. Widać nazwę hosta (to skrócony identyfikator kontenera) oraz wersję Pythona, która pochodzi z obrazu, a nie z naszego komputera.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/web_myapp.png" alt="Przeglądarka pod adresem localhost:5000 pokazuje stronę naszej aplikacji Flask z identyfikatorem kontenera i wersją Pythona" /></p>
<p>Ta sama aplikacja w przeglądarce. To już nie cudzy nginx, tylko nasz kod zapakowany we własny obraz. Dokładnie ten obraz moglibyśmy teraz wysłać na serwer albo do rejestru i uruchomić bez zmian, z gwarancją, że zachowa się identycznie. No dobrze, przyznajemy się bez bicia: samą stronę dodatkowo trochę ostylowaliśmy, bo w surowej wersji z powyższego kodu wyglądała naprawdę ubogo ;)</p>
<p>Chcesz budować własne obrazy i wdrażać je na produkcji pod okiem praktyka? <a href="https://jsystems.pl/szkolenia-docker-kubernetes;docker_i_kubernetes_od_zera.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=link_docker_build">Szkolenie Konteneryzacja Docker i Kubernetes</a> ma terminy gwarantowane.</p>
<h2>Docker Compose: wiele kontenerów jedną komendą</h2>
<p>Prawdziwe aplikacje rzadko składają się z jednego kontenera. Zwykle jest ich kilka: serwer aplikacji, baza danych, pamięć podręczna, może kolejka. Uruchamianie każdego z osobna i ręczne łączenie ich w sieć szybko robi się męczące. Od tego jest <strong>Docker Compose</strong>: opisujemy całą aplikację w jednym pliku <code>compose.yaml</code>, a potem stawiamy wszystko naraz jednym poleceniem. To, na ile usług w ogóle warto podzielić aplikację, zależy od jej architektury - rozwijamy ten wątek w artykule <a href="https://jsystems.pl/blog/show_post/Monolit_vs_Mikroserwisy_kiedy_warto_dzielic_aplikacje_przewodnik_architekta_2026/">Monolit vs Mikroserwisy - kiedy warto dzielić aplikację</a>.</p>
<p>Rozbudujemy naszą aplikację o drugą usługę: bazę Redis, która policzy odwiedziny strony. Zacznijmy od kodu aplikacji. Względem poprzedniej wersji dochodzą tylko trzy rzeczy: import biblioteki <code>redis</code>, połączenie z bazą po nazwie usługi (czyli po prostu <code>redis</code>) oraz zwiększanie licznika przy każdym wejściu na stronę.</p>
<pre><code>import os
import redis
from flask import Flask

app = Flask(__name__)

# "redis" to nazwa uslugi z compose.yaml - Docker sam zamienia
# ja na adres kontenera w wewnetrznej sieci Compose.
cache = redis.Redis(host="redis", port=6379)

@app.route("/")
def strona_glowna():
    licznik = cache.incr("odwiedziny")  # +1 przy kazdym wejsciu; stan trzyma Redis
    return f"""
      &lt;h1&gt;Witaj z kontenera Docker!&lt;/h1&gt;
      &lt;p&gt;Ta strona zostala wyswietlona {licznik} raz(y).&lt;/p&gt;
      &lt;p&gt;Licznik przechowuje kontener Redis, a strone serwuje
         kontener aplikacji: {os.uname().nodename}&lt;/p&gt;
      &lt;p&gt;Odswiez strone - liczba rosnie, bo stan zyje w Redisie, nie w aplikacji.&lt;/p&gt;
    """

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
</code></pre>
<p>Aplikacja potrzebuje więc dodatkowej biblioteki, dlatego <code>requirements.txt</code> ma teraz dwie linie:</p>
<pre><code>flask==3.0.3
redis==5.0.8
</code></pre>
<p>Teraz opisujemy całą aplikację w jednym pliku <code>compose.yaml</code>. Zwróć uwagę, że jedną usługę budujemy z naszego Dockerfile, a drugą bierzemy gotową z Docker Hub.</p>
<pre><code>services:
  # Usluga 1 - nasza aplikacja, budowana z lokalnego Dockerfile
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - redis

  # Usluga 2 - gotowy Redis prosto z Docker Hub, bez wlasnego Dockerfile
  redis:
    image: redis:7-alpine
</code></pre>
<p>Plik <code>compose.yaml</code> kładziemy w tym samym katalogu projektu, obok kodu aplikacji i <code>Dockerfile</code>. Usługa <code>web</code> ma przecież <code>build: .</code>, więc Compose zbuduje ją z tego samego <code>Dockerfile</code> co wcześniej. Cały projekt wygląda teraz tak:</p>
<p>moja-apka/</p>
<p>├─app.pyaplikacja, teraz zlicza wejścia w Redisie</p>
<p>├─requirements.txtflask oraz redis</p>
<p>├─Dockerfilebez zmian, ten sam co wcześniej</p>
<p>└─compose.yamlnowy plik: opis obu usług naraz</p>
<p>W środku aplikacja odwołuje się do bazy po prostu jako <code>redis</code>, czyli po nazwie usługi. To jedna z najwygodniejszych rzeczy w Compose: Docker sam tworzy prywatną sieć i zamienia nazwy usług na adresy, więc kontenery znajdują się nawzajem bez ręcznego wpisywania adresów IP. Całość uruchamiamy jednym poleceniem, wywołanym z wnętrza katalogu <code>moja-apka</code>, w którym leży <code>compose.yaml</code>.</p>
<pre><code># w katalogu moja-apka; -d uruchamia w tle, --build przebudowuje obraz web
PS C:\moja-apka&gt; docker compose up -d --build
</code></pre>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_compose.png" alt="Terminal: docker compose up buduje obraz web, tworzy sieć i uruchamia kontenery redis oraz web, a docker compose ps pokazuje obie usługi jako działające" /></p>
<p>Jedno polecenie, a Docker zbudował obraz aplikacji, utworzył wspólną sieć i wystartował obie usługi we właściwej kolejności (najpierw baza, potem aplikacja, bo tak zapisaliśmy w depends_on). <code>docker compose ps</code> potwierdza, że oba kontenery działają.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/web_compose.png" alt="Przeglądarka: strona aplikacji pokazuje licznik odwiedzin 10, przechowywany w kontenerze Redis" /></p>
<p>Efekt współpracy dwóch kontenerów. Aplikacja (kontener web) przy każdym wejściu pyta bazę (kontener redis) o licznik i go zwiększa. Po odświeżeniu liczba rośnie, bo stan żyje w Redisie. Gdyby aplikacja trzymała licznik u siebie, restart kontenera wyzerowałby go za każdym razem.</p>
<h2>Wolumeny i sieci: dane oraz komunikacja</h2>
<p>Wspomnieliśmy, że kontenery są ulotne. Gdy kontener usuniemy, znika razem z całą swoją zawartością. To świetne przy testach, ale fatalne dla bazy danych, której nie chcemy tracić przy każdym restarcie. Rozwiązaniem jest <strong>wolumen</strong>: wydzielone miejsce na dane, zarządzane przez Dockera, które istnieje niezależnie od kontenerów. Pokażmy to najprościej, jak się da. Zapiszemy plik w wolumenie z jednego kontenera, usuniemy ten kontener, a potem odczytamy plik z zupełnie nowego.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_volume.png" alt="Terminal: docker volume create tworzy wolumen, jeden kontener zapisuje do niego plik i znika, a nowy kontener odczytuje ten sam plik z wolumenu" /></p>
<p>Wolumen w akcji. Pierwszy kontener zapisał notatkę do wolumenu i został usunięty (opcja --rm kasuje kontener po zakończeniu). Drugi, całkiem nowy kontener bez trudu odczytał tę samą notatkę. Dane przetrwały, bo mieszkają w wolumenie, a nie w kontenerze.</p>
<p>Druga strona medalu to sieci. Widzieliśmy już, że Compose sam tworzy sieć dla naszych usług. Docker pozwala tworzyć wiele odizolowanych sieci, dzięki czemu można na przykład odgrodzić bazę danych tak, żeby była widoczna tylko dla aplikacji, a nie z zewnątrz. W skrócie: <strong>wolumeny odpowiadają za to, gdzie mieszkają dane, a sieci za to, kto z kim może rozmawiać.</strong> To dwa filary, na których stoją poważniejsze wdrożenia.</p>
<p>Sieci, wolumeny i uruchamianie wielu usług to już codzienność wdrożeń produkcyjnych, którą najszybciej opanujesz na żywej infrastrukturze. <a href="https://jsystems.pl/szkolenia-docker-kubernetes;docker_i_kubernetes_od_zera.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=link_docker_wolumeny">Szkolenie Docker i Kubernetes: od zera do bohatera</a> ma terminy gwarantowane.</p>
<h2>Docker Hub: skąd biorą się obrazy</h2>
<p>Kilka razy pobieraliśmy obrazy (nginx, redis, python), nie zastanawiając się skąd. Domyślnym źródłem jest <a href="https://hub.docker.com/">Docker Hub</a>, czyli publiczny rejestr z setkami tysięcy gotowych obrazów. Znajdziemy tam praktycznie każde popularne oprogramowanie: bazy danych, serwery WWW, języki programowania, gotowe aplikacje. Wystarczy <code>docker run</code>, a Docker sam pobierze obraz właśnie stąd.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/web_dockerhub.png" alt="Strona Docker Hub z oficjalnym obrazem nginx: opis, obsługiwane tagi i licznik ponad 20 milionów pobrań tygodniowo" /></p>
<p>Strona oficjalnego obrazu nginx na Docker Hub. Zwróć uwagę na etykietę „Docker Official Image" (obrazy weryfikowane i utrzymywane w zaufany sposób) oraz na skalę: same tygodniowe pobrania idą w dziesiątki milionów. Warto trzymać się obrazów oznaczonych jako oficjalne lub zweryfikowane, bo uruchamiamy w końcu cudzy kod.</p>
<p>Docker Hub działa w obie strony. Możemy nie tylko pobierać obrazy, ale i publikować własne poleceniem <code>docker push</code>, żeby zespół albo serwer produkcyjny mógł je pobrać. Firmy zwykle stawiają dodatkowo własny, prywatny rejestr na swoje wewnętrzne obrazy. Mechanizm jest ten sam, zmienia się tylko adres, spod którego obraz jest pobierany.</p>
<h2>Najważniejsze komendy na co dzień</h2>
<p>Docker ma dziesiątki poleceń, ale w codziennej pracy wraca ta sama garść. Poniższa ściąga to praktyczne minimum, które pozwala swobodnie uruchamiać, podglądać i sprzątać kontenery.</p>
<table>
<thead>
<tr>
<th>Polecenie</th>
<th>Co robi</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker run -d -p 8080:80 nginx</code></td>
<td>Uruchamia kontener w tle i wystawia jego port na naszym komputerze</td>
</tr>
<tr>
<td><code>docker ps</code> / <code>docker ps -a</code></td>
<td>Pokazuje kontenery działające / wszystkie, także zatrzymane</td>
</tr>
<tr>
<td><code>docker images</code></td>
<td>Wypisuje obrazy pobrane na dysk</td>
</tr>
<tr>
<td><code>docker build -t nazwa:1.0 .</code></td>
<td>Buduje obraz z Dockerfile w bieżącym katalogu</td>
</tr>
<tr>
<td><code>docker pull</code> / <code>docker push</code></td>
<td>Pobiera obraz z rejestru / wysyła własny do rejestru</td>
</tr>
<tr>
<td><code>docker logs nazwa</code></td>
<td>Pokazuje dziennik (wyjście) kontenera</td>
</tr>
<tr>
<td><code>docker exec -it nazwa bash</code></td>
<td>Wchodzi do wnętrza działającego kontenera</td>
</tr>
<tr>
<td><code>docker stop</code> / <code>docker rm</code></td>
<td>Zatrzymuje / usuwa kontener</td>
</tr>
<tr>
<td><code>docker compose up -d</code> / <code>down</code></td>
<td>Stawia / zatrzymuje całą aplikację z pliku compose.yaml</td>
</tr>
<tr>
<td><code>docker system df</code> / <code>prune</code></td>
<td>Pokazuje zajęte miejsce / usuwa nieużywane obrazy i kontenery</td>
</tr>
</tbody></table>
<p>Dwa ostatnie polecenia dotyczą sprzątania, bo Docker z czasem potrafi zająć sporo miejsca obrazami i nieużywanymi warstwami. Poleceniem <code>docker system df</code> sprawdzimy, ile dokładnie, zanim cokolwiek skasujemy.</p>
<p><img src="https://jsystems.pl/new_page_resources/images/DOCKER_INTRO/term_stats.png" alt="Terminal: docker stats pokazuje niskie zużycie pamięci przez kontenery (od 9 do 26 MiB), a docker system df ile miejsca zajmują obrazy, kontenery i wolumeny" /></p>
<p>Po lewej realne zużycie zasobów: nasze kontenery zajmowały od 9 do 26 megabajtów pamięci, co dobrze pokazuje, jak lekka jest konteneryzacja w porównaniu z maszynami wirtualnymi. Po prawej <code>docker system df</code> podpowiada, ile miejsca da się odzyskać sprzątaniem.</p>
<p><strong>Uwaga na <code>docker system prune</code>.</strong> To polecenie usuwa wszystkie nieużywane obrazy, kontenery i sieci naraz. Bywa bardzo pomocne, ale na komputerze, na którym trzymasz też inne projekty, potrafi skasować więcej, niż zakładasz. Zanim je uruchomisz, dodaj opcję pozwalającą zobaczyć, co zniknie, albo usuwaj konkretne zasoby po nazwie.</p>
<p>Konkretnie: <code>prune</code> nie ma trybu „na próbę", więc najpierw flagą <code>-v</code> podglądamy, co i ile zajmuje (polecenie wypisuje każdy obraz, kontener i wolumen z osobna wraz z kolumną „do odzyskania"), a potem zamiast masowego kasowania usuwamy po nazwie tylko to, czego naprawdę nie potrzebujemy:</p>
<pre><code># 1. Zobacz szczegolowo, co zajmuje miejsce i ile da sie odzyskac
PS C:\demo&gt; docker system df -v

# 2. Wypisz kandydatow do usuniecia
PS C:\demo&gt; docker ps -a      # kontenery (tez zatrzymane)
PS C:\demo&gt; docker images     # obrazy na dysku
PS C:\demo&gt; docker volume ls  # wolumeny

# 3. Usun po nazwie tylko to, czego juz nie potrzebujesz
PS C:\demo&gt; docker rm web               # konkretny kontener
PS C:\demo&gt; docker rmi moja-apka:1.0    # konkretny obraz
PS C:\demo&gt; docker volume rm moje-dane  # konkretny wolumen
</code></pre>
<h2>Najczęstsze błędy początkujących</h2>
<p>Na koniec zebraliśmy pułapki, w które łatwo wpaść na starcie. Znajomość ich z góry oszczędza sporo zdziwienia. Kilka z nich napotkaliśmy zresztą sami, przygotowując przykłady do tego artykułu.</p>
<p><strong>Port jest już zajęty (port is already allocated).</strong> Gdy próbujesz wystawić kontener na porcie, którego używa już inny program lub kontener, Docker odmówi startu. Rozwiązanie: wybierz inny port po lewej stronie dwukropka, na przykład <code>-p 8088:80</code> zamiast <code>-p 8080:80</code>, albo zatrzymaj to, co zajmuje port.</p>
<p><strong>Aplikacja nasłuchuje na 127.0.0.1 zamiast 0.0.0.0.</strong> To najczęstsza przyczyna sytuacji „kontener działa, ale strona się nie otwiera". Wewnątrz kontenera aplikacja musi nasłuchiwać na adresie 0.0.0.0, czyli na wszystkich interfejsach. Ustawiona na 127.0.0.1 rozmawia tylko sama ze sobą i mapowanie portu nic nie da.</p>
<p><strong>Mylenie obrazu z kontenerem.</strong> Obraz to szablon na dysku, kontener to jego uruchomiona instancja. <code>docker images</code> pokazuje obrazy, <code>docker ps</code> pokazuje kontenery. Usunięcie kontenera nie kasuje obrazu i odwrotnie. To rozróżnienie porządkuje większość początkowych nieporozumień.</p>
<p><strong>Utrata danych po usunięciu kontenera.</strong> Jeśli baza danych trzyma pliki wewnątrz kontenera, ich usunięcie oznacza utratę danych. Wszystko, co ma przetrwać, musi trafić do wolumenu. To nie jest opcja dla wygody, tylko podstawowa zasada pracy z danymi w Dockerze.</p>
<h2>Kiedy Docker się opłaca, a kiedy niekoniecznie</h2>
<p>Docker jest świetny, ale nie jest odpowiedzią na wszystko. Warto wiedzieć, gdzie daje najwięcej.</p>
<p><strong>Docker sprawdza się znakomicie, gdy:</strong> chcesz mieć identyczne środowisko na laptopie i na produkcji, szybko postawić bazę danych lub inne narzędzie do testów bez śmiecenia w systemie, uruchamiać aplikację złożoną z wielu usług, albo wdrażać powtarzalnie i bez niespodzianek. To codzienność w zespołach pracujących w duchu <a href="https://jsystems.pl/blog/show_post/czym-jest-devops-narzedzia-i-zastosowania/">DevOps</a>.</p>
<p>Z drugiej strony nie w każdym przypadku Docker jest wart zachodu. Prosty skrypt uruchamiany raz na jakiś czas nie potrzebuje konteneryzacji. Aplikacje z ciężką grafiką albo wymagające bezpośredniego dostępu do sprzętu bywają kłopotliwe. Konteneryzacja dokłada też pewną warstwę wiedzy, którą trzeba opanować, więc dla jednorazowego, malutkiego projektu może być po prostu nadmiarowa. Jak zawsze w inżynierii, chodzi o dobranie narzędzia do zadania, a nie o używanie go wszędzie.</p>
<h2>Podsumowanie</h2>
<p>Docker rozwiązuje bardzo konkretny problem: różnice między środowiskami, przez które oprogramowanie „działa u mnie, a nie działa na serwerze". Robi to, pakując aplikację razem z jej otoczeniem w przenośny obraz, który wszędzie uruchamia się tak samo. Po drodze przeszliśmy całą podstawową ścieżkę: od uruchomienia pierwszego kontenera, przez pracę z gotowymi obrazami, budowanie własnego obrazu z Dockerfile, aż po składanie wielu usług w jedną aplikację przez Docker Compose. Wszystko na prawdziwych, uruchomionych przykładach.</p>
<p>To solidny fundament, ale też dopiero początek. Naturalny kolejny krok to orkiestracja, czyli zarządzanie wieloma kontenerami na wielu serwerach, za co odpowiada Kubernetes. Jeśli chcesz przejść tę drogę uporządkowanie i od razu na realnej infrastrukturze, zamiast składać wiedzę z rozproszonych poradników, najszybciej zrobisz to pod okiem praktyka.</p>
<p><a href="https://jsystems.pl/szkolenia-docker-kubernetes;docker_i_kubernetes_od_zera.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=banner_docker"><img src="https://jsystems.pl/new_page_resources/images/other/dockerkubernetes.png" alt="Baner szkolenia Konteneryzacja Docker i Kubernetes: od zera do bohatera w JSystems, z terminem gwarantowanym" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-docker-kubernetes;docker_i_kubernetes_od_zera.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=link_docker">Szkolenie Docker i Kubernetes: od zera do bohatera --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<p><a href="https://jsystems.pl/szkolenia-docker-kubernetes;kubernetes_orkiestracja_kontenerow_szkolenie_kompleksowe.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=banner_k8s"><img src="https://jsystems.pl/new_page_resources/images/other/kubernetes.jpg" alt="Baner szkolenia Kubernetes: orkiestracja kontenerów, kompleksowe szkolenie w JSystems, z terminem gwarantowanym" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-docker-kubernetes;kubernetes_orkiestracja_kontenerow_szkolenie_kompleksowe.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=link_k8s">Szkolenie Kubernetes: orkiestracja kontenerów --&gt;</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=blog_czym_jest_docker&amp;utm_content=dofinansowanie2">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li><a href="https://jsystems.pl/blog/show_post/kubernetes-vs-docker-roznice/">Kubernetes vs Docker - czym się różnią i kiedy co wybrać</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-devops-narzedzia-i-zastosowania/">Czym jest DevOps i jakich narzędzi używa</a></li>
<li><a href="https://jsystems.pl/blog/show_post/Monolit_vs_Mikroserwisy_kiedy_warto_dzielic_aplikacje_przewodnik_architekta_2026/">Monolit vs Mikroserwisy - kiedy warto dzielić aplikację</a></li>
<li><a href="https://jsystems.pl/blog/show_post/Linux_w_codziennej_pracy_programisty_dlaczego_warto_znac_terminal_Bash/">Linux w codziennej pracy programisty - dlaczego warto znać terminal</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-ansible/">Czym jest Ansible - automatyzacja serwerów bez agenta</a></li>
<li><a href="https://jsystems.pl/blog/show_post/czym-jest-git-przewodnik-krok-po-kroku/">Czym jest Git - przewodnik krok po kroku</a></li>
</ul>
<p>✕<img alt="" /></p>
<hr />
<p><strong>Chcesz pogłębić temat na żywym szkoleniu z trenerem?</strong> Zobacz kurs <a href="https://jsystems.pl/szkolenia-docker-kubernetes;docker_i_kubernetes_od_zera.szczegoly">Docker i Kubernetes od zera</a> w JSystems — termin gwarantowany.</p>
<p>Więcej zrzutów ekranu i przykładów: <a href="https://jsystems.pl/blog/show_post/czym-jest-docker-i-jak-go-uzywac/">blog.jsystems.pl</a></p>
]]></content:encoded></item><item><title><![CDATA[Jak wybrać prework przed kursem administracji PostgreSQL]]></title><description><![CDATA[Dobre przygotowanie środowiska przed kursem administracji PostgreSQL oszczędza godziny na starcie. Zebrałem konkretne wskazówki jak wybrać prework.
Prework - czyli przygotowanie środowiska na potrzeby]]></description><link>https://jsystems.hashnode.dev/jak-wybrac-prework-kurs-administracji-postgresql</link><guid isPermaLink="true">https://jsystems.hashnode.dev/jak-wybrac-prework-kurs-administracji-postgresql</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 09:19:19 GMT</pubDate><content:encoded><![CDATA[<p>Dobre przygotowanie środowiska przed kursem administracji PostgreSQL oszczędza godziny na starcie. Zebrałem konkretne wskazówki jak wybrać prework.</p>
<h1>Prework - czyli przygotowanie środowiska na potrzeby kursu</h1>
<p>Do udziału w warsztatowej części kursu będzie Ci potrzebne środowisko. Przygowaliśmy instrukcje dla trzech wariantów przygotowania środowiska, zarówno w formie video jak i tekstowej. Przedstawiamy też wady i zalety każdego z rozwiązań. Wybierz rozwiązanie najbardziej Ci odpowiadające i zrealizuj prework jeszcze przed rozpoczęciem kursu.</p>
<h3>Wariant 1 - wykorzystanie VirtualBox</h3>
<p>VirtualBox służy do wirtualizacji na lokalnym komputerze. Sam program jest bezpłatny, tworzenie hostów również nie wiąże się z żadnymi kosztami. Hosty wirtualne znajdują się na Twoim komputerze. Rozwiązanie dobre jeśli nie chcesz ponosić kosztów wirtualizacji w chmurze Azure, ale ma też pewne ograniczenia. Pamiętaj, że każdy host będzie wymagał odpowiedniej ilości pamięci RAM (po 2GB na każdy serwer w przypadku tego kursu), czasu procesora i paredziesiąt gigabajtów miejsca na dysku. Jeśli będziesz tworzyć jeden host - problemu raczej nie będzie. Jeśli jednak zechcesz stworzyć więcej hostów - np. na potrzeby replikacji, może się okazać że nie wystarczy Ci pamięci RAM, przestrzeni na dysku lub hosty będą działały wolno ze względu na współdzielenie procesora.</p>
<p><a href="https://jsystems.pl/blog/show_post/PREWORK:_Tworzenie_wirtualnych_host%C3%B3w_z_Ubuntu_z_wykorzystaniem_VirtualBox/">Przejdź do wariantu 1</a></p>
<h3>Wariant 2 - wykorzystanie chmury Azure - plik template.json</h3>
<p>Wykorzystanie chmury Azure daje nam większą elastyczność niż w przypadku VirtualBox, nie jesteśmy ograniczeni zasobami lokalnego komputera. Możesz więc stworzyć klaster składający się z dowolnej liczby serwerów. Z drugiej strony po wykorzystaniu bezpłatnych zasobów w ramach "Free Tier" Azure, utrzymanie hostów będzie kosztowało nawet jeśli hosty będą wyłączone. Jedna włączona maszyna wirtualna z parametrami niezbędnymi dla prawidłowego przebiegu warsztatów będzie kosztowała 14 groszy za godzinę - czyli ok 104zł miesięcznie, wyłączona 4 grosze za godzinę - czyli ok 30zł miesięcznie (stan na dzień 22.07.2024). Maszyny nie muszą być uruchomione cały czas, wystarczy że uruchomisz je na czas ćwiczeń. Aby maksymalnie ułatwić Ci zadanie, przygotowaliśmy gotowy plik konfiguracyjny dla Azure - co zmacznie ułatwi Ci stworzenie maszyny.</p>
<p><a href="https://jsystems.pl/blog/show_post/PREWORK:_Tworzenie_wirtualnych_host%C3%B3w_z_Ubuntu_w_chmurze_Azure_-_plik_template.json/">Przejdź do wariantu 2</a></p>
<h3>Wariant 3 - wykorzystanie chmury Azure - konfiguracja ręczna</h3>
<p>Ten wariant jest wariacją wariantu 2 z tą różnicą, że w tym przypadku proces konfiguracji wirtualnego hosta jest wykonywany całkowicie ręcznie. Daje Ci to większą kontrolę nad ustawieniami maszyny, ale wymaga więcej pracy.</p>
<p><a href="https://jsystems.pl/blog/show_post/PREWORK:_Tworzenie_wirtualnych_host%C3%B3w_z_Ubuntu_w_chmurze_Azure_-_konfiguracja_r%C4%99czna/">Przejdź do wariantu 3</a></p>
<h3>Nasza sugestia</h3>
<p>Naszym zdaniem, najlepszym wyjściem będzie rozpoczęcie od VirtualBox i przejście na chmurę Azure w chwili gdy zechcesz stawiać wieloserwerowe klastry lub wykorzystać nabytą wiedzę produkcyjnie.</p>
<p>Na potrzeby kursu najlepiej przygotuj sobie dwa równoległe środowiska. Jeden na potrzeby powtarzania czynności trenera podczas kursu, drugi na potrzeby realizacji ćwiczeń. Konfiguracje będą miejscami wchodzić w konflikt, dlatego najlepiej mieć dwa osobne hosty.</p>
<p>W ramach Azure funkcjonuje "Free Tier" czyli bezpłatny dostęp do pewnej części zasobów Azure. W ramach tej opcji możesz uruchomić bardzo podstawowy serwer bezpłatnie na 750h w ciągu roku.
Parametry tego serwera jednak nie powalają i do poważnych zastosowań na pewno nie wystaczą. Więcej na temat "Free Tier"
<a href="https://azure.microsoft.com/en-us/pricing/free-services">przeczytasz tutaj</a>. Pamiętaj też, że przed uruchomieniem pierwszych zasobów (w tym w ramach "Free Tier") będzie trzeba podać dane z karty kredytowej, a więc należy pilnować zużycia zasobów aby nie zaskoczyło Cię pobranie pięniędzy z karty gdy wykorzystasz darmowe limity.</p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post259&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post259&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post259&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_najwazniejsze_pojecia">PostgreSQL - Najważniejsze pojęcia</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_upgrade_klastra">Upgrade klastra PostgreSQL - pg_upgrade krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_rodzaje_replikacji">PostgreSQL - Rodzaje replikacji</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
<hr />
<p><strong>Chcesz pogłębić temat na żywym szkoleniu z trenerem?</strong> Zobacz kurs <a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly">Administracja bazami danych PostgreSQL z elementami HA, optymalizacji i replikacji</a> w JSystems — termin gwarantowany.</p>
<p>Więcej zrzutów ekranu i przykładów: <a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka/">blog.jsystems.pl</a></p>
]]></content:encoded></item><item><title><![CDATA[VirtualBox + Ubuntu: jak przygotowac lokalne srodowisko cwiczeniowe pod PostgreSQL]]></title><description><![CDATA[Lokalne srodowisko w VirtualBox to najtanszy sposob na poligon do nauki administracji PostgreSQL - bez rachunku za chmure. Pokazujemy jak przygotowac hosty Ubuntu od zera.
Ogólny opis
VirtualBox to da]]></description><link>https://jsystems.hashnode.dev/virtualbox-ubuntu-prework-postgresql-lokalnie</link><guid isPermaLink="true">https://jsystems.hashnode.dev/virtualbox-ubuntu-prework-postgresql-lokalnie</guid><category><![CDATA[VirtualBox ]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:04:11 GMT</pubDate><content:encoded><![CDATA[<p>Lokalne srodowisko w VirtualBox to najtanszy sposob na poligon do nauki administracji PostgreSQL - bez rachunku za chmure. Pokazujemy jak przygotowac hosty Ubuntu od zera.</p>
<h3>Ogólny opis</h3>
<p>VirtualBox to darmowe oprogramowanie do wirtualizacji, umożliwia tworzenie i zarządzanie wieloma maszynami wirtualnymi na jednym fizycznym komputerze, co znacząco ułatwia procesy testowania, rozwoju i wdrażania.</p>
<p>W niniejszym szkoleniu omówimy krok po kroku proces tworzenia i konfiguracji podstawowej infrastruktury z wykorzystaniem VirtualBox.</p>
<h3>Wymagania</h3>
<ul>
<li>Oprogramowanie VirtualBox<br /><a href="https://www.oracle.com/pl/virtualization/technologies/vm/downloads/virtualbox-downloads.html">https://www.oracle.com/pl/virtualization/technologies/vm/downloads/virtualbox-downloads.html</a></li>
<li>Obraz Ubuntu Server LTS<br /><a href="https://ubuntu.com/download/server">https://ubuntu.com/download/server</a></li>
</ul>
<h3>Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox</h3>
<ol>
<li><p>W zainstalowanym programie Oracle VirtualBox utwórz nową maszynę wirtualną klikając przycisk “New”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/10.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox" /></p>
</li>
<li><p>Uzupełnij nazwę maszyny, folder docelowy oraz wskaż pobrany obraz <strong>Ubuntu Server LTS</strong> w formacie .iso. Zaznacz opcję “Skip Unattended Installation”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/20.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (2)" /></p>
</li>
<li><p>W sekcji “Hardware” pozostaw domyślne parametry. Są one wystarczające na cel przeprowadzanego szkolenia.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/30.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (3)" /></p>
</li>
<li><p>W zakładce “Virtual Hard disk” pozostaw domyślne ustawienia lub rozszerz dysk powyżej 25 GB - jeśli jest taka potrzeba.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/40.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (4)" /></p>
</li>
<li><p>W zakładce “Summary” zweryfikuj konfiguracje i zatwierdź utworzenie maszyny wirtualnej za pomocą przycisku “Finish”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/50.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (5)" /></p>
</li>
<li><p>Wybierz utworzoną maszynę wirtualną oraz przejdź do panelu zarządzania, klikając przycisk “Settings”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/60.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (6)" /></p>
</li>
<li><p>W sekcji “Network” upewnij się, że “Adapter 1” ma zaznaczoną opcję “Enable Network Adapter” oraz konfiguracja “Attached to” ustawiona jest jako “NAT”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/70.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (7)" /></p>
</li>
<li><p>Przejdź do zakładki “Adapter 2”, włącz adapter zaznaczając opcję przy “Enable Network Adapter” oraz wybierz opcję dla konfiguracji “Attached to” jako “Internal Network”. Pole “Name” może zostać domyślne. Na cel tego szkolenia zostało zamienione na “SiecPrywatna”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/80.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (8)" /></p>
</li>
<li><p>Uruchom maszynę wirtualną za pomocą przycisku “Start”. Przy pierwszym rozruchu rozpocznie się instalacja systemu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/90.png" alt="Tworzenie oraz konfiguracja maszyny wirtualnej w programie VirtualBox: Wirtualna maszyna Ubuntu w VirtualBox (9)" /></p>
</li>
<li><p>Powtórz kroki 1-9 dla maszyny <strong>ubuntu2</strong>. Pamiętaj aby maszynie <strong>ubuntu2</strong> przydzielić odpowiednio inny adres IP, przykładowo 10.0.0.20.</p>
</li>
</ol>
<h3>Instalacja systemu</h3>
<ol>
<li><p>Pierwszym krokiem w instalacji systemu <strong>Ubuntu Server LTS</strong> jest wybór instalatora. W tym celu za pomocą strzałem góra-dół wybierz opcję “Try or Install Ubuntu Server” oraz zatwierdź wybór za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/100.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox" /></p>
</li>
<li><p>Za pomocą strzałem góra-dół wybierz język systemu - “English” lub “Polski” - zależnie od preferencji. Wybór zatwierdź przyciskiem Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/110.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (2)" /></p>
</li>
<li><p>W tej części instalacji mamy możliwość zainstalowania najnowszej dostępnej wersji Ubuntu Server. Nie jest to wymagane, dlatego wykorzystaj opcję “Kontynuuj bez aktualizacji”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/120.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (3)" /></p>
</li>
<li><p>W zakładce “Konfiguracja klawiatury” domyślnie powinny pojawić się opcje “Układ” oraz “Wariant”, odpowiednie dla wybranego języka. Aby zaakceptować, wybierz opcję “Gotowe” oraz zatwierdź za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/130.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (4)" /></p>
</li>
<li><p>Upewnij się, że opcja “Ubuntu Server” jest zaznaczona oraz potwierdź opcją “Gotowe” za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/140.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (5)" /></p>
</li>
<li><p>Kolejnym krokiem jest konfiguracja interfejsu sieciowego. Pierwszy interfejs sieciowy jest wykorzystywany w połączeniu NAT. Tego interfejsu nie należy edytować. Drugi interfejs posłuży za interfejs w komunikacji w sieci prywatnej pomiędzy maszynami wirtualnymi. W celu jego konfiguracji wybierz drugi interfejs sieciowy za pomocą strzałem góra-dół, rozwiń menu kontekstowe za pomocą przycisku Enter oraz wybierz opcję “Edit IPv4”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/150.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (6)" /></p>
</li>
<li><p>W otwartym konfiguratorze wprowadź poniższe dane:<br /><strong>Podsieć</strong>: 10.0.0.0/24<br /><strong>Adres IP</strong>: 10.0.0.10<br /><strong>Brama sieciowa</strong>: 10.0.0.255<br /><strong>Serwery DNS</strong>: 8.8.8.8<br />Oraz zatwierdź konfigurację za pomocą przycisku Enter, wybierając pole “Zapisz”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/160.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (7)" /></p>
</li>
<li><p>Zakładka “Konfiguracja proxy” może zostać pominięta bez żadnych zmian. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/170.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (8)" /></p>
</li>
<li><p>Na tym etapie przeprowadzony zostanie krótki test połączenia do repozytorium Ubuntu. Jeśli konfiguracja interfejsów sieciowych została wykonana zgodnie z poradnikiem, wtedy powinniśmy otrzymać informację “This mirror location passed tests.”. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/180.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (9)" /></p>
</li>
<li><p>W zakładce “Konfiguracja pamięci masowej z przewodnikiem” nie jest wymagana żadna zmiana. Przejdź do następnego okna za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/190.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (10)" /></p>
</li>
<li><p>Zakładka “Konfiguracja pamięci masowej” jest swego rodzaju podsumowaniem partycjonowania dysku. Domyślna konfiguracja jest satysfakcjonująca. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/200.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (11)" /></p>
</li>
<li><p>Zaakceptuj informację o usunięciu zawartości wskazanego dysku. Jako iż maszyna wirtualna wykorzystuje zwirtualizowany dysk - twoje dane na komputerze są bezpieczne. Zaakceptuj za pomocą przycisku Enter.   </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/210.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (12)" /></p>
</li>
<li><p>W zakładce “Ustawienia profilu” wpisz dowolne dane do poświadczeń lub skorzystaj z poniższej konfiguracji:<br /><strong>Twoje imię</strong>: JSystemsSzkolenie<br /><strong>Your servers name</strong>: ubuntu1<br /><strong>Wybierz nazwę użytkownika</strong>: localadmin<br />Zatwierdź konfigurację za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/220.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (13)" /></p>
</li>
<li><p>Zakładka “Upgrade to Ubuntu Pro” proponuje aktualizację systemu do wersji Pro, która nie jest wymagana. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/230.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (14)" /></p>
</li>
<li><p>W zakładce “Ustawienia SSH” zaznacz opcję “Zainstaluj serwer SSH”, którą wybierz za pomocą strzałem góra-dół oraz zatwierdź przyciskiem Enter. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/240.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (15)" /></p>
</li>
<li><p>W zakładce “Polecane snapy serwerowe” nie zaznaczaj żadnej opcji, jedynie zaznacz pole “Gotowe” za pomocą strzałem góra-dół oraz przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/250.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (16)" /></p>
</li>
<li><p>Na tym etapie rozpocznie się instalacja systemu Ubuntu Server LTS, która może potrwać około 5 minut.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/260.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (17)" /></p>
</li>
<li><p>Gdy otrzymasz powiadomienie “Instalacja ukończona!” - a aktualizacja zabezpieczeń została ukończona - wybierz opcję za pomocą strzałem góra-dół “Uruchom ponownie”. Maszyna wirtualna zostanie ponownie uruchomiona.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/270.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (18)" /></p>
</li>
<li><p>Po ponownym uruchomieniu otrzymasz informację o błędzie spowodowanym niemożliwością odłączenia partycji /cdrom. Nie jest to błąd krytyczny i można go całkowicie zignorować. Przejdź dalej za pomocą przycisku Enter.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/280.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (19)" /></p>
</li>
<li><p>Nastąpi pierwszy rozruch systemu. Gdy dojdzie do akcji przedstawionej na zrzucie ekranu, możliwym jest przymus odczekania około 2 minut, zanim instalator przejdzie dalej.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/290.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (20)" /></p>
</li>
<li><p>Po zakończeniu procesu rozruchu powita nas ekran przedstawiony na załączonym zdjęciu. Prośba o podanie loginu do systemu może być mało widoczna, lecz powinna się ona znajdować w lewym górnym rogu ekranu. Możesz bezpośrednio wpisać login użytkownika podany w konfiguracji oraz nacisnąć Enter. Zostaniemy poproszeni o hasło, które również wpisujemy i zatwierdzamy przyciskiem Enter. Należy pamiętać, iż wpisywane hasło jest niewidoczne. Fakt ten może być mylący.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/300.png" alt="Instalacja systemu: Wirtualna maszyna Ubuntu w VirtualBox (21)" /></p>
</li>
<li><p>Powtórz kroki 1-21 dla maszyny <strong>ubuntu2</strong>. Pamiętaj aby maszynie <strong>ubuntu2</strong> przydzielić odpowiednio inny adres IP, przykładowo 10.0.0.20.</p>
</li>
</ol>
<h3>Przygotowanie systemu</h3>
<ol>
<li><p>W celu przygotowania systemu najpierw wyczyść informacje wyświetlone w konsoli za pomocą komendy “clear”.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/310.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox" /></p>
</li>
<li><p>Rozpocznij przygotowywanie systemu od aktualizacji paczek systemowych za pomocą komendy:<br />"sudo apt-get update"<br />Zostaniemy poproszeni o hasło, które podaliśmy podczas instalacji oraz logowania.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/320.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox (2)" /></p>
</li>
<li><p>Aktualizacja paczek przeprowadzona z sukcesem powinna zaowocować następującymi informacjami jak na załączonym zdjęciu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/330.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox (3)" /></p>
</li>
<li><p>Następnym krokiem jest instalacja podstawowego oprogramowania oraz narzędzi sieciowych za pomocą komendy:<br />"sudo apt-get install net-tools"  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/340.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox (4)" /></p>
</li>
<li><p>Instalacja paczek oraz narzędzi przeprowadzona z sukcesem powinna zaowocować następującymi informacjami jak na załączonym zdjęciu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/350.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox (5)" /></p>
</li>
<li><p>Na tym etapie możemy zweryfikować informacje sieciowe naszej maszyny wirtualnej za pomocą komendy:<br />"Ifconfig"<br />Drugi wpis - w tym przypadku "enp0s8" podaje informacje na temat interfejsu sieciowego przygotowanego dla sieci prywatnej.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/360.png" alt="Przygotowanie systemu: Wirtualna maszyna Ubuntu w VirtualBox (6)" /></p>
</li>
<li><p>Powtórz kroki 1-6 dla maszyny ubuntu2.</p>
</li>
</ol>
<h3>Test połączenia pomiędzy maszynami wirtualnymi</h3>
<ol>
<li><p>Zestaw okna dwóch uruchomionych maszyn wirtualnych ubuntu1 oraz ubuntu2. Na obu maszynach wykonaj komende "ifconfig". Zapamiętaj poszczególne adresy IP. W tym przypadku są one następujące:<br /><strong>Ubuntu1</strong>: 10.0.0.10<br /><strong>Ubuntu2</strong>: 10.0.0.20  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/370.png" alt="Test połączenia pomiędzy maszynami wirtualnymi: Wirtualna maszyna Ubuntu w VirtualBox" /></p>
</li>
<li><p>Zweryfikuj połączenie pomiędzy maszynami za pomocą komendy "ping". Przykłady komend:<br /><strong>Komenda wykonywana na maszynie wirtualnej ubuntu1</strong>: ping 10.0.0.20<br /><strong>Komenda wykonywana na maszynie wirtualnej ubuntu2</strong>: ping 10.0.0.10  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/380.png" alt="Test połączenia pomiędzy maszynami wirtualnymi: Wirtualna maszyna Ubuntu w VirtualBox (2)" /></p>
</li>
</ol>
<h2><strong>HOTFIX - jak podłączyć się za pomocą SSH?</strong></h2>
<p>Aby połączyć się do hosta za pomocą Putty lub innego klienta SSH, wykonaj poniższe czynności:</p>
<p><strong>1. Przestaw pierwszą kartę sieciową z NAT na "bridged". Zapisz sobie adres MAC tej karty (będzie nam za chwilę potrzebny):</strong></p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/hotfix/1.png" alt="HOTFIX - jak podłączyć się za pomocą SSH: Wirtualna maszyna Ubuntu w VirtualBox" /></p>
<p><strong>2. Zaloguj się do hosta i sprawdź adres IP tej karty sieciowej. Łatwo odnajdziesz właściwą kartę sieciową za pomocą adresu MAC:</strong></p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/hotfix/2.png" alt="HOTFIX - jak podłączyć się za pomocą SSH: Wirtualna maszyna Ubuntu w VirtualBox (2)" /></p>
<p>**3. Pobierz program "Putty" z <a href="https://www.putty.org/">https://www.putty.org/</a></p>
<p><strong>4. Uruchom Putty i w polu "Host Name" wprowadź adres IP hosta:</strong></p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/hotfix/3.png" alt="HOTFIX - jak podłączyć się za pomocą SSH: Wirtualna maszyna Ubuntu w VirtualBox (3)" /></p>
<p><strong>5. Zaloguj się swoim użytkownikiem i hasłem. Po zalogowaniu powinien być widoczny taki ekran:</strong></p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/virtualbox/hotfix/4.png" alt="HOTFIX - jak podłączyć się za pomocą SSH: Wirtualna maszyna Ubuntu w VirtualBox (4)" />**</p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post228&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post228&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post228&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_profesjonalne_wdrozenie_klastra_postgresql_na_ubuntu">Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_konfiguracja_patroni_z_etcd_na_ubuntu">PostgreSQL - Konfiguracja Patroni z ETCD na Ubuntu</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Azure krok po kroku: reczne stawianie hostow Ubuntu pod PostgreSQL]]></title><description><![CDATA[Reczne postawienie maszyny Ubuntu w Azure to najlepszy sposob zeby zrozumiec co pozniej robi za nas szablon template.json. Ten tekst prowadzi przez cala konfiguracje w portalu.
Ogólny opis
W niniejszy]]></description><link>https://jsystems.hashnode.dev/azure-ubuntu-konfiguracja-reczna-prework-postgresql</link><guid isPermaLink="true">https://jsystems.hashnode.dev/azure-ubuntu-konfiguracja-reczna-prework-postgresql</guid><category><![CDATA[Azure]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:03:46 GMT</pubDate><content:encoded><![CDATA[<p>Reczne postawienie maszyny Ubuntu w Azure to najlepszy sposob zeby zrozumiec co pozniej robi za nas szablon template.json. Ten tekst prowadzi przez cala konfiguracje w portalu.</p>
<h3>Ogólny opis</h3>
<p>W niniejszym dokumencie omówimy proces tworzenia subskrypcji oraz - podstawowej infrastruktury w chmurze Microsoft Azure, skupiając się na kluczowych elementach, takich jak:</p>
<ul>
<li>grupa zasobów (Resource Group)</li>
<li>sieć wirtualna (Virtual Network)</li>
<li>sieciowe grupy zabezpieczeń (Network Security Group - NSG).</li>
</ul>
<p>Połączymy te elementy, konfigurując sieć i uruchamiając dwie maszyny wirtualne. Następnie przeprowadzimy test połączenia pomiędzy tymi maszynami, wykorzystując proste narzędzie sieciowe..</p>
<p>Zrozumienie procesu tworzenia i konfiguracji tych fundamentalnych elementów w Azure jest kluczowe dla każdego, kto chce efektywnie korzystać z infrastruktury chmurowej. Dlatego też ten dokument będzie stanowił krok po kroku przewodnik dla tych, którzy chcą rozpocząć swoją podróż w świecie chmury Azure, jak również dla tych, którzy chcą pogłębić swoją wiedzę na temat konfiguracji sieci i maszyn wirtualnych.</p>
<h3>Wymagania</h3>
<p>Jedynym wymogiem jest posiadanie konta Microsoft. Jeśli takowego konta nie posiadamy, możemy je utworzyć klikając w poniższy link:<br /><a href="https://signup.live.com">https://signup.live.com</a></p>
<h3>Tworzenie pierwszej subskrypcji w Microsoft Azure</h3>
<ol>
<li><p>Zaloguj się na portal Azure.<br />Po utworzeniu konta Microsoft zaloguj się na portal Azure, odwiedzając stronę: <a href="https://portal.azure.com">https://portal.azure.com</a></p>
</li>
<li><p>Po zalogowaniu się na portalu Azure, wybierz ikonę klucza, oznaczonego jako "Subskrypcje" w pasku szybkiego wyboru. Jeśli takowa ikona nie jest widoczna, możliwym jest jej wyszukanie za pomocą wyszukiwarki, która znajduje się w górnej części ekranu wpisując "Subskrypcje".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/10.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK" /></p>
</li>
<li><p>Na stronie "Subskrypcje" kliknij przycisk "Dodaj", aby rozpocząć proces tworzenia nowej subskrypcji.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/20.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (2)" /></p>
</li>
<li><p>Następnie wybierz opcję "Płatność zgodnie z rzeczywistym użyciem" klikając w odpowiednim miejscu "Wybierz ofertę".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/30.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (3)" /></p>
</li>
<li><p>Wypełnij formularz kontaktowy, który jest wymagany do konfiguracji subskrypcji na platformie Microsoft Azure.</p>
</li>
<li><p>Zaakceptuj wymagane zgody w formularzu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/40.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (4)" /></p>
</li>
<li><p>Zweryfikuj się za pomocą numeru telefonu w dogodny dla siebie sposób. Otrzymany kod za pomocą wiadomości SMS lub rozmowy telefonicznej wpisz w następnym oknie.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/50.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (5)" /></p>
</li>
<li><p>Dodaj nową kartę płatniczą lub wybierz już istniejącą kartę, która to zostanie przypisana do konta i nowo-utworzonej subskrypcji. Następnie zatwierdź przyciskiem "Dalej".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/60.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (6)" /></p>
</li>
<li><p>Zaznacz opcję "Brak pomocy technicznej lub korzystam już z pomocy technicznej Premier firmy Microsoft." i potwierdź przyciskiem "Utwórz konto"  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/70.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (7)" /></p>
</li>
<li><p>Następnie zostaniemy przeniesieni do kroku, w którym jesteśmy proszeni o ustawienie MFA dla naszego konta - jeśli takowe nie zostało do tej pory skonfigurowane.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/80.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (8)" /></p>
</li>
<li><p>Zostaniemy przeniesieni do ekranu powitalnego, gdzie zaproponowane zostanie nam krótkie szkolenie odnośnie zarządzania zasobami oraz subskrypcją. Możemy skorzystać w propozycji lub zamknąć okno za pomocą przycisku "X", znajdującego się w prawym górnym rogu ekranu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/90.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (9)" /></p>
</li>
<li><p>Ponownie przechodzimy do zakładki "Subskrypcje" za pomocą paska szybkiego wyboru lub wyszukując tę frazę w wyszukiwarce, znajdującej się w górnej części ekranu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/100.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (10)" /></p>
</li>
<li><p>Wybieramy naszą nowo utworzoną subskrypcję, klikając na nią.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/110.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (11)" /></p>
</li>
<li><p>Następnie zmieniamy jej nazwę przyjazną dla użytkownika, klikając w przycisk "Zmień nazwę".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/120.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (12)" /></p>
</li>
<li><p>Wybieramy nową nazwę subskrypcji - w tym wypadku jest to "Szkolenie" i klikamy przycisk "Zapisz". Subskrypcja natychmiast zmieni swoją nazwę.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/130.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (13)" /></p>
</li>
</ol>
<h3>Tworzenie grupy zasobów</h3>
<p>Pierwszym, a zarazem najbardziej podstawowym zasobem - zaraz po subskrypcji - jest <strong>grupa zasobów</strong> (resource group). Jest to swoisty kontener lub folder, pozwalający na grupowanie zasobów wedle dowolnej dla nas logiki. Przykładową dobrą praktyką w grupowaniu zasobów jest łączenie ich ze względu na ich tzw. Lifecycle.</p>
<ol>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Grupy zasobów". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/140.png" alt="Tworzenie grupy zasobów: PREWORK" /></p>
</li>
<li><p>W zakładce "Grupy zasobów" utwórz nowy zasób, klikając przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/150.png" alt="Tworzenie grupy zasobów: PREWORK (2)" /></p>
</li>
<li><p>W zakładce "Podstawowe" konfiguratora zasobu "Grupa zasobów", wypełnij następująco poniższe pola:<br /><strong>Subskrypcja</strong>: Szkolenie (lub inna nazwa nadana we wcześniejszych krokach)<br /><strong>Grupa zasobów</strong>: rg-szkolenie<br /><strong>Region</strong>: (Europe) Poland Central  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/160.png" alt="Tworzenie grupy zasobów: PREWORK (3)" /></p>
</li>
<li><p>Zweryfikuj konfigurację w zakładce "Przeglądanie + tworzenie" i utwórz zasób klikając w przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/170.png" alt="Tworzenie grupy zasobów: PREWORK (4)" /></p>
</li>
<li><p>Grupa zasobów "rg-szkolenie" powinna zostać utworzona niemalże natychmiast.</p>
</li>
</ol>
<h3>Tworzenie maszyn wirtualnych</h3>
<ol>
<li><p>Dane konfiguracyjne maszyn wirtualnych:<br /><strong>Maszyna wirtualna no. 1</strong><br /><strong>Subskrypcja</strong>: Szkolenie (lub inna nazwa nadana we wcześniejszych krokach)<br /><strong>Grupa zasobów</strong>: rg-szkolenie<br /><strong>Nazwa maszyny wirtualnej</strong>: pg1<br /><strong>Region</strong>: (Europe) Poland Central<br /><strong>Opcje dostępności</strong>: Nie jest wymagana żadna nadmiarowość infrastruktury<br /><strong>Typ zabezpieczeń</strong>: Maszyny wirtualne zaufanego uruchamiania<br /><strong>Obraz</strong>: Ubuntu Server 22.04 LTS - x64 Gen2<br /><strong>Architektura maszyny wirtualnej</strong>: x64<br /><strong>Rozmiar</strong>: Standard_B1ms<br /><strong>Typ uwierzytelnienia</strong>: Hasło<br /><strong>Nazwa użytkownika</strong>: jsystems<br /><strong>Hasło</strong>: Dowolne hasło spełniające wymogi<br /><strong>Publiczne porty ruchu przychodzącego</strong>: Brak<br /><strong>Podsieć</strong>: Subnet1<br /><strong>Nazwa publicznego adresu IP</strong>: pip-pg1  </p>
<p><strong>Maszyna wirtualna no. 2</strong><br /><strong>Subskrypcja</strong>: Szkolenie (lub inna nazwa nadana we wcześniejszych krokach)<br /><strong>Grupa zasobów</strong>: rg-szkolenie<br /><strong>Nazwa maszyny wirtualnej</strong>: pg2<br /><strong>Region</strong>: (Europe) Poland Central<br /><strong>Opcje dostępności</strong>: Nie jest wymagana żadna nadmiarowość infrastruktury<br /><strong>Typ zabezpieczeń</strong>: Maszyny wirtualne zaufanego uruchamiania<br /><strong>Obraz</strong>: Ubuntu Server 22.04 LTS - x64 Gen2<br /><strong>Architektura maszyny</strong> wirtualnej: x64<br /><strong>Rozmiar</strong>: Standard_B1ms<br /><strong>Typ uwierzytelnienia</strong>: Hasło<br /><strong>Nazwa użytkownika</strong>: jsystems<br /><strong>Hasło</strong>: Dowolne hasło spełniające wymogi<br /><strong>Publiczne porty ruchu przychodzącego</strong>: Brak<br /><strong>Podsieć</strong>: Subnet1<br /><strong>Nazwa publicznego adresu IP</strong>: pip-pg2</p>
</li>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Maszyny wirtualne". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/180.png" alt="Tworzenie maszyn wirtualnych: PREWORK" /></p>
</li>
<li><p>W zakładce "Maszyny wirtualne" utwórz nowy zasób, klikając przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/190.png" alt="Tworzenie maszyn wirtualnych: PREWORK (2)" /></p>
</li>
<li><p>W zakładce "Podstawowe informacje" konfiguratora zasobu "Grupa zasobów", wypełnij następująco poniższe pola:  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/200.png" alt="Tworzenie maszyn wirtualnych: PREWORK (3)" />  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/210.png" alt="Tworzenie maszyn wirtualnych: PREWORK (4)" /></p>
</li>
<li><p>W zakładce Dyski zmieniamy "Rozmiar dysku systemu operacyjnego" na 32 GB oraz "Typ dysku systemu operacyjnego" na "SSD w warstwie Standardowa".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/220.png" alt="Tworzenie maszyn wirtualnych: PREWORK (5)" /></p>
</li>
<li><p>W zakładce "Sieć" utworzona zostanie nowa sieć wirtualna wraz z podsiecią. Domyślna konfiguracja jest odpowiednia. Zmieniamy wyłącznie nazwę sieci klikając pod listą konfiguracji "Sieć wirtualna" przycisk "Utwórz nowy".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/230.png" alt="Tworzenie maszyn wirtualnych: PREWORK (6)" /></p>
</li>
<li><p>Zmieniamy nazwę sieci wirtualnej oraz zatwierdzamy konfigurację za pomocą przycisku "OK".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/240.png" alt="Tworzenie maszyn wirtualnych: PREWORK (7)" /></p>
</li>
<li><p>Zaznaczamy opcję "Usuwanie publicznego adresu IP i karty sieciowej po usunięciu maszyny wirtualnej".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/250.png" alt="Tworzenie maszyn wirtualnych: PREWORK (8)" /></p>
</li>
<li><p>W zakładce "Zarządzanie" odznacz opcję "Bezpłatnie włącz plan podstawowy" w sekcji "Microsoft Defender dla Chmury". Pozostałe opcje pozostaw domyślne.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/260.png" alt="Tworzenie maszyn wirtualnych: PREWORK (9)" /></p>
</li>
<li><p>W zakładce "Monitorowanie" zaznacz opcję "Diagnostyka rozruchu" jako "Wyłącz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/270.png" alt="Tworzenie maszyn wirtualnych: PREWORK (10)" /></p>
</li>
<li><p>Wszystkie ustawienia w zakładce "Zaawansowane" pozostawiamy domyślne.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/280.png" alt="Tworzenie maszyn wirtualnych: PREWORK (11)" /></p>
</li>
<li><p>Wszystkie ustawienia w zakładce "Tagi" pozostawiamy domyślne.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/290.png" alt="Tworzenie maszyn wirtualnych: PREWORK (12)" /></p>
</li>
<li><p>Zweryfikuj konfigurację w zakładce "Przeglądanie + tworzenie" i utwórz zasób klikając w przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/300.png" alt="Tworzenie maszyn wirtualnych: PREWORK (13)" /></p>
</li>
<li><p>Powtórz kroki 2-10 dla maszyny wirtualnej numer 2.</p>
</li>
</ol>
<h3>Połączenie z maszyną wirtualną</h3>
<ol>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Maszyny wirtualne". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/310.png" alt="Połączenie z maszyną wirtualną: PREWORK" /></p>
</li>
<li><p>W centralnym dashboardzie maszyny wirtualnej skopiuj publiczny adres IP i połącz się za pomocą klienta SSH - w tym wypadku PuTTy - do maszyny. Wykonaj tożsame połączenie z drugą maszyną wirtualną.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/320.png" alt="Połączenie z maszyną wirtualną: PREWORK (2)" /></p>
</li>
</ol>
<h3>Testowanie połączenia pomiędzy maszynami wirtualnymi</h3>
<ol>
<li><p>Przetestuj połączenie pomiędzy maszynami za pomocą prostej komendy "ping". Adresy prywatne IP znajdują się w dashboardzie maszyn wirtualnych. Jeśli adres sieciowy nie był zmieniany, wtedy maszyny powinny posiadać poniższe adresy IP:<br /><strong>pg1</strong>: 10.0.0.4<br /><strong>pg2</strong>: 10.0.0.5  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/330.png" alt="Testowanie połączenia pomiędzy maszynami wirtualnymi: PREWORK" /></p>
</li>
<li><p>Poprawnie skonfigurowane maszyny powinny zezwolić na połączenie za pomocą komendy ping.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/340.png" alt="Testowanie połączenia pomiędzy maszynami wirtualnymi: PREWORK (2)" /></p>
</li>
</ol>
<h3>Kosztorys</h3>
<p>Zdecydowana większość zasobów na platformie Microsoft Azure generuje odpowiednie dla siebie koszta. Duża część z tych zasobów pozwala na optymalizację kosztów, przykładowo poprzez wyłączenie usługi, gdy ta nie jest użytkowana. W przypadku konfiguracji przedstawionej w tym szkoleniu, możemy ograniczyć koszta poprzez wyłączenie maszyn wirtualnych, gdy z nich nie korzystamy. Niemniej jednak koszta związane z dyskami czy publicznymi adresami IP pozostaną tak długo, jak długo dany zasób będzie istniał. Koszta przestają być naliczane, gdy całkowicie usuniemy nasze zasoby, kiedy te już nie będą nam potrzebne.</p>
<p>Poniższa tabela prezentuje koszta związane z konfiguracją przedstawioną w szkoleniu.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure/350.png" alt="Kosztorys: PREWORK" /></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post229&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post229&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post229&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_konfiguracja_patroni_z_etcd_na_ubuntu">PostgreSQL - Konfiguracja Patroni z ETCD na Ubuntu</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PREWORK:_Tworzenie_wirtualnych_host%C3%B3w_z_Ubuntu_z_wykorzystaniem_VirtualBox">Wirtualna maszyna Ubuntu w VirtualBox - instalacja krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Azure + Ubuntu z template.json: jak przygotowac hosty pod kurs PostgreSQL]]></title><description><![CDATA[Powtarzalne srodowisko cwiczeniowe do administracji PostgreSQL zaczyna sie od infrastruktury. Pokazujemy jak w Azure odtworzyc hosty Ubuntu z gotowego szablonu template.json.
Ogólny opis
W niniejszym ]]></description><link>https://jsystems.hashnode.dev/azure-ubuntu-template-json-prework-postgresql</link><guid isPermaLink="true">https://jsystems.hashnode.dev/azure-ubuntu-template-json-prework-postgresql</guid><category><![CDATA[Azure]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:03:21 GMT</pubDate><content:encoded><![CDATA[<p>Powtarzalne srodowisko cwiczeniowe do administracji PostgreSQL zaczyna sie od infrastruktury. Pokazujemy jak w Azure odtworzyc hosty Ubuntu z gotowego szablonu template.json.</p>
<h3>Ogólny opis</h3>
<p>W niniejszym dokumencie omówimy proces tworzenia subskrypcji oraz podstawowej infrastruktury w chmurze Microsoft Azure za pomocą szablonu.</p>
<h3>Wymagania</h3>
<p>Jedynym wymogiem jest posiadanie konta Microsoft. Jeśli takowego konta nie posiadamy, możemy je utworzyć klikając w poniższy link:<br /><a href="https://signup.live.com">https://signup.live.com</a></p>
<h3>Tworzenie pierwszej subskrypcji w Microsoft Azure</h3>
<ol>
<li><p>Zaloguj się na portal Azure.<br />Po utworzeniu konta Microsoft zaloguj się na portal Azure, odwiedzając stronę: <a href="https://portal.azure.com">https://portal.azure.com</a></p>
</li>
<li><p>Po zalogowaniu się na portalu Azure, wybierz ikonę klucza, oznaczonego jako "Subskrypcje" w pasku szybkiego wyboru. Jeśli takowa ikona nie jest widoczna, możliwym jest jej wyszukanie za pomocą wyszukiwarki, która znajduje się w górnej części ekranu wpisując "Subskrypcje".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/10.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK" /></p>
</li>
<li><p>Na stronie "Subskrypcje" kliknij przycisk "Dodaj", aby rozpocząć proces tworzenia nowej subskrypcji.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/20.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (2)" /></p>
</li>
<li><p>Następnie wybierz opcję "Płatność zgodnie z rzeczywistym użyciem" klikając w odpowiednim miejscu "Wybierz ofertę".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/30.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (3)" /></p>
</li>
<li><p>Wypełnij formularz kontaktowy, który jest wymagany do konfiguracji subskrypcji na platformie Microsoft Azure.</p>
</li>
<li><p>Zaakceptuj wymagane zgody w formularzu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/40.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (4)" /></p>
</li>
<li><p>Zweryfikuj się za pomocą numeru telefonu w dogodny dla siebie sposób. Otrzymany kod za pomocą wiadomości SMS lub rozmowy telefonicznej wpisz w następnym oknie.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/50.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (5)" /></p>
</li>
<li><p>Dodaj nową kartę płatniczą lub wybierz już istniejącą kartę, która to zostanie przypisana do konta i nowo-utworzonej subskrypcji. Następnie zatwierdź przyciskiem "Dalej".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/60.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (6)" /></p>
</li>
<li><p>Zaznacz opcję "Brak pomocy technicznej lub korzystam już z pomocy technicznej Premier firmy Microsoft." i potwierdź przyciskiem "Utwórz konto"  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/70.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (7)" /></p>
</li>
<li><p>Następnie zostaniemy przeniesieni do kroku, w którym jesteśmy proszeni o ustawienie MFA dla naszego konta - jeśli takowe nie zostało do tej pory skonfigurowane.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/80.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (8)" /></p>
</li>
<li><p>Zostaniemy przeniesieni do ekranu powitalnego, gdzie zaproponowane zostanie nam krótkie szkolenie odnośnie zarządzania zasobami oraz subskrypcją. Możemy skorzystać w propozycji lub zamknąć okno za pomocą przycisku "X", znajdującego się w prawym górnym rogu ekranu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/90.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (9)" /></p>
</li>
<li><p>Ponownie przechodzimy do zakładki "Subskrypcje" za pomocą paska szybkiego wyboru lub wyszukując tę frazę w wyszukiwarce, znajdującej się w górnej części ekranu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/100.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (10)" /></p>
</li>
<li><p>Wybieramy naszą nowo utworzoną subskrypcję, klikając na nią.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/110.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (11)" /></p>
</li>
<li><p>Następnie zmieniamy jej nazwę przyjazną dla użytkownika, klikając w przycisk "Zmień nazwę".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/120.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (12)" /></p>
</li>
<li><p>Wybieramy nową nazwę subskrypcji - w tym wypadku jest to "Szkolenie" i klikamy przycisk "Zapisz". Subskrypcja natychmiast zmieni swoją nazwę.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/130.png" alt="Tworzenie pierwszej subskrypcji w Microsoft Azure: PREWORK (13)" /></p>
</li>
</ol>
<h3>Tworzenie grupy zasobów</h3>
<p>Pierwszym, a zarazem najbardziej podstawowym zasobem - zaraz po subskrypcji - jest <strong>grupa zasobów</strong> (resource group). Jest to swoisty kontener lub folder, pozwalający na grupowanie zasobów wedle dowolnej dla nas logiki. Przykładową dobrą praktyką w grupowaniu zasobów jest łączenie ich ze względu na ich tzw. Lifecycle.</p>
<ol>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Grupy zasobów". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/140.png" alt="Tworzenie grupy zasobów: PREWORK" /></p>
</li>
<li><p>W zakładce "Grupy zasobów" utwórz nowy zasób, klikając przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/150.png" alt="Tworzenie grupy zasobów: PREWORK (2)" /></p>
</li>
<li><p>W zakładce "Podstawowe" konfiguratora zasobu "Grupa zasobów", wypełnij następująco poniższe pola:<br /><strong>Subskrypcja</strong>: Szkolenie (lub inna nazwa nadana we wcześniejszych krokach)<br /><strong>Grupa zasobów</strong>: rg-szkolenie<br /><strong>Region</strong>: (Europe) Poland Central  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/160.png" alt="Tworzenie grupy zasobów: PREWORK (3)" /></p>
</li>
<li><p>W zakładce "Tagi" konfiguratora zasobu "Grupa zasobów", wypełnij następująco poniższe pola:<br /><strong>Nazwa</strong>: Cel<br /><strong>Wartość</strong>: Szkolenie  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/170.png" alt="Tworzenie grupy zasobów: PREWORK (4)" /></p>
</li>
<li><p>Zweryfikuj konfigurację w zakładce "Przeglądanie + tworzenie" i utwórz zasób klikając w przycisk "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/180.png" alt="Tworzenie grupy zasobów: PREWORK (5)" /></p>
</li>
<li><p>Grupa zasobów "rg-szkolenie" powinna zostać utworzona niemalże natychmiast.</p>
</li>
</ol>
<h3>Tworzenie konfiguracji za pomocą szablonu</h3>
<ol>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Wdróż szablon niestandardowy". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/190.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK" /></p>
</li>
<li><p>W konfiguratorze szablonu niestandardowego, w zakładce "Wybierz szablon" wybierz opcję "Utwórz własny szablon w edytorze". Otworzy to okno edytora szablonu.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/200.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK (2)" /></p>
</li>
<li><p>Wklej do okna edytora szablonu <a href="https://jsystems.pl/nowy_blog/download/postgresql/template.json">udostępniony szablon infrastruktury</a>. Zweryfikuj przygotowane zasoby w panelu bocznym. Po weryfikacji zatwierdź szablon za pomocą przycisku "Zapisz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/210.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK (3)" /></p>
</li>
<li><p>W konfiguratorze szablonu niestandardowego - w zakładce "Podstawowe" - wybierz odpowiednią subskrypcję, wcześniej przygotowaną grupę zasobów "rg-szkolenie" oraz region "(Europe) Poland Central". Ostatnim konfigurowalnym polem jest pole "Admin Password" domyślną wartością pola jest <strong>JSystems!</strong>. Jest to hasło, dzięki któremu zalogujemy się do maszyny. Hasło można ustawić dowolne (minimum 6 znaków, znak specjalny oraz duża/mała litera).  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/220.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK (4)" /></p>
</li>
<li><p>W ostatniej zakładce "Przejrzy i utwórz" zweryfikuj konfigurację oraz rozpocznij wdrożenie za pomocą przycisku "Utwórz".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/230.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK (5)" /></p>
</li>
<li><p>Po kliknięciu przycisku "Utwórz" przeniesieni zostaniemy do dashboardu wdrożenia naszego szablonu niestandardowego. Po zakończonym wdrożeniu możesz przejść do grupy zasobów, klikając przycisk "Przejdź do grupy zasobów".  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/240.png" alt="Tworzenie konfiguracji za pomocą szablonu: PREWORK (6)" /></p>
</li>
</ol>
<h3>Połączenie z maszyną wirtualną</h3>
<ol>
<li><p>Z ekranu głównego platformy Microsoft Azure wybierz na pasku szybkiego wybierania przycisk "Maszyny wirtualne". Jeśli takowy przycisk nie jest widoczny, wyszukaj tę frazę w wyszukiwarce, umieszczonej na górze strony.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/250.png" alt="Połączenie z maszyną wirtualną: PREWORK" /></p>
</li>
<li><p>W centralnym dashboardzie maszyny wirtualnej skopiuj publiczny adres IP i połącz się za pomocą klienta SSH - w tym wypadku PuTTy - do maszyny. Wykonaj tożsame połączenie z drugą maszyną wirtualną.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/260.png" alt="Połączenie z maszyną wirtualną: PREWORK (2)" /></p>
</li>
</ol>
<h3>Testowanie połączenia pomiędzy maszynami wirtualnymi</h3>
<ol>
<li><p>Przetestuj połączenie pomiędzy maszynami za pomocą prostej komendy "ping". Adresy prywatne IP znajdują się w dashboardzie maszyn wirtualnych. Jeśli adres sieciowy nie był zmieniany, wtedy maszyny powinny posiadać poniższe adresy IP:<br /><strong>pg1</strong>: 10.0.0.10<br /><strong>pg2</strong>: 10.0.0.20  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/270.png" alt="Testowanie połączenia pomiędzy maszynami wirtualnymi: PREWORK" /></p>
</li>
<li><p>Poprawnie skonfigurowane maszyny powinny zezwolić na połączenie za pomocą komendy ping.  </p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/280.png" alt="Testowanie połączenia pomiędzy maszynami wirtualnymi: PREWORK (2)" /></p>
</li>
</ol>
<h3>Kosztorys</h3>
<p>Zdecydowana większość zasobów na platformie Microsoft Azure generuje odpowiednie dla siebie koszta. Duża część z tych zasobów pozwala na optymalizację kosztów, przykładowo poprzez wyłączenie usługi, gdy ta nie jest użytkowana. W przypadku konfiguracji przedstawionej w tym szkoleniu, możemy ograniczyć koszta poprzez wyłączenie maszyn wirtualnych, gdy z nich nie korzystamy. Niemniej jednak koszta związane z dyskami czy publicznymi adresami IP pozostaną tak długo, jak długo dany zasób będzie istniał. Koszta przestają być naliczane, gdy całkowicie usuniemy nasze zasoby, kiedy te już nie będą nam potrzebne.</p>
<p>Poniższa tabela prezentuje koszta związane z konfiguracją przedstawioną w szkoleniu.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/azure_template/290.png" alt="Kosztorys: PREWORK" /></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post230&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post230&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post230&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_profesjonalne_wdrozenie_klastra_postgresql_na_ubuntu">Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_przygotowanie_hostow_-_zakres_enterprise">PostgreSQL - Przygotowanie hostów - zakres enterprise</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL PG_CRON: harmonogram zadan bez zewnetrznego crona]]></title><description><![CDATA[pg_cron przenosi harmonogram zadan bazodanowych tam gdzie realnie powinien byc - do samej bazy PostgreSQL. Ten tekst pokazuje instalacje, skladnie i typowe zastosowania.

Rozszerzenie PG_CRON pozwala ]]></description><link>https://jsystems.hashnode.dev/postgresql-pg-cron-zadania-cykliczne</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-pg-cron-zadania-cykliczne</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[automation]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:02:57 GMT</pubDate><content:encoded><![CDATA[<p>pg_cron przenosi harmonogram zadan bazodanowych tam gdzie realnie powinien byc - do samej bazy PostgreSQL. Ten tekst pokazuje instalacje, skladnie i typowe zastosowania.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/comm/pg_cron.jpg" alt="Pg cron: PG_CRON" /></p>
<p>Rozszerzenie PG_CRON pozwala na automatyczne uruchamianie cyklicznych zadań w serwerze PostgreSQL. Możesz to wykorzystać np. do przeładowywania danych w hurtownii danych, czy uruchamiania procesów konserwacyjnych.</p>
<p><strong>Z tego artykułu dowiesz się:</strong></p>
<ul>
<li>czym jest pg_cron i w jakim celu się go stosuje,</li>
<li>jak zainstalować pg_cron na Ubuntu,</li>
<li>jak zainstalować pg_cron na systemach z rodziny Red Hat,</li>
<li>w jaki sposób konfigurować automatyczne uruchamianie zadań w PostgreSQL za pomocą pg_cron,</li>
<li>jak przeglądać zaplanowane zadania,</li>
<li>jak modyfikować zaplanowane zadania,</li>
<li>jak wyłączać zaplanowane zadania,</li>
<li>jak przeglądać historię wykonanych zaplanowanych zdań wraz z ewentualnymi błędami i ich przyczynami.</li>
</ul>
<p>Zaczynając swoją przygodę z Postgresem, często jedną z pierwszych przeszkód, z którą się stykamy, jest problem planowania cyklicznych zadań w bazie danych. Postgres domyślnie nie posiada takiej funkcjonalności (jak na przykład DBMS_JOB w Oracle), a jedyną możliwością jest zaplanowanie zadań w cronie systemowym. Istnieje jednak rozszerzenie pg_cron, dostępne w oficjalnych repozytoriach PGDG oraz do pobrania i własnej kompilacji ze strony projektu na github (<a href="https://github.com/citusdata/pg_cron">https://github.com/citusdata/pg_cron</a>), umożliwiające zaplanowanie powtarzalnych zadań bezpośrednio w Postgresie z wykorzystaniem składni znanej ze wspomnianego wcześniej unixowego crona.</p>
<h3>Instalacja i konfiguracja</h3>
<p>Instalacja zależnie od systemu, z którego korzystamy, odbywa się za pomocą yum na systemach z rodziny RedHat lub apt na pochodnych Debiana.</p>
<pre><code>## RHEL, CentOS, Fedora, Rocky

1) wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

2) sudo yum install pgdg-redhat-repo-latest.noarch.rpm

3) sudo yum install -y pg_cron_15

## Debian, Ubuntu

1) sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" &gt; /etc/apt/sources.list.d/pgdg.list'

2) wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \

sudo apt-key add -

3) sudo apt-get update

4) sudo apt-get -y install postgresql-15-cron
</code></pre>
<p>Inną możliwością jest pobranie projektu bezpośrednio z githuba i własnoręczna kompilacja.</p>
<pre><code>git clone https://github.com/citusdata/pg_cron.git

cd pg_cron

# upewnij się, że zmienna PATH zawiera ścieżkę do pg_config

# przykładowo: /usr/lib/postgresql/15/bin dla ubuntu, albo /usr/pgsql-15/bin dla redhata

export PATH=/usr/pgsql-15/bin:$PATH

make &amp;&amp; sudo PATH=$PATH make install
</code></pre>
<p>Następnie dodajemy ‘pg_cron’ do parametru <em>shared_preload_libraries</em> w pliku "postgresql.conf", albo przez ALTER SYSTEM i restartujemy Postgresa, aby zmiany zostały wczytane podczas startu Postgresa.</p>
<pre><code>#Sprawdź czy nie masz już ustawionych jakichś bibliotek w "shared_preload_libraries"

show shared_preload_libraries;

  

#Zmiana parametru w postgresql.conf lub przez ALTER SYSTEM:

alter system set shared_preload_libraries='pg_cron';  #można po przecinku: 'pg_prewarm,pg_cron'

  

# na Ubuntu

/usr/lib/postgresql/15/bin/pg_ctl -D /katalog/pg/data restart -m fast

# na RHEL

/usr/pgsql-15/bin/pg_ctl -D /katalog/pg/data restart -m fast

# ścieżkę do katalogu z danymi znajdziemy za pomocą 

postgres=# show data_directory;

       data_directory          

-----------------------------

 /var/lib/postgresql/15/main

(1 row)
</code></pre>
<p>Rozszerzenie tworzymy zawsze tylko w jednej bazie, którą później wykorzystujemy jako pojedynczy punkt do zarządzania wszystkimi zadaniami. Jeżeli planujemy stworzenie rozszerzenia w bazie innej niż domyślna Postgres, powinniśmy dodać do pliku konfiguracyjnego nowy parametr <em>cron.database_name</em>, na przykład:</p>
<pre><code>shared_preload_libraries = 'pg_cron'

cron.database_name = 'apka'
</code></pre>
<p>Po ponownym uruchomieniu możemy dodać rozszerzenie do jednej wybranej bazy, w której będziemy planować zadania. Opcjonalnie możemy również nadać uprawnienia dla schematu “cron” użytkownikom, którzy powinni mieć możliwość planowania zadań.</p>
<pre><code>postgres@vagrant:~$ psql -c "create extension pg_cron;" apka

CREATE EXTENSION

postgres@vagrant:~$ psql -c "grant usage on schema cron to planer;" apka

GRANT
</code></pre>
<p>Jak skorzystamy z domyślnych wartości i stworzymy rozszerzenie oraz zaplanujemy zadania jako użytkownicy Postgres w bazie Postgres.</p>
<pre><code>postgres@vagrant:~$ psql -c "create extension pg_cron;"

CREATE EXTENSION
</code></pre>
<h3>Sposoby wykonywania zadań w pg_cron</h3>
<p>Domyślnie pg_cron otwiera lokalnie połączenia do bazy, aby wykonywać zaplanowane zadania, dlatego musimy zadbać o odpowiednią konfigurację pg_hba.conf orac .pgpass, jeżeli logowanie wymaga hasła. Korzystając z użytkownika Postgres oraz bazy Postgres, wystarczy zastosować wpis dla połączeń lokalnych za pomocą socketa z metodą autentykacji “peer”.</p>
<pre><code>local - postgres      postgres - peer
</code></pre>
<p>Jeżeli chcielibyśmy korzystać z innego użytkownika, lub z hasła, musimy odpowiednio zmodyfikować oba pliki konfiguracyjne.</p>
<p>Drugim sposobem wykorzystania zadań jest korzystanie z procesów tła do wykonywania zadań, zamiast nawiązywania lokalnych połączeń do bazy. Aby pg_cron przygotować do działania w ten sposób, musimy zmienić dwa parametry, oba wymagają restartu Postgresa, aby zmiany weszły w życie:</p>
<pre><code>cron.use_background_workers = on

max_worker_processes = 20
</code></pre>
<p><em>cron.use_background_workers</em> aby pg_cron korzystał z procesów tła oraz za pomocą parametru <em>max_worker_processes</em> określić ile zadań będzie mogło się wykonywać jednocześnie, domyślnie liczba procesów ograniczona jest do 8.</p>
<p>Warto też pamiętać, że pg_cron wykonuje zadania tylko na instancji głównej klastra. Rozszerzenie może być zainstalowane i skonfigurowane na instancjach standby, jednak zadania nie będą wykonywane na serwerach standby do momentu awansowania ich na instancję primary i otwarciu na zapis.</p>
<h3>Planowanie zadań</h3>
<p>Zadania możemy zaplanować za pomocą funkcji <em>cron.schedule()</em>, która przyjmuje dwie lub trzy wartości. W pierwszej wersji- harmonogram oraz polecenie do wykonania, w drugiej- nazwę zadania, harmonogram oraz polecenie. Harmonogram ustalamy za pomocą składni znanej z systemowego crona.</p>
<pre><code> ┌───────────── minuty (0 - 59)

 │ ┌────────────── godziny (0 - 23)

 │ │ ┌─────────────── dzień miesiąca (1 - 31)

 │ │ │ ┌──────────────── miesiąc (1 - 12)

 │ │ │ │ ┌───────────────── dzień tygodnia (0 - 7) (0 - 6, niedziela do soboty, 7 to

 │ │ │ │ │                            również niedziela)

 * * * * *
</code></pre>
<p>Przykładowe zaplanowanie zadania</p>
<pre><code>SELECT - cron.schedule('select','* * * * *', 'SELECT 1');
</code></pre>
<p>Wszystkie zaplanowane zadania możemy znaleźć w tabeli <em>cron.job</em>.<br />Jeżeli korzystamy z większej liczby użytkowników do planowania zadań, każdy z nich może zobaczyć tylko swoje zadania. Ograniczenie to nie dotyczy użytkownika Postgres, który jest superuserem i może zobaczyć wszystkie zadania. Należy również pamiętać, że użytkownik, który jest “właścicielem” zadania, powinien mieć uprawnienia do obiektów, na których będzie pracował.</p>
<pre><code>postgres=# set role=test;

SET                                                                 ^

postgres=&gt; SELECT - cron.schedule('select','* * * * *', 'SELECT 1');

 schedule 

----------

        1

(1 row)

postgres=&gt; select * from cron.job;

 jobid | schedule - | command - | nodename - | nodeport | database | username | active | jobname 

-------+-----------+----------+-----------+----------+----------+----------+--------+---------

     1 | * * * * * | SELECT 1 | localhost |      5432 | postgres | test      | t        | select

(1 row)

postgres=&gt; set role=planer;

SET

postgres=&gt; select * from cron.job;

 jobid | schedule | command | nodename | nodeport | database | username | active | jobname 

-------+----------+---------+----------+----------+----------+----------+--------+---------

(0 rows)

postgres=&gt; set role=postgres;

SET

postgres=# select * from cron.job;

 jobid | schedule - | command - | nodename - | nodeport | database | username | active | jobname 

-------+-----------+----------+-----------+----------+----------+----------+--------+---------

     1 | * * * * * | SELECT 1 | localhost |      5432 | postgres | test      | t        | select

(1 row)
</code></pre>
<p>Wszystkie zadania, które tworzymy za pomocą funkcji <em>cron.schedule()</em>, są domyślnie tworzone w bazie Postgres, chyba że ustawiliśmy inaczej w parametrze <em>cron.database_name</em> oraz w innej bazie stworzyliśmy rozszerzenie. Chcąc tworzyć zadania dla innych baz, powinniśmy skorzystać z funkcji <em>cron.schedule_in_database()</em>. Przyjmuje ona wartości: nazwa zadania, harmonogram, polecenie, nazwa bazy, nazwa użytkownika oraz informację, czy zadanie powinno być aktywne. Jeżeli pominiemy ostatni parametr, domyślnie utworzy się jako aktywny.</p>
<pre><code>postgres=# SELECT cron.schedule_in_database('zadanie w innej bazie','0 6 * * *','SELECT 1', 'app_db','planer','f');

 schedule_in_database 

----------------------

                    2

(1 row)

postgres=# select * from cron.job;

 jobid | schedule - | command - | nodename - | nodeport | database | username | active |          jobname          

-------+-----------+----------+-----------+----------+----------+----------+--------+-----------------------

     1 | * * * * * | SELECT 1 | localhost |      5432 | postgres | test      | t        | select

     2 | 0 6 * * * | SELECT 1 | localhost |      5432 | app_db - | planer - | f        | zadanie w innej bazie

(2 rows)
</code></pre>
<p>Tak stworzone zadanie nie będzie się wykonywało do momentu zmiany flagi “active” na “t” za pomocą funkcji <em>cron.alter_job()</em> przyjmującej wartości: jobid, schedule, command, database, username, active. Jedynie pierwsza wartość jest obowiązkowa, pozostałe wartości możemy zmienić, aby zmodyfikować zadanie lub podać dla nich wartość NULL, aby zachować oryginalne wartości.</p>
<pre><code>postgres=# select cron.alter_job(2,null,null,null,null,'t');

 alter_job 

-----------

(1 row)

postgres=# select * from cron.job;

 jobid | schedule - | command - | nodename - | nodeport | database | username | active |          jobname          

-------+-----------+----------+-----------+----------+----------+----------+--------+-----------------------

     1 | * * * * * | SELECT 1 | localhost |      5432 | postgres | test      | t        | select

     2 | 0 6 * * * | SELECT 1 | localhost |      5432 | app_db - | planer - | t        | zadanie w innej bazie

(3 rows)
</code></pre>
<p>Zadania, które są już niepotrzebne, można usunąć za pomocą funkcji <em>cron.unschedule()</em>, która przyjmuje jako parametr jobid lub jobname.</p>
<pre><code>select cron.unschedule('zadanie w innej bazie');

select cron.unschedule(2);
</code></pre>
<p>Oba powyższe wywołania mają ten sam efekt, spowodują usunięcie drugiego zadania w bazie “app_db”. Jeżeli mielibyśmy więcej niż jedno zadanie z taką samą nazwą, zostanie usunięte tylko jedno, z najniższym jobid.</p>
<p>Historię wykonanych zadań możemy przejrzeć w tabeli <em>cron.job_run_details.</em></p>
<pre><code>postgres=# select * from cron.job_run_details ; 

 jobid | runid | job_pid | database | username | command - | status | - return_message - | start_time | end_time 

-------+-------+---------+----------+----------+----------+--------+-------------------+------------+----------

     1 |     27 |           | postgres | test      | SELECT 1 | failed | connection failed |               | 

     1 |      1 |           | postgres | test      | SELECT 1 | failed | connection failed |               |
</code></pre>
<p>Bardziej szczegółowe informacje odnośnie rezultatu zadania, lub jego błędu, znajdziemy w postgresowym pliku loga. Przykładowo:</p>
<pre><code>postgres@vagrant:/var/log/postgresql$ tail -f postgresql-15-main.log

2023-05-11 19:37:00.007 UTC [35712] LOG: - cron job 1 connection failed

2023-05-11 19:38:00.065 UTC [35712] LOG: - cron job 1 starting: SELECT 1

2023-05-11 19:38:00.070 UTC [45866] test@postgres FATAL: - password authentication failed for user "test"

2023-05-11 19:38:00.070 UTC [45866] test@postgres DETAIL: - User "test" has no password assigned.

        Connection matched pg_hba.conf line 97: "host     all                all                127.0.0.1/32               scram-sha-256"
</code></pre>
<p>W powyższym przykładzie widzimy, że pierwsze wykonania zadania nie powiodły się, ponieważ konfiguracja pg_hba.conf wymagała od użytkownika “test” hasła przy logowaniu. Po nadaniu mu hasła oraz stworzeniu pliku .pgpass w katalogu domowym użytkownika Postgres zadanie zaczęło się wykonywać poprawnie.</p>
<pre><code>postgres=# alter user test with password '123';

ALTER ROLE

postgres@vagrant:/var/log/postgresql$ cat ~/.pgpass

*:*:*:test:123

postgres@vagrant:/var/log/postgresql$ tail -f postgresql-15-main.log

2023-05-11 19:40:00.003 UTC [35712] LOG: - cron job 1 starting: SELECT 1

2023-05-11 19:40:00.011 UTC [35712] LOG: - cron job 1 completed: 1 row

postgres=# select * from cron.job_run_details where status = 'succeeded';

 jobid | runid | job_pid | database | username | command - | - status - | return_message |             start_time             |             end_time               

-------+-------+---------+----------+----------+----------+-----------+----------------+-------------------------------+-------------------------------

     1 | - 29 - | - 50703 | postgres | test      | SELECT 1 | succeeded | 1 row                | 2023-05-11 19:40:00.010307+00 | 2023-05-11 19:40:00.010722+00
</code></pre>
<p>Powyższy przykład obrazuje, jak w prosty sposób pg_cron może ułatwić planowanie oraz zarządzanie zadaniami cyklicznymi w Postgresie. Dzięki temu, że rozszerzenia oraz ich obiekty są zachowywane w kopiach zapasowych, możemy mieć pewność, iż wszystkie zaplanowane zadania zostaną zachowane nawet w przypadku odtwarzania klastra z backupu na innym serwerze.</p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post237&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post237&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post237&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_uruchamianie_zatrzymywanie_i_restartowanie_klastra_postgresql">Uruchamianie i zatrzymywanie PostgreSQL - pg_ctl i systemctl</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_role_grupowe_czyli_zbiorcze_zarzadzanie_uprawnieniami">PostgreSQL - role grupowe, czyli zbiorcze zarządzanie uprawnieniami</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL PG_PREWARM: jak w minute przyspieszyc zimny start bazy]]></title><description><![CDATA[Restart PostgreSQL czysci cache pamieciowy i pierwsze zapytania po starcie potrafia byc dotkliwie wolne. pg_prewarm rozwiazuje to w kilku liniach konfiguracji. Pokazujemy jak to dziala w praktyce.

Ro]]></description><link>https://jsystems.hashnode.dev/postgresql-pg-prewarm-tuning-cache</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-pg-prewarm-tuning-cache</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[performance]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:02:32 GMT</pubDate><content:encoded><![CDATA[<p>Restart PostgreSQL czysci cache pamieciowy i pierwsze zapytania po starcie potrafia byc dotkliwie wolne. pg_prewarm rozwiazuje to w kilku liniach konfiguracji. Pokazujemy jak to dziala w praktyce.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/comm/pg_prewarm.jpg" alt="Pg prewarm: PG_PREWARM" /></p>
<p>Rozszerzenie PG_PREWARM pozwala na ładowanie całych obiektów - bazodanowych do pamięci.
Dzięki PG_PREWARM możesz wybrać ładowany do - pamięci obiekt, możesz spowodować automatyczne ładowanie obiektów do - pamięci po restarcie, możesz przywracać stan shared_buffers po - restarcie.</p>
<p><strong>Z tego artykułu dowiesz się:</strong>  </p>
<ul>
<li>co to jest pg_prewarm i w jakim celu się go stosuje,- jak zainstalować pg_prewarm,- w jaki sposób za pomocą pg_prewarm ładować do pamięci całe obiekty bazodanowe,- jak z pomocą pg_prewarm przywrócić zawartość shared_buffers po restarcie</li>
</ul>
<p>PostgreSQL cierpi na problem ten sam, z którym borykają się inne współczesne systemy bazodanowe. Mianowicie każdy restart powoduje wyczyszczenie buforów,
<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">pamięci współdzielonej przez użytkowników Postgresa</a> do przechowywania najczęściej odczytywanych danych. Co za tym idzie,
<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">po każdym restarcie wydajność zapytań drastycznie spada</a>, ponieważ wszystkie bloki danych muszą być przeczytane z dysku przed wróceniem do wyniku.
Aby powrócić do wydajności sprzed restartu, musimy ponownie wypełnić je danymi, co może zająć dłuższy czas, szczególnie przy ogromnych wielkościach buforów współdzielonych (shared_buffers),
które nierzadko potrafią mieć setki gigabajtów.
Społeczność Postgresa wyszła temu naprzeciw i stworzyła rozszerzenie nazwane pg_prewarm. Pozwala ono na załadowanie obiektów do pamięci shared buffers.
Mamy też możliwość wskazać obiekty, które chcemy wczytać, wykonać automatyczny zrzut bloków w shared_buffers do pliku dumpa w momencie zatrzymania klastra lub cyklicznie,
aby nawet w przypadku crasha mieć możliwość załadowania danych do buforów. Wczytanie ze zrzutu pamięci może wykonać się automatycznie podczas startu klastra lub możemy wywołać funkcję - uruchamiającą procesy,
które zaczną wypełniać pamięć współdzieloną blokami danych z dumpa. Ładowanie zrzutów pamięci odbywa się zawsze za pomocą dwóch procesów roboczych uruchamianych w tle.<br />Rozszerzenie pg_prewarm jest dostępne z każdą instalacją Postgresa od wersji 11, wcześniejsze wersje mogą wymagać instalacji dodatkowych paczek.</p>
<h3>Konfiguracja pg_prewarm</h3>
<p>Pierwszym krokiem konfiguracji będzie weryfikacja, czy rozszerzenie jest dostępne w widoku pg_available_extensions, który zwraca wszystkie dostępne rozszerzenia razem z ich wersją oraz krótkim opisem.</p>
<pre><code>postgres=# select * from pg_available_extensions where name = 'pg_prewarm';

    name     | default_version | installed_version |          comment          

------------+-----------------+-------------------+-----------------------

 pg_prewarm | 1.2                |                       | prewarm relation data

(1 row)
</code></pre>
<p>Widzimy dostępny pg_prewarm w wersji 1.2, możemy więc przejść do następnego kroku, czyli załadowania rozszerzenia w aktualnej bazie. Dodając nowe rozszerzenia, należy pamiętać - o załadowaniu ich do każdej bazy, w której chcemy z niego korzystać, jednak w przypadku pg_prewarm wystarczy, że dodamy je w bazie Postgresql, ponieważ pamięć współdzielona shared_buffers jest wspólna dla wszystkich baz w klastrze.</p>
<pre><code>postgres=# create extension pg_prewarm;

CREATE EXTENSION

postgres=# select * from pg_available_extensions where name = 'pg_prewarm';

    name     | default_version | installed_version |          comment          

------------+-----------------+-------------------+-----------------------

 pg_prewarm | 1.2                | 1.2                  | prewarm relation data

(1 row)
</code></pre>
<p>Po załadowaniu rozszerzenia w kolumnie installed_version widzimy aktualnie zainstalowaną wersję danego rozszerzenia. Jeżeli zainstalowaliśmy paczkę z nowszą wersją rozszerzenia, które mamy załadowane w naszej bazie w widoku pg_available_extensions, będziemy widzieli nową, wyższą wersję w kolumnie default_version, a wartość w kolumnie installed version powiększy się po wywołaniu polecenia "<code>ALTER EXTENSION pg_prewarm UPDATE;</code>", które spowoduje aktualizację rozszerzenia.</p>
<h3>pg_prewarm w akcji</h3>
<p>Na potrzeby demonstracji prześlę do bazy “postgres” dumpa z przykładowymi danymi:</p>
<pre><code>postgres@vagrant:~$ wget https://jsystems.pl/nowy_blog/download/postgresql/tuning.zip 

postgres@vagrant:~$ psql &lt; tuning.sql
</code></pre>
<p>W dumpie znajduje się tabela “companies”, która ma ponad 2GB. Postgres, którego użyję, posiada wartość buforów współdzielonych ustawioną na 4GB, więc powinna się w nich zmieścić cała tabela, pozostawiając 2GB pamięci dla systemu.</p>
<pre><code>postgres=# show shared_buffers;

 shared_buffers 

----------------

 4GB

(1 row)

postgres=# \dt+ companies

                                         List of relations

 Schema |        Name        | Type - | - Owner - | Persistence | Access method | - Size - | Description 

--------+------------------+-------+----------+-------------+---------------+---------+-------------

 public | companies          | table | postgres | permanent - | heap             | 2177 MB |

 

(1 row)
</code></pre>
<p>Wykonam teraz kilkakrotnie ten sam select, aby załadować jak najwięcej bloków tabeli companies do pamięci.</p>
<pre><code>postgres=# explain (analyze,buffers)select * from companies;

                        QUERY PLAN                                                                      

------------------------------------------------------------------------------

 Seq Scan on companies - (cost=0.00..298560.52 rows=1999852 width=1060) (actual

           time=0.727..3457.154 rows=2000000 loops=1)

   Buffers: shared read=278562

 Planning:

   Buffers: shared hit=100 read=23

 Planning Time: 6.552 ms

 Execution Time: 3518.307 ms

(6 rows)

postgres=# explain (analyze,buffers)select * from companies;

                        QUERY PLAN                                                                      

------------------------------------------------------------------------------

 Seq Scan on companies - (cost=0.00..298560.52 rows=1999852 width=1060) (actual 

           time=0.032..593.641 rows=2000000 loops=1)

   Buffers: shared hit=32 read=278530

 Planning Time: 0.062 ms

 Execution Time: 646.925 ms

(4 rows)
</code></pre>
<p>Pierwsze wykonanie potrzebowało ok 3,5 sekundy do zwrócenia wyniku, po kilku kolejnych wykonaniach część bloków danych została wrzucona do pamięci, a czas wykonania zapytania spadł do około 650 milisekund. W wierszach “Buffers: …” widzimy informację o ilości bloków przeczytanych z pamięci oraz z dysku lub z pamięci podręcznej dysku, “hit” - wartości znalezione w pamięci RAM, “read” - wartości odczytane z dysku. Warto pamiętać, że Postgres korzysta również z cache, więc często nawet jeżeli czegoś nie mamy w buforach współdzielonych, sam fakt, że linux przechowuje je w pamięci podręcznej, pozwala nam znacznie przyspieszyć wykonanie takiego zapytania. Na powyższym przykładzie widzieliśmy, że pierwsze wykonanie czytało wszystko z dysku, przy następnych kolejne bloki lądowały w shared buforach, ale nadal większość czytana była z “dysku” przy jednoczesnym znacznym przyspieszeniu czasu wykonania zapytania. Jest to spowodowane właśnie korzystaniem z pamięci podręcznej, do której linux wrzuca często używane bloki danych.</p>
<p>Sprawdzę teraz, jak będzie wyglądał plan wykonania zapytania po ręcznym załadowaniu całej tabeli companies do pamięci współdzielonej. Zacznę od restartu serwera, aby upewnić się, że pamięć jest pusta - , następnie wywołuję funkcję wczytującą tabele to pamięci i ponownie wykonam select z explain.</p>
<pre><code>postgres=# select pg_prewarm('companies');

 pg_prewarm 

------------

     278562

(1 row)

 

postgres=# explain (analyze,buffers)select * from companies;

                                                       QUERY PLAN                                                                      

-------------------------------------------------------------------------------------------------------------------------

 Seq Scan on companies - (cost=0.00..298567.12 rows=2000512 width=1062) (actual time=0.047..177.284 rows=2000000 loops=1)

   Buffers: shared hit=278562

 Planning Time: 0.033 ms

 Execution Time: 227.135 ms

(4 rows)
</code></pre>
<p>Po wczytaniu całej tabeli czas potrzebny na wykonanie zapytania spadł ponownie o ponad połowę w porównaniu do wcześniejszego wyniku!</p>
<p>Powyższy test wykonany był w izolowanych warunkach, na bezczynnej bazie z wykorzystaniem tylko jednego zapytania i tabeli. Sprawdźmy jeszcze, jaką różnicę będziemy w stanie osiągnąć dla bardziej różnorodnego obciążenia wygenerowanego za pomocą pgbench.</p>
<p>Przeprowadziliśmy testy ręczne dla kilku wywołań, teraz sprawdzimy, jaki wzrost wydajności możemy osiągnąć przy użyciu masowych testów benchmarkiem PG_BENCH. Najpierw wygeneruję testowe dane, a następnie uruchomię test trwający minutę. Następnie zrestartuję serwer, aby upewnić się, że pamięci współdzielona i podręczna są wyczyszczone, załaduję tabele za pomocą pg_prewarm i wykonam test ponownie.</p>
<pre><code>postgres@vagrant:~$ pgbench -i -s 150

dropping old tables...

NOTICE: - table "pgbench_accounts" does not exist, skipping

NOTICE: - table "pgbench_branches" does not exist, skipping

NOTICE: - table "pgbench_history" does not exist, skipping

NOTICE: - table "pgbench_tellers" does not exist, skipping

creating tables...

generating data (client-side)...

15000000 of 15000000 tuples (100%) done (elapsed 10.28 s, remaining 0.00 s)

vacuuming...

creating primary keys...

done in 17.21 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 10.38 s, vacuum 0.52 s, primary keys 6.21 s).

postgres=# \dt+

                                         List of relations

 Schema |        Name        | Type - | - Owner - | Persistence | Access method | - Size - | Description 

--------+------------------+-------+----------+-------------+---------------+---------+-------------

 public | pgbench_accounts | table | postgres | permanent - | heap             | 1922 MB | 

 public | pgbench_branches | table | postgres | permanent - | heap             | 40 kB - | 

 public | pgbench_history - | table | postgres | permanent - | heap             | 0 bytes | 

 public | pgbench_tellers - | table | postgres | permanent - | heap             | 104 kB - | 

(4 rows)

postgres@vagrant:~$ pgbench -T 60 -S

pgbench (15.2 (Ubuntu 15.2-1.pgdg22.04+1))

starting vacuum...end.

transaction type: &lt;builtin: select only&gt;

scaling factor: 150

query mode: simple

number of clients: 1

number of threads: 1

maximum number of tries: 1

duration: 60 s

number of transactions actually processed: 373662

number of failed transactions: 0 (0.000%)

latency average = 0.161 ms

initial connection time = 1.953 ms

tps = 6227.712352 (without initial connection time)
</code></pre>
<p>Pgbench świeżo po restarcie systemu, z pustymi buforami, w ciągu minuty osiągnął - w sumie 373662 transakcji, 6227 transakcji na sekundę. Wykonam teraz restart serwera i uruchomię test ponownie, ale po wcześniejszym załadowaniu największej tabeli do shared buforów.</p>
<pre><code>postgres=# select pg_prewarm('pgbench_accounts');

 pg_prewarm 

------------

     248895

(1 row)

postgres@vagrant:~$ pgbench -T 60 -S

pgbench (15.2 (Ubuntu 15.2-1.pgdg22.04+1))

starting vacuum...end.

transaction type: &lt;builtin: select only&gt;

scaling factor: 150

query mode: simple

number of clients: 1

number of threads: 1

maximum number of tries: 1

duration: 60 s

number of transactions actually processed: 1173817

number of failed transactions: 0 (0.000%)

latency average = 0.051 ms

initial connection time = 1.689 ms

tps = 19559.914627 (without initial connection time)
</code></pre>
<p>Po wstępnym “rozgrzaniu” buforów pgbench osiągnął 1173817 transakcji w sumie, a 19559 transakcji na sekundę, czyli około trzykrotnie lepszy rezultat. Test był przeprowadzony na małej wielkości shared_buffers, tylko kilku tabelach i mało zróżnicowanych zapytaniach. Im więcej obiektów odpytujemy i im większa jest pamięć współdzielona, tym dłużej może trwać rozgrzewanie buforów, a tym samym niższa wydajność bazy może utrzymywać się przez dłuższy czas po restarcie, żeby finalnie zapytania powróciły do wydajności przed restartem.</p>
<p>W powyższych przykładach załadowaliśmy dane z tabeli ręcznie, ale pg_prewarm ma możliwość robienia tego za nas automatycznie, bez jakiejkolwiek ingerencji z naszej strony.<br />Działa to w ten sposób, że pg_prewarm zrzuca co jakiś czas stan bufora shared_buffers na dysk. W przypadku restartu, po uruchomieniu serwera wczytywany jest stan bufora z dysku z chwili niewiele przed restartem.<br />Aby z tej funkcjonalności skorzystać, musimy dodać <em>pg_prewarm</em> to do parametru <em>shared_preload_libraries</em> oraz dodać dwa kolejne parametry dla pg_prewarma w pliku postgresql.conf, a także zrestartować klaster. Parametry te, oprócz <em>autoprewarm_interval</em>, są wczytywane tylko podczas startu Postgresa.</p>
<pre><code>shared_preload_libraries = 'pg_prewarm'

pg_prewarm.autoprewarm = true

pg_prewarm.autoprewarm_interval = 300s
</code></pre>
<p>Od tej chwili pg_prewarm będzie wykonywał zrzut pamięci co <em>autoprewarm_interval</em> sekund oraz w momencie zatrzymania instancji. Podczas startu uruchomi proces roboczy, który załaduje bloki ze zrzutu do pamięci. W ten sposób odtworzymy stan buforów z chwili max “pg_prewarm.autoprewarm_interval” sekund przed restartem.</p>
<p>Jak widać na powyższym przykładzie restart i spowodowane tym wyczyszczenie pamięci współdzielonej Postgresa nie musi być skomplikowane. W łatwy sposób możemy przeprowadzić te czynności.</p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post239&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post239&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post239&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/migracja_oracle_do_postgresql_kompletny_przewodnik">Migracja z Oracle do PostgreSQL w praktyce</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/co-to-jest-knime-przewodnik">Co to jest KNIME? Tutorial krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/co-to-jest-snowflake">Co to jest Snowflake? Prosty przewodnik po chmurowej hurtowni danych</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/wspolczesne-rozwiazania-big-data-2026">Współczesne rozwiązania Big Data 2026</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL PG_AUDIT: jak sledzic uzytkownikow, zmiany i selecty na obiektach]]></title><description><![CDATA[Audyt dostepu do danych to wymog coraz wiekszej liczby firm - i standardowe logi PostgreSQL tego nie pokrywaja. Rozszerzenie pgAudit dodaje granularny audyt uzytkownikow i selectow. Ten tekst pokazuje]]></description><link>https://jsystems.hashnode.dev/postgresql-pg-audit-sledzenie-uzytkownikow-selectow</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-pg-audit-sledzenie-uzytkownikow-selectow</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[Security]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sun, 06 Sep 2026 07:02:08 GMT</pubDate><content:encoded><![CDATA[<p>Audyt dostepu do danych to wymog coraz wiekszej liczby firm - i standardowe logi PostgreSQL tego nie pokrywaja. Rozszerzenie pgAudit dodaje granularny audyt uzytkownikow i selectow. Ten tekst pokazuje jak to skonfigurowac.</p>
<p>Rozszerzenie PG_AUDIT umożliwia śledzenie działań użytkowników, a także zmian i selectów na tabelach.</p>
<p><strong>Z tego artykułu dowiesz się:</strong>  </p>
<ul>
<li>co to jest pg_audit i w jakim celu się go stosuje,- jakie są alternatywy dla pg_audit,- jak zainstalować pg_audit na Ubuntu,- jak zainstalować pg_audit na systemach z rodziny Red Hat,- jak za pomocą pg_audit audytować wybrane obiekty.</li>
</ul>
<h3>Audytowanie w PostgreSQL</h3>
<p>PostgreSQL udostępnia zestaw funkcjonalności umożliwiających skonfigurowanie podstawowego audytowania aktywności do logu. Między innymi audytowanie połączeń do bazy za pomocą parametrów: log_connection, log_disconnection, audytowanie zapytań dzięki parametrom: log_statement czy audytowanie cięższych zapytań: log_temp_files, log_lock_waits. Rozwiązanie to nie wymaga instalowania żadnych dodatkowych rozszerzeń, nie tworzy nowych obiektów i triggerów w bazie, dzięki temu, że wyniki są zapisywane poza klastrem, w pliku loga, nie powoduje obciążenia Postgresa dodatkowymi transakcjami i obiektami, które muszą być obsłużone przez autovacuum. Ale z drugiej strony, nie ma możliwości ograniczenia audytowanych obiektów. Zawsze zapisujemy aktywność w całej instancji, dla wszystkich baz, przez wszystkich użytkowników, przez co dobrze sprawdza się tylko dla baz o małej aktywności. Przy bazach z większym obciążeniem metoda ta może wygenerować bardzo dużo wpisów do pliku loga, nawet kilkadziesiąt GB na godzinę lub więcej.</p>
<p>Innym bardzo prostym sposobem na stworzenie audytowania obiektów, również bez instalacji żadnych dodatkowych rozszerzeń, jest skorzystanie z triggerów. Tutaj już z możliwością wskazania obiektów, które będę audytował.<br />Na początek stworzę tabelę, do której będę logował wszystkie zapytania na wybranych obiektach.</p>
<pre><code>CREATE TABLE audyt.dziennik_aktywnosci (

    schemat text NOT NULL,

    tabela text NOT NULL,

    uzytkownik text,

    typ text,

    data TIMESTAMP WITH TIME zone NOT NULL DEFAULT CURRENT_TIMESTAMP,

    stara_wartosc text,

    nowa_wartosc text,

    zapytanie text

);
</code></pre>
<p>Następnie tworzę funkcję, którą będziemy wywoływać triggerem po każdej wykonanej operacji DML (Data Modification Language - INSERT, UPDATE, DELETE).</p>
<pre><code>CREATE OR REPLACE FUNCTION audyt.zmiana_wartosci() RETURNS TRIGGER AS \(body\)

DECLARE

    stara_wartosc TEXT;

    nowa_wartosc TEXT;

BEGIN

    IF (TG_OP = 'UPDATE') THEN

        stara_wartosc:= ROW(OLD.*);

        nowa_wartosc:= ROW(NEW.*);

        INSERT INTO audyt.dziennik_aktywnosci (schemat,tabela,uzytkownik,typ,stara_wartosc,nowa_wartosc,zapytanie) 

        VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),stara_wartosc,nowa_wartosc, current_query());

        RETURN NEW;

    ELSIF (TG_OP = 'DELETE') THEN

        stara_wartosc:= ROW(OLD.*);

        INSERT INTO audyt.dziennik_aktywnosci (schemat,tabela,uzytkownik,typ,stara_wartosc,zapytanie)

        VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),stara_wartosc, current_query());

        RETURN OLD;

    ELSIF (TG_OP = 'INSERT') THEN

        nowa_wartosc:= ROW(NEW.*);

        INSERT INTO audyt.dziennik_aktywnosci (schemat,tabela,uzytkownik,typ,nowa_wartosc,zapytanie) 

        VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),nowa_wartosc, current_query());

        RETURN NEW;

    ELSE

        RAISE WARNING '[audyt.zmiana_wartosci] - Other action occurred: %, at %',TG_OP,now();

        RETURN NULL;

    END IF;

EXCEPTION

    WHEN data_exception THEN

        RAISE WARNING '[audyt.zmiana_wartosci] - UDF ERROR [DATA EXCEPTION] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;

        RETURN NULL;

    WHEN unique_violation THEN

        RAISE WARNING '[audyt.zmiana_wartosci] - UDF ERROR [UNIQUE] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;

        RETURN NULL;

    WHEN OTHERS THEN

        RAISE WARNING '[audyt.zmiana_wartosci] - UDF ERROR [OTHER] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;

        RETURN NULL;

END;

\(body\)

LANGUAGE plpgsql

SECURITY DEFINER

SET search_path = pg_catalog, audyt;
</code></pre>
<p>Stworzę trigger dla tabeli, którą chcę audytować.</p>
<pre><code>CREATE TRIGGER audyt_test

AFTER INSERT OR UPDATE OR DELETE ON test

FOR EACH ROW EXECUTE PROCEDURE audyt.zmiana_wartosci();
</code></pre>
<p>Po wykonaniu każdej operacji podanej w triggerze do tabeli audyt.dziennik_aktywnosci zostanie dodany nowy wpis.</p>
<pre><code>SELECT * FROM audyt.dziennik_aktywnosci ;

-[ RECORD 1 ]-+---------------------------------

schemat        | public

tabela          | test

uzytkownik     | postgres

typ             | I

data             | 2023-05-19 19:55:28.370979+00

stara_wartosc | 

nowa_wartosc - | (1,2)

zapytanie      | INSERT INTO test VALUES (1,2);

-[ RECORD 2 ]-+---------------------------------

schemat        | public

tabela          | test

uzytkownik     | postgres

typ             | U

data             | 2023-05-19 19:56:06.715819+00

stara_wartosc | (2,2)

nowa_wartosc - | (2,2)

zapytanie      | UPDATE test SET x=2 WHERE y = 2;

-[ RECORD 3 ]-+---------------------------------

schemat        | public

tabela          | test

uzytkownik     | postgres

typ             | D

data             | 2023-05-19 19:56:57.534169+00

stara_wartosc | (2,2)

nowa_wartosc - | 

zapytanie      | DELETE FROM test WHERE x=2;

(3 rows)
</code></pre>
<p>Od razu można zauważyć, że tutaj audytować można tylko zmiany wartości w tabeli (AFTER INSERT OR UPDATE OR DELETE). Nie ma możliwości wywołania triggera dla zapytań, które tylko odczytują dane. Kolejnym problemem jest fakt, że każda transakcja zmieniająca dane w audytowanej tabeli zostanie wydłużona o czas potrzebny na wywołanie funkcji, co przy często modyfikowanej tabeli może się przełożyć sumarycznie na znacznie niższą liczbę transakcji na sekundę.</p>
<h3>PgAudit - zaawansowane audytowanie obiektów i sesji użytkowników</h3>
<p>PgAudit rozszerza możliwości audytowania w Postgresie o bardziej precyzyjną kontrolę nad logowaniem sesji użytkowników i obiektów. Logowanie odbywa się do pliku na dysku. Rozwiązanie powyższe jest dużo lżejsze niż to z wykorzystaniem triggerów, więc jego wpływ na audytowaną instancję jest znacznie mniejszy.</p>
<p>Pakiety instalacyjne dla rozszerzenia dostępne są w oficjalnych repozytoriach PGDG (PostgreSQL Global Development Group).</p>
<pre><code>### Ubuntu/Debian

sudo apt-get -y install postgresql-15-pgaudit

### RHEL/CentOS

sudo yum install -y pgaudit17_15.x86_64
</code></pre>
<p>Przed stworzeniem rozszerzenia w bazie muszę je dodać też do parametru “shared_preload_libraries” i zrestartować instancję.</p>
<pre><code>postgres@vagrant:~$ psql -c "ALTER SYSTEM SET shared_preload_libraries=pg_cron,pgaudit"

# restart na Debian/Ubuntu

/usr/lib/postgresql/15/bin/pg_ctl -D /katalog/pg/data restart -m fast

# restart na RHEL/Centos

/usr/pgsql-15/bin/pg_ctl -D /katalog/pg/data restart -m fast
</code></pre>
<p>Po restarcie upewniam się, że rozszerzenie zostało poprawnie załadowane.</p>
<pre><code>SHOW shared_preload_libraries;

  shared_preload_libraries -  

-----------------------------

  pg_cron, pgaudit

SELECT * FROM pg_available_extensions WHERE name LIKE '%audit';

  name - | default_version | installed_version |                comment                

---------+-----------------+-------------------+---------------------------------

 pgaudit | 1.7                |                       | provides auditing functionality
</code></pre>
<p>Teraz mogę przejść do stworzenia rozszerzenia w bazie oraz ustawienia poziomu audytowania.</p>
<pre><code>CREATE EXTENSION pgaudit;

SELECT * FROM pg_available_extensions WHERE name LIKE '%audit';

  name - | default_version | installed_version |                comment                

---------+-----------------+-------------------+---------------------------------

 pgaudit | 1.7                | 1.7                  | provides auditing functionality

ALTER SYSTEM SET pgaudit.log TO 'read, write';

SELECT pg_reload_conf();

SHOW pgaudit.log;

 pgaudit.log 

-------------

 read, write
</code></pre>
<p>Parameter pgaudit.log przyjmuje następujące wartości:</p>
<ul>
<li>READ - zapytań odczytujących dane (SELECT, COPY),</li>
<li>WRITE - zapytań zmieniających dane (INSERT, UPDATE, TRUNCATE oraz COPY, jeżeli miejscem docelowym jest relacja w bazie),</li>
<li>FUNCTION - funkcji oraz bloków DO,</li>
<li>ROLE - roli i użytkowników (GRANT, REVOKE, CREATE/ALTER/DROP ROLE),</li>
<li>DDL (zmiany obiektów, które nie należą do klasy ROLE),</li>
<li>MISC (pozostałe, np. DISCARD, FETCH, CHECKPOINT, VACUUM),</li>
<li>ALL - wszystkie powyższe.</li>
</ul>
<p>Wartości można podawać oddzielone przecinkiem, na powyższym przykładzie audytowane będą wszystkie zapytania, które odczytują i zmieniają dane (READ, WRITE). Można też użyć wartości <em>'all, -misc, -ddl'</em>, za pomocą którego rozpocznę audytowanie wszystkiego oprócz MISC oraz DDL.</p>
<p>Poziom audytu można ustawić też dla każdego z użytkowników oraz dla każdej bazy z osobna, na przykład:</p>
<pre><code>ALTER USER superuser SET pgaudit.log TO 'read, write, ddl';

ALTER DATABASE testdb SET pgaudit.log=read,write,function;
</code></pre>
<p>Po włączeniu audytowania Postgres zacznie dodawać do swojego pliku loga dodatkowe wpisy:</p>
<pre><code>postgres@vagrant:~/15/main$ less /var/log/postgresql/postgresql-15-main.log

2023-05-19 19:51:00.153 UTC [5458] test@postgres LOG: - AUDIT: SESSION,1,1,READ,SELECT,,,SELECT 1,&lt;not logged&gt;

2023-05-19 19:51:12.648 UTC [5400] postgres@postgres LOG: - AUDIT: SESSION,38,1,WRITE,INSERT,,,"INSERT INTO test VALUES (1,2);",&lt;not logged&gt;

2023-05-19 19:51:58.831 UTC [5400] postgres@postgres LOG: - AUDIT: SESSION,43,1,WRITE,UPDATE,,,UPDATE test SET x=2 WHERE y = 2;,&lt;not logged&gt;
</code></pre>
<p> na końcu każdej linii oznacza, że pgaudit nie loguje wartości parametrów dla zapytań. Jeżeli potrzebowałbym logować parametry zapytań, można je dodać za pomocą parametru <em>pgaudit.log_parameter = on</em>, po czym należy przeładować konfigurację. Parametry pojawią się na końcu linii, oddzielone przecinkiem, a dla zapytań bez parametrów dodana zostanie końcówka .</p>
<pre><code>2023-05-19 20:12:00.043 UTC [1683] LOG: - AUDIT: SESSION,181,1,WRITE,INSERT,,,"INSERT INTO cron.job_run_details (jobid, runid, database, username, command, status) VALUES (\(1,\)2,\(3,\)4,\(5,\)6)","1,5273,postgres,test,SELECT 1,starting"

2023-05-19 20:12:00.057 UTC [5556] test@postgres LOG: - AUDIT: SESSION,1,1,READ,SELECT,,,SELECT 1,&lt;none&gt;
</code></pre>
<h3>Audytowanie poszczególnych obiektów</h3>
<p>PgAudit umożliwia logowanie zapytań na wybranych obiektach. Aby z niego skorzystać, należy stworzyć dedykową rolę, która zostanie “audytorem” i dodać ją do parametru <em>pgaudit.role</em>. Zanim rozpocznę, wyłączę też poprzednie globalne ustawienia audytowania.</p>
<pre><code>ALTER SYSTEM RESET pgaudit.log;

SELECT pg_reload_conf();

SHOW pgaudit.log;

 pgaudit.log 

-------------

 none

CREATE ROLE audytor NOLOGIN;

ALTER SYSTEM SET pgaudit.role TO 'audytor';

SELECT pg_reload_conf();
</code></pre>
<p>Od tego momentu każda relacja i kolumna, do której “audytor” ma dostęp, będzie audytowana do pliku loga pod kątem operacji, do której ma uprawnienia.</p>
<pre><code>CREATE TABLE tabela_audytowana (x int, y int);

GRANT SELECT ON tabela_audytowana TO audytor;

INSERT INTO tabela_audytowana VALUES (1,2);

SELECT * FROM tabela_audytowana ;

 x | y 

---+---

 1 | 2

2023-05-19 20:27:30.697 UTC [5622] postgres@postgres LOG: - AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.tabela_audytowana,SELECT * FROM tabela_audytowana ;,&lt;none&gt;
</code></pre>
<p>W tym przypadku audytorowi nadałem uprawnienia SELECT, dlatego w logu pojawił się tylko jeden wpis odnośnie SELECT, INSERT został pominięty. Zmienił się też kontekst, <em>AUDIT: OBJECT</em> zamiast wcześniejszego <em>AUDIT: SESSION</em>.</p>
<p>Parametr <em>pgaudit.role</em> przyjmuje jako wartość tylko jednego użytkownika, jeżeli potrzebowałbym stworzyć kilku audytorów, na przykład dla każdej bazy lub aplikacji osobną rolę, mógłbym skorzystać z możliwości Postgresa do dziedziczenia roli.</p>
<pre><code>CREATE ROLE audytor_odczyt NOLOGIN;

CREATE ROLE audytor_zapis NOLOGIN;

GRANT audytor_odczyt TO audytor;

GRANT audytor_zapis TO audytor;
</code></pre>
<p>Następnie należałoby dodać odpowiednie uprawnienia. Chcę logować zapytania, które czytają wartości z kolumn ‘x’ i ‘y’, wszystkie INSERT i DELETE oraz UPDATE na kolumnie ‘y’.</p>
<pre><code>GRANT SELECT (x,y) ON tabela_audytowana TO audytor_odczyt ;

GRANT INSERT,UPDATE(y),DELETE ON tabela_audytowana TO audytor_zapis ;

INSERT INTO tabela_audytowana VALUES (2,3);

UPDATE tabela_audytowana SET x = 5 WHERE x = 2;

UPDATE tabela_audytowana SET y = 5 WHERE x = 5;

SELECT * FROM tabela_audytowana ;

 x | y 

---+---

 1 | 2

 5 | 5

2023-05-19 20:40:15.614 UTC [5675] postgres@postgres LOG: - AUDIT: OBJECT,1,1,WRITE,INSERT,TABLE,public.tabela_audytowana,"INSERT INTO tabela_audytowana VALUES (2,3);",&lt;none&gt;

2023-05-19 20:40:49.308 UTC [5675] postgres@postgres LOG: - AUDIT: OBJECT,4,1,WRITE,UPDATE,TABLE,public.tabela_audytowana,UPDATE tabela_audytowana SET y = 5 WHERE x = 5;,&lt;none&gt;

2023-05-19 20:42:51.538 UTC [5675] postgres@postgres LOG: - AUDIT: OBJECT,5,1,READ,SELECT,TABLE,public.tabela_audytowana,SELECT * FROM tabela_audytowana ;,&lt;none&gt;
</code></pre>
<p>Ważna uwaga, jeżeli skonfigurowałbym audytowanie sesji użytkowników oraz poszczególnych obiektów jednocześnie, pgaudit dodawałby podwójne wpisy dla wszystkich pasujących zapytań, różniłby się tylko kontekst, “SESSION” lub “OBJECT”.</p>
<p>Tak generowane logi mogę wyparsować w bashu za pomocą narzędzi takich jak grep, awk, - i tym podobne, aby zwracały interesujące mnie wiersze z audytu. Mogę również wczytać plik loga do tabeli w Postgresie i przeanalizować sobie go za pomocą SQLa lub przygotowanych wcześniej widoków, funkcji, itp.</p>
<p>Aby wczytać plik loga do tabeli, muszę się upewnić, że parametry w Postgresie są odpowiednio ustawione. Szczególnie na Ubuntu, gdzie często logging collector jest domyślnie wyłączony, a logowanie odbywa się za pomocą przekierowania informacji zwracanych przez proces Postgrsa do pliku tekstowego. Parametr <em>logging_collector</em> przy zmianie wymaga restartu Postgresa.</p>
<pre><code>CREATE TABLE postgres_log

(

  log_time timestamp(3) with time zone,

  user_name text,

  database_name text,

  process_id integer,

  connection_from text,

  session_id text,

  session_line_num bigint,

  command_tag text,

  session_start_time timestamp with time zone,

  virtual_transaction_id text,

  transaction_id bigint,

  error_severity text,

  sql_state_code text,

  message text,

  detail text,

  hint text,

  internal_query text,

  internal_query_pos integer,

  context text,

  query text,

  query_pos integer,

  location text,

  application_name text,

  backend_type text,

  leader_pid integer,

  query_id bigint,

  PRIMARY KEY (session_id, session_line_num)

);

# ścieżka do pliku powinna odpowiadać ścieżce do pliku loga do którego zapisuje postgres

COPY postgres_log FROM '/var/log/postgresql/postgresql.csv' WITH csv;
</code></pre>
<p>Tak stworzoną tabelę mogę w łatwy sposób przeszukiwać za pomocą SQLa.</p>
<pre><code>postgres=# select * from postgres_log where message like 'AUDIT%' AND command_tag = 'INSERT';

-[ RECORD 1] ----------+-------------------------------------------------------------------------------------------------------------------

log_time                  | 2023-05-23 20:07:45.589+00

user_name                  | postgres

database_name             | postgres

process_id                | 10503

connection_from          | [local]

session_id                | 646d16f7.2907

session_line_num        | 3

command_tag               | INSERT

session_start_time      | 2023-05-23 19:41:43+00

virtual_transaction_id | 4/100

transaction_id           | 0

error_severity           | LOG

sql_state_code           | 00000

message                    | AUDIT: OBJECT,1,1,WRITE,INSERT,TABLE,public.tabela_audytowana,"insert into tabela_audytowana values (2,3);",&lt;none&gt;

detail                     | 

hint                       | 

internal_query           | 

internal_query_pos      | 

context                    | 

query                       | 

query_pos                  | 

location                  | 

application_name        | psql

backend_type             | client backend

leader_pid                | 

query_id                  | 0
</code></pre>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post241&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post241&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post241&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_upgrade_klastra">Upgrade klastra PostgreSQL - pg_upgrade krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_rodzaje_replikacji">PostgreSQL - Rodzaje replikacji</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL od podstaw: slownik najwazniejszych pojec administracyjnych]]></title><description><![CDATA[Terminologia PostgreSQL potrafi zaskoczyc osoby przychodzace z innych baz danych - 'klaster' nie znaczy tu tego, co w Oracle czy MS SQL. Ten tekst porzadkuje najwazniejsze pojecia raz na zawsze.
Słów ]]></description><link>https://jsystems.hashnode.dev/postgresql-najwazniejsze-pojecia-slownik</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-najwazniejsze-pojecia-slownik</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[sysadmin]]></category><category><![CDATA[SQL]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sat, 05 Sep 2026 07:04:00 GMT</pubDate><content:encoded><![CDATA[<p>Terminologia PostgreSQL potrafi zaskoczyc osoby przychodzace z innych baz danych - 'klaster' nie znaczy tu tego, co w Oracle czy MS SQL. Ten tekst porzadkuje najwazniejsze pojecia raz na zawsze.</p>
<p><strong>Słów kilka o najważniejszych pojęciach związanych z administracją serwerami PostgreSQL. Od bazy danych do high availability.</strong></p>
<p><strong>Z tego artykułu dowiesz się:</strong></p>
<ul>
<li>jakie są najważniejsze pojęcia związane z bazami danych PostgreSQL,- jaki jest podział fizyczny i logiczny klastra PostgreSQL,- czym są i jak działają pliki WAL,- czym jest i jak działa checkpoint,- jaki jest związek pomiędzy plikami WAL a checkpointami,- jakie są rodzaje kopii zapasowych i czym się charakteryzują,- czym jest replikacja, w jakim celu się ją stosuje i jak działa,- czym jest HA - High Availability - czyli jak zapewnić dostępność klastra przez nawet 99,999% czasu.</li>
</ul>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/005/cala_struktura.jpg" alt="Cala struktura: PostgreSQL" /></p>
<h3>Klaster</h3>
<p>Pojedyncza instancja instalacji serwera PostgreSQL. - Klaster zawiera wszystkie pliki niezbędne do działania serwera PostgreSQL. Są to pliki danych, pliki konfiguracyjne, a także inne pliki niezbędne do działania serwera np. pliki WAL.</p>
<p>Klaster zawiera w sobie bazy danych, przestrzenie tabel, schematy etc. Klaster ma wspólną konfigurację w plikach takich jak postgresql.conf, postgresql.auto.conf czy pg_hba. Ustawienia na tym poziomie dotyczą wszystkich baz danych.</p>
<p>Przestrzeń pamięci operacyjnej klastra jest współdzielona przez wszystkie zawarte w nim bazy danych. Wspólne są też procesy.</p>
<p>Fizyczne kopie zapasowe - (zimne i gorące) robimy zawsze na poziomie klastra. Nie możemy zrobić fizycznej (w przeciwieństwie do logicznej) kopii zapasowej wybranej bazy danych.</p>
<h3>PGDATA</h3>
<p>Główny katalog klastra PostgreSQL. Znajdują się tu wszystkie pliki danych, pliki konfiguracyjne oraz wszelkie pliki niezbędne do działania klastra z wyłączeniem plików binarnych, które znajdują się w innej lokalizacji.</p>
<h3>Baza danych</h3>
<p>Baza danych to osobny zbiór danych w ramach klastra. Umożliwiają odseparowanie logiczne danych np. różnych systemów.</p>
<p>Bazy danych są strukturą logiczną, choć wiążą się ze strukturą fizyczną. Każda baza danych ma swój osobny katalog na serwerze. - Dane pomiędzy poszczególnymi bazami danych są od siebie odseparowane fizycznie i logicznie. Niestety nie są na tyle niezależne jak np. w Oracle czy SQL Server, by można było osobno robić fizyczne kopie zapasowe i osobno przywracać bazy danych. Co prawda można wykonać eksport danych do pliku tekstowego za pomocą pg_dump, ale nie jest to kopia zapasowa w pełnym tego słowa znaczeniu i nie pozwala np. przywrócić bazy do wybranego punktu w czasie.</p>
<h3>Przestrzeń tabel</h3>
<p>Przestrzenie tabel fizycznie są katalogami. Zakłada się je na przykład, by trzymać część danych na osobnym dysku. Robi się tak, - kiedy chcemy rozłożyć obciążenie I/O na kilka dysków i dzięki temu poprawić wydajność. Możemy też wykorzystać osobne przestrzenie tabel, gdy kończy się miejsce na dysku zawierającym klaster PostgreSQL. W przestrzeniach tabel możemy umieszczać pojedyncze obiekty (tabele, indeksy etc.), ale też całe bazy danych.</p>
<h3>Użytkownik/rola</h3>
<p>Użytkownik to po prostu konto na które się logujemy. Umożliwia łączenie się do serwera bazodanowego i wykonywanie na nim operacji. Jeśli potrzebujemy konta które ma być właścicielem jakichś obiektów ale nikt nie powinien się na nie logować, tworzymy rolę czyli użytkownika bez możliwości logowania.</p>
<h3>Sesja</h3>
<p>Sesja to połączenie do bazy danych. Łącząc się do klastra zawsze łączymy się do wybranej bazy danych jako konkretny użytkownik. Każda sesja jest związana ze swoim procesem w systemie operacyjnym po stronie serwera baz danych.</p>
<h3>Tuple (krotka)</h3>
<p>PostgreSQL wywodzi się od Ingresa, systemu zarządzania bazami danych mającego swoje początki na Uniwersytecie Kalifornijskim Berkeley. Dlatego też wiele pojęć z którymi możemy spotkać się w dokumentacji Postgresa, bądź słuchając/czytając ludzi zajmujących się głównie postgresem, możemy usłyszeć nazwy niepokrywające się z pozostałymi systemami danych.
Pierwszy przykład to właśnie “tuple”, po polsku “krotka” czyli uporządkowana kolekcja stałych wartości lub inaczej tablica stałych wartości. A tak naprawdę “tuple” to po prostu wiersz w tabeli.</p>
<h3>Relation (relacja)</h3>
<p>Tak samo jak w przypadku tuple, relacja to w języku naukowym to po prostu tabela. Warto o tym pamiętać, ponieważ nawet sam PostgreSQL się do tego w ten sposób odwołuje. Np. w widoku pg_class, wartość relkind wskazuje na typ obiektu. I tak kolejno: i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table, I = partitioned index i wreszcie r = table.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/005/schematy.jpg" alt="Schematy: PostgreSQL" />  </p>
<h3>Schemat</h3>
<p>Bazy danych zawierają jeden lub więcej schematów, w których znajdują się obiekty bazodanowe. Podział na schematy nie wiąże się z podziałem fizycznym, jest to tylko podział logiczny. Umożliwiają posiadanie kilku tabel o tej samej nazwie, ale w różnych schematach. Pozwalają też łatwiej zarządzać obiektami bazy danych dzięki zorganizowaniu w podgrupy, a także zbiorowe nadawanie i odbieranie uprawnień do obiektów.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/005/pliki_wal.jpg" alt="Pliki wal: PostgreSQL" />  </p>
<h3>Pliki WAL</h3>
<p>Zanim zmiany na danych zostaną wprowadzone do plików danych, odnotowywane są w plikach WAL. Zapis do plików WAL musi zawierać wszystko co potrzebne do powtórzenia operacji. Zapis do plików danych następuje w zdarzeniu “checkpoint”, wtedy utrwalane są w nich wszystkie brudne bloki - czyli zmiany które znajdują się tylko w plikach WAL, a nie zostały jeszcze zmienione na poziomie plików danych. Pliki WAL są niezbędne w sytuacji odtwarzania stanu klastra po ewentualnej awarii. W takiej sytuacji przy uruchamianiu serwer PostgreSQL odczytuje wpisy z plików WAL od ostatniego checkpointa i powtarza je, celem odtworzenia stanu klastra tuż przed awarią. Po takim awaryjnym odtworzeniu następuje automatyczny checkpoint.</p>
<h3>Checkpoint</h3>
<p>W trakcie checkpointa następuje zapis wszystkich brudnych bloków do plików danych. W przypadku awarii PostgreSQL sprawdza punkt czasowy ostatniego checkpoint'a, by określić punkt, od którego ma rozpocząć odzyskiwanie REDO na podstawie plików WAL. Dzięki temu wie, od którego pliku WAL i jakiego offsetu w tym pliku ma rozpocząć odzyskiwanie.</p>
<h3>Fizyczna kopia zapasowa</h3>
<p>Kopia klastra zawierająca pliki danych, pliki konfiguracyjne - i inne pliki niezbędne do działania klastra. Taka kopia umożliwia odtworzenie tylko całego klastra, a nie pojedynczych baz danych.
Dzięki kopii fizycznej i plikom WAL możemy odtworzyć klaster do wskazanego punktu w czasie.
Takie kopie zapasowe tworzymy np za pomocą pg_basebackup.</p>
<h3>Logiczna kopia zapasowa</h3>
<p>To kopia zawierająca instrukcje tworzenia i wypełniania struktur bazodanowych, użytkowników etc. Dotyczy więc tylko logicznej struktury danych. Nie zawiera plików konfiguracyjnych klastra. Plikiem wynikowym może być plik SQL lub plik binarny. Nie współpracuje z plikami WAL, więc nie umożliwia odtworzenia klastra do wskazanego punktu w czasie. Pozwala tworzyć kopie zapasowe dla wybranych baz danych, ale także np dla wybranych tabel. Takie kopie zapasowe tworzymy za pomocą narzędzi pg_dump i pg_dumpall.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/005/replikacja.jpg" alt="Replikacja: PostgreSQL" />  </p>
<h3>Replikacja</h3>
<p>PostgreSQL umożliwia stworzenie repliki, czyli serwera będącego kopią serwera źródłowego zasilanego zmianami z serwera źródłowego. Dzięki temu, stan repliki cały czas pozostaje identyczny jak stan serwera master. Aby stworzyć replikę, najpierw tworzymy kopię serwera master na serwerze repliki, a następnie strumieniujemy wszystkie zmiany w plikach WAL z serwera master na serwer repliki. - Serwer replikujący pozostaje w stanie tylko do odczytu. Posiadanie takiej repliki może być użyteczne gdy chcemy stworzyć osobny serwer na potrzeby analityczne - tak aby związane z tym obciążenie przenieść na replikę. Może też nam się przydać gdy coś się stanie z serwerem źródłowym. Możemy przełączyć replikę do trybu zapis-odczyt i dzięki temu może ona przejąć rolę serwera źródłowego.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/005/ha.jpg" alt="Replikacja: PostgreSQL (2)" />  </p>
<h3>High Availability - wysoka dostępność</h3>
<p>To zestaw technik wykorzystywanych w celu zapewnienia nieprzerwanego dostępu do aplikacji, w tym przypadku bazy danych Postgresql, nawet podczas awarii niektórych komponentów.
Dla baz danych, mechanizmy wysokiej dostępności zazwyczaj sprowadzają się do monitoringu statusu postgresa oraz w przypadku problemów z dostępnością wykonywania awaryjnego przerzucenia roli "primary", czyli serwera obsługującego operacje zapisu i odczytu, na replikę która do tej pory obsługiwała jedynie odczyt. Często stosuje się dodatkowy mechanizm "witness", czyli świadka, który jest niezależny od pozostałych serwerów bazodanowych, i może pomóc podjąć decyzję, czy aktualny serwer główny rzeczywiście przestał odpowiadać, czy to tylko tymczasowa przerwa w działaniu sieci pomiędzy serwerem głównym i repliką.
Popularnymi narzędziami stosowanymi w Postgresie do osiągnięcia wysokiej dostępności są np. Patroni oraz REPMGR.</p>
<p>A jeżeli już korzystamy z wysokiej dostępności, warto dodać też loadbalancing, czyli automatyczne rozrzucanie połączeń pomiędzy serwerami w klastrze HA w celu ogólnej poprawy wydajności klastra i przyspieszenia odpowiedzi z bazy. Drugim wartym dodania komponentem jest connection pooling, czyli mechanizm pozwalający na poprawę wydajności przy nawiązywaniu i zamykaniu połączeń poprzez utrzymywanie puli stałych otwartych połączeń, które mogą być naprzemiennie wykorzystywane przez różne połączenia z aplikacji. Oba te mechanizmy bardzo często implementuje się po stronie aplikacji, a jeżeli nie jest to możliwe, lub jest trudne do wykonania, dodaje się zewnętrzne narzędzia, takie jak HAProxy dla loadbalancingu oraz pgBouncer dla kolejkowania połączeń.</p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post244&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post244&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post244&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_upgrade_klastra">Upgrade klastra PostgreSQL - pg_upgrade krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_rodzaje_replikacji">PostgreSQL - Rodzaje replikacji</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL na Ubuntu: profesjonalne wdrozenie krok po kroku]]></title><description><![CDATA[Wdrozenie klastra PostgreSQL na Ubuntu robione 'na szybko' czesto koczy sie problemami przy pierwszym powaznym obciazeniu. Ten tekst prowadzi przez instalacje zgodnie z dobrymi praktykami.
Jak poprawn]]></description><link>https://jsystems.hashnode.dev/postgresql-wdrozenie-klastra-ubuntu</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-wdrozenie-klastra-ubuntu</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[Ubuntu]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sat, 05 Sep 2026 07:03:36 GMT</pubDate><content:encoded><![CDATA[<p>Wdrozenie klastra PostgreSQL na Ubuntu robione 'na szybko' czesto koczy sie problemami przy pierwszym powaznym obciazeniu. Ten tekst prowadzi przez instalacje zgodnie z dobrymi praktykami.</p>
<p><strong>Jak poprawnie wdrożyć klaster PostgreSQL na Ubuntu? Jak sprawić by uruchamiał się automatycznie z systemem? Jak określić położenie PGDATA? Na te i inne pytania znajdziesz odpowiedzi w tym artykule :)</strong></p>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/010_Instrukcja_instalacji_na_Ubuntu_cheatsheet.pdf">Ikona pliku PDF do pobrania   Cheatsheet</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/010_Instrukcja_instalacji_na_Ubuntu_cheatsheet.docx">Ikona notatek   Cheatsheet edytowalny</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cwiczenia/010_Instalacja_klastra_PostgreSQL_na_Ubuntu_cwiczenie.pdf">Ikona ćwiczenia   Ćwiczenie</a></td>
<td><a href="https://www.youtube.com/watch?v=5MmUgMIzRQY">Ikona wskazówki   Rozwiązanie ćwiczenia</a></td>
</tr>
</tbody></table>
<p><strong>Z tego artykułu dowiesz się:</strong></p>
<ul>
<li>jak zainstalować binaria wybranej wersji (a nie - domyślnej dla systemu) na serwerach z systemem Ubuntu,- gdzie co leży,- jak dodać binaria PostgreSQL do PATHa,- jak samemu zdefiniować położenie klastra,- jak skonfigurować by PostgreSQL działał jako usługa (dzięki czemu wygodniej się nim zarządza),- jak skonfigurować automatyczny start PostgreSQL z systemem,- jak skonfigurować system Ubuntu w taki sposób, by nie restartował PostgreSQL w przypadku gdy zacznie kończyć się pamięć RAM,- jak skonfigurować system Ubuntu w taki sposób, by nie wpadał w nieskończony cykl odtwarzania.</li>
</ul>
<p>Pierwszy krok to stworzenie pliku konfiguracji dla repozytorium jako użytkownik z uprawnieniami sudo albo root. W drugim przypadku pomijamy sudo na początku poleceń z instrukcji:</p>
<pre><code>sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" &gt; /etc/apt/sources.list.d/pgdg.list'
</code></pre>
<p>Pobranie i import klucza dla oficjalnego repozytorium Ubuntu do listy zaufanych kluczy w apt:</p>
<pre><code>wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
</code></pre>
<p>Aktualizacja listy dostępnych pakietów:</p>
<pre><code>sudo apt-get update
</code></pre>
<p>Instalacja dostępnych aktualizacji:</p>
<pre><code>sudo apt-get upgrade -y
</code></pre>
<p>Restart serwera po aktualizacji niektóre paczki, szczególnie te aktualizujące jądro linuxa, nie będą “aktywne” do następnego startu serwera:</p>
<pre><code>sudo reboot
</code></pre>
<p>Przystępujemy do instalacji binariów PostgreSQL. Łączymy się do serwera ponownie (na pewno nas rozłączyło przy restarcie) i wykonujemy:</p>
<pre><code>sudo apt-get -y install postgresql-15
</code></pre>
<p>Po instalacji pakietów PostgreSQL - Ubuntu automatycznie stworzy i wystartuje domyślny klaster. Sprawdzamy, czy działa:</p>
<pre><code>systemctl status postgres*
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/10.png" alt="Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu: ilustracja poglądowa" /></p>
<p>Domyślnie PostgreSQL w Ubuntu będzie miał pliki rozmieszczone w takich lokalizacjach:  </p>
<p><strong>Katalog z binariami: /usr/lib/postgresql/15/bin/<br />Katalog domowy postgresa: /var/lib/postgresql</strong></p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/20.png" alt="Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu: ilustracja poglądowa (2)" /></p>
<p>Część plików konfiguracyjnych znajduje się w /etc/postgresql/15/main. W tym dwa bardzo ważne i często aktualizowane: „postgresql.conf”i „pg_hba.conf”. Zajmiemy się nimi nieco później:</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/30.png" alt="Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu: ilustracja poglądowa (3)" /></p>
<p>Dosyć często będziemy działać z poziomu użytkownika systemowego postgres (zostaje on utworzony w chwili instalacji PostgreSQL), dlatego warto, by miał - w swoim PATH binarki PostgreSQL. Dzięki temu nie będziemy musieli wskazywać pełnych ścieżek do binarek, które chcemy - użyć. W tym celu logujemy się na postgresa:</p>
<pre><code>sudo su - postgres
</code></pre>
<p>Następnie już jako użytkownik systemowy postgres wykonujemy:</p>
<pre><code>cat &lt;&lt; EOF &gt;&gt; ~/.bash_profile
PATH=$PATH:/usr/lib/postgresql/15/bin
export PATH

EOF
</code></pre>
<p>Zmiana ta nie będzie widoczna od razu. Istnieją dwie możliwości. Możemy - się wylogować i zalogować na użytkownika postgres ponownie lub wykonać skrypt, który przeładuje nam zmienne środowiskowe. Aby przeładować zmienne środowiskowe, - jako użytkownik postgres musimy wykonać:</p>
<pre><code>. ~/.bash_profile
</code></pre>
<p>Po tej operacji nasza zmienna środowiskowa PATH powinna zostać uzupełniona o katalog z binarkami PostgreSQL:</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/40.png" alt="Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu: ilustracja poglądowa (4)" /></p>
<h3>PGDATA w wybranej lokalizacji + autostart usługi</h3>
<p>Nie zawsze chcemy pozostawić domyślną konfigurację. Przyjmijmy, że planujemy mieć wszystkie pliki danych i konfiguracyjne PostgreSQL w innej lokalizacji, np. na innym dysku. Miejsce, w którym składowane są dane i configi, nazywamy w PostgreSQL PGDATA. Do tego usługa powinna startować automatycznie, korzystając z nowej lokalizacji plików. W tym celu musimy wykonać kilka czynności.</p>
<p><strong>Jeśli planujemy zarządzanie instancjami PostgreSQL za pomocą klastra wysokiej dostępności Patroni, to nie konfigurujemy usługi serwera PostgreSQL (poniżej), ponieważ Patroni sam zajmie się uruchamianiem i wyłączaniem usług PostgreSQL.</strong></p>
<p>Przede wszystkim trzeba zatrzymać aktualnie działającą usługę i wyłączyć jej automatyczne włączanie:</p>
<pre><code>sudo systemctl stop postgresql@15-main.service
sudo systemctl disable postgresql@15-main.service

sudo systemctl stop postgresql.service
sudo systemctl disable postgresql.service
</code></pre>
<p>Sprawdzamy, czy usługa na pewno jest wyłączona:</p>
<pre><code>systemctl status postgres*
</code></pre>
<p>Jeśli ta lista jest pusta, możemy przystąpić do kolejnej czynności, to jest do utworzenia katalogu na nową PGDATA w wybranym miejscu i spowodowanie, by jej właścicielem był użytkownik systemowy postgres (jest tworzony automatycznie przy instalacji PostgreSQL).</p>
<pre><code>sudo mkdir -m 700 /data_pg
sudo chown postgres: /data_pg/
</code></pre>
<p>Teraz należy zainicjalizować klaster, tj. za pomocą postgresowego narzędzia initdb utworzyć niezbędne struktury i pliki. Następnie przechodzimy na użytkownika systemowego postgres i inicjalizujemy klaster:</p>
<pre><code>sudo su - postgres
initdb -D /data_pg/
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/50.png" alt="PGDATA w wybranej lokalizacji + autostart usługi: Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu" /></p>
<p>Jeśli otrzymamy komunikat : “command initdb not found”, - to znaczy, że nie dodaliśmy binarek PostgreSQL do zmiennej PATH lub nie przeładowaliśmy zmiennych środowiskowych użytkownika systemowego postgres. Możemy wrócić do tego punktu i go wykonać albo podawać ścieżkę bezwzględną do konkretnej binarki, np:<br /><strong>/usr/lib/postgresql/15/bin/initdb</strong><br />Włączamy klaster, by sprawdzić, czy działa:</p>
<pre><code>pg_ctl -D /data_pg/ start
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/60.png" alt="PGDATA w wybranej lokalizacji + autostart usługi: Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu (2)" /></p>
<p>Jeśli widzimy takie informacje również u siebie (chodzi o końcowe “server started”), to znaczy, że nowy klaster działa.</p>
<p>Zatrzymamy teraz klaster, ponieważ za chwilę skonfigurujemy go jako usługę i uruchomimy.</p>
<pre><code>pg_ctl -D /data_pg/ stop
</code></pre>
<p>Zadbamy też o to, by usługa PostgreSQL automatycznie się uruchamiała. Inaczej musielibyśmy startować klaster za pomocą “pg_ctl” przy każdym restarcie maszyny.</p>
<p>Przechodzimy teraz do użytkownika systemowego z prawami do sudo i wykonujemy:</p>
<pre><code>sudo nano /lib/systemd/system/postgresql-15.service
</code></pre>
<p>Powstanie nowy plik. Wklejamy do niego:</p>
<pre><code>[Unit]
Description=PostgreSQL 15 database server
Documentation=https://www.postgresql.org/docs/15/static/
After=syslog.target
After=network-online.target

[Service]
Type=notify
User=postgres
Group=postgres
Environment=PGDATA=/data_pg/

#Wyłączenie OOM (Out Of Memory) killera dla postgresa:

OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0

ExecStart=/usr/lib/postgresql/15/bin/postmaster -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT

# wyłączony timeout, żeby postgres mógł w spokoju wykonać crash recovery podczas startu
# inaczej linux mógłby spróbować restartować usługę jeżeli nie wystartowała w X sekund
TimeoutSec=0
TimeoutStartSec=0
TimeoutStopSec=1h

[Install]
WantedBy=multi-user.target
</code></pre>
<p>Należy dostosować ten element pliku do swojej ścieżki do PGDATA (jeśli jest inna niż tworzona w tej instrukcji):</p>
<pre><code>Environment=PGDATA=/data_pg/
</code></pre>
<p>Zapisujemy plik, włączamy autostart i uruchamiamy usługę:</p>
<pre><code>#włączenie autostartu:

sudo systemctl enable postgresql-15.service

#uruchomienie usługi:

sudo systemctl start postgresql-15.service
</code></pre>
<p>Możemy ponownie sprawdzić status usługi:</p>
<pre><code>systemctl status postgresql-15.service
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/10/70.png" alt="PGDATA w wybranej lokalizacji + autostart usługi: Profesjonalne wdrożenie klastra PostgreSQL na Ubuntu (3)" /></p>
<p>Wykonujemy - restart serwera i sprawdzamy ponownie, czy usługa wstała:</p>
<pre><code>sudo reboot
sudo systemctl status postgresql-15.service
</code></pre>
<p><strong>Jeżeli konfigurujemy PostgreSQL jako usługę, to należy startować i zatrzymać klaster już z poziomu systemctl, a nie pg_ctl dlatego, że proces uruchomiony przez pg_ctl i usługa nie wiedzą o sobie wzajemnie.</strong></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post245&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post245&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post245&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_upgrade_klastra">Upgrade klastra PostgreSQL - pg_upgrade krok po kroku</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_katalogi_i_pliki_klastra">PostgreSQL - katalogi i pliki klastra</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL: bezpieczne start/stop/restart klastra - roznice miedzy trybami]]></title><description><![CDATA[Zatrzymanie PostgreSQL to nie zawsze proste 'stop' - tryb smart, fast i immediate dzialaja zupelnie inaczej wobec aktywnych polaczen. Pokazujemy, ktorego uzyc w jakiej sytuacji.
Start/stop, w skrócie
]]></description><link>https://jsystems.hashnode.dev/postgresql-start-stop-restart-klastra</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-start-stop-restart-klastra</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[sysadmin]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sat, 05 Sep 2026 07:03:11 GMT</pubDate><content:encoded><![CDATA[<p>Zatrzymanie PostgreSQL to nie zawsze proste 'stop' - tryb smart, fast i immediate dzialaja zupelnie inaczej wobec aktywnych polaczen. Pokazujemy, ktorego uzyc w jakiej sytuacji.</p>
<p>Start/stop, w skrócie</p>
<p>Sterowanie klastrem:</p>
<pre><code>pg_ctl start -D /sciezka/do/data
pg_ctl stop -m fast -D /sciezka/do/data

systemctl restart postgresql
</code></pre>
<p><strong>Jak zarządzać stanem klastra? Zarówno za pomocą PG_CTL, jak i usługi systemowej.</strong></p>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/020_Uruchamianie_zatrzymywanie_i_restart_PostgreSQL_cheatsheet.pdf">Ikona pliku PDF do pobrania   Cheatsheet</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/020_Uruchamianie_zatrzymywanie_i_restart_PostgreSQL_cheatsheet.docx">Ikona notatek   Cheatsheet edytowalny</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cwiczenia/020_Uruchamianie_zatrzymywanie_i_restartowanie_PostgreSQL_cwiczenie.pdf">Ikona ćwiczenia   Ćwiczenie</a></td>
<td><a href="https://www.youtube.com/watch?v=DsJAQUvHPzA&amp;feature=youtu.be">Ikona wskazówki   Rozwiązanie ćwiczenia</a></td>
</tr>
</tbody></table>
<p><strong>Z tego artykułu dowiesz się:</strong></p>
<ul>
<li>jak sprawdzać stan usługi PostgreSQL,- jak zatrzymywać, uruchamiać i restartować PostgreSQL za pomocą pg_ctl,- jak zatrzymywać, uruchamiać i restartować PostgreSQL za pomocą usługi,- jak ustawić zmienną środowiskową PGDATA, by nie musieć ciągle podawać położenia klastra,- jak przeładowywać konfigurację bez restartu klastra.</li>
</ul>
<p>Uruchamiać, zatrzymywać, restartować i przeładowywać konfigurację usługi możemy na dwa sposoby. Albo wykorzystując pg_ctl, albo systemctl. W pierwszym przypadku jest to skrypt PostgreSQL. W drugim- zarządzamy usługą systemu operacyjnego.</p>
<p>Po wykonaniu wszystkich kroków z instrukcji instalacji PostgreSQL - mamy już działającą usługę. Możemy to zweryfikować, wywołując:</p>
<pre><code>systemctl status postgresql-15.service
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/10.png" alt="Uruchamianie i zatrzymywanie PostgreSQL: ilustracja poglądowa" /></p>
<h3>Uruchamianie, zatrzymywanie i restart za pomocą pg_ctl</h3>
<p>Aby uruchamiać, zatrzymywać, restartować czy przeładowywać PostgreSQL za pomocą pg_ctl, przechodzimy najpierw do użytkownika systemowego postgres:</p>
<pre><code>sudo su - postgres
</code></pre>
<p>Do startowania i zatrzymywania klastra służy skrypt pg_ctl. Jednak do czasu, aż nie ustawimy zmiennej środowiskowej PGDATA, będziemy musieli wskazać katalog instalacji klastra poprzez przełącznik -D. <strong>Startowanie klastra</strong>:</p>
<pre><code>pg_ctl -D /data_pg start
</code></pre>
<p>Jeśli mamy dodane binaria PostgreSQL do zmiennej środowiskowej PATH użytkownika Postgres, wywołujemy bezpośrednio pg_ctl bez ścieżki do niej. Informacja na temat konfiguracji zmiennej PATH znajduje się w rozdziale o instalacji PostgreSQL. - Jeśli nie mamy dodanego katalogu binariów PostgreSQL do PATHa, możemy też uruchamiać pg_ctl (oraz inne skrypty), podając pełną ścieżkę. Dla Ubuntu:</p>
<pre><code>/usr/lib/postgresql/15/bin/pg_ctl -D /data_pg start
</code></pre>
<p>Dla CentOSa:</p>
<pre><code>/usr/pgsql-15/bin/pg_ctl -D /data_pg start
</code></pre>
<p><strong>Zatrzymywanie klastra</strong> to również wywołanie pg_ctl z przełącznikiem -D, ale z argumentem stop w miejscu start:</p>
<pre><code>pg_ctl -D /data_pg stop
</code></pre>
<p>Aby <strong>zrestartować klaster</strong>, wystarczy dać argument restart:</p>
<pre><code>pg_ctl -D /data_pg restart
</code></pre>
<p>Możemy też sprawić, że podawanie katalogu instalacji klastra nie będzie konieczne, konfigurując zmienną środowiskową PGDATA. Możemy to zrobić dla aktualnej sesji:</p>
<pre><code>export PGDATA=/data_pg
pg_ctl stop
pg_ctl start
pg_ctl restart
</code></pre>
<p>Możliwe jest - też skonfigurowanie PGDATA dla wszystkich przyszłych sesji. Wystarczy dodać tę zmienną - środowiskową do ~/.bash_profile. Edytujemy plik:</p>
<pre><code>nano ~/.bash_profile
</code></pre>
<p>Następnie dodajemy poniższe linijki do tego pliku:</p>
<pre><code>PGDATA=/data_pg
export PGDATA
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/20.png" alt="Uruchamianie, zatrzymywanie i restart za pomocą pg_ctl: Uruchamianie i zatrzymywanie PostgreSQL" /></p>
<p>Po tej czynności wylogowujemy się z użytkownika Postgres i logujemy się ponownie lub uruchamiamy skrypt ~./bash_profile:</p>
<pre><code>. ~/.bash_profile
</code></pre>
<p>Możemy teraz sprawdzić, czy zmienna poprawnie się dodała, wywołując:</p>
<pre><code>Echo $PGDATA
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/30.png" alt="Uruchamianie, zatrzymywanie i restart za pomocą pg_ctl: Uruchamianie i zatrzymywanie PostgreSQL (2)" /></p>
<p>Niezależnie od tego, czy ustawiliśmy PGDATA dla sesji czy dla użytkownika, możemy teraz wywoływać pg_ctl bez argumentu -D i wskazywania katalogu domowego PostgreSQL.</p>
<pre><code>pg_ctl stop
pg_ctl start
pg_ctl restart
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/40.png" alt="Uruchamianie, zatrzymywanie i restart za pomocą pg_ctl: Uruchamianie i zatrzymywanie PostgreSQL (3)" /></p>
<p>Pamiętajmy, że jeśli mamy zainstalowane w systemie kilka klastrów równolegle (będą musiały słuchać na innych portach), to pozostałe klastry (poza domyślnym, czyli ustawionym w zmiennej PGDATA) będzie trzeba uruchamiać i zatrzymywać z użyciem przełącznika -D.</p>
<h3>Uruchamianie, zatrzymywanie i restart PostgreSQL za pomocą systemctl</h3>
<p>Jeśli chcemy mieć klaster w innej lokalizacji niż domyślna „/var/lib/postgresql”, to nie zapomnijmy uaktualnić plik konfiguracyjny usługi “/lib/systemd/system/postgresql-15.service”. Konfiguracja tego pliku została opisana w rozdziale o instalacji PostgreSQL.</p>
<p>Poniższe czynności wykonujemy jako użytkownik systemowy z prawami do sudo!</p>
<p>Startowanie usługi:</p>
<pre><code>sudo systemctl start postgresql-15
</code></pre>
<p>Zatrzymywanie usługi:</p>
<pre><code>sudo systemctl stop postgresql-15
</code></pre>
<p>Restart usługi:</p>
<pre><code>sudo systemctl restart postgresql-15
</code></pre>
<p><strong>Wybierzmy jedną formę startowania i zatrzymywania klastra - - pg_ctl albo systemctl. Jeśli uruchomimy usługę z pg_ctl, to systemctl nic nie wie na temat uruchomienia usługi przez pg_ctl.</strong></p>
<h3>Sprawdzanie statusu usługi</h3>
<p>Jeśli uruchomimy usługę z poziomu systemctl, to również za jego pomocą możemy sprawdzić stan tej usługi:</p>
<pre><code>sudo systemctl status postgresql-15
</code></pre>
<p>Tę komendę możemy wydać również bez sudo jako użytkownik postgres.</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/50.png" alt="Sprawdzanie statusu usługi: Uruchamianie i zatrzymywanie PostgreSQL" /></p>
<p><strong>Jeśli uruchomimy usługę za pomocą pg_ctl, to systemctl powie, że usługa nie działa, ponieważ nie wie o jej uruchomieniu.</strong></p>
<p>Status usługi dla wskazanego PGDATA można sprawdzić też za pomocą pg_ctl status np. (wykonujemy jako użytkownik systemowy postgres):</p>
<pre><code>Pg_ctl -D /data_pg status
</code></pre>
<p>Dostaniemy jasną informację:</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/60.png" alt="Sprawdzanie statusu usługi: Uruchamianie i zatrzymywanie PostgreSQL (2)" /></p>
<p>Pozostaje jeszcze możliwość sprawdzenie otwartego portu za pomocą nmap. W takim przypadku nie ma znaczenia, czy uruchomimy usługę za pomocą pg_ctl czy systemctl. Jeżeli port jest otwarty, - zostanie to pokazane. Możemy też sprawdzić, czy w katalogu PGDATA (u nas /data_pg) istnieje plik “postmaster.pid”. Plik ten tworzony jest przy starcie klastra i usuwany przy jego zamykaniu. Jest to taki specjalny znacznik określający, czy instancja związana z tą PGDATA jest już uruchomiona.</p>
<p>Sprawdzenie otwartego portu nmapem:</p>
<pre><code>nmap localhost
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/70.png" alt="Sprawdzanie statusu usługi: Uruchamianie i zatrzymywanie PostgreSQL (3)" /></p>
<p>Sprawdzenie istnienia pliku pid w katalogu domowym PostgreSQL możemy wykonać, korzystając ze zmiennej środowiskowej PGDATA (o ile ją wcześniej skonfigurowaliśmy) lub podając ścieżkę bezwzględną. Poniższe instrukcje wykonujemy jako użytkownik systemowy postgres bądź inny użytkownik - ale mający uprawnienia do sudo (wtedy instrukcję poprzedzamy “sudo”), to jest kwestia uprawnień do tego katalogu. Wyszukujemy w katalogu wszystkie pliki mające w nazwie “postmaster”:</p>
<pre><code>ls $PGDATA | grep postmaster
ls /data_pg | grep postmaster
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/80.png" alt="Sprawdzanie statusu usługi: Uruchamianie i zatrzymywanie PostgreSQL (4)" /></p>
<p>Jeśli - taki plik istnieje, - ta instancja PostgreSQL jest uruchomiona.</p>
<h3>Przeładowywanie konfiguracji</h3>
<p>Niektóre parametry wymagają do zmiany restartu, inne tylko przeładowania konfiguracji. - Restart instancji wiąźe się z czyszczeniem wszystkich buforów, a tego z powodu utraty wydajności bazy chcemy uniknąć. W przypadku wpisów w pg_hba.conf (taki ACL - czyli Access Control List określający kto, na jakich zasadach i do czego ma dostęp) wystarczy przeładowanie konfiguracji w miejsce restartu. - W przypadku postgresql.conf (plik z konfiguracją najważniejszych parametrów klastra) jest to zależne od parametru. W postgresql.conf jeśli zmiana jakiegoś parametru wymaga restartu, zostało to przy nim napisane:</p>
<p>Konfigurację możemy przeładować na dwa sposoby: za pomocą pg_ctl i za pomocą psql. W przypadku pg_ctl wywołujemy:</p>
<pre><code>pg_ctl reload
</code></pre>
<p>Jeśli nie mamy ustawionego PATHa i PGDATA, trzeba będzie stosownie podać ścieżkę do binarki oraz katalog domowy PostgreSQL który chcemy przeładować.</p>
<p>Dla Ubuntu:</p>
<pre><code>/usr/lib/postgresql/15/bin/pg_ctl -D /data_pg reload
</code></pre>
<p>Dla CentOSa:</p>
<pre><code>/usr/pgsql-15/bin/pg_ctl -D /data_pg reload
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/90.png" alt="Przeładowywanie konfiguracji: Uruchamianie i zatrzymywanie PostgreSQL" /></p>
<p>Konfigurację możemy też przeładować za pomocą psql:</p>
<pre><code>psql -c "select pg_reload_conf()"
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/20/100.png" alt="Przeładowywanie konfiguracji: Uruchamianie i zatrzymywanie PostgreSQL (2)" /></p>
<p>Jeśli nie zaktualizowaliśmy zmiennej środowiskowej PATH, dodając do niej binarki PostgreSQL, to musimy podać pełną ścieżkę do psql. Dla Ubuntu:</p>
<pre><code>/usr/lib/postgresql/15/bin/psql -c "select pg_reload_conf()"
</code></pre>
<p>Dla CentOSa:</p>
<pre><code>/usr/pgsql-15/bin/psql -c "select pg_reload_conf()"
</code></pre>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post246&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post246&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post246&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_CRON_-_czyli_cykliczne_uruchamianie_zada%C5%84_w_PostgreSQL">PG_CRON - czyli cykliczne uruchamianie zadań w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_najwazniejsze_pojecia">PostgreSQL - Najważniejsze pojęcia</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[PostgreSQL: konfiguracja logowania serwera krok po kroku]]></title><description><![CDATA[Logi serwera PostgreSQL moga zapisywac wszystko od bledow po kazde zapytanie - pytanie brzmi, co ma sens logowac na produkcji bez zapychania dysku. Ten tekst pokazuje realna konfiguracje.
Jak skonfigu]]></description><link>https://jsystems.hashnode.dev/postgresql-konfiguracja-logow-serwera</link><guid isPermaLink="true">https://jsystems.hashnode.dev/postgresql-konfiguracja-logow-serwera</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[database]]></category><category><![CDATA[logging]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Andrzej Klusiewicz]]></dc:creator><pubDate>Sat, 05 Sep 2026 07:02:46 GMT</pubDate><content:encoded><![CDATA[<p>Logi serwera PostgreSQL moga zapisywac wszystko od bledow po kazde zapytanie - pytanie brzmi, co ma sens logowac na produkcji bez zapychania dysku. Ten tekst pokazuje realna konfiguracje.</p>
<p><strong>Jak skonfigurować szczegółowe logowanie błędów i zdarzeń w PostgreSQL? Jak wyłapywać wolno działające zapytania? Jak przeszukiwać logi SQLem?</strong></p>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/030_Konfiguracja_logow_serwera_cheatsheet.pdf">Ikona pliku PDF do pobrania   Cheatsheet</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cheatsheety/030_Konfiguracja_logow_serwera_cheatsheet.docx">Ikona notatek   Cheatsheet edytowalny</a></td>
<td><a href="https://jsystems.pl/nowy_blog/download/postgresql/cwiczenia/030_Konfiguracja_logow_serwera_cwiczenie.pdf">Ikona ćwiczenia   Ćwiczenie</a></td>
<td><a href="https://www.youtube.com/watch?v=bpQsJh1jPP0">Ikona wskazówki   Rozwiązanie ćwiczenia</a></td>
</tr>
</tbody></table>
<p><strong>Z tego artykułu dowiesz się:</strong></p>
<ul>
<li>jak spowodować rejestrowanie logów do pliku,- jak konfigurować położenie logów,- jak konfigurować nazewnictwo plików logów,- jak konfigurować rotację plików logów,- jak konfigurować poziom logowania,- jak rejestrować w logach wolne zapytania (na potrzeby dalszej analizy i tuningu),- jak rejestrować w logach trwające zbyt długo operacje autovacuum,- jak rejestrować w logach zdarzenia checkpoint wraz z ich statystykami,- jak rejestrować w logach zdarzenia połączenia i rozłączenia sesji,- jak określać prefix linii logu w taki sposób, byśmy mieli komplet informacji o tym kto, z jakiego hosta, jaką aplikacją, kiedy, do której bazy się podłączył i wykonał daną zalogowaną czynność,- jak logować zdarzenia blokad zasobów (niekorzystne z perspektywy tuningu zdarzenie),- jak logować poszczególne typy operacji - tworzące, kasujące lub zmieniające np. tabele i indeksy, zmieniające dane lub wszystkie operacje,- jak logować zdarzenia tworzenia plików tymczasowych (niekorzystne z perspektywy tuningu zdarzenie),- jak generować logi do formatu CSV,- jak przeszukiwać logi za pomocą SQL.</li>
</ul>
<p>Jeśli PostgreSQL - nie uruchamia się bądź pojawiają się jakieś błędy, pierwsze miejsce, które powinniśmy sprawdzić, to logi serwera PostgreSQL. Zajmiemy się więc teraz konfiguracją tego, gdzie i w jakim formacie logi te będą wyrzucane.</p>
<p>W tym celu musimy omówić kilka istotnych parametrów. Plik konfiguracyjny, w którym znajdziemy ustawienia parametrów, nazywa się "postgresql.conf" i mieści się w katalogu instalacji klastra PostgreSQL - tam, gdzie między innymi pliki danych. W naszym przypadku przyjmujemy, że <strong>katalog instalacji klastra (czyli PGDATA</strong>) to /data_pg.</p>
<h3>Parametry logowania</h3>
<p><strong>Pierwszym parametrem który będziemy musieli przestawić będzie "logging_collector" którego włączenie spowoduje dodatkowe przekierowanie strumienia loga do pliku tekstowego w PGDATA. Zmiana parametru "logging_collector" będzie wymagała restartu klastra. Zmiana pozostałych- tylko przeładowania konfiguracji.</strong></p>
<p>Aby sprawdzić aktualne ustawienie dowolnego parametru, należy - zalogować - się z poziomu użytkownika systemowego postgres do psql i zastosować komendę: "show nazwa_parametru":</p>
<pre><code>psql
show logging_collector;
</code></pre>
<p>Jeśli nie mamy dodanych binarek PostgreSQL do PATHa i system zgłosi, że nie wie, co to "psql", należy użyć ścieżki bezwzględnej do psql:</p>
<pre><code>/usr/lib/postgresql/15/bin/psql
show logging_collector;
</code></pre>
<p>Aby zmienić parametr "logging_collector", musimy zalogować się z poziomu użytkownika systemowego postgres do psql, wykonać komendę: "ALTER SYSTEM", wyjść z psql i zrestartować cały klaster. Można też modyfikować bezpośrednio plik postgresql.conf znajdujący się w PGDATA.</p>
<pre><code>psql
alter system set logging_collector=true;
\q
pg_ctl restart
</code></pre>
<p>Jeśli nie mamy dodanych binarek PostgreSQL do PATHa i ustawionego katalogu dla PGDATA, możemy - użyć ścieżek bezwzględnych do wykorzystanych - binarek i wskazać katalog PGDATA za pomocą przełącznika -D:</p>
<pre><code>/usr/lib/postgresql/15/bin/psql
alter system set logging_collector=true;
\q
/usr/lib/postgresql/15/bin/pg_ctl -D /data_pg restart
</code></pre>
<p>Zmiana dowolnego z pozostałych parametrów (opisanych tu, związanych z logowaniem) - wymaga tylko przeładowania konfiguracji. Logujemy się z poziomu użytkownika systemowego postgres do psql, wykonujemy komendę: "ALTER SYSTEM" i przeładowujemy konfigurację.</p>
<pre><code>psql
alter system set log_directory='logi';
select pg_reload_conf();
</code></pre>
<p>Warto wiedzieć, że zmiana parametrów przez "ALTER SYSTEM" powoduje dodanie nowego wpisu do pliku postgresql.auto.conf. Plik ten jest czytany (razem z postgresql.conf i pg_hba.conf) przy przeładowaniu konfiguracji i starcie klastra. Ponieważ plik postgresql.auto.conf jest czytany po postgresql.conf, to ustawienia w postgresql.auto.conf nadpisują ustawienia postgresql.conf. Inaczej mówiąc, cokolwiek ustawimy przez "ALTER SYSTEM", - będzie to nadpisywało ustawienia tego samego parametru bezpośrednio w pliku postgresql.conf.</p>
<h4>logging_collector</h4>
<p>Jest to parametr typu boolean - przyjmuje wartości true/false/on/off/t/f/1/0. Włączenie tego parametru powoduje uruchomienie procesu tła, który odpowiada za przekierowanie logów( lecących domyślnie do stderr w Ubuntu ) do plików logów PostgreSQL. W przypadku włączenia tworzony jest katalog w położeniu i nazwie określonych w parametrze "log_directory" i w nim znajdą się pliki logów. Domyślnie parametr "log_directory" ustawiony jest na wartość "log", czyli - logi znajdują się w podkatalogu "log" - katalogu PGDATA. <strong>Zmiana "logging_collector" wymaga restartu klastra.</strong></p>
<p><strong>Domyślną wartością dla Ubuntu jest off. Domyślną wartością dla CentOS jest on.</strong> W przypadku Ubuntu logi lecą do /var/log/postgresql/. W przypadku CentOs logi domyślnie znajdą się w podkatalogu "log" umiejscowionym w PGDATA.</p>
<p><strong>Na potrzeby testowania pozostałych ustawień opisanych w tym rozdziale należy ustawić - ten parametr na on.</strong></p>
<h4>log_directory</h4>
<p>Parametr ten określa katalog, w którym będą powstawać pliki logów PostgreSQL. Domyślne ustawienie:</p>
<p><strong>log_directory='log'</strong></p>
<p>Jako wartość możemy podać zarówno ścieżkę bezwzględną jak i względną wobec PGDATA (katalog instalacji klastra). Domyślnie pliki logów będą powstawały w katalogu "log" w PGDATA. Jeśli zamierzamy ustawić ścieżkę bezwzględną, to należy pamiętać, by użytkownik systemowy "postgres" miał uprawnienia do pisania w tym katalogu.<br /><strong>Zmiana "log_directory" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_destination</h4>
<p>PostgreSQL wspiera kilka metod logowania wiadomości serwera, między innymi stderr, csvlog, syslog. Domyślna wartość to "stderr". Jeśli chcemy, by logi były dodatkowo zapisywane w pliku csv (np. w celu późniejszego importu do bazy i analizy), musimy zmodyfikować ustawienie tego parametru na taką wartość:</p>
<p><strong>log_destination='stderr,csvlog'</strong></p>
<p><strong>Zmiana "log_directory" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_filename</h4>
<p>Parametr określa nazwę pliku loga. Domyślna jego wartość dla Ubuntu:</p>
<p><strong>"postgresql-%Y-%m-%d_%H%M%S.log"</strong></p>
<p>Nazwa loga będzie zawierała datę i czas powstania loga.<br />Domyślna wartość dla CentOS:</p>
<p><strong>"postgresql-%a.log"</strong></p>
<p>Nazwa loga będzie zawierała skróconą nazwę dnia tygodnia.</p>
<p>Kolejny plik będzie powstawał po upływie czasu określonego w parametrze "log_rotation_age", którego domyślną wartością jest 1 doba.<br />W nazwie pliku loga możemy stosować wszystkie znaczniki strftime. Listę dostępnych znajdziemy np. tutaj: <a href="https://strftime.org/">https://strftime.org/</a></p>
<p><strong>Zmiana "log_filename" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_rotation_age</h4>
<p>Parametr określa maksymalny czas, po jakim tworzony jest nowy plik logu. Domyślną wartością dla tego parametru jest "1d", co oznacza - jeden dzień. Jeśli podajemy wartość bez jednostki, np. tak:</p>
<p><strong>log_rotation_age=30,</strong></p>
<p>będzie to oznaczało 30 minut, - bo taka jest przyjmowana domyślna jednostka. Jeśli chcemy mieć nowy plik loga tworzony co 30 dni a nie minut, to musimy dodać literkę "d":</p>
<p><strong>log_rotation_age=30d</strong></p>
<p>Wartość domyślna (jedna doba) jest dobra dla środowisk produkcyjnych. Dla testów wydajnościowych warto ustawić na 1 godzinę. Parametr ten możemy przestawić na zero, powodując wyłączenie nadpisywania logów:</p>
<p><strong>log_rotation_age=0</strong></p>
<p><strong>Zmiana "log_filename" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_rotation_size</h4>
<p>Parametr zbliżony do "log_rotation_age". Dotyczy jednak wielkości logów. Możemy za jego pomocą spowodować, że nowy log będzie tworzony po przekroczeniu przez loga określonej wielkości. Domyślnie parametr ten ustawiony jest na 10MB. Podając wartość liczbową większą od 0, podajemy wartość <strong>wyrażoną w kB</strong>. Możemy ją ustawić np. tak:</p>
<p><strong>log_rotation_size=1024</strong></p>
<p>lub podając jednostkę:</p>
<p><strong>log_rotation_size='1MB'</strong></p>
<p>co będzie oznaczało w obu przypadkach, że log zostanie nadpisany, gdy osiągnie wielkość 1MB.</p>
<p><strong>Zmiana "log_rotation_size" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_min_messages</h4>
<p>Określa poziom logowania, czyli co ma być rejestrowane w logu. Domyślnym ustawieniem jest "warning", ale możemy ten parametr przestawić - w ten sposób:</p>
<p><strong>log_min_messages=info</strong></p>
<p>Poniżej lista dostępnych trybów. Każdy poziom obejmuje również rejestrację z wszystkich wyższych poziomów:</p>
<table>
<thead>
<tr>
<th>Poziom</th>
<th>Opis</th>
</tr>
</thead>
<tbody><tr>
<td>PANIC</td>
<td>Wpisy o krytycznych błędach powodujących przerwanie działania klastra</td>
</tr>
<tr>
<td>FATAL</td>
<td>Zdarzenia typu przerwanie jakiegoś procesu w sposób nieplanowany np przerwanie sesji wykonującej jakieś działanie.</td>
</tr>
<tr>
<td>LOG</td>
<td>Informacje takie jak nawiązywanie nowego połączenia, czy kończenie połączenia (ale tylko jeśli ustawimy log_connections i log_disconnections).</td>
</tr>
<tr>
<td>ERROR</td>
<td>Błędy spowodowane przez aplikacje. Na przykład próba dodania wiersza do tabeli z naruszeniem klucza głównego, czy próba odczytu danych z nieistniejącej tabeli.</td>
</tr>
<tr>
<td>WARNING</td>
<td>Ostrzeżenia od PostgreSQL które mogą być potencjalnie niebezpieczne. Przykładowo informacja o zbyt często pojawiających się checkpointach.</td>
</tr>
<tr>
<td>NOTICE</td>
<td>Informacje które mogą być użyteczne dla użytkowników - np. wywołane przez RAISE NOTICE w funkcjach plpgsql.</td>
</tr>
<tr>
<td>INFO</td>
<td>Powoduje logowanie dodatkowych informacje do operacji wywołanych przez użytkownika, np. poprzez dodanie “VERBOSE” do operacji VACUUM. Sam VACUUM nie zapisze się w logu, ale VACUUM VERBOSE zwróci szczegółowe informacje do terminala i do pliku loga.</td>
</tr>
<tr>
<td>DEBUG1-DEBUG5</td>
<td>Informacje związane z debugowaniem samego PostgreSQL.</td>
</tr>
</tbody></table>
<p><strong>Zmiana "log_min_messages" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_min_duration_statement</h4>
<p>Parametr ten umożliwia rejestrowanie w logach informacji o wszystkich zapytaniach trwających dłużej niż czas określony w tym parametrze. Domyślną jednostką tego parametru są milisekundy. Możesz mu ustawić jakąś wartość by wyłapywać zapytania które warto poddać optymalizacji. Domyślna wartość tego parametru to -1, czyli logowanie takich zapytań jest wyłączone. Wartość 0 spowoduje rejestrowanie wszystkich zapytań, w tym zapytań do słowników systemowych, towarzyszących każdemu zapytaniu - więc nie warto tego robić, ponieważ log będzie szybko zapełniany zbędnymi wpisami. Warto ustawić na jakąś rozsądną wartość, np zapytania trwające powyżej 1000ms.<br />Możesz tę wartość ustawić podając w milisekundach np:</p>
<p><strong>log_min_duration_statement=1000</strong></p>
<p>Lub podając jednostkę:</p>
<p><strong>log_min_duration_statement=1s</strong></p>
<p>albo:</p>
<p><strong>log_min_duration_statement=1min</strong></p>
<p><strong>Zmiana "log_min_duration_statement" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_autovacuum_min_duration</h4>
<p>Parametr ten umożliwia rejestrowanie w logach informacji o operacjach autovacuum trwających dłużej niż czas określony w tym parametrze.Domyślna wartość tego parametru to -1, czyli logowanie operacji autovacuum jest wyłączone. Wartość 0 spowoduje rejestrowanie wszystkich operacji autovacuum.<br />Możesz tę wartość ustawić podając w milisekundach np:</p>
<p><strong>log_autovacuum_min_duration=1000</strong></p>
<p>Lub podając jednostkę:</p>
<p><strong>log_autovacuum_min_duration=1s</strong></p>
<p>albo:</p>
<p><strong>log_autovacuum_min_duration=10min</strong></p>
<p><strong>Zmiana "log_autovacuum_min_duration" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_checkpoints</h4>
<p>Parametr ten jest domyślnie włączony i powoduje rejestrowanie wszystkich zdarzeń checkpoint. Wraz z informacją o samym fakcie wystąpienia checkpointa otrzymamy też informacje o czasie jego trwania, a także ilości zapisanych w jego ramach danych. Możesz pozostawić go włączonego:</p>
<p><strong>log_checkpoints=on</strong></p>
<p>lub wyłączyć:</p>
<p><strong>log_checkpoints=off</strong></p>
<p><strong>Zmiana "log_checkpoints" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_connections</h4>
<p>Parametr ten umożliwia rejestrowanie w logu wszystkich zdarzeń nawiązania połączenia z klastrem. Rejestrowany jest również adres IP hosta z którego połączenie jest nawiązywane, użytkownik, baza danych i nazwa aplikacji. Domyślnie parametr ten jest wyłączony. Możesz go włączyć:</p>
<p><strong>log_connections=on</strong></p>
<p>lub wyłączyć:</p>
<p><strong>log_connections=off</strong></p>
<p><strong>Zmiana "log_connections" wymaga restartu klastra.</strong></p>
<h4>log_disconections</h4>
<p>Parametr ten umożliwia rejestrowanie zakończenie trwania połączenia do klastra. Rejestrowany jest adres IP hosta z którego było to połączenie, użytkownik, baza danych, nazwa aplikacji i czas trwania połączenia. Domyślnie parametr ten jest wyłączony. Możesz go włączyć:</p>
<p><strong>log_disconnections=on</strong></p>
<p>lub wyłączyć:</p>
<p><strong>log_disconnections=off</strong></p>
<p><strong>Zmiana "log_disconnections" wymaga restartu klastra.</strong></p>
<h4>log_line_prefix</h4>
<p>Pozwala skonfigurować prefiks każdej linii logu. Każda linia logu będzie miała format ustawiony przez ten parametr. Warto rozszerzyć sobie standardowe ustawienie o dodatkowe taki, ponieważ domyślnie logowany będzie tylko identyfikator procesu i timestamp (czyli domyślnie jest %m [%p]).Musimy pamiętać, że nie wszystkie tagi będą zawsze uzupełniane - np. w przypadku procesów wewnętrznych. Nierozpoznane tagi będą ignorowane. Dostępne tagi:</p>
<table>
<thead>
<tr>
<th>Symbol</th>
<th>Znaczenie</th>
</tr>
</thead>
<tbody><tr>
<td>%a</td>
<td>Nazwa aplikacji</td>
</tr>
<tr>
<td>%u</td>
<td>Nazwa użytkownika</td>
</tr>
<tr>
<td>%r</td>
<td>Nazwa zdalnego hosta lub jego IP oraz port.</td>
</tr>
<tr>
<td>%h</td>
<td>Nazwa zdalnego hosta lub jego IP.</td>
</tr>
<tr>
<td>%b</td>
<td>Rodzaj backendu</td>
</tr>
<tr>
<td>%p</td>
<td>ID procesu</td>
</tr>
<tr>
<td>%t</td>
<td>Timestamp bez milisekund</td>
</tr>
<tr>
<td>%m</td>
<td>Timestamp z milisekundami</td>
</tr>
<tr>
<td>%n</td>
<td>Timestamp z milisekundami (UNIX epoch)</td>
</tr>
<tr>
<td>%i</td>
<td>Typ komendy</td>
</tr>
<tr>
<td>%e</td>
<td>Kod błędu SQLSTATE</td>
</tr>
<tr>
<td>%c</td>
<td>ID sesji</td>
</tr>
<tr>
<td>%l</td>
<td>Numer linii loga</td>
</tr>
<tr>
<td>%s</td>
<td>Timestamp rozpoczęcia procesu</td>
</tr>
<tr>
<td>%v</td>
<td>ID transakcji wirtualnej</td>
</tr>
<tr>
<td>%x</td>
<td>ID transakcji</td>
</tr>
</tbody></table>
<p>Przykładowe ustawienie poniżej, moim zdaniem w miarę wystarczające. Daje nam ono informację o nazwie aplikacji, nazwie hosta, bazy danych, której log dotyczy, użytkownika, który spowodował powstanie loga, id sesji, id procesu systemowego i timestampie zdarzenia:</p>
<p><strong>log_line_prefix='%m [%p]:[%l] user=%u,db=%d,app=%a'</strong></p>
<p><strong>Zmiana "log_line_prefix" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_lock_waits i deadlock_timeout</h4>
<p>Parametr log_lock_waits powoduje rejestrowanie w logu transakcji które blokują inne transakcje przez czas określony w parametrze deadlock_timeout. Parametr log_lock_waits jest domyślnie wyłączony. Możesz go włączyć:</p>
<p><strong>log_lock_waits=on</strong></p>
<p>lub wyłączyć:</p>
<p><strong>log_lock_waits=off</strong></p>
<p><strong>Zmiana "log_lock_waits" i "deadlock_timeout" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_statement</h4>
<p>Pozwala określić jakie operacje na danych i strukturach będą logowane. Możemy mu ustawić "none" (tak jest domyślnie) - czyli nic nie jest logowane (chyba że wpis do loga będzie wynikał z log_min_duration_statement, log_lock_waits lub log_temp_files). "ddl" - czyli wszystkie operacje tworzące, zmieniające czy kasujące struktury danych. "mod" - czyli operacje zmieniające dane ale nie struktury danych. "all" - wszystkie operacje. Możesz go ustawić w ten sposób:</p>
<p><strong>log_statement='ddl'</strong></p>
<p><strong>Zmiana "log_statement" wymaga tylko przeładowania ustawień.</strong></p>
<h4>log_temp_files</h4>
<p>Pozwala rejestrować w logach wszystkie zdarzenia które spowodowały tworzenie plików tymczasowych, takie jak sortowanie, hashowanie czy grupowanie. Pomaga nam znaleźć zapytania warte optymalizacji. Domyślną wartością tego parametru jest -1, czyli rejestracja jest wyłączona. Wartość 0 spowoduje zarejestrowanie wszystkich powstających plików tymczasowych. Wartość większa od 0 określa wielkość pliku tymczasowego wyrażonego w kilobajtach powyżej której fakt tworzenia pliku tymczasowego zostanie odnotowany. Możesz go ustawić np. w ten sposób:</p>
<p><strong>log_temp_files=1024</strong></p>
<p><strong>Zmiana "log_temp_files" wymaga tylko przeładowania ustawień.</strong></p>
<h3>Log w formacie csv i ładowanie logu do tabeli (w celu późniejszej analizy SQLem)</h3>
<h4>Logi w formacie CSV</h4>
<p>Domyślny format logu jest z reguły niewystarczający do analizy danych w nich zawartych jeżeli nie mamy dobrej znajomości linuksowych narzędzi do parsowania plików teksowych, takich jak grep czy awk. W domyślnej konfiguracji logi zrzucane są do pliku tekstowego, który nadaje się do podglądania pojawiających się komunikatów o błędach etc, ale nie pozwalają np. wyłapać wszystkich wpisów dotyczących długo trwających zapytań. Znalezienie wszystkich takich wpisów w zwykłym pliku tekstowym wymagałoby napisania jakiegoś parsera. Mamy jednak możliwość rejestrowania logów do pliku CSV, który następnie możemy załadować do tabeli. Dzięki temu będziemy mogli przeszukiwać logi za pomocą SQL!</p>
<p>Przede wszystkim musimy spowodować, żeby logi zaczęły być rejestrowane do pliku CSV. W tym celu modyfikujemy parametr "<strong>log_destination</strong>". Możemy zmienić go w pliku "postgresql.conf" lub za pomocą "alter system...". Trzeba tylko pamiętać o przeładowaniu konfiguracji za pomocą pg_reload_conf(). Jego wartość powinna wyglądać tak:</p>
<p><strong>log_destination='stderr,csvlog'</strong></p>
<p>Osiągamy to - na przykład tak:</p>
<pre><code>psql
alter system set log_destination='stderr,csvlog';
select pg_reload_conf();
</code></pre>
<p>Dodajemy frazę "csvlog", domyślnie jest tylko "stderr", by nie nadpisać stderr, a dodać frazę csvlog.</p>
<p>Po tej operacji w naszym katalogu z logami powinien znaleźć się dodatkowy plik z rozszerzeniem "csv":</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/30/10.png" alt="Logi w formacie CSV: Konfiguracja logów serwera PostgreSQL (logging_collector)" /></p>
<p>Wpisy w tym pliku będą - miały stały format prefiksu loga. Ustawienie "log_line_prefix" nie ma na niego wpływu. Wynika to z tego, że załadujemy ten log do tabeli, która ma z góry zdefiniowany format i dane muszą do tego formatu pasować.</p>
<h4>Ładowanie logów CSV do tabeli i ich analiza</h4>
<p>Poniżej komenda tworząca tabelę, do której będziemy ładować dane.Należy pamiętać, że między wersjami struktura tej tabeli będzie różna - i - dane mogą nie pasować do tabeli. Poniższy przykład dotyczy wersji 15. Jeśli korzystamy z innej wersji, trzeba odnaleźć właściwą strukturę w dokumentacji.</p>
<p>Zalogujemy się do psql z poziomu użytkownika systemowego postgres i stworzymy tę tabelę:</p>
<pre><code>CREATE TABLE postgres_log
(
 - log_time timestamp(3) with time zone,
 - user_name text,
 - database_name text,
 - process_id integer,
 - connection_from text,
 - session_id text,
 - session_line_num bigint,
 - command_tag text,
 - session_start_time timestamp with time zone,
 - virtual_transaction_id text,
 - transaction_id bigint,
 - error_severity text,
 - sql_state_code text,
 - message text,
 - detail text,
 - hint text,
 - internal_query text,
 - internal_query_pos integer,
 - context text,
 - query text,
 - query_pos integer,
 - location text,
 - application_name text,
 - backend_type text,
 - leader_pid integer,
 - query_id bigint,
 - PRIMARY KEY (session_id, session_line_num)
);
</code></pre>
<p>Do załadowania tej tabeli posłużymy się poleceniem "<strong>copy</strong>". Wskazujemy tabelę docelową oraz plik, który ma zostać załadowany. Z poziomu psql wywołujemy (oczywiście zmieniając nazwę pliku loga):</p>
<pre><code>copy postgres_log from '/data_pg/log/postgresql-2023-08-16_000000.csv' with csv;
</code></pre>
<p>Po tej czynności w bazie "postgres", w schemacie public, w tabeli postgres_log znajdą się nasze logi. Sprawdzamy je:</p>
<pre><code>\x
select * from postgres_log limit 1;

Lub zmieniamy ustawienia pagera, wyłączając zawijanie wierszy i dodając ich numerację
\setenv PAGER 'less -S -N'
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/30/20.png" alt="Ładowanie logów CSV do tabeli i ich analiza: Konfiguracja logów serwera PostgreSQL (logging_collector)" /></p>
<p>Możemy teraz użyć SQLa do przeszukiwania logów pod kątem interesujących nas informacji.</p>
<h4>Logowanie nawiązywanych połączeń</h4>
<p>PostgreSQL umożliwia rejestrowanie nowo nawiązywanych sesji. Aby rejestrować nowe połączenia, będziemy musieli włączyć parametr "log_connections", a następnie zrestartować klaster (pg_reload_conf() nie przeładowuje tego parametru). W pierwszej kolejności z poziomu użytkownika systemowego postgres zmiana parametru za pomocą psql:</p>
<pre><code>psql
alter system set log_connections=on;
</code></pre>
<p>Po tej operacji cofamy się do poziomu użytkownika z prawami do sudo, restartujemy usługę i sprawdzamy jej status:</p>
<pre><code>sudo systemctl restart postgresql-15
sudo systemctl status postgresql-15
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/30/30.png" alt="Logowanie nawiązywanych połączeń: Konfiguracja logów serwera PostgreSQL (logging_collector)" /></p>
<p>Wracamy do użytkownika systemowego postgres i sprawdzamy ustawienie parametru "log_connections":</p>
<pre><code>psql
show log_connections;
</code></pre>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/30/40.png" alt="Logowanie nawiązywanych połączeń: Konfiguracja logów serwera PostgreSQL (logging_collector) (2)" /></p>
<p>Po wykonaniu tej operacji parokrotnie zalogowałem się i wylogowałem z serwera, zarówno lokalnie jak i po sieci (wymagało to dodatkowych nieopisanych tutaj czynności - dostępem po sieci zajmiemy się nieco później). Następnie podłączyłem się do PostgreSQL (w tym przypadku za pomocą programu DBeaver) i wyświetliłem logi związane z połączeniami za pomocą zapytania:</p>
<pre><code>select log_time,user_name,database_name,connection_from ,message - from postgres_log pl where message like '%connection%';
</code></pre>
<p>Mój wynik:</p>
<p><img src="https://jsystems.pl/nowy_blog/img/postgresql_adm/30/50.png" alt="Logowanie nawiązywanych połączeń: Konfiguracja logów serwera PostgreSQL (logging_collector) (3)" /></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post250&amp;utm_content=banner"><img src="https://jsystems.pl/new_page_resources/images/other/pgadm1.jpg" alt="Baner szkolenia Administracja, replikacja i tuning baz danych PostgreSQL w JSystems, terminy gwarantowane" /></a></p>
<p><a href="https://jsystems.pl/szkolenia-postgresql;administracja_bazami_danych_postgresql_z_elementami_ha__optymalizacji_i_replikacji.szczegoly?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post250&amp;utm_content=link">Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL →</a></p>
<p>To szkolenie może być <a href="https://jsystems.pl/dofinansowanie?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=post250&amp;utm_content=dofinansowanie">dofinansowane dla Ciebie z KFS lub BUR</a>.</p>
<p>★★★★★Średnia ocena naszych szkoleń w Google: <strong>5/5</strong></p>
<h2>Powiązane artykuły</h2>
<ul>
<li>›<a href="https://jsystems.pl/blog/show_post/kurs_administracji_postgresql_-_wybor_preworka">Kurs administracji PostgreSQL - wybór preworka</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_konfiguracja_patroni_z_etcd_na_ubuntu">PostgreSQL - Konfiguracja Patroni z ETCD na Ubuntu</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_konfiguracja_pgbackrest_dla_klastra_patroni">PostgreSQL - Konfiguracja pgBackRest dla klastra Patroni</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/bezplatny_kurs_administracji_postgresql">Kurs administracji PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/PG_PREWARM_-_prosty_i_szybki_tuning_w_PostgreSQL">PG_PREWARM - prosty i szybki tuning w PostgreSQL</a></li>
<li>›<a href="https://jsystems.pl/blog/show_post/postgresql_-_pg_repack__przenoszenie_przebudowa_i_klastrowanie_tabel_i_indeksow_online">PostgreSQL - PG_REPACK : przenoszenie, przebudowa i klastrowanie tabel i indeksów</a></li>
</ul>
]]></content:encoded></item></channel></rss>