Use a Custom Buildpack
If you need to deploy a technology which is not supported by Scalingo, you can use an open-source buildpack or a buildpack you have developed.
To achieve this, you must define the following environment variable in
the environment of the concerned application: BUILDPACK_URL
.
Example:
BUILDPACK_URL=https://github.com/cloudfoundry/java-buildpack
Then the deployment logs contain:
<-- Start deployment of my-app -->
-----> Cloning custom buildpack: 'https://github.com/cloudfoundry/java-buildpack'
-- SNIP --
If you need to test a branch of a custom buildpack different than master
, specify its name at the
end of the URL:
BUILDPACK_URL=https://github.com/cloudfoundry/java-buildpack#branch_name
Build a Custom Buildpack
Our execution stack is public and can be found as a docker image on the Docker
Hub. Its name is
scalingo/scalingo-22. The base
image is based on Ubuntu 22.04. The Scalingo stack contains every tool from the
ubuntu:22.04
Docker image.
Run the following command to start a container in the same environment a custom buildpack will be executed:
docker run --pull always --rm --interactive --tty -e STACK=scalingo-22 -v /path/to/custom-buildpack:/buildpack -v /path/to/application:/build scalingo/scalingo-22:latest bash
Then, export the environment variables from your application into the Docker container, and create the folders that will be used by the buildpack scripts:
mkdir /tmp/{cache,env}
If you need to build third-party binaries, you are assured that they will work on the Scalingo platform.
Architecture of a Buildpack
A buildpack has three mandatory entrypoints:
-
bin/detect
: exit with success (return code is 0) if the buildpack applies to the current application. -
bin/compile
: installs the technology. -
bin/release
: handles some metadata.
All these entrypoints are usually Bash script.
Script detect
The purpose of the script located in bin/detect
is to detect if the buildpack
applies to the application. It takes the build directory in argument. If the
buildpack is applicable, the script must print on the standard output the name
of the technology and return with the code 0.
Here is an example of such script which detects a buildpack as applicable for
our technology if the file biniou.yml
is present at the root of the
application.
#!/bin/bash
BUILD_DIR=${1:-}
if [ -f "${BUILD_DIR}/biniou.yml" ]; then
echo "My Wonderful Technology" && exit 0
fi
echo "no" && exit 1
Script compile
The purpose of the script located in bin/compile
is to actually compile the
application. It is called with three arguments:
- The build directory: contains the code of the application.
- The cache directory: used to store information one wants to keep between two builds.
- The environment directory: contains a file per environment variable defined.
For instance, an environment variable
TEST=1234
leads to a file namedTEST
containing1234
.
Here is an example of a (very basic) compile script to compile a C application:
#!/bin/bash
BUILD_DIR=${1:-}
CACHE_DIR=${2:-}
ENV_DIR=${3:-}
echo "-----> Install gcc"
apt-get install --yes gcc
echo "-----> Compile the client application"
gcc -o my-app .
You can test this script in the Docker container with the command:
/buildpack/bin/compile /build /tmp/cache /tmp/env
Script release
The purpose of the script located in bin/release
is to generate some metadata
about the application. It takes the build directory in argument. It must print
on the standard output a YAML file with a couple of keys:
-
addons
: list of addons to install. It is only applied the first time an application is deployed. -
config_vars
: hash of default environment variables. -
default_process_types
: hash of default Procfile entries.
Here is an example of such script for a Node.js application:
#!/bin/bash
cat << EOF
---
addons:
- scalingo-postgresql
config_vars:
PATH: /app/bin:/app/vendor/nginx/sbin:/app/vendor/php/bin:/app/vendor/php/sbin:/usr/local/bin:/usr/bin:/bin
default_process_types:
web: npm start
EOF
Script .profile.d
During startup of any container types, the container starts a Bash shell that sources all the files in the .profile.d/
folder, before executing the container start command. This allows a buildpack to customize the environment of the application. You can take inspiration of what has been done in Scalingo PHP buildpack with this folder.
Feel free to take inspiration from the various buildpacks proposed by Scalingo: https://github.com/Scalingo?utf8=%E2%9C%93&q=buildpack&type=&language=.
Private buildpack
If the url of BUILDPACK_URL
is ending with .tar.gz
or .tgz
we will download and extract this archive. This allows you to host a private buildpack archive with typically a secret hash inside the url (for ex. https://myhostingsite/secret-hash-with-lot-letters-and-numbers.tgz).