Próbuję skonfigurować plik Dockerfile dla mojego projektu LAMP, ale mam kilka problemów podczas uruchamiania MySQL. Mam następujące wiersze w moim pliku Dockerfile:
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
Ale ciągle otrzymuję ten błąd:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
Masz jakieś pomysły, jak skonfigurować tworzenie bazy danych i importować zrzuty podczas kompilacji pliku Dockerfile?
RUN
polecenie jest wykonywane w innym kontenerze. Jest to dobrze wyjaśnione tutaj: stackoverflow.com/questions/17891669/…RUN
linii.RUN
z kilkoma krokami. Przykład z wieloetapową instalacją oprogramowania można znaleźć tutaj: stackoverflow.com/questions/25899912/install-nvm-in-docker/ ...Odpowiedzi:
Każda
RUN
instrukcja w aDockerfile
jest wykonywana w innej warstwie (jak wyjaśniono w dokumentacjiRUN
).W swoim
Dockerfile
masz trzyRUN
instrukcje. Problem w tym, że serwer MySQL jest uruchamiany dopiero w pierwszej. W innych nie działa MySQL, dlatego pojawia się błąd połączenia zmysql
klientem.Aby rozwiązać ten problem, masz 2 rozwiązania.
Rozwiązanie 1: użyj jednej linii
RUN
Rozwiązanie 2: użyj skryptu
Utwórz wykonywalny skrypt
init_db.sh
:Dodaj te wiersze do
Dockerfile
:źródło
docker run
wykonaniach, musisz zamontować woluminy. Jeśli chcesz tylko mieć kontener ze swoim zrzutem, ale nie chcesz utrwalać dalszych modyfikacji, możesz pozbyć sięVOLUME
instrukcji w swoimDockerfile
.ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
, próbując Rozwiązanie 1. Postępując zgodnie z logamimysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
imysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
mysql_init_db
i załaduj strukturę bazy danych. Pozwala to na elastyczność automatycznego resetowania bazy danych podczas testowania, ale jeśli chcesz, aby utrzymywała lub testowała różne zestawy danych, po prostu montujesz wolumin w / var / lib / mysql za pomocądocker run -v ...
.Najnowsza wersja oficjalnego obrazu dockera mysql umożliwia importowanie danych podczas uruchamiania. Oto mój plik docker-compose.yml
Tutaj mam
docker/data
plik data-dump.sql, pod którym jest względny folder, z którego działa docker-compose. Podłączam ten plik sql do tego katalogu/docker-entrypoint-initdb.d
w kontenerze.Jeśli jesteś zainteresowany, aby zobaczyć, jak to działa, spójrz na ich
docker-entrypoint.sh
w GitHub. Dodali ten blok, aby umożliwić importowanie danychDodatkowa uwaga, jeśli chcesz, aby dane były utrwalane nawet po zatrzymaniu i usunięciu kontenera mysql, musisz mieć oddzielny kontener danych, jak widać w pliku docker-compose.yml. Zawartość kontenera danych Dockerfile jest bardzo prosta.
Aby zachować trwałość, kontener danych nie musi nawet znajdować się w stanie początkowym.
źródło
- ./docker/data:/docker-entrypoint-initdb.d
usunięto.
przed katalogiem kontenerów.To, co zrobiłem, to pobranie zrzutu sql do folderu „db-dump” i zamontowanie go:
Kiedy uruchamiam
docker-compose up
po raz pierwszy, zrzut jest przywracany w bazie danych.źródło
mysql
wydaje się nie ładuje zrzuconego pliku sql, a nawet używając 5.6 mam problem z silnikami pamięci masowej InnoDb.Użyłem podejścia docker-entrypoint-initdb.d (dzięki @Kuhess) Ale w moim przypadku chcę utworzyć moją bazę danych na podstawie niektórych parametrów, które zdefiniowałem w pliku .env, więc zrobiłem te
1) Najpierw definiuję plik .env coś takiego w moim głównym katalogu projektu docker
2) Następnie definiuję mój plik docker-compose.yml. Więc użyłem dyrektywy args do zdefiniowania moich zmiennych środowiskowych i ustawiłem je z pliku .env
3) Następnie definiuję folder mysql zawierający plik Dockerfile. Więc to jest plik Dockerfile
4) Teraz używam mysqldump do zrzucenia mojej bazy danych i umieszczenia data.sql w folderze mysql
Plik jest zwykłym plikiem zrzutu sql, ale dodaję 2 wiersze na początku, aby plik wyglądał tak
Więc co się stało, to że użyłem polecenia "RUN sed -i 's / MYSQL_DATABASE /' $ MYSQL_DATABASE '/ g' /etc/mysql/data.sql", aby zastąpić
MYSQL_DATABASE
symbol zastępczy nazwą mojej bazy danych, w której ją ustawiłem plik .env.Teraz możesz zbudować i uruchomić swój kontener
źródło
.env
pliku. Jednak zgodnie z tym ,.env
funkcja plik działa tylko podczas korzystania zdocker-compose up
polecenia i nie pracowaćdocker stack deploy
. Tak więc, jeśli chcesz użyć.env
pliku w środowisku produkcyjnym, możesz sprawdzić sekrety Dockera, które zostały wprowadzone wdocker 17.06
. Następnie można użyć pliku .env w połączeniu z tajemnic zarówno w rozwojudocker compose up
i produkcjidocker stack deploy
fazachRUN sed -i '1s/^/CREATE DATABASE IF NOT EXISTS
$ MYSQL_DATABASE;\nUSE
$ MYSQL_DATABASE;\n/' data.sql
zamiastsed
sugerowanego polecenia. W ten sposób można użyć dowolnego pliku zrzutu masz - to przydatny jeśli pracujesz z dużą ilością danych :)Oto działająca wersja korzystająca
v3
zdocker-compose.yml
. Kluczem jest dyrektywa o objętości :W katalogu Mam
docker-compose.yml
Mamdata
dir, który zawiera.sql
pliki zrzutu. Jest to miłe, ponieważ możesz mieć.sql
plik zrzutu na tabelę.Po prostu biegnę
docker-compose up
i jestem gotowy. Dane pozostają automatycznie między przystankami. Jeśli chcesz usunąć dane i „zassać” nowe.sql
pliki, uruchomdocker-compose down
wtedydocker-compose up
.Jeśli ktoś wie, jak zmusić
mysql
dockera do ponownego przetwarzania plików/docker-entrypoint-initdb.d
bez usuwania woluminu, zostaw komentarz, a zaktualizuję tę odpowiedź.źródło
docker-compose down
była bardzo ważna, ponieważ nie widziałem żadnych zmian pomimo ponownego uruchomienia docker-compose. MYSQL_DATABASE jest zmienną wymaganą w tym przypadku