Porque criámos os nossos próprios Cloud Native Buildpacks no Ubuntu 26.04
Em resumo
- A Nodion faz o build das aplicações a partir do Git com Cloud Native Buildpacks próprios na stack nodion-26, baseada no Ubuntu 26.04 LTS; não são buildpacks do Paketo, do Heroku nem da Google.
- Doze buildpacks escritos em Go cobrem Node.js, sites estáticos, Ruby, Python, PHP, Go, Rust, Elixir, Java e .NET, além de Procfiles e pacotes Debian adicionais.
- A Nodion mantém uma linha de versões de uma linguagem enquanto não chega ao fim de vida e até três meses depois, e uma versão minor pedida recebe o patch publicado mais recente.
- A deteção experimenta 14 grupos por ordem e trata aplicações poliglotas como Laravel com Vite ou Rails com JS; os detalhes estão na documentação dos buildpacks.
A Nodion faz o build das aplicações a partir do Git com Cloud Native Buildpacks próprios. Seguimos a especificação Cloud Native Buildpacks para detect, build e launch, mas a stack, os buildpacks de linguagem e as versões de runtime são nossos. A stack chama-se nodion-26 e baseia-se no Ubuntu 26.04 LTS. Não são buildpacks do Paketo, do Heroku nem da Google. Eis por que razão os criámos e o que isso significa para os seus builds.
Buildpacks em 30 segundos
Um buildpack transforma código-fonte numa imagem de contentor sem Dockerfile. Deteta a linguagem, instala um runtime e as dependências, faz o build da aplicação e define um comando de arranque. Os Cloud Native Buildpacks são a norma aberta para isto. Um builder agrupa os buildpacks, o lifecycle que os executa e as imagens base para o build e a execução. Primeiro contacto com o tema? Comece por Cloud Native Buildpacks: o que são e como funcionam.
Porque não reutilizar um builder existente?
O Paketo, o Heroku e a Google publicam Cloud Native Buildpacks, e são projetos sólidos. Adotar um deles teria sido o atalho.
Decidimos não o fazer porque, para uma plataforma, o builder não é um pormenor. É ele que decide em que sistema operativo corre a sua aplicação, que versões de runtime existem, como se escolhe uma versão e o que acontece quando uma versão chega ao fim de vida. São decisões de produto que os nossos utilizadores sentem em cada deploy. Queríamos controlar estas decisões, documentá-las num só lugar e aplicá-las de forma igual a todas as linguagens.
O que construímos
Uma única stack assente no Ubuntu 26.04 LTS
A stack nodion-26 tem duas imagens. A imagem de build inclui compiladores e ficheiros de cabeçalho. A imagem de execução (run image) inclui as bibliotecas cliente de que as aplicações costumam precisar, como os clientes de Postgres e MySQL, o ImageMagick e os certificados de CA. O seu processo corre com um utilizador sem privilégios de root.
Escolhemos o Ubuntu 26.04 por ser a versão LTS mais recente. A Canonical lançou-a em abril de 2026 e indica manutenção de segurança padrão até maio de 2031, por isso a base da sua aplicação tem uma longa vida útil antes da próxima grande mudança.
Doze buildpacks, uma só base de código
Há doze buildpacks: Node.js, sites estáticos, Ruby, Python, PHP, Go, Rust, Elixir, Java e .NET, mais um para Procfiles e outro para pacotes Debian adicionais. Todos estão escritos em Go com a libcnb, a biblioteca Go do projeto Cloud Native Buildpacks, e vivem num único módulo. Partilham uma única biblioteca para resolução de versões, transferências e logs, pelo que a fixação de versões, a apresentação de mensagens de erro e a verificação dos ficheiros descarregados seguem as mesmas regras em todas as linguagens.
Deteção que conhece aplicações poliglotas
O builder experimenta 14 grupos de cima para baixo, e seleciona o primeiro grupo cujos ficheiros obrigatórios estejam todos presentes. Em projetos reais, a ordem importa:
- Um frontend JavaScript estático é construído com Node.js e depois servido pelo buildpack de sites estáticos.
composer.jsonmaispackage.jsondá PHP e Node.js num só build (por exemplo, Laravel com Vite).Gemfilemaispackage.jsondá Ruby e Node.js (Rails com um pipeline de JS).- Depois vêm as linguagens isoladas, um servidor Node.js autónomo, um site puramente estático e, por fim, uma aplicação só com Procfile.
Os pacotes Debian adicionais são uma parte opcional de cada grupo, por isso qualquer aplicação os pode adicionar.
O nosso próprio pipeline de runtimes
Os runtimes disponíveis estão definidos numa única matriz de versões no nosso repositório. Uma tarefa que corre de hora a hora verifica as datas de fim de vida e as novas versões, aplica a política de suporte e abre um pull request que atualiza a matriz. Depois do merge, cada versão de runtime em falta é construída e publicada, e as aplicações passam a usá-la no build seguinte.
Ruby, Python, PHP e Erlang são compilados a partir do código-fonte na nossa imagem de build. Os restantes runtimes são reempacotados a partir dos binários publicados pelos próprios projetos. Quando um build descarrega um runtime, verifica o ficheiro com o checksum publicado antes de o extrair.
O que ganha com isto
Uma política de versões que cabe num parágrafo
Mantemos uma linha de versões de uma linguagem enquanto não chega ao fim de vida, e até três meses depois. Se indicar uma versão minor, recebe o patch publicado mais recente dessa versão. Se indicar uma versão anterior à linha publicada mais antiga, o build falha por a versão ter chegado ao fim de vida. Se indicar uma versão posterior a todas as que já foram construídas, falha por ainda não estar disponível. Em ambos os casos, o build termina com uma mensagem clara, em vez de usar discretamente outra versão.
Go e Rust são a exceção: a toolchain publicada mais recente faz o build da aplicação, e o código que indica versões mais antigas em go.mod ou rust-version continua a compilar.
| Linguagem | Por omissão | Linhas publicadas (setembro de 2026) |
|---|---|---|
| Node.js | 24 | 22, 24, 25, 26 |
| Python | 3.13 | 3.10 a 3.14 |
| PHP | 8.3 | 8.2 a 8.5 |
| Ruby | 3.4 | 3.3, 3.4, 4.0 |
| Go | 1.26 | Toolchain mais recente (1.25 a 1.27) |
| Rust | 1.96 | Toolchain mais recente (1.95 a 1.98) |
| Java | 21 | 11, 17, 21, 25, 26 |
| .NET | 10 | 8, 9, 10 |
| Elixir | 1.20 | 1.15 a 1.20 (Erlang/OTP 26 a 29) |
Os patches avançam à medida que os publicamos. A página de cada linguagem explica como fixar uma versão, por exemplo com .node-version ou .python-version.
Flexibilidade onde faz falta
- Procfile: defina os seus próprios tipos de processo. Cada tipo passa a ser um processo separado da aplicação, e as definições por omissão da linguagem só se aplicam quando não há Procfile.
- Pacotes de sistema adicionais: indique pacotes Debian em
project.toml(ou numAptfile). São extraídos para a imagem; os scripts de manutenção dos pacotes não são executados. - Monorepos: aponte o Base directory para a pasta da aplicação.
[com.nodion.buildpacks.deb-packages]
install = ["ffmpeg", "pandoc"] O que não mudámos
A especificação. Detect, build e launch funcionam como em qualquer plataforma Cloud Native Buildpacks, e o resultado é uma imagem OCI normal. Por omissão, a Nodion usa o seu próprio builder, mas pode escolher outro builder se preferir. Se o seu repositório já tiver um Dockerfile, ou não for um projeto numa linguagem suportada, use antes o Dockerfile. Não sabe qual escolher? Leia Dockerfile vs buildpacks.
Para experimentar, ligue um repositório em Applications → New, escolha Buildpacks e confirme que a sua aplicação escuta em PORT. Tudo o resto está na documentação dos buildpacks.
Perguntas frequentes
Que buildpacks usa a Nodion?
Os Cloud Native Buildpacks próprios da Nodion, na stack nodion-26 (Ubuntu 26.04 LTS). Seguem a especificação Cloud Native Buildpacks, mas os buildpacks de linguagem, a stack e as versões de runtime são da Nodion, e não buildpacks do Paketo, do Heroku ou da Google.
Que linguagens suportam os buildpacks da Nodion?
Node.js, Python, Ruby, PHP, Go, Rust, Elixir, Java, .NET e sites estáticos, além de aplicações só com Procfile. Pode incluir pacotes Debian adicionais com project.toml ou um Aptfile.
Durante quanto tempo a Nodion suporta uma versão de linguagem?
Uma linha de versões de uma linguagem continua disponível enquanto não chega ao fim de vida e até três meses depois. Go e Rust usam sempre a toolchain publicada mais recente para o build, que também compila código mais antigo.
Posso usar um Dockerfile em vez de buildpacks na Nodion?
Sim. Use um Dockerfile quando o seu repositório já tiver um ou não for um projeto numa linguagem suportada, e a Nodion faz o build dessa imagem e executa-a.