0027 — Bump das libs xadm-comum + prefixo de storage s3.* → garage.*¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-08-20 · Decidido em: 2026-08-20
Contexto¶
Auditoria de defasagem contra o xadm-commons (Forgejo Packages, org xadm): 4 das 5 libs
adotadas (0023, 0024,
0025) estavam uma minor atrás. xadm-comum-util
já na última (0.1.0).
| lib | de → para | mudança de API |
|---|---|---|
xadm-seguranca |
0.3.0 → 0.4.0 | aditiva (AuthSettings.getFirebaseJwksUrl) |
xadm-comum-web |
0.4.0 → 0.5.0 | nenhuma (API pública idêntica) |
xadm-comum-storage |
0.1.0 → 0.2.0 | ver abaixo |
xadm-comum-teste |
0.1.0 → 0.2.0 | GarageTestResource.s3Properties() → garageProperties() |
O xadm-comum-storage 0.2.0 trouxe duas mudanças que tocam o app:
- Interface nova
ObjetoStorage(+ implS3ObjetoStorage):S3ArquivoXlsStoragedeixou de receber(S3Client, S3Config)e passou a receber(ObjetoStorage). Refactor interno da lib — DI resolve sozinho (o app não constrói o bean à mão;compileJavado main passou limpo). - Prefixo de config
@ConfigurationProperties("s3")→("garage")noS3Configda lib. Oapplication.ymldo app amarrava sobs3:; precisa mover pragarage:ou o binding some (endpoint/credenciais nulos → storage quebra). Os componentes (endpoint, region, accessKey, secretKey, bucket, criarBucket) não mudaram. O modo (app.storage.modo/ envS3_FILE_STORAGE) não mudou — o prefixoapp.storagefoi preservado.
Decisão¶
Bumpar as 4 libs. Migrar o bloco s3: → garage: no application.yml, mantendo compatibilidade
das duas envs (S3_* antigas e GARAGE_* novas) durante a transição no Coolify.
Compatibilidade das duas envs — SEM placeholder aninhado¶
O reflexo é ${GARAGE_X:${S3_X:default}}. Não funciona no Micronaut: quando o default do
placeholder externo contém : (a URL do endpoint, http://…:3900), o resolver quebra o aninhamento
— o valor vaza como http://localhost:3900} (URISyntaxException, "Illegal character in
authority"). Backtick de escape só cobre um nível; aninhar backtick (`${…`…`}`) também
vaza (3900\}`).
Solução adotada — uma env por property, override por prioridade de fonte:
garage:
endpoint: ${S3_ENDPOINT:`http://localhost:3900`}
region: ${S3_REGION:garage}
# … demais componentes idem, lendo a env antiga S3_* como default
O YAML lê a antiga S3_* como default; a nova GARAGE_* sobrescreve automaticamente
porque a env var vira a property garage.* direto e a fonte de ambiente vence o
application.yml no Micronaut. Precedência efetiva GARAGE_* > S3_* > default, verificada
com teste discriminante (setar GARAGE_ENDPOINT inválido faz a instanciação do storage falhar
citando esse valor — prova que a env chegou na property).
Migração no Coolify (sem downtime)¶
Cadastrar as GARAGE_* com os mesmos valores das S3_* atuais e só então remover as S3_*:
| Novo (cadastrar) | Antigo (fallback) |
|---|---|
GARAGE_ENDPOINT |
S3_ENDPOINT |
GARAGE_REGION |
S3_REGION |
GARAGE_ACCESS_KEY |
S3_ACCESS_KEY |
GARAGE_SECRET_KEY |
S3_SECRET_KEY |
GARAGE_BUCKET |
S3_BUCKET |
GARAGE_CRIAR_BUCKET |
S3_CRIAR_BUCKET |
S3_FILE_STORAGE (o modo) não muda. Detalhe operacional: operacao/deploy;
mapa env→property: projeto/03-object-storage-garage.
Alternativas preteridas¶
- Placeholder aninhado
${GARAGE_X:${S3_X:default}}— quebra no Micronaut (colisão do:da URL com o separador de default). Descartada por evidência de teste, não por gosto. - Só
GARAGE_*, sem fallback — exigiria janela de downtime (renomear todas as envs no Coolify de uma vez). A cadeia de fallback torna a migração sem interrupção.
Consequências¶
- Migração de env no Coolify é gradual e reversível; as
S3_*seguem válidas até removê-las. - Gotcha de stack (vale pra outros apps Micronaut da casa): placeholder aninhado com
:no default é furado — preferir uma env por property + override por prioridade de fonte de ambiente.