Estou tentando configurar um Dockerfile para o meu projeto LAMP, mas estou tendo alguns problemas ao iniciar o MySQL. Eu tenho as seguintes linhas no meu 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
Mas continuo recebendo este erro:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
Alguma idéia de como configurar a criação do banco de dados e a importação de despejo durante uma compilação do Dockerfile?
RUN
comando é executado em um contêiner diferente. É bem explicado aqui: stackoverflow.com/questions/17891669/…RUN
linha.RUN
com várias etapas. Você pode encontrar um exemplo com uma instalação em várias etapas de um software aqui: stackoverflow.com/questions/25899912/install-nvm-in-docker/…Respostas:
Cada
RUN
instrução em aDockerfile
é executada em uma camada diferente (conforme explicado na documentação deRUN
).No seu
Dockerfile
, você tem trêsRUN
instruções. O problema é que o servidor MySQL é iniciado apenas no primeiro. Nos outros, nenhum MySQL está sendo executado, é por isso que você obtém seu erro de conexão com omysql
cliente.Para resolver este problema, você tem 2 soluções.
Solução 1: use uma linha
RUN
Solução 2: use um script
Crie um script executável
init_db.sh
:Adicione estas linhas ao seu
Dockerfile
:fonte
docker run
execuções, é necessário montar volumes. Se você quiser apenas ter um contêiner com seu despejo, mas não quiser persistir em outras modificações, poderá se livrar dasVOLUME
instruções contidas no seu arquivoDockerfile
.ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
ao tentar a Solução 1. Seguindo os logsmysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
emysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
mysql_init_db
e carregue na estrutura do banco de dados. Isso permite a flexibilidade de redefinir o banco de dados automaticamente durante o teste, mas se você deseja persistir ou testar conjuntos de dados diferentes, basta montar um volume em / var / lib / mysql usandodocker run -v ...
.A versão mais recente da imagem oficial do docker mysql permite importar dados na inicialização. Aqui está o meu docker-compose.yml
Aqui, eu tenho meu data-dump.sql sob o
docker/data
qual é relativo à pasta da qual o docker-compose está sendo executado. Estou montando esse arquivo sql neste diretório/docker-entrypoint-initdb.d
no contêiner.Se você estiver interessado em ver como isso funciona, dê uma olhada no
docker-entrypoint.sh
GitHub. Eles adicionaram este bloco para permitir a importação de dadosUma observação adicional: se você deseja que os dados sejam mantidos mesmo após a parada e remoção do contêiner mysql, é necessário ter um contêiner de dados separado, como você vê no docker-compose.yml. O conteúdo do Dockerfile do contêiner de dados é muito simples.
O contêiner de dados nem precisa estar no estado inicial para persistência.
fonte
- ./docker/data:/docker-entrypoint-initdb.d
removeu o diretório.
na frente do contêiner.O que fiz foi baixar o meu sql dump em uma pasta "db-dump" e montá-lo:
Quando executo
docker-compose up
pela primeira vez, o dump é restaurado no banco de dados.fonte
mysql
parece não carregar o arquivo sql despejado e, mesmo usando o 5.6, tenho problemas com os mecanismos de armazenamento do InnoDb.Eu usei a abordagem docker-entrypoint-initdb.d (Graças a @Kuhess) Mas, no meu caso, quero criar meu banco de dados com base em alguns parâmetros definidos no arquivo .env, então fiz isso
1) Primeiro, defino o arquivo .env no diretório do projeto raiz do docker
2) Em seguida, defino meu arquivo docker-compose.yml. Então, usei a diretiva args para definir minhas variáveis de ambiente e as defini no arquivo .env
3) Em seguida, defino uma pasta mysql que inclui um Dockerfile. Então o Dockerfile é esse
4) Agora eu uso o mysqldump para despejar meu db e colocar o data.sql dentro da pasta mysql
O arquivo é apenas um arquivo de despejo de sql normal, mas adiciono duas linhas no início para que o arquivo fique assim
Então, o que está acontecendo é que eu usei o comando "RUN sed -i 's / MYSQL_DATABASE /' $ MYSQL_DATABASE '/ g' /etc/mysql/data.sql" para substituir o
MYSQL_DATABASE
espaço reservado pelo nome do meu banco de dados em que eu o configurei arquivo .env.Agora você está pronto para criar e executar seu contêiner
fonte
.env
arquivo. No entanto, de acordo com isso , o.env
recurso de arquivo funciona apenas quando você usa odocker-compose up
comando e não funcionadocker stack deploy
. Portanto, caso você queira usar o.env
arquivo em produção, verifique os segredos da janela de encaixe que foram introduzidosdocker 17.06
. Então você pode usar o arquivo .env em conjunto com segredos tanto no desenvolvimentodocker compose up
e produçãodocker stack deploy
fasesRUN sed -i '1s/^/CREATE DATABASE IF NOT EXISTS
$ MYSQL_DATABASE;\nUSE
$ MYSQL_DATABASE em;\n/' data.sql
vez dosed
comando que você sugeriu. Dessa forma, você pode usar qualquer arquivo de despejo que você possui - é útil se você estiver trabalhando com grande quantidade de dados :) #Aqui está uma versão de trabalho usando
v3
ofdocker-compose.yml
. A chave é a diretiva volumes :No diretório que eu tenho o meu
docker-compose.yml
, tenho umdata
diretório que contém.sql
arquivos de despejo. Isso é bom porque você pode ter um.sql
arquivo de despejo por tabela.Eu simplesmente corro
docker-compose up
e estou pronto para ir. Os dados persistem automaticamente entre as paradas. Se você quiser remover os dados e "sugar" novos.sql
arquivos executadodocker-compose down
em seguidadocker-compose up
.Se alguém souber como fazer com que a
mysql
janela de encaixe processe novamente os arquivos/docker-entrypoint-initdb.d
sem remover o volume, deixe um comentário e atualizarei esta resposta.fonte
docker-compose down
foi muito importante, pois eu não estava vendo alterações, apesar de reiniciar o docker-compondo. MYSQL_DATABASE é uma variável necessária neste caso