DEV Community

Vinícius Beloni
Vinícius Beloni

Posted on

Rodando o SEU de banco de dados num container!

"Vocês não me escolheram, mas eu os escolhi para irem e darem fruto, fruto que permaneça, a fim de que o Pai lhes conceda o que pedirem em meu nome.
Este é o meu mandamento: amem-se uns aos outros".
"Se o mundo os odeia, tenham em mente que antes odiou a mim."
- João 15.16-18

Quem nunca precisou subir o próprio banco de dados para testar as alterações feitas numas tabelas? Melhor ainda manter isso versionado e rodando em container. Hoje vou compartilhar com vocês como fazer isso.

Sumário

Criando o projeto

Topo

Vamos iniciar criando um projeto para o DB, esse projeto será responsável por verificar se seu banco está tudo certo. Mas antes devemos instalar o template MSBUild.Sdk.Sqlproj:

> dotnet new --install MSBuild.Sdk.SqlProj.Templates
> dotnet new sqlproj -n MyDb -o my-db/src -s Sql130
> cd my-db
> dotnet sln -n MyDb
> dotnet sln add src #se exitir um .sqlproj pode adicionar também
Enter fullscreen mode Exit fullscreen mode

Perceba que foi criado um arquivo chamado MyDb.csproj, ele será responsável por gerenciar o Pre e PostDeploy e "compilar" todo o seu banco de dados. Vamos criar umas tabelas, depois voltaremos para mexer neste arquivo.

> mkdir src/Schemas
> mkdir src/Tables

> 'CREATE SCHEMA [Bible]' > src/Schemas/Bible.sql

> 'CREATE TABLE [Bible].[Verse](
>>  [VerseId] INT,
>>  [Content] VARCHAR(MAX)
>> )
>> ' > src/Tables/Verse.sql

> dotnet build
Enter fullscreen mode Exit fullscreen mode

Ao fazer isso, será concluído o build com sucesso. Ao criar um script incorreto, será lançado o erro no seu terminal:

> 'CREATE SCHEMA [Pimba] errrrou' > src/Schemas/Pimba.sql
> dotnet build
EXEC : error SQL46010: Incorrect syntax near errrrou. [...]
Enter fullscreen mode Exit fullscreen mode

Agora vamos criar o script de PostDeploy e adaptar o arquivo MyDb.csproj para buscar as Seeds:

> mkdir src/PostDeploy
> '' > src/PostDeploy/SeedTables.sql
Enter fullscreen mode Exit fullscreen mode

SeedTables.sql:

PRINT 'Merging [Bible].[Verse]'

MERGE INTO [Bible].[Verse] AS TARGET
USING 
(
VALUES
    (1, 'Joao 15.16'),
    (2, 'Joao 15.17'),
    (3, 'Joao 15.18')
)
AS SOURCE ([VerseId], [Content])
ON TARGET.[VerseId] = SOURCE.[VerseId]
WHEN NOT MATCHED BY TARGET THEN
    INSERT ([VerseId], [Content])
    VALUES ([VerseId], [Content])
WHEN MATCHED THEN
    UPDATE SET
        TARGET.[Content] = SOURCE.[Content];
Enter fullscreen mode Exit fullscreen mode

Adaptando o MyDb.csproj:

<Project Sdk="MSBuild.Sdk.SqlProj/2.0.0">
    <!-- [...] -->

    <!-- Adicione este bloco para utilizar o PostDeploy -->
    <ItemGroup>
        <Content Include=".\**\*.sql" />

        <!--Remove all Seed files from the build, but add them as post-deploy https://github.com/rr-wfm/MSBuild.Sdk.SqlProj/issues/103 -->

        <Content Remove="..\**\Seed\*.sql" />
        <Content Remove=".\PostDeploy\SeedTables.sql" />

        <PostDeploy Include=".\PostDeploy\SeedTables.sql" />
    </ItemGroup>
</Project>
Enter fullscreen mode Exit fullscreen mode

Vamos testar:

> dotnet build
[...]
Build succeeded.
    0 Warning(s)
    0 Error(s)
Enter fullscreen mode Exit fullscreen mode

