Você já se pegou precisando usar uma massa de dados específica para reproduzir um bug ainda mais específico, mas que “na minha máquina funciona”? Eu já! E para “ajudar” na depuração eu tinha recém trocado de máquina e não tinha SQL Server instalado. Entre instalar o SQL Server ou o Docker, eu fui na segunda opção dada a versatilidade que o Docker oferece.
Obs. 1: Vou assumir que você possui conhecimento prévio e necessário de Docker.
Obs. 2: Se você estiver realmente trabalhando com um backup de produção LGPD mandou um “oi”, então não deixei de anonimizar os seus dados 😉.
Para esse artigo usarei uma base de dados genérica que encontrei no GitHub. Caso você seja uma pessoa mais mão na massa e queira acompanhar o passo a passo aqui descrito, pode baixá-la em Contoso-Data-Generator.
Com o backup em mãos precisamos subir um container do SQL Server. Para isso rodamos o seguinte comando em um terminal:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Strong@Passw0rd" -p 1433:1433 --name na_minha_maquina_funciona -d mcr.microsoft.com/mssql/server:2022-latest
Lembrando que na versão 2022 SA_PASSWORD
está marcado como depreciado e em versões futuras apenas a variável MSSQL_SA_PASSWORD
será suportada pelos desenvolvedores do projeto.
Com o container em pé o próximo passo é copiar o backup lá para dentro com a seguinte instrução:
docker cp Contoso.1M.bak na_minha_maquina_funciona:/var/opt/mssql/data/Contoso.1M.bak
Por hoje é só pessoal?! Não, precisamos entrar no container, saber qual o caminho lógico dos dados e dos logs dentro do arquivo de backup e só então de fato restaurar o nosso banco de dados. Respira!
Acessamos o container com a seguinte instrução:
docker exec -it na_minha_maquina_funciona bash
Obtendo o caminho dos dados e do .bak:
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Strong@Passw0rd
A partir desse ponto estamos no console do SQL Server e para restaurar o banco de dados precisamos do caminho físico dos dados e dos logs dentro do .bak. Pra isso rodamos:
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Strong@Passw0rd \ -Q "RESTORE FILELISTONLY FROM DISK = N'/var/opt/mssql/data/Contoso.1M.bak'"
O resultado pode ser bem confuso, principalmente se o nome do banco de dados tiver espaço em branco – nosso caso – pois a Microsoft usou espaço como delimitador ao invés de tabs. Então o ideal é copiar o resultado e colar em um editor de texto. Estamos interessados apenas na primeira coluna:
LogicalName Contoso 1M Contoso 1M_log
Com esta informação, ainda dentro do container, podemos rodar:
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Strong@Passw0rd \ -Q "RESTORE DATABASE Contoso FROM DISK = '/var/opt/mssql/data/Contoso.1M.bak' WITH MOVE 'Contoso 1M' TO '/var/opt/mssql/data/Contoso.mdf', MOVE 'Contoso 1M_log' TO '/var/opt/mssql/data/Contoso.ldf'"
O resultado:
UFA! Feito, porém ainda não terminamos…
Até esse ponto resolvemos a restauração na nossa máquina, porém se precisássemos compartilhar este banco com mais alguém o ideal seria que tivéssemos uma imagem Docker para não fazer com que nossos colegas de trabalho tenham que reproduzir todos esses passos.
Com o conhecimento dos passos anteriores temos todas as informações pra criar nossa imagem Docker. Vamos lá!
FROM mcr.microsoft.com/mssql/server:2022-latest # Copia os arquivos necessários para restaurar o backup # e para coordenar a restauração e o início do servidor # do SQL Server. COPY Contoso.1M.bak /var/opt/mssql/data/Contoso.1M.bak COPY ponto_de_entrada.sh . COPY restaurar_banco.sh . # Muda pro usuário `root` afim de ajustar a permissão # de pastas e execução de scripts. USER root RUN chown -R mssql. /var/opt/mssql RUN chmod +x ./restaurar_banco.sh # Define o usuário padrão para execução do servidor e # da restauração. USER mssql # Expõe mais uma vez a porta padrão do SQL Server. EXPOSE 1433 # Coordena o início do servidor e da restauração do # backup. ENTRYPOINT /bin/bash ./ponto_de_entrada.sh
ponto_de_entrada.sh
#!/bin/bash ./restaurar_banco.sh & /opt/mssql/bin/sqlservr
Repare que primeiro chamamos o script de restauração e em paralelo o servidor do SQL Server, isso se dá ao fato de que o ciclo de vida do container está ligado ao último comando executado, então subir o servidor precisa ser o último comando e ao mesmo tempo precisamos do servidor rodando pra restaurar o banco. (Mais detalhes de como burlar essa inversão da execução na descrição do próximo arquivo).
https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-configure?view=sql-server-ver16&source=recommendations&pivots=cs1-bash#customcontainer
restaurar_banco.sh
#!/bin/bash sleep 10 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD \ -Q "RESTORE DATABASE Contoso \ FROM DISK = '/var/opt/mssql/data/Contoso.1M.bak' \ WITH MOVE 'Contoso 1M' TO '/var/opt/mssql/data/Contoso.mdf', \ MOVE 'Contoso 1M_log' TO '/var/opt/mssql/data/Contoso.ldf'"
E aqui está o pulo do gato, pedimos que a restauração espere 10 segundos antes de tentar restaurar o nosso backup, esse valor pode variar de máquina pra máquina, então aqui vale a pena testar e encontrar o ponto ótimo pra média das máquinas das pessoas do seu time.
Finalmente podemos criar nossa imagem:
docker build -t na_minha_maquina_funciona .
E então subir nosso container:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Strong@Passw0rd" \ -p 1433:1433 --name db_bug_xpto \ -d na_minha_maquina_funciona:latest
Agora é só subir a imagem em um repositório que o time tenha acesso e todas as pessoas terão acesso a exatamente aos mesmos dados.
Todas as dúvidas, críticas e sugestões – desde que de maneira respeitosa – são bem vindas.