Tạo một container mysql docker với sơ đồ cơ sở dữ liệu đã chuẩn bị


17

Tôi muốn tạo một hình ảnh docker trên đầu trang mysql đã chứa sơ đồ cần thiết cho ứng dụng của tôi.

Tôi đã thử thêm các dòng vào Dockerfile sẽ nhập lược đồ của tôi dưới dạng tệp sql. Tôi đã làm như vậy (Dockerfile của tôi):

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"

Theo hiểu biết của tôi, điều đó không hoạt động vì hình ảnh docker mysql không chứa ứng dụng khách mysql (trạng thái thực hành tốt nhất "không thêm mọi thứ chỉ vì chúng sẽ rất tốt để có") (tôi có sai về điều này không?)

Điều gì có thể là một cách tốt để làm điều này? Tôi đã có một vài điều trong tâm trí, nhưng tất cả chúng có vẻ như cách giải quyết lộn xộn.

  1. cài đặt máy khách mysql, làm những gì tôi phải làm với nó, sau đó loại bỏ / thanh lọc nó.
  2. sao chép tệp nhị phân máy khách mysql vào hình ảnh, làm những gì tôi phải làm, sau đó loại bỏ nó.
  3. Tạo lược đồ trong một máy chủ sql khác và sao chép trực tiếp tệp db (điều này có vẻ rất lộn xộn và nghe có vẻ như là một vấn đề bị ô nhiễm)

Bất kỳ đề xuất? Hy vọng theo cách sẽ dễ dàng duy trì sau này và có thể phù hợp với các thực tiễn tốt nhất là tốt?


Câu trả lời:


14

Bạn nên đặt tập lệnh init của mình vào một thư mục được gắn dưới dạng /docker-entrypoint-initdb.d- xem phần "Khởi tạo một thể hiện mới" trong tài liệu hình ảnh Docker của MySQL .


2
Nó hoạt động để đưa lên một container mới và tải nó với lược đồ của tôi. Đó là một cách hay xung quanh nó, nhưng nếu tôi đang tìm cách tạo ra hình ảnh docker của riêng tôi đã có lược đồ được cài đặt sẵn thì sao?
Tom Klino

Trên thực tế, nevermind :-) Tôi nghĩ rằng nó /docker-entrypoint-initdb.dđã ở trong máy chủ nhưng nó thực sự nằm trong container. Tôi đã thay đổi ADDlệnh để sao chép vào thư mục đó và loại bỏ RUNlệnh. Docker đã xây dựng hình ảnh thành công và tôi đã thử nghiệm nó và nó hoạt động.
Tom Klino

14

Tôi đã phải làm điều này cho mục đích thử nghiệm.

Đây là cách tôi đã làm bằng cách tận dụng hình ảnh MySQL / MariaDB thực tế trên dockerhub và bản dựng nhiều giai đoạn:

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

Ví dụ hoạt động đầy đủ tại đây: https://github.com/lindycoder/prepopulation-mysql-container-example


2
Câu trả lời hay nhất tôi đã tìm thấy trên toàn bộ internet, của tôi là dành cho người đăng bài, vì vậy nó khó hơn một chút, nhưng cuối cùng nó cũng hoạt động. Và nó hoạt động hoàn hảo!
snowe2010

Các phiên bản cũ hơn của mysql (5.7.9) không có /usr/local/bin/docker-entrypoint.sh được liên kết với /entrypoint.sh, thay vào đó chỉ có entrypoint.sh trong /. Thay đổi /usr/local/bin/docker-entrypoint.sh thành /entrypoint.sh hoạt động và có lẽ cũng hoạt động cho các bản phát hành "hiện đại".
Marvin

2

Tín dụng cho @Martin Roy

Thực hiện các thay đổi nhỏ để làm việc cho mysql ...

Dockerfile nội dung

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

Thiết lập nội dung

CREATE DATABASE myexample;

USE myexample;

CREATE TABLE mytable (myfield VARCHAR(20));

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

Ví dụ làm việc đầy đủ ở đây: https://github.com/iamdvr/prepopulation-mysql-container-example


-1

Phần mềm quản lý như Ansible có thể giúp bạn tự động hóa việc nhập mysql dễ dàng mà không cần cài đặt và cài đặt lại máy khách. Ansible có các tính năng tích hợp tuyệt vời để quản lý hình ảnh và bộ chứa docker và cơ sở dữ liệu mysql.


Điều đó thật thú vị - Tôi đã sử dụng Ansible nhưng chưa sử dụng nó cho hình ảnh Docker. Bạn có thể mở rộng câu trả lời của bạn với một số ví dụ, Patrick?
Greg Dubicki

Ansible có một trang tài liệu tuyệt vời, bạn có thể tìm thấy mô-đun Ansible trên url này: docs.ansible.com/ansible/docker_module.html Trên mỗi trang trong chương mô-đun của hướng dẫn này là một số ví dụ.
Patrick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.