MySQL + Docker Compose + Nodejs/Python — przewodnik krok po kroku
MySQL to jedna z najpopularniejszych relacyjnych baz danych wszech czasów. Używanie MySQL z Dockerem i docker-compose bardzo ułatwia i przyspiesza testowanie wszelkich zmian w dowolnej aplikacji używającej MySQL jako bazy danych. W tym samouczku szczegółowo opiszemy, jak używać MySQL z Dockerem i komponować docker krok po kroku, aby wszystko było łatwe do zrozumienia.

Kod TLDR tutaj . Ruszajmy!
Dlaczego warto używać MySQL z Dockerem do rozwoju lokalnego
Istnieje wiele wspaniałych powodów, aby używać dowolnej bazy danych, w tym MySQL z Dockerem, do lokalnego rozwoju, niektóre z nich są następujące:
- Używanie dowolnej wersji MySQL, takiej jak 5.6, 5.7 lub 8, zgodnie z projektem lub z dowolnego innego powodu, jest bardzo łatwe.
- Zwykle z dokerem, jeśli działa na twojej maszynie, będzie działał na maszynie innego inżyniera oprogramowania, w środowisku przejściowym, a także na produkcji, biorąc pod uwagę, że zachowana jest pewna kompatybilność.
- Nowy członek zespołu może być produktywny w ciągu godzin, a nie dni, jeśli doker i inne narzędzia są skonfigurowane w efektywny sposób.
Wymagania wstępne
Zanim ubrudzimy sobie ręce niektórymi kodami i poleceniami CLI, poniżej przedstawiamy kilka wymagań wstępnych:
- W tym przewodniku przydatna będzie podstawowa znajomość Dockera i powiązanych poleceń, takich jak budowanie dokera, uruchamianie, wykonywanie itp.
- Wszelkie wcześniejsze informacje o Docker-compose będą bardzo przydatne
- Ogólne zrozumienie działania relacyjnych baz danych, w szczególności MySQL, będzie korzystne.
Uruchom MySQL z Dockerem
W tym przewodniku dla początkujących użyjemy oficjalnego obrazu MySQL Docker z DockerHub . Oficjalny obraz MySQL Docker nie ma wersji Alpine Linux, jednak wersja Debiana ma również 147 MB, co nie jest zbyt duże dla obrazu dokera.
Aby uruchomić kontener MySQL 8.0 przy użyciu oficjalnego obrazu, po prostu uruchom następujące polecenie:
mkdir /tmp/mysql-data
docker run --name basic-mysql --rm -v /tmp/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=ANSKk08aPEDbFjDO -e MYSQL_DATABASE=testing -p 3306:3306 -it mysql:8.0
--name
nazwać kontenerbasic-mysql
--rm
aby usunąć pojemnik, gdy jest zatrzymany-v /tmp/mysql-data:/var/lib/mysql
zostanie dodany, aby zachować dane po ponownym uruchomieniu kontenera, zniknie, gdy komputer hosta uruchomi się ponownie tak, jak jest/tmp
-e MYSQL_ROOT_PASSWORD=ANSKk08aPEDbFjDO -e MYSQL_DATABASE=testing
do ustawienia hasła użytkownika root i zainicjowania bazy danych o nazwietesting
-p 3306:3306
mapuje port hosta 3306 na port kontenera 3306, port 3306 jest domyślnym portem MySQL.-it mysql:8.0
- -pokaże wszystkie logi i używamy oficjalnego obrazu MySQL w wersji 8.0, który będzie działał w wersji Debian.
2022-10-27 06:11:09+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
2022-10-27 06:11:10+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-10-27 06:11:10+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
2022-10-27 06:11:11+00:00 [Note] [Entrypoint]: Initializing database files
2022-10-27T06:11:11.957280Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
2022-10-27T06:11:11.957392Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.31) initializing of server in progress as process 80
2022-10-27T06:11:11.987130Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2022-10-27T06:11:12.013548Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-10-27T06:11:16.919522Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-10-27T06:11:20.772591Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2022-10-27 06:11:27+00:00 [Note] [Entrypoint]: Database files initialized
2022-10-27 06:11:27+00:00 [Note] [Entrypoint]: Starting temporary server
mysqld will log errors to /var/lib/mysql/729f35877b11.err
mysqld is running as pid 133
2022-10-27 06:11:40+00:00 [Note] [Entrypoint]: Temporary server started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
2022-10-27 06:11:44+00:00 [Note] [Entrypoint]: Creating database testing
2022-10-27 06:11:44+00:00 [Note] [Entrypoint]: Stopping temporary server
2022-10-27 06:11:48+00:00 [Note] [Entrypoint]: Temporary server stopped
2022-10-27 06:11:48+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
2022-10-27T06:11:48.661152Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
2022-10-27T06:11:48.670274Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.31) starting as process 1
2022-10-27T06:11:48.683339Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2022-10-27T06:11:48.700826Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-10-27T06:11:51.317151Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-10-27T06:11:52.336910Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2022-10-27T06:11:52.336965Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2022-10-27T06:11:52.352191Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2022-10-27T06:11:52.548249Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2022-10-27T06:11:52.548394Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
docker exec -it basic-mysql /bin/bash
#once inside the container
mysql -u root -p
#put/paste the password, ANSKk08aPEDbFjDO, and once inside MySQL CLI run
show databases;

