jcloud · para os serviços da Japode Cloud

Um manifesto. Todo arquivo que precisa concordar com ele.

O jcloud lê o japode.yml de um serviço e o confere com o Dockerfile, o Caddyfile e os workflows do repositório, e com o compose, a rota, o backup.conf e o .env.example que a plataforma publica ao lado. Uma porta trocada num lugar e não no outro falha naquele commit, e não no deploy.

  • Linux · macOS · Windows
  • Um binário Go
  • Roda no GitHub Actions

japode.yml, trecho

version: 1
name: notes
image: ghcr.io/example/notes
port: 8080
health:
  path: /healthz
  probe: curl
  start_period: 10s
volumes:
  - name: data
    path: /data
    sqlite: [notes.db]
routes:
  - hosts: [notes.example.com]
    max_body: 2MB

terminal

$ jcloud check japode.yml
  ✓ japode.yml: notes states what it declares (1 volume(s), 1 route(s), 2 variable(s))

1 manifest(s) state what they declare
Uma execução real num manifesto de demonstração, copiada do terminal.

O que ele detecta

Os erros que nenhuma outra ferramenta compara

O docker compose config e o caddy validate leem um arquivo cada. Uma porta escrita em três arquivos passa nos dois enquanto a rota aponta para o nada. Cada aba é um comando do jcloud num pequeno serviço de demonstração, com exatamente o que ele imprimiu.

Um primeiro rascunho

O check lê um manifesto e recusa o que um serviço precisa declarar e não declara. Aqui: falta o caminho de health, uma rota não tem endereço e uma variável é fixa e tem padrão ao mesmo tempo. Todos os problemas saem de uma vez, então basta rodar uma vez.

  • japode.yml

demo/checksaída 1

$ jcloud check japode.yml
  ✗ japode.yml (.)
      health.path: is missing — the deploy waits on it and the route probes it
      routes[0].hosts: is missing — a route with no address reaches nothing
      env[0]: names both default: and value: — a fixed value is not configurable

1 of 1 manifest(s) refused

Cada linha acima foi impressa pelo jcloud v0.3.0 (schema version 1, built with go1.26.8), rodando sobre os arquivos de site/demo.

Onde ele roda

Um manifesto, três lugares que precisam concordar com ele

O manifesto fica no repositório do serviço e uma cópia fica no da plataforma. O jcloud roda nos dois, e contra o que o servidor informa.

  1. Repositório do serviço

    no CI dele, a cada pull request

    • japode.yml
    • Dockerfile
    • Caddyfile
    • .github/workflows

    jcloud checkjcloud check --repo

  2. Repositório da plataforma

    no CI dela, e antes de um deploy

    • services/<nome>/japode.yml
    • docker-compose.yml
    • caddy/sites/<nome>.caddy
    • backup.conf
    • .env.example
    • .env.age

    jcloud agreejcloud comparejcloud upjcloud env

  3. Servidor

    lido por um coletor, nunca pelo jcloud

    • contêineres rodando
    • digests fixados

    jcloud survey

Instalar

Um binário, três jeitos de obtê-lo

A versão atual é a v0.4.0. Todos os jeitos abaixo instalam essa versão.

Baixar um binário

Pegue no release o arquivo do seu sistema, confira com o checksums.txt e coloque o jcloud no PATH.

  • Linux · amd64, arm64
  • macOS · amd64, arm64
  • Windows · amd64, arm64

Cada arquivo aparece com seu SHA-256 no checksums.txt.

Instalar com Go

Qualquer toolchain Go nova o bastante para o go.mod compila a partir do código.

go install github.com/Japode/[email protected]

Rodar no GitHub Actions

É onde o jcloud mais vale: no repositório do próprio serviço, para que o commit que muda uma porta sem mudar o manifesto falhe na frente de quem o fez. O passo baixa o release, confere o checksum e roda o check --repo.

.github/workflows/manifest.yml

name: manifest
on: [push, pull_request]
jobs:
  japode-yml:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: jcloud check --repo
        env:
          V: 0.4.0
        run: |
          A=jcloud_${V}_linux_amd64.tar.gz
          curl -fsSLO "https://github.com/Japode/jcloud/releases/download/v$V/$A"
          curl -fsSL "https://github.com/Japode/jcloud/releases/download/v$V/checksums.txt" | grep " $A\$" | sha256sum -c
          tar -xzf "$A" jcloud
          ./jcloud check --repo . --repository ${{ github.repository }} japode.yml