การสร้างคอนเทนเนอร์นักเทียบท่า mysql ด้วยแบบแผนฐานข้อมูลที่เตรียมไว้


17

ฉันต้องการสร้างภาพนักเทียบท่าที่ด้านบนของ mysql ที่มีรูปแบบที่จำเป็นสำหรับแอพของฉันอยู่แล้ว

ฉันพยายามเพิ่มบรรทัดลงใน Dockerfile ที่จะนำเข้าโครงร่างของฉันเป็นไฟล์ sql ฉันทำเช่นนั้น (Dockerfile ของฉัน):

FROM mysql

ENV MYSQL_ROOT_PASSWORD="bagabu"
ENV MYSQL_DATABASE="imhere"

ADD imhere.sql /tmp/imhere.sql

RUN "mysql -u root --password="bagabu" imhere < /tmp/imhere.sql"

เพื่อความเข้าใจของฉันที่ไม่ทำงานเพราะภาพนักเทียบท่า mysql ไม่ได้มีลูกค้า mysql (ปฏิบัติที่ดีที่สุดรัฐ "อย่าเพิ่มสิ่งเพียงเพราะพวกเขาจะดีที่จะมี") (ฉันผิดเกี่ยวกับเรื่องนี้?)

สิ่งที่อาจเป็นวิธีที่ดีในการทำเช่นนี้? ฉันมีบางสิ่งที่อยู่ในใจ แต่พวกเขาทั้งหมดดูเหมือนการแก้ไขปัญหายุ่ง

  1. ติดตั้งไคลเอนต์ mysql ทำในสิ่งที่ฉันต้องทำจากนั้นลบ / กำจัดมัน
  2. คัดลอกไบนารีไคลเอนต์ mysql ไปยังรูปภาพทำสิ่งที่ฉันต้องทำแล้วลบออก
  3. สร้างสคีมาในเซิร์ฟเวอร์ sql อื่นและคัดลอกไฟล์ db โดยตรง (ดูเหมือนว่าจะยุ่งมากและฟังฉันเหมือนสระว่ายน้ำที่ปนเปื้อนของปัญหา)

ข้อเสนอแนะใด ๆ หวังว่าในวิธีที่จะง่ายต่อการบำรุงรักษาในภายหลังและอาจสอดคล้องกับแนวทางปฏิบัติที่ดีเช่นกัน?


คำตอบ:


14

คุณควรใส่สคริปต์ init ของคุณในไดเรกทอรีติดตั้งเป็น/docker-entrypoint-initdb.d- ดูที่ "เริ่มต้นอินสแตนซ์สด" ในเอกสารภาพ MySQL เทียบท่า


2
ใช้งานได้สำหรับการนำขึ้นคอนเทนเนอร์ใหม่และโหลดด้วยสคีมาของฉัน ซึ่งเป็นวิธีที่ดีรอบ ๆ แต่ถ้าฉันกำลังมองหาวิธีการสร้างภาพนักเทียบท่าของตัวเองที่มี schema ติดตั้งไว้แล้ว?
Tom Klino

จริงๆแล้วไม่เป็นไร :-) ฉันคิดว่า/docker-entrypoint-initdb.dมันอยู่ในโฮสต์ แต่จริง ๆ แล้วมันอยู่ในคอนเทนเนอร์ ฉันเปลี่ยนADDคำสั่งเพื่อคัดลอกไปยังไดเรกทอรีนั้นและลบRUNคำสั่ง นักสร้างภาพประสบความสำเร็จและฉันทดสอบและใช้งานได้
Tom Klino

14

ฉันต้องทำสิ่งนี้เพื่อการทดสอบ

นี่คือวิธีที่ฉันทำโดยใช้ประโยชน์จากภาพ MySQL / MariaDB จริงบน dockerhub และโครงสร้างหลายขั้นตอน:

FROM mariadb:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"]

FROM mariadb:latest

COPY --from=builder /initialized-db /var/lib/mysql

ตัวอย่างการทำงานเต็มรูปแบบที่นี่: https://github.com/lindycoder/prepopulated-mysql-container-example


2
คำตอบที่ดีที่สุดที่ฉันพบบนอินเทอร์เน็ตทั้งหมดของฉันมีไว้สำหรับ postgres ดังนั้นมันจึงยากขึ้นเล็กน้อย แต่ในที่สุดมันก็ใช้งานได้ และมันทำงานได้อย่างสมบูรณ์แบบ!
snowe2010

เวอร์ชันเก่าของ mysql (5.7.9) ไม่มี /usr/local/bin/docker-entrypoint.sh symlinked ไปยัง /entrypoint.sh แทนที่จะมีเพียง entrypoint.sh ใน / การเปลี่ยน /usr/local/bin/docker-entrypoint.sh ไปเป็น /entrypoint.sh จะทำงานได้และน่าจะใช้งานได้กับ "modern" release เช่นกัน
Marvin

2

เครดิตให้กับ @Martin Roy

ทำการเปลี่ยนแปลงเล็กน้อยเพื่อให้ทำงานกับ mysql ...

Content Dockerfile

FROM mysql:latest as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=root

COPY setup.sql /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db"]

FROM mysql:latest

COPY --from=builder /initialized-db /var/lib/mysql

เนื้อหา setup.sql

CREATE DATABASE myexample;

USE myexample;

CREATE TABLE mytable (myfield VARCHAR(20));

INSERT INTO mytable VALUES ('Hello'), ('Dolly');

ตัวอย่างการทำงานเต็มรูปแบบที่นี่: https://github.com/iamdvr/prepopulated-mysql-container-example


-1

ซอฟต์แวร์การจัดการเช่น Ansible สามารถช่วยให้คุณนำเข้า mysql อัตโนมัติได้ง่ายโดยไม่จำเป็นต้องติดตั้งและติดตั้งไคลเอนต์อีกครั้ง Ansible มีคุณสมบัติในตัวที่ยอดเยี่ยมในการจัดการอิมเมจและคอนเทนเนอร์ของฐานข้อมูลและฐานข้อมูล mysql


น่าสนใจ - ฉันใช้ Ansible แต่ไม่ได้ใช้สำหรับภาพ Docker คุณช่วยขยายคำตอบของคุณด้วยตัวอย่าง Patrick ได้ไหม?
Greg Dubicki

Ansible มีหน้าเอกสารที่ยอดเยี่ยมคุณสามารถค้นหาโมดูลAnsible ได้ ในurl นี้: docs.ansible.com/ansible/docker_module.htmlในแต่ละหน้าของบทโมดูลในคู่มือนี้เป็นตัวอย่าง
แพทริค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.