.symfony.cloud.yaml
.symfony.cloud.yaml¶
SymfonyCloud configuration is made of several files that need to be stored along
side the project’s code. The main file is called .symfony.cloud.yaml
and
must be stored in the application root directory. This file configures how the
application is built and then deployed on SymfonyCloud.
The best way to get started is to run symfony init
. This command detects
what technologies are used by a project and generates configuration files with
sensible defaults. This generation is made using Open-Source templates. Below is an example for a
Symfony application using Flex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # .symfony.cloud.yaml
name: 'app'
type: 'php:7.4'
build:
flavor: 'none'
disk: 128
runtime:
extensions:
- apcu
- mbstring
- pdo_pgsql
relationships:
database: "mydatabase:postgresql"
elasticsearch: "mysearch:elasticsearch"
mounts:
'/var': { source: local, source_path: var }
'/public/upload': { source: local, source_path: uploads }
web:
locations:
'/':
root: 'public'
passthru: '/index.php'
'/upload':
root: 'public/upload'
scripts: false
allow: true
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2 symfony-build)
deploy: |
set -x -e
(>&2 symfony-deploy)
|
Note
This file configures one application. If you have multiple applications
inside your project, you need one .symfony.cloud.yaml
file at the root
directory of each application.
See the Multiple applications cookbook for more information.
Name¶
A unique identifier for the application inside the project. Only lower case
alpha-numeric characters (a-z0-9
) are allowed.
This name is used in the .symfony/routes.yaml
file to define the HTTP
upstream or in the relationships section in another symfony.cloud.yaml
within the same multi-applications project.
Caution
Changing the name of an app once it has been deployed destroys all storage volumes; this is like deleting it and starting from scratch.
Type¶
The type value defines the application language and the version to use. Current supported values are:
- php
- nodejs
- python
- ruby
- go
- java (alpha support)
Build¶
Defines the build flavor; use none
for PHP projects.
Size¶
Tweaks the container size. Supported values for the size key are AUTO
(the
default), XS
, S
, M
, L
, XL
, 2XL
and 4XL
.
Read the documentation about resources allocations for more details about the impact of this parameter.
Disk¶
Defines the disk quota for the application, in MB. The minimum disk size is 128MB. The following are counted toward the application’s disk quota:
- The application root directory (source code, assets, vendors, etc);
- Writable and persistent directories (see Mounts);
- logs (each trimmed to 10 MB automatically)
- About 50MB for internal state and configuration
When an application reaches its quota, writes are not allowed anymore. Depending on the application requirements, this might lead to errors.
Mounts¶
By default, the application’s disk is read-only. Some directories can be marked
as persistent and writable via the mounts
section; their contents are shared
from one deployment to the next:
1 2 3 | # .symfony.cloud.yaml
mounts:
'/public/upload': { source: local, source_path: uploads }
|
The keys represent the path relative to the application root directory where the
directory is exposed (/public/upload
in the example).
The source_path
property is the name of a subdirectory exposed from the
global persistent storage (uploads
in our example).
Dependencies¶
Specifies dependencies that the application needs during the build process. These dependencies are independent of the application
dependencies, and are installed globally in the PATH
before the build process and are always available. SymfonyCloud supports pulling
dependencies for the following languages:
- PHP
- Python
- Ruby
- Node.js
- Java (with integrated Maven and Ant support)
1 2 3 4 5 6 7 8 9 10 | # .symfony.cloud.yaml
dependencies:
php:
symfony/var-dumper: "*"
python:
behave: "*"
ruby:
sass: "3.4.7"
nodejs:
grunt-cli: "~0.1.13"
|
Runtime¶
The runtime
section customizes the runtime language. Possible values vary
greatly from one language to the other. Please refer to specific language
documentation:
Relationships¶
Defines how services are exposed to the application:
1 2 3 4 | # .symfony.cloud.yaml
relationships:
database: "mydatabase:postgresql"
elasticsearch: "mysearch:elasticsearch"
|
A service exposed to an application is called a relationship. Services are
exposed to the application using environment variables. The key defines the name
of the relationship and the prefix of the environment variables. The value is
formed as <service>:<endpoint>
. service
refers to the name of one
service as defined in .symfony/services.yaml
and endpoint
refers to the
available endpoints exposed by the service.
Note
See the Services documentation for a complete description of currently supported services types, endpoints and associated environment variables.
Caution
At this time SymfonyCloud does not support circular relationships between
services or applications. That means you cannot add a relationship in your
.symfony.cloud.yaml
that points to another application or service that
itself points back to the first application.
Web¶
The web
section defines how the application is publicly exposed.
The following subkeys are available:
Locations¶
The locations
section associates absolute URI prefixes (location) to
a specific configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # .symfony.cloud.yaml
web:
locations:
"/":
root: "public"
passthru: "/index.php"
#index: [ index.php ]
expires: -1
scripts: true
allow: true
rules:
'\.(gif|jpe?g|png)$':
expires: 60
"/admin":
expires: 300
passthru: true
allow: true
|
Here is the reference of location
configurations:
root
defines the folder used to serve static content for the given location, relative to the application root. Typical values for this property arepublic
orweb
. Absolute paths are not supported.Caution
SymfonyCloud requires that the location root must not be the root of the project. It is important for security that private file mounts are not web-accessible.
expires
: Enables theCache-Control
andExpires
headers for static resources. Can be a duration or-1
for no caching (default). Times can be suffixed with “ms” (milliseconds), “s” (seconds), “m” (minutes), “h” (hours), “d” (days), “w” (weeks), “M” (months, 30d) or “y” (years, 365d).index
determines the file (or files) to consider when serving a request for a directory. It can be a filename, an array of filenames, ornull
. Typicallyindex.php
.scripts
allows or disallows execution of scripts in that location. Possible values aretrue
orfalse
, default istrue
.passthru
makes requests forwarded to the application if the resource is missing. Typical values for non-PHP applications aretrue
orfalse
. In a PHP application, the value is the path to the front controller such as/index.php
or/app.php
. The default value isfalse
.headers
defines any additional headers to apply to static assets. This section is a mapping of header names to header values. Responses sent by the application aren’t affected.allow
allows or disallows serving files which don’t match a rule. Possible values aretrue
orfalse
, default istrue
.request_buffering
allows to enable or disable request buffering. As most application servers do not support chunked requests (e.g. fpm, uwsgi),request_buffering
is enabled by default.rules
defines rules to override current settings for some requests. The key is a PCRE regular expression that is matched against the full request URI, content is the same structure as locations configuration.
Upstream¶
Note
For PHP applications, this section is optional and generally do not need to be specified.
upstream
is an optional key that describes how the application listens to
requests, in particular which protocol is used:
1 2 3 4 5 | # .symfony.cloud.yaml
web:
upstream:
socket_family: tcp
protocol: http
|
socket_family
describes whether the application listens on a Unix socket (unix
) or a TCP one (tcp
, the default). When defined tounix
, SymfonyCloud sets theSOCKET
environment variable with the path to the socket that the application must listen to. Withtcp
, SymfonyCloud sets thePORT
environment variable with the port that the application must listen on.Tip
If the application is not listening at the expected location, SymfonyCloud returns 502 Bad Gateway errors.
protocol
specifies if the application expects to receive incoming requests over the HTTP or the FastCGI protocol. Possible values arehttp
andfastcgi
. The default varies depending on the runtime the application is using.
Commands¶
Note
For PHP applications, this section is optional and generally do not need to be specified.
Under the commands
section, the start
entry defines the command used to
launch the application server listening according to the upstream
configuration:
1 2 3 4 | # .symfony.cloud.yaml
web:
commands:
start: "gunicorn -b $PORT project.wsgi:application"
|
Hooks¶
The hooks
section defines the scripts that SymfonyCloud runs at specific
times of an application lifecycle, build, deploy and post-deploy:
1 2 3 4 5 6 7 8 9 10 11 12 13 | # .symfony.cloud.yaml
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2 symfony-build)
deploy: |
set -x -e
(>&2 symfony-deploy)
post_deploy: |
symfony console app:index
|
Caution
Each hook is executed as a single script, so they will be considered failed
only if the final command fails. Starts the script with set -e
to
make them fail on the first failed command, this is the behavior of default
templates.
Three hooks are available:
First, the build script runs when SymfonyCloud packages the application. At this time, the application source code is checked out, global dependencies are installed and the filesystem can be written at will but no services are available.
Caution
The build step creates a container image that is tied to the Git tree content being built. This image is reused for all deployments and all environments, including production. This means that the build step must be environment agnostic.
This is the best time to run heavy-duty tasks that can be performed offline such as assets build or Symfony container compilation. A persisted build cache directory is available to you for storing reusable artifacts.
/tmp
is also writable but its content is wiped after the build.Note
Build environments (the application plus the build cache directory - not limited to the
app
subdirectory) are limited to 4 GB during the build step - independently of the mounted disk size that is allocated for deployment. If you exceed this limit you will receive aNo space left on device error
. You can clear the build cache directory by using the--clear-build-cache
flag available on thesymfony deploy
command.
Then, the deploy script runs when SymfonyCloud is deploying the application. During the execution of this script, services are available. However, the filesystem where the application lives is read-only, except for the
mounts
. This is the perfect time to run tasks requiring services and essential for a successful deployment such as database migrations.Caution
All incoming requests are held until the end of the execution of the deploy script. Make sure this script runs as fast as possible.
- Finally, the post_deploy script runs once the application is deployed and started. Requests are flowing in and as for the deploy script, services are available but filesystem is read-only. This is the perfect time to run tasks that need to be performed online but are not essential for deployment, search engine indexation for example.
Tip
symfony deploy
streams the build logs only. Logs for the deploy
and post_deploy
hooks are stored in /var/log/deploy.log
. Access them
via symfony log deploy
.
To better understand the big picture and how those three steps articulate with each other, we invite you to read about building the application and deploying the application in the What is SymfonyCloud? article.
Tip
To execute some actions during the deploy or post_deploy hooks only for
a specific environment (to do some anonymization for example), the simplest
way is to use the SYMFONY_BRANCH
environment variable in a condition:
1 2 3 4 5 6 | # .symfony.cloud.yaml
hooks:
deploy: |
if [ "$SYMFONY_BRANCH" != "master" ]; then
symfony console app:dev:anonymize
fi
|
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)¶
The configurator is a script specially crafted for SymfonyCloud. It ensures that projects are always using the most up-to-date version of some tools:
Additionally, it creates some helpers: symfony-build, symfony-start, symfony-deploy, symfony-database-migrate, php-ext-install, and yarn-install.
(>&2 symfony-build)¶
symfony-build is our recipe to build a Symfony application the best way possible. It removes the development frontend, install the application dependencies using Composer (and Yarn, by running yarn-install), optimize the autoloader, build Symfony cache if possible and finally build the production assets using Encore.
Composer install is run using default flag values. If you need to override those
flags, you can define them using the $COMPOSER_FLAGS
environment variable:
1 2 3 4 5 6 7 | # .symfony.cloud.yaml
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2 COMPOSER_FLAGS="--ignore-platform-reqs" symfony-build)
|
One can also set NO_YARN
to any value to disable all Yarn and assets
automation during the symfony-build run.
(>&2 symfony-deploy)¶
symfony-deploy is to be used each time a Symfony application is deployed. Its purpose is to run the symfony-start helper and when executed from the web container, restart FPM and run the symfony-database-migrate helper.
(>&2 symfony-start)¶
symfony-start is to be used each time a Symfony application starts in a new container. Its purpose is to move the Symfony cache built by symfony-build to be used by the application or built the cache otherwise. It is automatically executed by symfony-deploy and SymfonyCloud automatically runs it before starting (or restarting) workers.
(>&2 symfony-database-migrate)¶
You usually don’t need to worry about this helper.
symfony-database-migrate purpose is to run database migrations. By default,
it will run your Doctrine migrations if doctrine/doctrine-migrations-bundle
is installed. If your application uses another migration system you can
override /app/.global/bin/symfony-database-migrate
during build time and
symfony-deploy will make use of it. You can use this script at any moment if
you need to run migrations manually or if you need to run them for
workers.
php-ext-install¶
php-ext-install is a script that you can use to compile and install PHP extensions not provided out of the box by SymfonyCloud. It is written specifically for SymfonyCloud to ensure fast and reliable setup during the build step. It currently supports three ways to fetch the sources from:
- From PECL:
php-ext-install redis 5.3.2
- From a URL:
php-ext-install redis https://github.com/phpredis/phpredis/archive/5.3.2.tar.gz
- From a Git repository:
php-ext-install redis https://github.com/phpredis/phpredis.git 5.3.2
To ensure your application can be built properly, it is recommended to run
php-ext-install
after the configurator but before symfony-build:
1 2 3 4 5 6 7 8 9 10 | # .symfony.cloud.yaml
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2
php-ext-install redis 5.3.2
symfony-build
)
|
When installing PECL PHP extensions, you can configure them directly as variables instead:
1 2 3 4 | # .symfony.cloud.yaml
variables:
php-ext:
redis: 5.3.2
|
Note
Source code is cached between builds and compilation is skipped if it has already been done. Changing the source of downloads or the version will invalidate this cache.
Tip
When downloading the source code, the compression algorithm will be automatically detected. The usual algorithms used by GNU tar are supported.
yarn-install¶
yarn-install is a script that installs Node and Yarn the best way possible in a PHP container on SymfonyCloud. Similarly to Composer install, you can customize Node setup and Yarn install behaviors using the following environment variables:
NVM_DIR
: Directory used to install NVM and Node. Default value is/app/.nvm
.NODE_VERSION
: Pinpoint the Node version that NVM is going to install. Default is--lts
YARN_FLAGS
: Flags to pass toyarn install
. No value by default.
Shall you need to use the Node installation setup by symfony-build, you can use the following snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # .symfony.cloud.yaml
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2 symfony-build)
(>&2
# Setup everything to use the Node installation
unset NPM_CONFIG_PREFIX
export NVM_DIR=${SYMFONY_APP_DIR}/.nvm
set +x && . "${NVM_DIR}/nvm.sh" use --lts && set -x
# Starting from here, everything is setup to use the same Node
yarn encore dev
)
|
Or if you want to use two different Node versions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # .symfony.cloud.yaml
hooks:
build: |
set -x -e
curl -s https://get.symfony.com/cloud/configurator | (>&2 bash)
(>&2 symfony-build)
(>&2
cd web/js_app
unset NPM_CONFIG_PREFIX
export NVM_DIR=${SYMFONY_APP_DIR}/.nvm
NODE_VERSION=8 yarn-install
# Setup everything to use the Node installation
set +x && . "${NVM_DIR}/nvm.sh" use 8 && set -x
# Starting from here, everything is setup to use Node 8
yarn build --environment=prod
)
|
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.