Ciąg dalszy zabaw z Django i Dockerem. Tym razem pójdziemy krok dalej i na potrzeby naszego projektu użyjemy nie domyślnej bazy sqlite tylko osobnego kontenera dockerowego hostującego bazę mariadb. Pierwszym krokiem będzie przygotowanie obrazu dockerowego z instalacją bazy danych.
MariaDB
Na potrzeby tego projektu wystarczy podstawowa instalacja bazy wraz z utworzonym użytkownikiem i bazą.
FROM mariadb:10.5
ENV MYSQL_ROOT_PASSWORD=BardzoTajneHaslo
ENV MYSQL_DATABASE=onlinelogger
ENV MYSQL_USER=django
ENV MYSQL_PASSWORD=DrugieBardzoTajneHaslo
RUN apt update && apt install vim -y
EXPOSE 3306
Dodatkowo instaluję vim’a, ale to raczej standard gdybym musiał ręcznie coś zmieniać w kontenerze. Bardzo ważną tutaj rzeczą jest ustawienie odpowiedniego portu dla EXPOSE. Inne bazy jak mysql, postgresql mogą mieć inne domyślne porty, które należy „udostępnić”.
Następnie budujemy obraz
docker build -t mariadb .
Jeśli chcemy trzymać w jednym miejscu pliki Dockerfile dla bazy danych i naszej aplikacji, możemy wskazywać bezpośrednio który plik ma zostać użyty podczas budowy poprzez opcję „-f”
docker build -t mariadb -f Dockerfile_baza .
Sieć
Mając utworzoną bazę danych należy teraz zająć się siecią, która połączy kontener hostujący bazę i django. Do stworzenia takiej sieci wykorzystamy proste polecenie
docker network create mojasieć
Polecenie to utworzy wewnątrz dockera sieć o nazwie „mojasieć” typu bridge i jej użyjemy do zapewnienia komunikacji pomiędzy dwoma obrazami. Chwilowo zostawiamy ten temat i przechodzimy do ustawień projektu django.
Projekt Django
Aby nie powielać informacji, które zawarte są w poprzednim wpisie https://sp6mi.pl/index.php/2024/08/08/django-docker/ opiszę pokrótce zmiany jakie należy wprowadzić do samego projektu.
Pierwszą i zasadniczą zmianą będzie modyfikacja pliku settings.py i sekcji odpowiedzialnej za bazę danych
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'onlinelogger',
'USER': 'django',
'PASSWORD': 'DrugieBardzoTajneHaslo',
'HOST': '172.18.0.2',
'PORT': '',
}
}
Za komentowana sekcja pokazuje jak pierwotnie wyglądało ustawienie. Zmiennej NAME podajemy nazwę naszej bazy danych – nie obrazu dokerowego, w USER nazwę użytkownika i oczywiście hasło tego użytkownika w sekcji PASSWORD. Co do zawartości pola HOST to nim zajmiemy się za chwilę.
Łączymy w całość
Przyszedł czas aby połączyć nasze elementy układanki w całość.
Krok 1. Uruchamiamy kontener z bazą danych
docker run --name mariadb -p3306:3306 --network mojasiec -d mariadb
Warto tutaj zaznaczyć dwie nowe opcje jakich używamy: -p3306:3306 odpowiada za otwarcie portu dla kontenera i hosta (podanie jednej wartości upublicznia port dla kontenera ale już nie dla interfejsu hosta), a opcja –network określa z jakieś sieci dokerowej obraz ma korzystać.
Krok 2. Uruchamiamy kontenera z aplikacją django
docker run --name docker_test -p8000:8000 --network mojasiec -d docker_test
Tutaj również upubliczniamy porty, tym razem domyślne na jakich django hostuje serwer www, oraz zaznaczamy z jakiej sieci korzystamy.
Wydawać by się mogło, że to wszystko, jednak połączenie bazy i aplikacji wciąż nie działa. Musimy dokonać jeszcze jednej edycji ustawień django i wykonać „migracje”.
Krok 3. Korygujemy ustawienia sieci
Aby django poprawie połączyło się z bazą musimy wskazać na jakim adresie IP/hoście działa ta baza, w tym celu wykonamy inspekcję naszej sieci.
docker network inspect mojasiec
Po wykonaniu tego polecenia powinniście otrzymać mniej więcej takie inforamcje
[
{
"Name": "logger",
"Id": "77de7acf1d8d0db6811138ae94b438422611578da5e96c0e139e3b078be0901f",
"Created": "2024-08-14T19:59:22.900551934+02:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"27c4a3723b9db1296f7dab5bb9ba7215636d6724471e7b321873496f6fd50bb6": {
"Name": "onlinelogger",
"EndpointID": "797a5b999490892a2b9f4b0aa6c3cfccfd25246b7aa1e092aaa51c0251d5d196",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"d5d99508c57896076c679475b63b273f66fbee5128a0cd60d1f52845e1a70183": {
"Name": "mariadb",
"EndpointID": "bb57b7a54996b84eef881c3127e9410fd839ae072645e59c693b75b3be8334d3",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Interesuje Was tylko ostatnia sekcja „mariadb” a dokładniej wartość pola IPv4Address, które w tym przypadku to 172.18.0.2/16. I ten adres – ale bez maski podsieci /16 – musimy wpisać w pole HOST w pliku settings.py projektu django.
Krok 4. Logujemy się do kontenera z aplikacją django i wykonujemy tradycyjne migracje, tak aby w naszej bazie zostały utworzone wszelkie tabele i niezbędne wpisy. W tym celu wystarczy wykonać
python manage.py makemigrations
python manage.py migrate
Dla pewności można zalogować się również do kontenera z bazą danych i sprawdzić czy baza zawiera pożądane tabele.