Implantação

Implantando via a imagem base genérica

O caminho recomendado para produção é o mesmo descrito em Primeiro projeto: nenhum projeto C#, só o YAML da aplicação rodando dentro da imagem base genérica de host do Pipevine. O host lê o YAML montado, descobre sozinho quais pacotes (Postgres, JWT, Redis, RabbitMQ, Kafka etc.) precisa carregar a partir do que o próprio documento declara, e sobe — sem build de aplicação, sem Program.cs.

services:
  api:
    image: pipevine/hosting-generic:latest
    ports: ["8080:8080"]
    environment:
      PIPEVINE_PG_CONNECTION: "Host=postgres;Port=5432;Database=minhaapi;Username=postgres;Password=postgres"
    volumes:
      - ./minha-api.pipevine.yaml:/app/config/minha-api.pipevine.yaml:ro

Um pacote de terceiro que implemente o mecanismo de descoberta de módulos do host, solto num diretório de plugins montado no container, é descoberto e registrado automaticamente — o mesmo princípio de extensibilidade sem fork se aplica também ao caminho conteinerizado.

O footgun do volume recursivo

O diretório configurado para o host genérico procurar arquivos *.pipevine.yaml é escaneado recursivamente. Isso é conveniente quando você realmente tem vários arquivos YAML organizados em subpastas — e é uma armadilha quando você monta, por engano, um diretório de projeto inteiro em vez de só o arquivo YAML.

Um diretório de projeto C# típico tem bin/ e obj/, e ambos costumam conter cópias do mesmo arquivo *.pipevine.yaml (copiado para o diretório de saída do build). Se você montar esse diretório inteiro, o host encontra múltiplas cópias do mesmo YAML e registra a mesma aplicação mais de uma vez — sintomas típicos: rotas duplicadas, ou um erro de conflito de rota no startup que não faz sentido à primeira vista, porque só existe um arquivo .pipevine.yaml "de verdade" do ponto de vista de quem escreveu o projeto.

A prevenção é simples: monte só o arquivo YAML em si, nunca a pasta do projeto:

volumes:
  - ./minha-api.pipevine.yaml:/app/config/minha-api.pipevine.yaml:ro   # correto
  # - .:/app/config:ro                                                  # errado — pega bin/ e obj/ juntos

Health checks

Dois endpoints de verificação de saúde vêm prontos, sem nenhuma configuração adicional:

  • GET /health/live — sempre 200 se o processo está de pé. Não verifica nenhuma dependência externa; é o sinal de "o processo não travou", o que a maioria dos orquestradores usa para decidir se deve reiniciar o container.
  • GET /health/ready — reflete conectividade real com as dependências declaradas (Postgres, se a aplicação declarou dataSources, por exemplo). É o sinal de "pronto para receber tráfego", o que a maioria dos orquestradores usa para decidir se deve incluir a instância no balanceamento de carga.

Use /health/live para a liveness probe e /health/ready para a readiness probe do seu orquestrador de containers.

Para onde ir daqui

  • Observabilidade — o que sua aplicação expõe de telemetria por padrão.
  • Testando sua aplicação
  • samples/06-full-stack no repositório do Pipevine — um docker compose up completo, com múltiplos serviços, bancos e brokers reais.