We have a static site that consumes an outside API from the browser.
This API has different keys for prod and dev mode.
How can a static site serve different files per environment?
Steps
1. Add your key files to the repository
$ touch keys/dev.json
$ touch keys/prod.json
2. Add a writable path
Supposing your site is served from the web directory, we’ll add a writable path underneath it to host our symlink.
Add the mount in your .platform.app.yaml file:
mounts:
'web/keys':
source: local
source_path: keys
3. Symlink the changed files at deploy time
Now that we have our key files in the repository and a writable path available, we can use our deploy hook to create a symlink to the appropriate file:
hooks:
deploy: |
set -e
if [ "$PLATFORM_BRANCH" = "master" ] ; then
ln -sfv ~/keys/prod.json web/keys/key.json
else
ln -sfv ~/keys/dev.json web/keys/key.json
fi
Conclusion
Now we can serve different content to the browser per-environment without changing the static nature of our site.
this is a perfect example. thanks, @royall.
Some doubts, what’s the meaning of this line - ln -sfv ~/keys/prod.json? what is sfv?
Just one question, is it only working for the JSON file, or .js file path also work inside hook? (Suppose, I have two different js files inside the web/keys)
what’s the meaning of this line - ln -sfv ~/keys/prod.json ? what is sfv?
This means “create a symbolic link from keys/prod.json in my home directory”. The ~ placeholder stands for the $HOME directory, which is /app in this case.
I’m using 3 options for ln:
s for “symbolic link” (pointing to another file) instead of a hardlink (using the same inode at 2 locations)
f for “force” in order to overwrite the link if it already exists
v for “verbose” so it always prints a message in the deploy log
You can use this approach for files of any type that need to change at deploy time, as many as you need. You could even link a whole directory, if necessary.
Thanks, @royall. Understand now.
Just one small doubt, correct me if I’m wrong.
the first one is the symlink u create temporarily in home dir and 2nd one is the actual file path. So, for symlink, '/web' not needed? I thought ‘home’ means where '.platform, web, .yaml' files are there.
is a single command that creates a link at ~/web/keys/key.json pointing to the file ~/keys/prod.json.
Specifying the link’s target file with ~ in front creates an absolute path. If I used keys/prod.json instead, the link at /app/web/keys/key.json would use a relative path to /app/web/keys/keys/prod.json, which is not what we want.
The problem that will very likely occur is for static sites that require outside API at bulld time (Static Site Generators). This is a current annoying limitation that would be great to overcome in Platform.sh’s roadmap, since the JAMStack is more and more important these days.
If someone finds a solution or workaround, I’m interested!