MySQL + Docker Compose + Nodejs/Python: una guida dettagliata
MySQL è uno dei database relazionali più popolari di tutti i tempi. L'utilizzo di MySQL con Docker e docker-compose rende molto facile e veloce testare eventuali modifiche in qualsiasi applicazione utilizzando MySQL come database. In questo tutorial, descriveremo in dettaglio come utilizzare MySQL con Docker e docker-compose passo dopo passo mantenendo le cose facili da comprendere.
Codice TLDR qui . Andiamo a rotazione!
Perché utilizzare MySQL con Docker per lo sviluppo locale
Esistono molti ottimi motivi per utilizzare qualsiasi database, incluso MySQL con Docker, per lo sviluppo locale, alcuni dei quali sono i seguenti:
- L'utilizzo di qualsiasi versione di MySQL come 5.6, 5.7 o 8 secondo il progetto o qualsiasi altro motivo è molto semplice.
- Di solito con la finestra mobile, se viene eseguito sulla tua macchina, verrà eseguito sulla macchina di un altro ingegnere del software, su un ambiente di staging e anche sulla produzione, a condizione che venga mantenuta una certa compatibilità.
- Un nuovo membro del team può essere produttivo in poche ore, non in giorni dato che docker e altri strumenti sono configurati in modo efficiente.
Prerequisiti
Prima di sporcarci le mani con alcuni comandi di codice e CLI, di seguito sono riportati alcuni buoni prerequisiti:
- La conoscenza di base di Docker e dei comandi correlati come docker build, run, execute, ecc. sarà utile per questa guida.
- Qualsiasi informazione preliminare su Docker-compose sarà molto utile
- Una comprensione generale di come funzionano i database relazionali, in particolare MySQL, sarà vantaggiosa.
Esegui MySQL con Docker
Per questa guida per principianti, utilizzeremo l'immagine MySQL Docker ufficiale da DockerHub . L'immagine MySQL Docker ufficiale non ha una versione Alpine Linux, tuttavia, anche la versione Debian è di 147 MB, che non è troppo grande per un'immagine docker.
Per eseguire il contenitore MySQL 8.0 utilizzando l'immagine ufficiale, è sufficiente eseguire il seguente comando:
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
--nameper nominare il contenitorebasic-mysql--rmrimuovere il contenitore quando è fermo-v /tmp/mysql-data:/var/lib/mysqlviene aggiunto per conservare i dati quando il contenitore si riavvia, svanirà quando la macchina host si riavvia così com'è/tmp-e MYSQL_ROOT_PASSWORD=ANSKk08aPEDbFjDO -e MYSQL_DATABASE=testingper impostare la password dell'utente root e inizializzare un database denominatotesting-p 3306:3306mappa la porta host 3306 alla porta container 3306, la porta 3306 è la porta predefinita di MySQL.-it mysql:8.0- -mostrerà tutti i log e stiamo usando l'immagine MySQL ufficiale versione 8.0 che eseguirà il sapore 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;
Possiamo fermare il contenitore condocker stop basic-mysql
Anche se non fosse troppo difficile non lo considererei facile così come i parametri del comando non erano semplici da ricordare. Un altro aspetto è che abbiamo eseguito MySQL in isolamento, non esiste alcun collegamento tra l'applicazione Quotes API Node.js e il contenitore MySQL. È qui che la natura dichiarativa di docker-compose torna molto utile, come vedremo nella prossima sezione.
Esecuzione di MySQL con docker-compose
Aggiungi gli script di injection iniziali
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
- Utilizza il file docker-compose versione 3.8 , uno degli ultimi.
- Di conseguenza, definiamo
dbcome servizio, ogni servizio sarà equivalente a un nuovo comando docker run - Successivamente, indichiamo docker-compose per utilizzare l'immagine MySQL 8.0 ufficiale per questo servizio DB.
- Il
cap_addset toSYS_NICEsopprime alcuni messaggi di errore non utili. - Successivamente chiediamo a docker-compose di riavviare sempre questo contenitore in caso di errore.
- Successivamente aggiungiamo 2 variabili d'ambiente per il database MySQL e la password dell'utente root. In base alle necessità, possiamo aggiungere un altro utente per dargli meno privilegi con altre variabili env.
- Quindi, mappiamo la porta dell'host
3306alla porta del contenitore3306poiché il server MySQL è in esecuzione sulla porta del contenitore3306. A seconda delle preferenze, la porta dell'host può essere modificata. - Quindi, eseguiamo lo script di seeding per inserire i dati iniziali nel nostro database mysql
testing - Quindi aggiungiamo 2 volumi, il primo è il volume DB mappato ai volumi seguenti
basic-mysql. Che sostanzialmente dice a docker e docker-compose di gestire il volume per noi. Successivamente, aggiungiamo unoinit.sqlscript che inizializzerà il nostrotestingdatabase con il file SQL specificato.
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
Connettersi al database tramite UI, come MySQL Workbench e verificare che le nostre tabelle siano correttamente seminate
Verifica la connessione tramite script python
Assicurarsi che la dipendenza sia installata. Corri pip install pymysqlopip3 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)
Verifica della connessione tramite script del nodo
Assicurarsi che la dipendenza sia installata. Correrenpm 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);
});
});
Richiedere un'azione
Se trovi utile la guida, sentiti libero di applaudire e seguirmi. Unisciti a medium tramite questo link per accedere a tutti gli articoli premium da me e da tutti gli altri fantastici scrittori qui su medium.
Codifica di livello superiore
Grazie per far parte della nostra comunità! Prima che tu vada:
- Batti le mani per la storia e segui l'autore
- Visualizza altri contenuti nella pubblicazione Level Up Coding
- Seguici: Twitter | Linkedin | Notiziario

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































