Runtime files
Ship templates, scripts and other repo files next to your binary.
By default a running service has only its binary: none of your repo's other files are on the server. Code that opens a repo file while running works locally and fails on Greyship:
read install.sh: open scripts/install.sh: no such file or directoryYou have two ways to fix it.
Option 1: list the files in greyship.toml
files = ["templates/", "static/", "scripts/install.sh"]Every service in the project then gets those files at the same paths as in your repo, read-only, in its working folder. Your code doesn't change:
tmpl := template.Must(template.ParseGlob("templates/*.html"))
script, _ := os.ReadFile("scripts/install.sh")
http.Handle("/static/", http.FileServer(http.Dir("static")))Rules:
- Put
filesat the top ofgreyship.toml, before any[section]. Inside a section it means something else, and the deploy tells you to move it. - Entries are files or folders inside the repo: no
.., no absolute paths, no wildcards. A folder includes everything under it. At most 100 entries. - The same rules as for source uploads apply: ignored files (
.gitignore,.greyshipignore),.git,.envfiles and symlinks are never shipped. - An entry that matches nothing fails the deploy, naming it, so a typo never deploys silently.
- At most 50 MB and 5,000 files in total.
- The files are read-only. To write, use
/tmp(up to 64 MB, emptied when the instance restarts), a database or object storage.
The deploy shows what's shipped:
Files: templates/ (12 files), scripts/install.sh · 340 KBWith Go installed, they're uploaded only when they change. Rollbacks bring back that deployment's files.
Option 2: embed them in the binary
Go can build files into the binary with //go:embed; then nothing needs shipping:
import "embed"
//go:embed templates
var templates embed.FS
tmpl := template.Must(template.ParseFS(templates, "templates/*.html"))//go:embed can't reach upward (../). For a file elsewhere in the repo, put a tiny package next to it:
// scripts/scripts.go
package scripts
import _ "embed"
//go:embed install.sh
var Install []byteThe warning
When your code reads a repo path at runtime that isn't shipped, the deploy warns (it never fails):
warning: cmd/install/main.go:42 reads scripts/install.sh while running, but only the binary is shipped;
add it to greyship.toml (files = ["scripts/install.sh"]) or use //go:embedIt spots literal paths passed to os.Open, os.ReadFile, os.ReadDir, os.Stat, os.DirFS,
template.ParseFiles, template.ParseGlob and http.Dir.