Opis instalacji Docker'a: https://docs.docker.com/install
Opis instalacji docker-compose: https://docs.docker.com/compose/install
Do zarządzania kodem źródłowym projektu używany jest system kontroli wersji Git. Instrukcja instalacji systemu znajduje się pod adresem: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
$ git clone https://gitlab.dane.gov.pl/mcod/backend.git
$ cd backend
Lokalne środowisko można uruchomić na dwa sposoby:
- w docker compose
- na swoim hoście
Obie opcje dockeryzują zależności, takie jak baza danych i obie wymagają konfiguracji wspólnej opisanej w następnej sekcji.
Aby projekt działał prawidłowo, należy skopiować zawartość pliku env.sample do nowo utworzonego pliku .env.
Do poprawnego działania biblioteki django-searchable-encrypted-fields należy wygenerować klucz szyfrowania
(encryption key) za pomocą biblioteki secrets, np.:
python -c "import secrets; print(secrets.token_hex(32))"Klucz ten jest niezbędny, ponieważ biblioteka szyfruje i odszyfrowuje dane zapisane w bazie – działa w obie strony.
Wygenerowany klucz należy przypisać do zmiennej FIELD_ENCRYPTION_KEYS w pliku .env.
Zmiennej tej należy przypisać listę kluczy, oddzielonych przecinkami. Nowe klucze dodaje się na początku listy (czyli przed starymi). Więcej informacji na stronie projektu.
Przykład:
FIELD_ENCRYPTION_KEYS=new_key,previous_key
Środowisko lokalne oferuje dwie opcje:
filebased, czyli zapis maili do pliku w/tmp,smtp, czyli użycie mailhog.
Środowisko domyślnie używa wersji z SMTP, żeby zobaczyć wysłane maile, wejdź na https://mail.mcod.local (proxy do
serwisu mcod-smtp).
Żeby to zmienić, wyedytuj plik local.py lub usuń zmienną środowiskową EMAIL_HOST.
Testy używają opcji filebased.
Aby projekt działał prawidłowo, należy skopiować zawartość pliku mcod/settings/local.py.sample do nowo utworzonego
pliku mcod/settings/local.py.
Konfiguracja Django realizowana jest na podstawie ustawień z pliku mcod/settings/base.py, które są nadpisywane
ustawieniem z pliku mcod/settings/local.py.
Zmienne konfiguracyjne idą w tej kolejności:
.envjest źródłem zmiennych środowiskowych- dla docker-compose'a (zmienne w plikach docker-compose*.yml)
- dla aplikacji za pośrednictwem
base.py
- aplikacja samodzielnie czyta zmienne środowiskowe w
base.py local.py,test.pyimportują wszystko zbase.py
Co oznacza, że plik .env nadpisuje zmienne środowiskowe, jeśli jest dostępny dla aplikacji.
Z tego powodu i dla przejrzystości lokalne serwisy w docker-compose.local.yml używają environment zamiast env_file
docker compose up -d mcod-dbPostgres przy pierwszym uruchomieniu utworzy bazę mcod i
użytkownika mcod z takim samym hasłem, zgodnie ze zmiennymi
środowiskowymi POSTGRES_*.
W przypadku korzystania z IDE PyCharm (Professional) możliwe jest dodanie konfiguracji dotyczącej zarządzania kontenerami. Więcej informacji pod linkiem.
Wybrany kontener uruchamia python manage.py w środowisku docker-compose'a, wraz z zależnościami.
Wyedytuj plik /etc/hosts, tak by nazwy serwisów mcod rozwiązywały się na adres IP usługi mcod-nginx (patrz
docker-compose.yml).
172.18.18.100 mcod.local api.mcod.local admin.mcod.local cms.mcod.local forum.mcod.local mail.mcod.local
Uwaga dla MacOS: zamień adres 172.18.18.100 na 127.0.0.1.
Docker na MacOS nie działa natywnie i adresy wewnętrzne z sieci dockerowych nie są osiągalne z poziomu hosta.
- Uruchom mcod-rdfdb
docker compose up mcod-rdfdb - Wejdź na localhost:3030
- Zaloguj się, username to
admin, a hasło toADMIN_PASSWORDz pliku.env - Utwórz Dataset o nazwie
ds(zmienna konfiguracyjnaFUSEKI_DATASETwbase.py)- zaznacz opcję Persistent (ale nie "Persistent TDB2").
🚧 Proces budowania środowiska może trwać nawet kilkadziesiąt minut w zależności od Twojego komputera, sieci itp.
W procesie tym osiągniesz następujące cele:
- działające zależności, takie jak baza danych
- możliwość uruchomienia testów lokalnie
- możliwość zalogowania się do Panelu Administracyjnego
- działający CMS Wagtail
- działające kolejki Celery
- zaślepioną wysyłkę maili
W związku z mirrorowaniem obrazu discource, przed wykonaniem poniższej komendy, trzeba się zalogować do gitlaba.
Wejdź na stronę rejestru, rozwiń "CLI Commands" i wykonaj
komendę rozpoczynającą się od
docker login. Alternatywnie — wyłącz kontenery discourse i przestaw zmienną DISCOURSE_FORUM_ENABLED na false.
docker compose -f docker-compose.local.yml builddocker compose -f docker-compose.local.yml run mcod-local-run python manage.py init_mcod_dbUwaga: zadanie do wykonania jednorazowo, również dla środowiska bare-metal, dane są zapisane w wolumenie mcod-db.
docker compose up mcod-db mcod-elasticsearch
docker compose -f docker-compose.local.yml run mcod-local-run python manage.pyUwaga: zadanie do wykonania jednorazowo, również dla środowiska bare-metal, dane są zapisane w wolumenie mcod-elasticsearch.
Nginx wymaga zmiennych środowiskowych MCOD_NGINX_* wskazujących na usługi w dockerze.
Ustaw je w .env:
MCOD_NGINX_WS=http://172.18.18.104:8001
MCOD_NGINX_PN_APPS=http://172.18.18.101:8001
MCOD_NGINX_API=http://172.18.18.102:8000
MCOD_NGINX_ADMIN=http://172.18.18.101:8001
MCOD_NGINX_CMS=http://172.18.18.103:8002Adresy odpowiadają adresom usług w docker-compose.local.yml.
docker compose -f docker-compose.local.yml upLub wybranych:
docker compose -f docker-compose.local.yml up mcod-local-admin mcod-local-cmsAby uruchomić shell w kontenerze:
docker compose -f docker-compose.local.yml run --entrypoint bash mcod-local-celeryAby uruchomić celery beat
wyedytuj zmienne środowiskowe serwisu mcod-local-celery w pliku docker-compose.local.yml.
Odkomentuj odpowiednią wartość CELERY_OPTS:
# no scheduler
CELERY_OPTS: "-l DEBUG"
# using beat
# CELERY_OPTS: "-l DEBUG -B --scheduler django_celery_beat.schedulers:DatabaseScheduler"Czy są kontenery, które wyszły z exit status != 0?
docker compose -f docker-compose.local.yml ps --allJeśli są — sprawdź ich logi.
Po uruchomieniu usługi mcod-local-admin, pod adresem https://admin.mcod.local będzie dostępny panel administracyjny.
Możliwe jest zalogowanie się na konta 2 użytkowników:
- login: admin@mcod.local, hasło:testadmin123!
- login: pelnomocnik@mcod.local, hasło: User123!
Na potrzeby np. harvestacji celery musi móc się połączyć do api. Kontener celery wykonuje setup certyfikatów w entrypoint'cie.
Poprawne zachowanie to 200:
❯ docker compose -f docker-compose.local.yml -f docker-compose.override.yml run --entrypoint bash mcod-local-celery
root@2f1ba9b58144:/usr/src/mcod_backend# /usr/local/bin/start-celery-local
Installing local SSL certificates for Celery->API communication
2025-10-07 12:07:24,475 mcod DEBUG Started configuring certifi..
2025-10-07 12:07:24,477 mcod INFO Certi file updated successfully.
wait-for-it: waiting 30 seconds for mcod-rabbitmq:5672
wait-for-it: mcod-rabbitmq:5672 is available after 0 seconds
^C
Aborted!
root@2f1ba9b58144:/usr/src/mcod_backend# python -c 'import requests; print(requests.get("https://cms.mcod.local"))'
<Response [502]>
root@2f1ba9b58144:/usr/src/mcod_backend#W razie problemów z certyfikatem dostaniemy taki błąd:
❯ docker compose -f docker-compose.local.yml -f docker-compose.override.yml run --entrypoint bash mcod-local-celery
[+] Creating 1/1
✔ Container mcod-nginx Running 0.0s
root@5878a8087580:/usr/src/mcod_backend# python -c 'import requests; print(requests.get("https://cms.mcod.local"))'
Traceback (most recent call last):
………
requests.exceptions.SSLError: HTTPSConnectionPool(host='cms.mcod.local', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1131)')))Powyższy przykład działa, ponieważ użyliśmy bash jako entrypoint.
❯ docker compose -f docker-compose.local.yml run --entrypoint bash mcod-local-celery
root@5878a8087580:/usr/src/mcod_backend# python manage.py configure_nginx_certs /usr/src/mcod_backend/mcod.local.pem
2025-09-19 09:35:59,353 mcod DEBUG Started configuring certifi..
2025-09-19 09:35:59,363 mcod INFO Certi file updated successfully.- czy jest podmontowany volume z certyfikatami
./docker/nginx/certs/mcod.local.pem:/usr/src/mcod_backend/mcod.local.pem - czy ścieżki w pliku start-celery-local.sh zgadzają się z w/w wolumenem
- czy
mcod-nginxużywa tych samych certyfikatów
docker compose -f docker-compose.local.yml up mcod-local-apiAPI jest dostępne pod api.mcod.local, dokumentacja OpenApi: /doc.
Do sprawdzenia stanu Celery najlepiej użyć Flower. Jest to opcjonalny komponent, więc trzeba uruchomić go osobno:
GUI będzie dostępne na porcie 8888, link.
Celery działa, jeśli na liście workerów na pierwszej stronie widać jeden o nazwie zaczynającej się od celery@.
docker compose -f docker-compose.local.yml up mcod-local-cmsWagtail jest dostępny pod cms.mcod.local. Dane do logowania są te same co dla Panelu Administracyjnego. CMS działa, jeśli da się zalogować, dalsza konfiguracja jest poza zakresem tego punktu.
Discourse jest dostępny pod forum.mcod.local. Po wykonaniu konfiguracji powinien być widoczny jeden wątek "Welcome to Discourse".
Komenda umożliwia skonfigurowanie instancji forum Discourse – od wygenerowania systemowego klucza API, przez ustawienia, aż po instalację motywu i synchronizację użytkowników.
Uwaga: username i password muszą się zgadzać z .env.
docker compose -f docker-compose.local.yml up -d mcod-local-admin mcod-nginx mcod-discourse
docker compose -f docker-compose.local.yml run mcod-local-run \
python manage.py set_up_forum \
--file data/discourse/settings.json \
--theme_path data/discourse/discourse-otwarte-dane-theme.zip \
--username user \
--password bitnami123Po wykonaniu powyższej komendy utworzy się plik mcod/api_key.txt. Zawartość pliku należy przekopiować i wkleić do
zmiennej DISCOURSE_API_KEY w pliku .env
Testy działają, jeśli da się uruchomić pojedynczy test. Działający przykład:
docker compose -f docker-compose.local.yml run mcod-local-tests -n1 mcod/resources/tests/test_admin/test_file_validation.pyPyCharm może używać interpretera Python zainstalowanego w kontenerze w serwisie w docker compose. Więcej informacji w dokumentacji.
- podczas konfiguracji wskaż oba pliki:
docker-compose.ymlidocker-compose.local.yml - wybierz serwis, który nie rezerwuje adresu IP ani portu, ani nie ma ustawionego entrypointa, np.
mcod-local-runPozwala to uruchomić np. celery pod debugerem wbudowanym w IDE.
Aby uruchomić wszystkie usługi w katalogu projektu backend wykonaj:
$ docker compose up
Opcjonalnie można uruchamiać tylko wybrane usługi wyspecyfikowane jako parametr polecenia:
$ docker compose up -d mcod-db mcod-elasticsearch
Aby zatrzymać wybraną usługę, w katalogu projektu backend wykonaj:
$ docker compose stop mcod-elasticsearch
Aby zatrzymać usługę łącznie z usunięciem kontenera, w katalogu backend wykonaj:
$ docker compose down mcod-db
Aby zatrzymać usługę łącznie z usunięciem kontenera oraz powiązanych z nim wolumenów (całkowite usunięcie usługi), w
katalogu backend wykonaj:
$ docker compose down -v mcod-db
Nginx wymaga zmiennych środowiskowych MCOD_NGINX_* wskazujących na usługi w dockerze.
Ustaw je w .env:
MCOD_NGINX_WS=http://host.docker.internal:8001
MCOD_NGINX_PN_APPS=http://host.docker.internal:8001
MCOD_NGINX_API=http://host.docker.internal:8000
MCOD_NGINX_ADMIN=http://host.docker.internal:8001
MCOD_NGINX_CMS=http://host.docker.internal:8002Ta konfiguracja oznacza, że nginx będzie proxował ruch na hosta.
Środowisko bare metal może używać mailhoga, ale należy ustawić zmienną środowiskową w .env:
EMAIL_HOST=localhost$ pip install -I pipenv==2022.10.12
$ pipenv run pip install setuptools"<58"
$ pipenv install
$ exit
$ pipenv shell
(backend) $ python manage.py init_mcod_db
Uwaga: zadanie do wykonania jednorazowo, również dla środowiska docker, dane są zapisane w wolumenie mcod-db.
(backend) $ python manage.py search_index --rebuild -f
Uwaga: zadanie do wykonania jednorazowo, również dla środowiska docker, dane są zapisane w wolumenie mcod-elasticsearch.
Pomocnicza zmienna środowiskowa USERS_TEST_LOGINGOVPL (False/True) umożliwia wyłączenie komunikacji z Węzłem Krajowym, poprzez wykorzystanie lokalnego formularza logowania, imitującego ten zwracany z Węzła Krajowego.
Aby biblioteka certifi poprawnie używała certyfikatów nginx, należy dodać odpowiedni wpis do pliku cacert.pem. Aby to zrobić, należy uruchomić komendę:
(backend) $ python manage.py configure_nginx_certs ./docker/nginx/certs/mcod.local.pem
Jest to konieczne, by lokalny harvester nie rzucał błędami związanymi z SSL.
Poza specyficznymi dla każdej usługi zmiennymi środowiskowymi, dla wszystkich usług należy ustawić zmienne środowiskowe:
PYTHONUNBUFFERED=1;
ENVIRONMENT=local;
NO_REPLY_EMAIL=env@test.local;
ALLOWED_HOSTS=*;
BASE_URL=https://mcod.local;
API_URL=https://api.mcod.local;
ADMIN_URL=https://admin.mcod.local;
CMS_URL=https://cms.mcod.local;
API_URL_INTERNAL=https://api.mcod.local;
DEBUG=yes;
COMPONENT=admin;(backend) $ python manage.py runserver 0:8001
(backend) $ python -m werkzeug.serving --bind 0:8000 --reload --debug mcod.api:app
COMPONENT=cms;
(backend) $ python manage.py runserver 0:8002
Po uruchomieniu usługi będzie ona dostępna pod adresem https://cms.mcod.local/admin/
Instrukcja uruchomienia frontend w pliku frontend/README.md
Do prawidłowego funkcjonowania niezbędne jest uruchomienie usługi API.
COMPONENT=celery;
Uruchomienie usługi jest niezbędne, jeżeli zamierzamy korzystać z zadań asynchronicznych, takich jak wysyłanie maili czy walidacja plików zasobów.
(backend) $ python -m celery --app=mcod.celeryapp:app worker -l DEBUG -E -Q default,resources,indexing,periodic,newsletter,notifications,search_history,watchers,harvester,indexing_data,history,graphs,datasets,archiving,reports,discourse,showcases
Aby uruchomić celery beat dodaj flagę
-B do powyższego polecenia.
Discourse jest dostępny pod forum.mcod.local.
Komenda umożliwia skonfigurowanie instancji forum Discourse – od wygenerowania systemowego klucza API, przez ustawienia, aż po instalację motywu i synchronizację użytkowników.
(backend) python manage.py set_up_forum --file data/discourse/settings.json --theme_path data/discourse/discourse-otwarte-dane-theme.zip --username user --password bitnami123
Po wykonaniu powyższej komendy utworzy się plik mcod/api_key.txt. Zawartość pliku należy przekopiować i wkleić do
zmiennej DISCOURSE_API_KEY w pliku .env
Sekcja zawiera kolejne, opcjonalne elementy setupu, do wykonania po pierwszym uruchomieniu.
Taski periodyczne są uruchamiane zgodnie z harmonogramem określonym w kodzie, w zmiennej beat_schedule. Można jednak
zmienić domyślny harmonogram startu dla tasków periodycznych poprzez ustawienie zmiennej środowiskowej
UPDATE_TASKS_CELERY_BEAT_TIME.
Na przykład — zmiana czasu startu 2 tasków periodycznych:
UPDATE_TASKS_CELERY_BEAT_TIME='{"kronika_sparql_performance": {"day_of_month":2, "hour": 23, "minute": 20}, "catalog_xml_file_creation":{"hour": 7, "minute": 15}}'
Tworzenie wykazu głównego: dla zadania realizującego tworzenie wykazu głównego DGA niezbędne jest ustawienie zmiennej środowiskowej określającej id Instytucji będącej jego właścicielem:
MAIN_DGA_DATASET_OWNER_ORGANIZATION_PK=\<organization_pk>
Tworzenie raportu katalog.xml przez task create_xml_metadata_files może zostać dezaktywowane przez ustawienie
zmiennej środowiskowej
ENABLE_CREATE_XML_METADATA_REPORT=False
Przykłady komend manage.py poniżej są minimalne; by uruchomić je w dockerze trzeba użyć:
docker compose -f docker-compose.local.yml run mcod-local-run python manage.py TUTAJ_KOMENDAPo zmianie tłumaczeń w pliku translations/system/pl/LC_MESSAGES/django.po należy przejść do katalogu
projektu,
w którym znajduje się plik manage.py. Następnie uruchomić polecenie:
(backend) $ python manage.py compilemessages
Standardowe dodanie nowej zależności (np. poprzez edycję Pipfile i uruchomienie instalacji) może spowodować niezamierzoną aktualizację wszystkich pozostałych pakietów w projekcie (Pipfile.lock).
Taka operacja niesie ryzyko wystąpienia błędów regresji i awarii testów, jeśli wersje innych bibliotek ulegną zmianie.
Aby dodać nowy pakiet, zachowując stabilne wersje pozostałych zależności, należy skorzystać z flagi --keep-outdated.
Zalecana komenda:
pipenv install django-csp=="3.7" --keep-outdatedParametr --keep-outdated wymusza na Pipenv zaktualizowanie pliku Pipfile.lock wyłącznie dla nowo dodawanego pakietu, pozostawiając resztę zależności w ich dotychczasowych wersjach.
Zapewnia to spójność środowiska deweloperskiego i produkcyjnego.
(backend) $ pytest
docker-compose.local.yml zawiera konfigurację pozwalającą uruchomić testy w odizolowanym środowisku Dockerowym, z
podmontowanym kodem.
Warto sprawdzić testy w ten sposób szczególnie przy okazji dodawania zależności, również systemowych (takich jak np.
xmlsec). Jest to niezależne od tego, czy uruchamiasz resztę środowiska za pomocą dockera czy w opcji bare metal.
Uruchomienie wszystkich testów (analogicznie do wywołania pytest):
docker compose -f docker-compose.local.yml run mcod-local-testsLub z argumentami:
docker compose -f docker-compose.local.yml run mcod-local-tests mcod/guides/tests/test_api.py --no-cov(backend) $ python manage.py search_index --rebuild
(backend) $ python manage.py search_index --rebuild --models resources.Resource(backend) $ python manage.py validate_resources --where 'id in (<id_1,...,id_N>)'
(backend) $ python manage.py validate_resources --where id=<id>
(backend) $ python manage.py index_file --pks <id_1,...,id_N>
(backend) $ python manage.py validate_resources --async
W przypadku użycia flagi async należy najpierw uruchomić Celery (instrukcja niżej), gdyż rewalidacja będzie odbywać
się w ramach tasków Celery.
Aby pre-commit uruchamiał się przy każdym commicie, trzeba go zainstalować:
(backend) pre-commit install
Dodanie pliku/plików jest niezbędne do sprawdzenia ich poprawności:
$ git add <filename>
Uruchomienie pre-commit sprawdzającego m.in. poprawność stylu i importów.
(backend) $ pre-commit run
Używamy black do zachowania stylu kodu.
Konfiguracja jest obecna tylko w .pre-commit-config.yaml, ponieważ nie używamy pyproject.toml.
git blame może ignorować commit z masowym reformatowaniem kodu, zobacz opcję
--ignore-revs-file .git-blame-ignore-revs
(backend) python manage.py shell_plus
(backend) python manage.py shell_plus --settings mcod.settings.test
Każdy użytkownik o roli Administrator lub Pełnomocnik, podczas dodawania, usuwania i edycji w Admin Panelu jest automatycznie synchronizowany z bazą forum Discourse, a jego status zostaje zaktualizowany. Podobnie przy wylogowaniu – użytkownik jest również wylogowywany z forum. Istnieje alternatywna komenda, która synchronizuje użytkowników między serwisem Otwarte Dane a forum Discourse, tworząc w bazie forum nowych użytkowników o statusie pełnomocnika lub administratora oraz zapisując ich klucz API w bazie OD.
(backend) python manage.py set_up_forum --step_name sync_users