Customizing and understanding vagrant-spk
What the files are for
vagrant-spk
will create a .sandstorm/
folder in your repo and set up some
files with some defaults for your app stack. You will likely need to modify
some of these to adapt their behavior to make the most sense for your app.
global-setup.sh
This installs Sandstorm using the official installer script, enables developer accounts, and stops unneeded services on the VM. It caches the Sandstorm bundle to speed up subsequent runs. You should not need to change this script.
setup.sh
This script runs when you set up the VM by vagrant-spk up
the first time and
does stack-specific setup, like installing tools or daemons needed to build and
run your app. vagrant-spk
provides some defaults based on commonly-used platform
stacks, but you'll likely want to modify this script as suitable for your package.
This is the ideal place to apt-get install
system packages your app relies on,
like:
- language runtimes (PHP, Node, Python, etc.)
- database engines (MySQL, PostgreSQL, Redis, etc.)
- frontend web servers (nginx, Apache)
and so on. Please note that this script is run only once for the lifetime of
the VM, and will not be run again when running vagrant-spk dev
or starting a
grain.
If you make changes to this script, you should destroy your VM (vagrant-spk destroy
)
and rebuild it cleanly from scratch (vagrant-spk up
) to make sure your
changes take effect and work as desired.
If you find yourself destroying and creating VMs from scratch frequently,
consider running an instance of apt-cacher-ng
on your host to speed up
package downloads.
build.sh
This script runs each time you run vagrant-spk dev
before exposing your app
to the Sandstorm server, so you can run it in "dev mode". Again, vagrant-spk
provides some defaults based on commonly-used patterns in the supported stacks,
but you'll likely need to modify this script to run your package's usual build
flow, since packages use many different workflows and directory structures.
This is the ideal place to invoke anything which is normally part of your app's build process: anything that you need to transform your project's source code into a runnable deployment, but explicitly not the project's deployment, configuration, or user data.
Usually you put things here which should be run again as the result of changes to your project's source code. Examples of things you might put here are:
- Compiling your project from source, for projects written in compiled languages.
- Calling
composer
to install or update PHP dependencies described in your app'scomposer.json
- Calling
pip
to install your app's Python-specific dependencies from therequirements.txt
in your app's repository - Calling
npm install
to install or update npm dependencies from your app'spackage.json
- Calling
bower install
to install or update web/css dependencies described in the app'sbower.json
- Calling
gulp
to compile and minify SASS/LESS into CSS, or collect javascript into bundles - Minifying dependencies
- Collecting various build artifacts or assets into a deployment-ready directory structure
launcher.sh
This script will be run every time an instance of your app - aka grain - starts in Sandstorm. It is run inside the Sandstorm sandbox. This script will be run both when a grain first launches, and when a grain resumes after being previously shut down. This script is responsible for launching everything that your app needs to run. The thing it should do last is:
- start a process in the foreground listening on port 8000 for HTTP requests.
Frequently this is something like nginx
serving static files and reverse
proxying for some other backend service. You want to run this last because
accepting requests on port 8000 is how you signal to the Sandstorm platform
that your application is completely up and ready for use. If you do this
before your backend is ready to go, users could get e.g. 502 errors or see a
broken page on first load - a poor first experience.
Other things you probably want to do in this script include:
- Building folder structures in
/var
./var
is the only non-tmpfs folder mounted R/W, and when a grain is first launched, it will start out empty. It will persist between runs of the same grain, but be unique per app instance. - Preparing a database and running migrations. You can also manually generate some tables once, place them somewhere under
/opt/app
, and copy them to/var/lib/mysql
if your app takes a while to do migrations, at the potential cost of producing a larger.spk
. - Launching other daemons that your app uses (
mysqld
,redis-server
,php5-fpm
,uwsgi
, etc.)
For apps which need the ability to self-modify code or configuration, or which
expect to be able to write data underneath their source tree, you
should create a dangling symlink from
/opt/app/where-your-app-keeps-its-self-modifiable-config.conf
to somewhere
under /var
, then copy or generate a default configuration to that symlink target under /var
in
launcher.sh
so your app will find it at runtime.
There's an example of this in the paperwork repository -
build.sh
removes the folder frontend/app/storage
and replaces it with a symlink
pointing to /var/storage
. Then,
launcher.sh
makes sure that /var/storage
exists and is populated with the appropriate
subdirectories.
These tend to be unique per-app, so again, vagrant-spk
provides appropriate
defaults for common stacks, but you'll likely need to make adjustments for your
app.
sandstorm-files.list
This file is generated by running vagrant-spk dev
and using the app.
It contains a list of all files that your app used at runtime. This
is used to construct a minimal package. See the raw packaging
guide for details.
In the fullness of time, we'd like to support a method of generating
sandstorm-files.list
that doesn't require the developer to carefully
use every app feature to make sure that e.g. default plugins get
included in the package.
sandstorm-pkgdef.capnp
See packaging tutorial for details.
Vagrantfile
See packaging tutorial for details.
Example setups
Default setup
Repo: https://github.com/paulproteus/php-app-to-package-for-sandstorm
This example shows how to setup a php + mysql app.
setup.sh
installs PHP, nginx, and MySQL from the distribution's repository,
then modifies default config files to support the /opt/app
layout and run
in the Sandstorm sandbox.
build.sh
installs/updates composer, and uses composer to install PHP
dependencies.
launcher.sh
creates a folder structure in /var
for MySQL, nginx, and
php5-fpm, creates MySQL tables, then launches the three daemons, checking that
mysqld
and php5-fpm
are ready to accept requests before launching nginx
,
which will listen for requests on port 8000.
Paperwork (php, mysql, composer, npm)
Repo: https://github.com/JamborJan/paperwork
setup.sh
installs PHP, nginx, nodejs, and npm. Additionally, it installs some
system-global tools (gulp
and bower
) with npm
.
build.sh
does several things: it installs and updates composer
, installs app-specific
npm
and bower
dependencies from package.json
and bower.json
manifests
in the repo, and runs gulp
to build static assets.
launcher.sh
creates the storage folders for notes in /var/storage
, which the app will
find because /opt/app/frontend/app/storage
(the standard storage location for
Paperwork) is a symlink to /var/storage
. Additionally, the script sets up
the default database, grants permissions, and runs migrations.