SP6MI

Krótkofalarstwo & DevOps

MariaDB + Django w Dockerze

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.