API REST para cadastro de produtos, em .NET 10 com PostgreSQL.
Para subir com Docker — o caminho recomendado — basta:
- Docker com Docker Compose
Não é preciso ter o .NET instalado: a compilação acontece dentro do container.
Só para rodar a API direto na máquina (ver Subindo localmente):
-
Ferramenta de migrations do EF Core:
dotnet tool install --global dotnet-ef
É o caminho recomendado, e resume-se a um comando. Banco, migrations e API sobem juntos — não há passo manual nenhum além de criar o .env na primeira vez.
1. Crie o arquivo .env na raiz do repositório. Ele não é versionado, então precisa ser criado na primeira vez:
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=produto
BASIC_AUTH_USER=admin
BASIC_AUTH_PASS=password2. Suba os containers:
docker compose up -dO docker-compose.yml sobe três serviços, nesta ordem:
| Serviço | Container | Porta no host | Papel |
|---|---|---|---|
| PostgreSQL | postgres |
5432 |
banco |
| Migrator | gestao-migrator |
— | aplica as migrations e encerra |
| API | gestao-api |
5000 (interna 8080) |
aplicação |
O encadeamento é garantido pelo depends_on: o migrator só roda depois que o healthcheck do Postgres passa, e a API só sobe depois que o migrator termina com sucesso (service_completed_successfully). Se uma migration falhar, a API não sobe.
Não é preciso aplicar migrations à mão neste modo — o docker compose up já faz tudo.
A API fica em http://localhost:5000 e o Swagger em http://localhost:5000/swagger.
Para conferir que subiu:
docker compose ps -aO esperado é postgres e gestao-api como Up, e gestao-migrator como Exited (0) — ele encerra depois de aplicar as migrations, e isso é o comportamento correto.
Nos logs do migrator aparece
Cannot load library libgssapi_krb5.so.2. É inofensivo: a biblioteca só seria usada para autenticação Kerberos no Postgres, que não é o caso aqui. As migrations são aplicadas normalmente.
Roda a API na máquina e usa só o Postgres em container. Útil para depurar no editor.
1. Suba apenas o banco:
docker compose up -d postgres2. Rode a API:
dotnet run --project src/Gestao.APIA API sobe em http://localhost:5039 e o navegador abre o Swagger automaticamente.
As migrations são aplicadas na inicialização: o Program.cs chama MigrateAsync() quando o ambiente é Development, e o launchSettings.json define esse ambiente no dotnet run. Não é preciso rodar nada à mão.
Nesse modo a configuração vem do src/Gestao.API/appsettings.json, não do .env:
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=produto;Username=postgres;Password=postgres"
}Se o .env usar credenciais diferentes dessas, ajuste a connection string — ou sobrescreva na linha de comando:
dotnet run --project src/Gestao.API -- --ConnectionStrings:DefaultConnection="Host=localhost;Port=5432;Database=produto;Username=usuario;Password=senha"O -- separa os argumentos do dotnet run dos que vão para a aplicação.
O serviço migrator cuida disso. Ele é um estágio à parte do Dockerfile que contém apenas um migration bundle — um executável gerado pelo EF Core que aplica as migrations pendentes e encerra. A imagem da API não carrega esse executável nem recebe permissão de alterar schema.
O bundle é gerado durante o build, no estágio migrations:
RUN dotnet ef migrations bundle --project "src/Gestao.Infra.Data" --startup-project "src/Gestao.API" --output /app/efbundleA connection string chega pelo command do serviço, montada a partir do .env.
Se você adicionar uma migration nova, é preciso reconstruir a imagem para o bundle incluí-la:
docker compose up -d --buildO dotnet run aplica as migrations sozinho, por conta deste trecho do Program.cs:
if (app.Environment.IsDevelopment())
{
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await db.Database.MigrateAsync();Como é restrito a Development, fora desse ambiente a aplicação sobe sem tocar no schema.
Se precisar aplicar as migrations sem subir a API — por exemplo para conferir o estado do banco — o comando avulso é:
dotnet ef database update --project src/Gestao.Infra.Data --startup-project src/Gestao.APIEle usa a connection string do appsettings.json (localhost:5432).
dotnet ef migrations add NomeDaMigration --project src/Gestao.Infra.Data --startup-project src/Gestao.APITodos os endpoints exigem Basic Auth. Tanto a porta quanto as credenciais mudam conforme o modo em que a aplicação subiu:
| Modo | Porta | Origem das credenciais | Padrão |
|---|---|---|---|
| Docker | 5000 |
.env (BASIC_AUTH_USER / BASIC_AUTH_PASS) |
o que você definir |
| Fora do Docker | 5039 |
appsettings.json (BasicAuth:User / BasicAuth:Pass) |
admin / password |
Exemplo com a aplicação em Docker, usando as credenciais do .env:
curl -u usuario:senha http://localhost:5000/api/produtoExemplo fora do Docker, com os valores padrão do appsettings.json:
curl -u admin:password http://localhost:5039/api/produtoNo Swagger, use o botão Authorize e informe usuário e senha.
Todos sob /api/produto:
| Método | Rota | Descrição |
|---|---|---|
GET |
/api/produto |
Lista paginada (pageNumber, pageSize) |
GET |
/api/produto/{id} |
Busca por id |
POST |
/api/produto |
Cadastra |
PATCH |
/api/produto/{id} |
Atualiza parcialmente |
DELETE |
/api/produto/{id} |
Remove |
O Swagger só é exposto no ambiente Development.
docker compose downPara apagar também os dados do Postgres:
docker compose down -v