Docs/ Operações/ Gerenciador de Arquivos

Gerenciador de arquivos

A aba Arquivos navega pelo sistema de arquivos do contêiner em execução do app. Serve para inspecionar e fazer pequenas correções, não para entrar ou sair com dados.

O que é

Cada operação executa um comando dentro do contêiner em execução (ls, head, tee, touch, mkdir -p, rm -rf), com o usuário do contêiner. Você vê o contêiner exatamente como o app o vê, montagens incluídas.

Warning
Uma alteração feita fora de um volume montado só existe no contêiner atual. A próxima implantação inicia um contêiner novo a partir da imagem e a alteração some. Para manter um arquivo, coloque-o numa montagem da aba Volumes, ou altere seu código e reimplante.

Usar a aba Arquivos

  • Abra o app e vá até a aba Arquivos. A árvore começa em /; Atualizar relê o diretório atual. Cada entrada mostra tamanho, data e Permissões (somente leitura).
  • Clique num arquivo para exibi-lo. Conteúdo binário não é exibido.
  • Editar e depois Salvar regrava o arquivo com o texto do editor.
  • Novo arquivo cria um arquivo vazio e Nova pasta um diretório, no diretório atual.
  • Excluir apaga um arquivo, ou um diretório com todo o conteúdo, após confirmação.
  • Num app com vários serviços, um seletor escolhe o contêiner; o padrão é o contêiner principal.

API

As mesmas operações pela API (respostas reais):

Terminal
$ curl -s -H "Authorization: Bearer $SH0_TOKEN" "https://panel.example.com/api/v1/apps/<app-id>/browse?path=/app"
{"data":{"entries":[{"file_type":"file","modified":"1970-01-01 00:00:00","name":"server.js","permissions":"-rw-r--r--","size":"182"}],"path":"/app"}}

$ curl -s -X PUT -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"path":"/app/notes/todo.txt","content":"hello from sh0\n"}' \
    https://panel.example.com/api/v1/apps/<app-id>/file
{"data":{"path":"/app/notes/todo.txt","written":true}}

$ curl -s -H "Authorization: Bearer $SH0_TOKEN" "https://panel.example.com/api/v1/apps/<app-id>/file?path=/app/notes/todo.txt"
{"data":{"content":"hello from sh0\n","path":"/app/notes/todo.txt"}}
  • GET /api/v1/apps/<id>/browse?path=… -- listar um diretório.
  • GET /api/v1/apps/<id>/file?path=… lê um arquivo; PUT na mesma rota, com path e content, grava-o.
  • POST /api/v1/apps/<id>/files/mkdir e POST …/files/new, com path -- criar um diretório ou um arquivo vazio.
  • DELETE /api/v1/apps/<id>/files?path=… -- excluir. /, /bin, /etc, /usr, /lib, /lib64, /sbin, /proc, /sys, /dev e /boot em si são recusados (“Cannot delete protected system directory”).
  • Os caminhos devem ser absolutos e não podem conter ... Ler exige o papel viewer no projeto do app; gravar, criar e excluir exigem o papel developer.

O que não existe

  • Sem upload. Não há rota para enviar um arquivo do seu computador; POST …/files/upload responde 404.
  • Sem download nem arquivo compactado. Não é possível baixar um arquivo nem um diretório como arquivo compactado; GET …/files/download responde 404.
  • Sem alteração de permissões ou dono. As permissões são exibidas, não editáveis.

Para essas operações, use o servidor: docker cp entre o host e o contêiner, ou trabalhe diretamente no diretório do volume no host (veja Volumes e montagens). No próprio servidor, sh0 ssh <app> abre um shell no contêiner (veja Acesso ao terminal).

Limites e cuidados

  • Leitura limitada a 1 MB. A leitura devolve no máximo os primeiros 1.048.576 bytes de um arquivo, sem avisar do corte. Não edite nem salve um arquivo maior pela aba Arquivos: o arquivo salvo ficaria só com esse primeiro megabyte.
  • A imagem precisa das ferramentas. Imagens sem utilitários de shell (distroless, scratch) não têm ls ou tee, e o gerenciador de arquivos não funciona nelas.
  • A exclusão é recursiva e definitiva. Não há lixeira.
  • O contêiner precisa estar rodando. Um app parado não tem contêiner para navegar.