Dockerfile 내에서 MySQL 설정 및 덤프 가져 오기
내 LAMP 프로젝트에 Dockerfile을 설정하려고하는데 MySQL을 시작할 때 몇 가지 문제가 있습니다. 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
그러나이 오류가 계속 발생합니다.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
Dockerfile 빌드 중 데이터베이스 작성 및 덤프 가져 오기 설정 방법에 대한 아이디어가 있습니까?
의 각 RUN명령어 Dockerfile는 문서의RUN 설명에 따라 다른 계층에서 실행됩니다 .
에 Dockerfile세 가지 RUN지침이 있습니다. 문제는 MySQL 서버가 첫 번째 서버에서만 시작된다는 것입니다. 다른 경우에는 MySQL이 실행되고 있지 않으므로 mysql클라이언트 와의 연결 오류가 발생 합니다.
이 문제를 해결하려면 두 가지 해결책이 있습니다.
해결 방법 1 : 한 줄 사용 RUN
RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE mydb" && \
mysql -u root mydb < /tmp/dump.sql
해결 방법 2 : 스크립트 사용
실행 스크립트를 작성하십시오 init_db.sh.
#!/bin/bash
/usr/bin/mysqld_safe --skip-grant-tables &
sleep 5
mysql -u root -e "CREATE DATABASE mydb"
mysql -u root mydb < /tmp/dump.sql
이 줄을 다음에 추가하십시오 Dockerfile.
ADD init_db.sh /tmp/init_db.sh
RUN /tmp/init_db.sh
공식 mysql docker 이미지 의 최신 버전을 사용하면 시작시 데이터를 가져올 수 있습니다. 여기 내 docker-compose.yml입니다
data:
build: docker/data/.
mysql:
image: mysql
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: 1234
volumes:
- ./docker/data:/docker-entrypoint-initdb.d
volumes_from:
- data
여기에 docker/datadocker-compose가 실행되는 폴더와 관련된 data-dump.sql 이 있습니다. 해당 SQL 파일을 /docker-entrypoint-initdb.d컨테이너 의이 디렉토리 에 마운트 하고 있습니다.
이것이 어떻게 작동하는지 알고 싶다면 docker-entrypoint.shGitHub 에서 살펴보십시오 . 데이터를 가져올 수 있도록이 블록을 추가했습니다.
echo
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
An additional note, if you want the data to be persisted even after the mysql container is stopped and removed, you need to have a separate data container as you see in the docker-compose.yml. The contents of the data container Dockerfile are very simple.
FROM n3ziniuka5/ubuntu-oracle-jdk:14.04-JDK8
VOLUME /var/lib/mysql
CMD ["true"]
The data container doesn't even have to be in start state for persistence.
What I did was download my sql dump in a "db-dump" folder, and mounted it:
mysql:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: pass
ports:
- 3306:3306
volumes:
- ./db-dump:/docker-entrypoint-initdb.d
When I run docker-compose up for the first time, the dump is restored in the db.
I used docker-entrypoint-initdb.d approach (Thanks to @Kuhess) But in my case I want to create my DB based on some parameters I defined in .env file so I did these
1) First I define .env file something like this in my docker root project directory
MYSQL_DATABASE=my_db_name
MYSQL_USER=user_test
MYSQL_PASSWORD=test
MYSQL_ROOT_PASSWORD=test
MYSQL_PORT=3306
2) Then I define my docker-compose.yml file. So I used the args directive to define my environment variables and I set them from .env file
version: '2'
services:
### MySQL Container
mysql:
build:
context: ./mysql
args:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
ports:
- "${MYSQL_PORT}:3306"
3) Then I define a mysql folder that includes a Dockerfile. So the Dockerfile is this
FROM mysql:5.7
RUN chown -R mysql:root /var/lib/mysql/
ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD
ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
ADD data.sql /etc/mysql/data.sql
RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d
EXPOSE 3306
4) Now I use mysqldump to dump my db and put the data.sql inside mysql folder
mysqldump -h <server name> -u<user> -p <db name> > data.sql
The file is just a normal sql dump file but I add 2 lines at the beginning so the file would look like this
--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;
-- Rest of queries
DROP TABLE IF EXISTS `x`;
CREATE TABLE `x` (..)
LOCK TABLES `x` WRITE;
INSERT INTO `x` VALUES ...;
...
...
...
So what happening is that I used "RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql" command to replace the MYSQL_DATABASE placeholder with the name of my DB that I have set it in .env file.
|- docker-compose.yml
|- .env
|- mysql
|- Dockerfile
|- data.sql
Now you are ready to build and run your container
Here is a working version using v3 of docker-compose.yml. The key is the volumes directive:
mysql:
image: mysql:5.6
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: theusername
MYSQL_PASSWORD: thepw
MYSQL_DATABASE: mydb
volumes:
- ./data:/docker-entrypoint-initdb.d
In the directory that I have my docker-compose.yml I have a data dir that contains .sql dump files. This is nice because you can have a .sql dump file per table.
I simply run docker-compose up and I'm good to go. Data automatically persists between stops. If you want remove the data and "suck in" new .sql files run docker-compose down then docker-compose up.
If anyone knows how to get the mysql docker to re-process files in /docker-entrypoint-initdb.d without removing the volume, please leave a comment and I will update this answer.
참고URL : https://stackoverflow.com/questions/25920029/setting-up-mysql-and-importing-dump-within-dockerfile
'Programing' 카테고리의 다른 글
| Laravel-5 'LIKE'동등 (Eloquent) (0) | 2020.07.19 |
|---|---|
| 20 개의 임의 바이트 배열을 만드는 방법은 무엇입니까? (0) | 2020.07.19 |
| Google Play에서 사용자가 다운로드 한 앱 목록 (유료 / 무료)을 얻는 방법은 무엇입니까? (0) | 2020.07.18 |
| Spark에서 단계는 어떻게 작업으로 분할됩니까? (0) | 2020.07.18 |
| 엔터티 프레임 워크를 "웜업"하는 방법? (0) | 2020.07.18 |