Kontener możemy zatrzymać za pomocądocker stop basic-mysql
Chociaż nie było to zbyt trudne, nie uważałbym tego za łatwe, podobnie jak parametry polecenia nie były łatwe do zapamiętania. Innym aspektem jest to, że uruchomiliśmy MySQL w izolacji, nie ma powiązania między aplikacją Quotes API Node.js a kontenerem MySQL. W tym miejscu deklaratywna natura docker-compose jest bardzo przydatna, jak zobaczymy w następnej sekcji.
Uruchamianie MySQL z docker-compose
Dodaj początkowe skrypty wstrzykiwania
mkdir basic-mysql && touch ./basic-mysql/init.sql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
USE testing;
DROP TABLE IF EXISTS `order`;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS coffee;
/*NEVER store passwords in clear text as it's done here!!!*/
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
role ENUM('admin', 'consumer')
);
INSERT INTO
users (name, email, password, role)
VALUES
('test', '[email protected]', 'test', 'consumer'),
('admin', '[email protected]', 'admin', 'admin');
CREATE TABLE coffee (
id SERIAL PRIMARY KEY,
blend_name char(64),
origin char(64),
variety char(64),
notes char(64),
intensifier char(64),
price float
);
INSERT INTO
coffee (
blend_name,
origin,
variety,
notes,
intensifier,
price
)
VALUES
(
'Good-morning Symphony',
'Dipilto, Nicaragua',
'Kona',
'crisp, coating, concord grape, fresh wood, maple syrup',
'astringent',
23.7
),
(
'KrebStar Mug',
'Central Valley, Costa Rica',
'Yellow Bourbon',
'mild, tea-like, pineapple, barley, musty',
'delicate',
40.0
);
CREATE TABLE `order` (
id SERIAL PRIMARY KEY,
coffeeId BIGINT UNSIGNED NOT NULL,
userId BIGINT UNSIGNED NOT NULL,
quantity INT NOT NULL,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_coffeeId FOREIGN KEY (coffeeId) REFERENCES coffee(id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_userId FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
);
-- insert data into order table
INSERT INTO
`order` (coffeeId, userId, quantity)
VALUES
(1, 1, 2),
(2, 2, 1);
version: '3.8'
services:
basic-mysql:
container_name: basic-mysql
image: mysql:8.0
cap_add:
- SYS_NICE
restart: always
environment:
- MYSQL_DATABASE=testing
- MYSQL_ROOT_PASSWORD=ANSKk08aPEDbFjDO
ports:
- '3306:3306'
- '33060:33060'
command: --init-file /docker-entrypoint-initdb.d/init.sql
volumes:
- basic-mysql:/var/lib/mysql
- ./basic-mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
basic-mysql:
driver: local
- Używa pliku docker-compose w wersji 3.8 , jednej z najnowszych.
- W związku z tym definiujemy
db
jako usługę, każda usługa będzie równoważna z nowym poleceniem docker run - Następnie wskazujemy docker-compose, aby używał oficjalnego obrazu MySQL 8.0 dla tej usługi DB.
- Ustawienie pomija
cap_add
niektóre nieprzydatne komunikaty o błędach.SYS_NICE
- Następnie prosimy docker-compose, aby zawsze restartował ten kontener, jeśli się nie powiedzie.
- Następnie dodajemy 2 zmienne środowiskowe dla bazy danych MySQL oraz hasło użytkownika root. W zależności od potrzeb możemy dodać innego użytkownika, aby nadać mu mniejsze uprawnienia z innymi zmiennymi env.
- Następnie mapujemy port hosta
3306
na port kontenera,3306
ponieważ serwer MySQL działa na porcie kontenera3306
. W zależności od preferencji port hosta może zostać zmieniony. - Następnie uruchamiamy skrypt inicjujący, aby wstrzyknąć początkowe dane do naszej bazy danych mysql
testing
- Następnie dodajemy 2 woluminy, pierwszy to wolumin DB zmapowany na poniższe woluminy
basic-mysql
. Co zasadniczo mówi dockerowi i docker-compose, aby zarządzali woluminem za nas. Następnie dodajemyinit.sql
skrypt, który zainicjalizuje naszątesting
bazę danych podanym plikiem SQL.
docker-compose up
[+] Running 1/1
⠿ Container basic-mysql Created 0.2s
Attaching to basic-mysql
basic-mysql | 2022-10-27 09:38:51+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
basic-mysql | 2022-10-27 09:38:51+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
basic-mysql | 2022-10-27 09:38:51+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
basic-mysql | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
basic-mysql | 2022-10-27T09:38:52.620935Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
basic-mysql | 2022-10-27T09:38:52.628931Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.31) starting as process 1
basic-mysql | 2022-10-27T09:38:52.649308Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
basic-mysql | 2022-10-27T09:38:53.380032Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
basic-mysql | 2022-10-27T09:38:53.698374Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
basic-mysql | 2022-10-27T09:38:53.698422Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
basic-mysql | 2022-10-27T09:38:53.705214Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
basic-mysql | 2022-10-27T09:38:53.904655Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
basic-mysql | 2022-10-27T09:38:53.904741Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
Łączenie się z bazą danych za pośrednictwem interfejsu użytkownika, takiego jak MySQL Workbench , i sprawdzanie, czy nasze tabele są prawidłowo wypełnione