Dockerfile

topo

Agora com suas tabelas funcionando, vamos rodar em um container:

Dockerfile (UTF-8):

ARG DBNAME=MyDb
ARG PASSWORD=C0mposed

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src

COPY src .
RUN dotnet build ./MyDb.csproj -c Release -o /app/build

FROM mcr.microsoft.com/mssql/server:2017-latest AS final

# Install Unzip
RUN apt-get update \
    && apt-get install unzip -y

# Install SQLPackage for Linux and make it executable
RUN wget -progress=bar:force -q -O sqlpackage.zip https://go.microsoft.com/fwlink/?linkid=2165213 \
    && unzip -qq sqlpackage.zip -d /opt/sqlpackage \
    && chmod +x /opt/sqlpackage/sqlpackage

# Add the DACPAC to the image
COPY --from=build /app/build/MyDb.dacpac /tmp/db.dacpac

# Configure external build arguments to allow configurability.
ARG DBNAME
ARG PASSWORD

# Configure the required environmental variables
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=$PASSWORD

# Launch SQL Server, confirm startup is complete, deploy the DACPAC, then terminate SQL Server.
# See https://stackoverflow.com/a/51589787/488695
RUN ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" \
    && /opt/sqlpackage/sqlpackage /a:Publish /tsn:. /tdn:$DBNAME /tu:sa /tp:$SA_PASSWORD /sf:/tmp/db.dacpac \
    && rm /tmp/db.dacpac \
    && pkill sqlservr
Enter fullscreen mode Exit fullscreen mode

Resumidamente estamos criando o nome da instância do banco de dados e fazendo o deploy do DACPAC que geramos. Para mais detalhes os links estarão no final do artigo.

Agora vamos ver se está criando o container corretamente:

> docker build -t my-db .
[+] Building 57.5s (15/15) FINISHED [...]
Enter fullscreen mode Exit fullscreen mode

Rodando

topo

Com tudo preparado, só falta executar o container:

> docker run --name testando -p 1433:1433 my-db
SQL Server 2019 will run as non-root by default.
This container is running as user root.
Your master database file is owned by root. [...]
Enter fullscreen mode Exit fullscreen mode

Para conectar utilize as seguintes informações(SQL Login):
user: sa
pwd: C0mposed
server: localhost, 1433

Image description

Os próximos passos serão versionar e configurar o Github Actions.

Versionando

topo

Crie o repositório normalmente, eu criarei no Github:

git init
git remote add origin https://github.com/confianodev/my-db-container
git branch -M main
git fetch
git pull origin main
git add .
git commit -m ":tada: a better commit message"
git push --set-upstream origin main
git checkout -b dev
Enter fullscreen mode Exit fullscreen mode

Dessa forma, qualquer pessoa que for evoluir as tabelas, views, schemas, indexes, etc. Devem conseguir versionar, compilar e executar o banco de dados.

Github Actions

topo

Agora precisamos automatizar isso para que ninguém fique refém dos testes locais. Lembre-se de criar a secret PACKAGES_TOKEN na organização ou no próprio repositório.

mkdir .github/workflows
'' > build-homolog.yml
'' > release-homolog.yml
'' > rollback-homolog.yml
Enter fullscreen mode Exit fullscreen mode

Conteúdo dos arquivos:
https://github.com/confianodev/my-db-container/blob/main/.github/workflows
Lembre-se de trocar o meu usuário(confianodev) pelo seu.

Feito isso, basta fazer o commit e seu container está pronto para ser compartilhado!

git add .
git commit -m ":wrench: github actions"
git push --set-upstream origin dev
Enter fullscreen mode Exit fullscreen mode

E é isso pessoal, a ideia não é fazer deploy em produção, mas sim facilitar os testes e evitar perder tempo com scripts no banco de homologação. Espero que tenha ajudado.

Fiquem com a graça e paz do nosso Senhor Jesus Cristo!

Fontes

topo

https://github.com/rr-wfm/MSBuild.Sdk.SqlProj
https://itnext.io/how-to-build-and-run-a-sql-container-using-a-dacpac-file-c7b0d30f6255

Discussion (0)