Saya mencoba menyiapkan Dockerfile untuk proyek LAMP saya, tetapi saya mengalami beberapa masalah saat memulai MySQL. Saya memiliki baris berikut di Dockerfile saya:
VOLUME ["/etc/mysql", "/var/lib/mysql"]
ADD dump.sql /tmp/dump.sql
RUN /usr/bin/mysqld_safe & sleep 5s
RUN mysql -u root -e "CREATE DATABASE mydb"
RUN mysql -u root mydb < /tmp/dump.sql
Tapi saya terus mendapatkan kesalahan ini:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
Adakah ide tentang cara mengatur pembuatan database dan membuang impor selama pembuatan Dockerfile?
RUN
perintah dieksekusi dalam wadah yang berbeda. Ini dijelaskan dengan baik di sini: stackoverflow.com/questions/17891669/…RUN
baris pertama Anda .RUN
dengan beberapa langkah. Anda dapat menemukan contoh dengan penginstalan multi-langkah perangkat lunak di sini: stackoverflow.com/questions/25899912/install-nvm-in-docker/…Jawaban:
Setiap
RUN
instruksi dalam aDockerfile
dieksekusi di lapisan yang berbeda (seperti yang dijelaskan dalam dokumentasiRUN
).Dalam Anda
Dockerfile
, Anda memiliki tigaRUN
instruksi. Masalahnya adalah bahwa server MySQL hanya dimulai di awal. Di sisi lain, tidak ada MySQL yang berjalan, itulah sebabnya Anda mendapatkan kesalahan koneksi denganmysql
klien.Untuk mengatasi masalah ini, Anda memiliki 2 solusi.
Solusi 1: Gunakan satu baris
RUN
Solusi 2: Gunakan skrip
Buat skrip yang dapat dieksekusi
init_db.sh
:Tambahkan baris ini ke Anda
Dockerfile
:sumber
docker run
eksekusi, Anda perlu memasang volume. Jika Anda hanya ingin memiliki wadah dengan dump Anda, tetapi Anda tidak ingin mempertahankan modifikasi lebih lanjut, Anda dapat membuangVOLUME
instruksi di fileDockerfile
.ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
ketika mencoba Solusi 1. Mengikuti logmysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
danmysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
mysql_init_db
dan muat dalam struktur database Anda. Hal ini memungkinkan fleksibilitas menyetel ulang database secara otomatis saat pengujian, tetapi jika Anda ingin mempertahankan atau menguji kumpulan data yang berbeda, Anda cukup memasang volume di / var / lib / mysql menggunakandocker run -v ...
.Versi terbaru dari image buruh pelabuhan mysql resmi memungkinkan Anda untuk mengimpor data saat startup. Ini adalah buruh pelabuhan-compose.yml saya
Di sini, saya memiliki data-dump.sql saya
docker/data
yang relatif terhadap folder tempat penulisan galangan berjalan. Saya memasang file sql itu ke direktori ini/docker-entrypoint-initdb.d
di wadah.Jika Anda tertarik untuk melihat cara kerjanya, lihat
docker-entrypoint.sh
di GitHub mereka. Mereka telah menambahkan blok ini untuk mengizinkan pengimporan dataCatatan tambahan, jika Anda ingin data tetap ada bahkan setelah kontainer mysql dihentikan dan dihapus, Anda perlu memiliki wadah data terpisah seperti yang Anda lihat di docker-compose.yml. Isi dari wadah data Dockerfile sangat sederhana.
Penampung data bahkan tidak harus dalam keadaan mulai untuk persistensi.
sumber
- ./docker/data:/docker-entrypoint-initdb.d
—hapus.
di depan direktori container.Yang saya lakukan adalah mengunduh sql dump saya di folder "db-dump", dan memasangnya:
Ketika saya menjalankan
docker-compose up
untuk pertama kalinya, dump dikembalikan di db.sumber
mysql
tampaknya tidak memuat file sql yang dibuang, dan bahkan menggunakan 5.6 Saya punya masalah dengan mesin penyimpanan InnoDb.Saya menggunakan pendekatan docker-entrypoint-initdb.d (Terima kasih kepada @Kuhess) Tetapi dalam kasus saya, saya ingin membuat DB saya berdasarkan beberapa parameter yang saya tentukan dalam file .env jadi saya melakukan ini
1) Pertama saya mendefinisikan file .env seperti ini di direktori proyek root docker saya
2) Kemudian saya mendefinisikan file docker-compose.yml saya. Jadi saya menggunakan arahan args untuk mendefinisikan variabel lingkungan saya dan saya mengaturnya dari file .env
3) Lalu saya mendefinisikan folder mysql yang menyertakan Dockerfile. Jadi Dockerfile adalah ini
4) Sekarang saya menggunakan mysqldump untuk membuang db saya dan meletakkan data.sql di dalam folder mysql
File ini hanya file dump sql biasa tetapi saya menambahkan 2 baris di awal sehingga file akan terlihat seperti ini
Jadi yang terjadi adalah saya menggunakan perintah "RUN sed -i 's / MYSQL_DATABASE /' $ MYSQL_DATABASE '/ g' /etc/mysql/data.sql" untuk mengganti
MYSQL_DATABASE
placeholder dengan nama DB saya yang telah saya setel di dalamnya file .env.Sekarang Anda siap untuk membangun dan menjalankan penampung Anda
sumber
.env
file. Namun menurut ini ,.env
fitur file hanya berfungsi ketika Anda menggunakandocker-compose up
perintah dan tidak berfungsidocker stack deploy
. Jadi, jika Anda ingin menggunakan.env
file dalam produksi, Anda mungkin ingin memeriksa rahasia buruh pelabuhan yang diperkenalkan dengandocker 17.06
. Kemudian Anda dapat menggunakan file .env bersama dengan rahasia dalam fase pengembangandocker compose up
dan produksidocker stack deploy
RUN sed -i '1s/^/CREATE DATABASE IF NOT EXISTS
$ MYSQL_DATABASE;\nUSE
$ MYSQL_DATABASE;\n/' data.sql
daripadased
perintah yang Anda sarankan. Dengan cara ini Anda dapat menggunakan file dump apa pun yang Anda miliki - berguna jika Anda bekerja dengan data dalam jumlah besar :)Berikut ini adalah versi kerja menggunakan
v3
daridocker-compose.yml
. Kuncinya adalah arahan volume :Di direktori yang saya miliki, saya
docker-compose.yml
memilikidata
dir yang berisi.sql
file dump. Ini bagus karena Anda dapat memiliki.sql
file dump per tabel.Saya hanya berlari
docker-compose up
dan saya siap berangkat. Data secara otomatis tetap ada di antara perhentian. Jika Anda ingin menghapus data dan "menyedot" baru.sql
file dijalankandocker-compose down
kemudiandocker-compose up
.Jika ada yang tahu cara meminta
mysql
buruh pelabuhan untuk memproses ulang file/docker-entrypoint-initdb.d
tanpa menghapus volume, silakan tinggalkan komentar dan saya akan memperbarui jawaban ini.sumber
docker-compose down
sangat penting karena saya tidak melihat perubahan meskipun memulai ulang docker-compose. MYSQL_DATABASE adalah variabel yang diperlukan dalam kasus iniSaya tidak terlalu menyukai jawaban yang diterima Kuhess sebagai
sleep 5
tampaknya agak hackish bagi saya karena mengasumsikan bahwa daemon db mysql telah dimuat dengan benar dalam kerangka waktu ini. Itu asumsi, tidak ada jaminan. Juga jika Anda menggunakan image buruh pelabuhan mysql yang disediakan, image itu sendiri sudah mengatur tentang memulai server; Saya tidak akan mencampuri ini dengan kebiasaan/usr/bin/mysqld_safe
.Saya mengikuti jawaban lain di sekitar sini dan menyalin skrip bash dan sql ke dalam folder
/docker-entrypoint-initdb.d/
di dalam kontainer buruh pelabuhan karena ini jelas merupakan cara yang dimaksudkan oleh penyedia gambar mysql. Semua yang ada di folder ini dijalankan setelah daemon db siap, oleh karena itu Anda harus dapat mengandalkannya.Sebagai tambahan dari yang lain - karena tidak ada jawaban lain yang secara eksplisit menyebutkan ini: selain skrip sql Anda juga dapat menyalin skrip bash ke folder itu yang mungkin memberi Anda kontrol lebih.
Ini adalah yang saya perlukan misalnya karena saya juga perlu mengimpor dump, tetapi dump saja tidak cukup karena tidak menyediakan database mana yang harus diimpor. Jadi dalam kasus saya, saya memiliki skrip yang diberi nama
db_custom_init.sh
dengan konten ini:dan Dockerfile ini menyalin skrip itu:
edit: Perhatikan bahwa ini hanya akan mengimpor sql dump pada saat pembuatan kontainer, bukan pada waktu pembuatan gambar!
sumber