Przetestuj połączenie za pomocą skryptu Pythona
Upewnij się, że zależność jest zainstalowana. Biegnij pip install pymysql
lubpip3 install pymysql
# main.py
import pymysql.cursors
# Connect to the database
connection = pymysql.connect(
host='localhost',
user='root',
password='ANSKk08aPEDbFjDO',
database='testing',
cursorclass=pymysql.cursors.DictCursor
)
with connection:
with connection.cursor() as cursor:
# Read a single record
sql = "SELECT * FROM `users`"
cursor.execute(sql)
result = cursor.fetchall()
print(result)
Testowanie połączenia za pomocą skryptu węzła
Upewnij się, że zależność jest zainstalowana. Biegaćnpm i mysql
// main.js
const mysql = require('mysql');
const con = mysql.createConnection({
host: "localhost",
user: "root",
password: "ANSKk08aPEDbFjDO",
database: "testing"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
con.query("SELECT * FROM `users`", function (err, result, fields){
if (err) throw err;
console.log(result);
});
});
Wezwanie do działania
Jeśli uznasz ten przewodnik za pomocny, nie wahaj się klaskać i podążać za mną. Dołącz do medium za pomocą tego linku , aby uzyskać dostęp do wszystkich artykułów premium ode mnie i wszystkich innych niesamowitych pisarzy tutaj na medium.
Kodowanie na wyższym poziomie
Dziękujemy za bycie częścią naszej społeczności! Zanim pójdziesz:
- Klaskajcie za relację i śledźcie autora
- Zobacz więcej treści w publikacji Level Up Coding
- Śledź nas: Twitter | LinkedIn | Biuletyn Informacyjny