Ma'lumotlar bazasi konteynerda — MySQL, PostgreSQL, init skriptlar

~15 daq · Docker · Ma'lumotlarni saqlash

Muammodan boshlaylik

Jamoaga yangi dasturchi keldi. Loyihani ishga tushirish uchun: MySQL 8.4 ni o'rnatish, root parol, dokon bazasi va app foydalanuvchisi, 15 ta jadval, test ma'lumotlari. Yarim kun — va har kimda biroz boshqacha.

Docker bilan — bitta buyruq va hammada aynan bir xil baza.


MySQL — to'liq sozlangan

docker run -d --name baza \
  -e MYSQL_ROOT_PASSWORD=root123 \
  -e MYSQL_DATABASE=dokon \
  -e MYSQL_USER=app \
  -e MYSQL_PASSWORD=app123 \
  -e TZ=Asia/Tashkent \
  -v baza-data:/var/lib/mysql \
  -p 127.0.0.1:3306:3306 \
  mysql:8.4

Ilova root bilan emas, app bilan ulanadi (MySQL kursi 50-dars).

[!INFO] Bu o'zgaruvchilar faqat birinchi ishga tushishda — volume bo'sh bo'lganda — ishlaydi. Volume da baza bo'lsa, MYSQL_ROOT_PASSWORD ni o'zgartirish parolni o'zgartirmaydi.

Sozlamalar

docker run -d --name baza ... mysql:8.4 \
  --character-set-server=utf8mb4 \
  --max-connections=300

Yoki konfiguratsiya fayli: -v "$(pwd)/mysql.cnf":/etc/mysql/conf.d/custom.cnf:ro.


Init skriptlar

Rasmiy baza image lari birinchi ishga tushishda /docker-entrypoint-initdb.d/ dagi fayllarni alifbo tartibida bajaradi:

init/
├── 01-schema.sql       ← jadvallar
└── 02-seed.sql         ← test ma'lumotlari
docker run -d --name baza \
  -e MYSQL_ROOT_PASSWORD=root123 -e MYSQL_DATABASE=dokon \
  -v baza-data:/var/lib/mysql \
  -v "$(pwd)/init":/docker-entrypoint-initdb.d:ro \
  -p 127.0.0.1:3306:3306 \
  mysql:8.4

01-schema.sql — MySQL kursining 5-darsidagi dokon sxemasi. Yangi dasturchi: klonlash → bitta buyruq → tayyor baza.

Formatlar: .sql, .sql.gz, .sh.

[!WARNING] Init skriptlar faqat volume bo'sh bo'lganda bajariladi. Mavjud bazadagi o'zgarishlar uchun — migratsiyalar (MySQL kursi 8-dars).


PostgreSQL

docker run -d --name pg \
  -e POSTGRES_PASSWORD=maxfiy \
  -e POSTGRES_USER=app \
  -e POSTGRES_DB=dokon \
  -v pg-data:/var/lib/postgresql/data \
  -v "$(pwd)/init":/docker-entrypoint-initdb.d:ro \
  -p 127.0.0.1:5432:5432 \
  postgres:17

docker exec -it pg psql -U app -d dokon

Boshqa bazalar

docker run -d --name mongo -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=x \
  -v mongo-data:/data/db -p 127.0.0.1:27017:27017 mongo:8

docker run -d --name kesh -v redis-data:/data -p 127.0.0.1:6379:6379 \
  redis:7-alpine redis-server --appendonly yes

Baza tayyormi?

Konteyner Up bo'lishi bilan baza tayyor emas — birinchi ishga tushishda init 10-30 soniya. Tekshirish:

docker exec baza mysqladmin ping -uroot -proot123 --silent && echo tayyor
docker exec pg pg_isready -U app

Compose da — healthcheck + depends_on: condition: service_healthy (28-dars).


Production da kerakmi?

Variant Afzalligi Kamchiligi
Boshqariladigan baza (RDS, DigitalOcean, Cloud SQL) Backup, failover — avtomatik Qimmatroq
Konteynerda, o'z serveringizda Arzon, to'liq nazorat Backup, monitoring — o'zingiz

Kichik va o'rta loyihalar uchun konteynerdagi baza normal — volume, backup (21-dars) va monitoring bilan. Ma'lumoti juda muhim loyihalarda — ko'pincha boshqariladigan xizmat. Ishlab chiqish va testlar uchun — doim konteyner.


Nima uchun shunday?

Init skriptlar sxema yaratadi va ma'lumot qo'shadi. Har ishga tushishda bajarilsa — CREATE TABLE xato beradi, INSERT ma'lumotlarni takrorlaydi. Init — "bo'sh bazani boshlang'ich holatga keltirish" uchun. Mavjud bazani o'zgartirish — versiyalangan migratsiyalarning ishi.


Xulosa

Eslab qoling:

  • Baza = image + env + nomlangan volume + 127.0.0.1 port
  • MYSQL_* / POSTGRES_* — faqat bo'sh volume da
  • /docker-entrypoint-initdb.d/ — sxema va test ma'lumotlari
  • Mavjud bazaga — migratsiyalar
  • Up ≠ tayyor: mysqladmin ping, pg_isready
  • Production: konteyner — backup bilan; muhim loyihalar — boshqariladigan xizmat

Keyingi dars

23-dars: Docker tarmog'i — bridge, host, none