Sources de arquivo (HTTPS e rsync)
A partir da v2.163.0, uma instância pode buscar o código sem git, de três jeitos:
type |
De onde vem | Como o cron detecta mudança |
|---|---|---|
local |
pasta no próprio servidor | árvore ou arquivo de controle — ver Deploy local |
https |
artefato baixado (.tar.gz, .tgz, .zip ou arquivo único) |
control_url, ou ETag/Last-Modified do servidor |
rsync |
árvore em outro servidor, por ssh ou rsync:// |
arquivo de controle (control_file) |
Nos três, o código chega em <app>/pull/ numa troca atômica (pasta nova +
rename): um deploy que falha no meio não deixa a app sem código. O resto do
deploy é o de sempre.
O que o cron faz
A cada ciclo, o runner fetch --deploy pergunta ao driver qual é a revisão
atual da origem, sem baixar o código:
- revisão diferente da implantada: pede deploy (
disponível); - igual:
atualizado; - origem fora do ar, URL errada, chave recusada: erro de fetch (conta para o auto-pause, como um repositório que não responde; falha de rede é transitória e não conta);
detect: manual: a app ficamanuale só orunner deployimplanta.
A revisão é http:<sha256> ou ctl:<sha256>. O runner status e o
snapshot mostram a revisão implantada inteira (revision).
A versão da pasta src/<instância>/<versão> segue o version: do manifesto,
lido só do código já baixado (pull/). Sem bloco version:, ou com
version.source: git-commit/git-tag (não há git), a versão é
<tipo>-<12 hex> da revisão (ex.: http-3f9a1c2b7d4e).
runner secrets push recusa instância com source de arquivo
(secrets_push_source_de_arquivo): não há repositório para o secrets.enc.
HTTPS
instances:
staging:
source:
type: https
url: https://cdn.exemplo.com/minha-app/minha-app.tar.gz
control_url: https://cdn.exemplo.com/minha-app/version.txt # opcional
checksum_url: https://cdn.exemplo.com/minha-app/minha-app.tar.gz.sha256 # opcional
signature: # opcional
url: https://cdn.exemplo.com/minha-app/minha-app.tar.gz.minisig
public_key: "RWQ..." # chave pública minisign
headers:
Authorization: "{{::CDN_TOKEN}}" # do cofre da app
max_bytes: 2147483648 # padrão: 2 GiBFormato pela extensão do último segmento da url: .tar.gz/.tgz e
.zip são extraídos; qualquer outra extensão é um arquivo só, gravado em
pull/ com esse nome.
Detecção de mudança:
- com
control_url: o sha256 do corpo dele. É o mais barato e o mais confiável — publique oversion.txtpor último; - sem:
HEADnaurl, peloETag(ouLast-Modified+Content-Length); - sem nenhum dos dois: o arquivo inteiro é baixado a cada ciclo (o log
avisa
source_https_sem_marca).
detect: manual desliga a sonda (só o runner deploy implanta); detect: tree não se aplica ao https (o validador avisa detect_ignorado).
Integridade. checksum_url (formato do sha256sum: <hex> <nome>, ou
só <hex>) e signature (minisign ≥ 0.8) são conferidos antes de
extrair. Sem nenhum dos dois, o deploy segue, mas o log e o
runner preflight avisam download sem verificação de integridade.
Extração segura. Caminho absoluto, .. e link simbólico que sai do
destino são recusados (zip-slip). Acima de max_bytes descompactados, o
deploy para.
Credenciais. Só https:// (o validador recusa http://, inclusive em
redirect). Os {{::VAR}} dos headers vêm do cofre da app (.env,
.env.<instância>, .secrets):
runner env set minha-app CDN_TOKEN 'Bearer ...' --secretO valor nunca entra em log nem em mensagem de erro. Com headers
declarados, redirect só é seguido para a mesma origem (esquema, host e
porta), até 5.
rsync
instances:
homolog:
source:
type: rsync
remote: [email protected]:/srv/build/minha-app/ # ou rsync://host/modulo/
control_file: VERSION # obrigatório
ssh_key: /opt/runner/keys/rsync_ed25519 # opcional, caminho absoluto
exclude: [".git"] # padrão: [".git"]Detecção de mudança: sempre pelo control_file (relativo ao remote):
a sonda baixa só ele. Quem entrega grava o VERSION por último. detect:
não se aplica (o validador avisa detect_ignorado se houver
detect: tree), exceto detect: manual.
Cópia. rsync -a --delete-excluded para uma pasta nova ao lado de
pull/ (o --delete age só no destino, nunca na origem), semeada com o
pull/ atual para transferir só a diferença. O control_file é conferido
antes, na cópia e de novo na origem: se mudou no meio, o deploy para com
source_em_mudanca e o próximo ciclo tenta de novo.
ssh. Sempre BatchMode=yes (nenhum prompt) e
StrictHostKeyChecking=yes: o host já tem de estar no known_hosts do
usuário do runner.
ssh-keyscan origem.exemplo.com >> ~/.ssh/known_hostsssh_key é um caminho absoluto (relativo é recusado com
source_rsync_chave_relativa), arquivo com modo 0600 ou 0400. Sem
ssh_key, valem as chaves do usuário do runner.
Link simbólico que aponta para fora da árvore não vem (--safe-links);
fifo, socket e device também não. Os arquivos ficam do usuário do runner.
Conferir antes do primeiro deploy
runner preflight minha-app # componente `source`: tipo, revisão, integridade
runner fetch minha-app # a sonda responde? (disponível / atualizado / erro)
runner deploy minha-app
runner status minha-app # revision: http:… / ctl:…Erros comuns
| Código | Causa |
|---|---|
source_https_url_nao_https |
url, control_url, checksum_url ou signature.url sem https:// |
source_https_header_sem_segredo |
header usa {{::VAR}} que não está no cofre da app |
source_https_sem_integridade |
aviso: sem checksum_url nem signature |
source_rsync_chave_relativa |
ssh_key não é caminho absoluto |
source_rsync_chave_ssh |
ssh_key ilegível ou com modo diferente de 0600/0400 |
source_em_mudanca |
a origem mudou durante a cópia; o próximo ciclo tenta de novo |