File Manager
The Files tab browses the filesystem of the app's running container. It is meant for inspecting and small fixes, not for moving data in and out.
What it is
Every operation runs a command inside the running container (ls, head, tee, touch, mkdir -p, rm -rf), as the container's user. You see the container exactly as the app sees it, mounts included.
Warning
A change made outside a mounted volume lives only in the current container. The next deployment starts a new container from the image and the change is gone. To keep a file, put it in a Volumes mount, or change your code and redeploy.
Using the Files tab
- Open the app and go to the Files tab. The tree starts at
/; Refresh re-reads the current directory. Each entry shows its size, date and Permissions (read-only). - Click a file to display it. Binary content is not displayed.
- Edit, then Save, rewrites the file with the text of the editor.
- New File creates an empty file and New Folder a directory, in the current directory.
- Delete removes a file, or a directory with everything it contains, after a confirmation.
- For an app with several services, a selector chooses the container; the default is the main container.
API
The same operations through the API (actual responses):
$ 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=…-- list a directory.GET /api/v1/apps/<id>/file?path=…reads a file;PUTon the same route, withpathandcontent, writes it.POST /api/v1/apps/<id>/files/mkdirandPOST …/files/new, withpath-- create a directory or an empty file.DELETE /api/v1/apps/<id>/files?path=…-- delete./,/bin,/etc,/usr,/lib,/lib64,/sbin,/proc,/sys,/devand/bootthemselves are refused (“Cannot delete protected system directory”).- Paths must be absolute and must not contain
... Reading needs the viewer role on the app's project; writing, creating and deleting need the developer role.
What is not there
- No upload. There is no route to send a file from your computer;
POST …/files/uploadanswers 404. - No download and no archive. You cannot download a file or a directory as an archive;
GET …/files/downloadanswers 404. - No change of permissions or owner. Permissions are displayed, not editable.
For those operations, use the server: docker cp between the host and the container, or work directly in the volume directory on the host (see Volumes and Mounts). On the server itself, sh0 ssh <app> opens a shell in the container (see Terminal Access).
Limits and cautions
- 1 MB read limit. Reading returns at most the first 1,048,576 bytes of a file, without saying it was cut. Do not edit and save a larger file from the Files tab: the saved file would keep only that first megabyte.
- The image needs the tools. Images without a shell toolbox (distroless, scratch) lack
lsortee, and the file manager cannot work in them. - Deletion is recursive and final. There is no recycle bin.
- The container must be running. A stopped app has no container to browse.