Configuration that differs between environments, where it is set, and which names you cannot use.
Variables are how an environment differs from its siblings without the code
differing. They are written into the application's .env file on every deploy.
On the project, where they apply to every environment. On an environment, where they apply there and nowhere else.
An environment defining a name the project already defines replaces it, there only. That is the entire rule — there is no third scope and no precedence table.
The console says which is which. A variable listed as inherited from project is not editable on the environment page: editing it there would silently create an override, and the next person to change the project value would wonder why one environment ignored them.
Mark a variable secret and its value is encrypted at rest and never shown again — not in the list, not in the edit form, not in a backup you can read. You can replace it; you cannot read it back.
Mark anything secret that would matter if it leaked: API keys, tokens, the mail relay password. There is no cost to marking too much.
Anybody from Developer up can add and change ordinary variables. A secret is replaced or removed by an Admin or Owner, and it cannot be turned back into a plain variable: a value that has been secret should be rotated, not revealed.
Some names are set for you and cannot be redefined. Redefining them would either break the environment or point it at another tenant's service, so the form refuses them when you type them.
They are also the contract your code reads. Every value below is written into
the environment's .env — the container's environment — and is what your
settings.php, config/database.php or wp-config.php should read instead
of anything committed to the repository. A value marked absent when is only
there when the condition holds, so read it with a fallback rather than
assuming it.
| Name | What it is |
|---|---|
VALLIC_ENVIRONMENT |
The environment's name — production, staging, pr-42. |
VALLIC_ENVIRONMENT_TYPE |
What kind it is: production, staging, development or preview. The value to switch behaviour on — error verbosity, an environment indicator, whether to send real mail. |
PROJECT_MODE |
The same as VALLIC_ENVIRONMENT_TYPE, under the name older images read. |
VALLIC_SLUG |
The environment's slug, {project}-{environment}, unique across the platform. |
PROJECT_NAME |
The same as VALLIC_SLUG, under the name the images read. |
VALLIC_HOSTNAMES |
Every hostname the edge routes to this environment, comma-separated. Trust these Host headers and no others. Absent until something routes here. |
PROJECT_BASE_URL |
https:// and the primary hostname — the one every other hostname redirects to. What to write into absolute links when no request says. Absent until something routes here. |
DRUSH_OPTIONS_URI |
Drupal projects only: PROJECT_BASE_URL under the name Drush reads, so cron and one-off commands write the same URLs a request would. |
| Name | What it is |
|---|---|
VALLIC_ENTROPY |
256 random bits, base64-encoded, generated once per environment and never changed. Derive the site's own secrets from it — Drupal's hash salt, WordPress's salts — rather than committing them. Arrives through the secret channel, so it is never in a task payload. |
| Name | What it is |
|---|---|
DB_HOST |
The database service, reachable by this name from every container. Absent when the stack runs no database. |
DB_PORT |
Its port. |
DB_DRIVER |
mysql for MariaDB, pgsql for PostgreSQL. |
DB_NAME |
The database, created on the service's first start. |
DB_USER |
The application's user — not the superuser. |
DB_PASSWORD |
Its password. Generated once with the environment and never regenerated. Arrives through the secret channel. |
DB_ROOT_PASSWORD |
The superuser's password, on engines that have one. For a migration or a repair, not for the site. |
DATABASE_URL |
The same credentials as one connection string, which is what Doctrine reads and what most Node and Go drivers accept. Arrives through the secret channel, because it carries the password. |
DB_CONNECTION |
The same value as DB_DRIVER, under the name Laravel reads. |
DB_DATABASE |
The same value as DB_NAME, under the name Laravel reads. |
DB_USERNAME |
The same value as DB_USER, under the name Laravel reads. |
| Name | What it is |
|---|---|
REDIS_HOST |
The cache service, whether it is Redis or Valkey — both speak the same protocol and the name is what the Drupal redis module reads. Absent when the stack runs neither. |
REDIS_PORT |
Its port, 6379. |
VALKEY_HOST |
The Valkey service by its own name, when the stack runs Valkey. |
SOLR_HOST |
The Solr service, when the stack runs it. Port 8983. |
SOLR_USER |
The user Solr's login accepts, solr. Solr refuses a request without it. |
SOLR_PASSWORD |
Its password. Derived per environment and never regenerated. Arrives through the secret channel. |
VARNISH_HOST |
The HTTP cache in front of the application, when the stack runs it — where to send purge requests. A purge sent here needs no key. |
VARNISH_PURGE_KEY |
The key a purge needs when it comes in from outside, in an X-VC-Purge-Key header. Arrives through the secret channel. |
SMTP_HOST |
The mail relay, when the stack runs one. Port 25 from inside the stack; the relay is what talks to the outside world. |
MEILISEARCH_HOST |
The Meilisearch service, when the stack runs it. Port 7700. |
RABBITMQ_HOST |
The RabbitMQ broker, when the stack runs it. |
RABBITMQ_PORT |
Its AMQP port, 5672. |
RABBITMQ_USER |
The user to connect as, app. The image's guest is removed. |
RABBITMQ_PASSWORD |
Its password. Derived per environment and never regenerated. Arrives through the secret channel. |
RABBITMQ_URL |
The same as one amqp:// URL, on the default virtual host. Arrives through the secret channel, because it carries the password. |
MEILI_MASTER_KEY |
Meilisearch's master key, which the service starts with and the application authenticates with. Derived per environment and never regenerated. Arrives through the secret channel. |
| Name | What it is |
|---|---|
VALLIC_CDN_PURGE_URL |
Where to POST a purge, on this machine's loopback. Present only when the project has bought a CDN. |
VALLIC_CDN_PURGE_TOKEN |
Says which environment is asking. It is not a CDN credential and cannot reach another environment's cache. Arrives through the secret channel. |
| Name | What it is |
|---|---|
VALLIC_PUBLIC_DIR |
Absolute path, inside the container, of the directory the framework serves uploads from. It outlives every release. |
VALLIC_PRIVATE_DIR |
Absolute path of the directory that is never served — Drupal's private files, Laravel's storage/app. It outlives every release. |
S3_FILES_ENDPOINT |
Object storage for the site's files, when a bucket is attached to the environment: the endpoint. |
S3_FILES_REGION |
Its region. |
S3_FILES_BUCKET |
The bucket. |
S3_FILES_PATH_STYLE |
1 when the endpoint needs the bucket in the path rather than the hostname. |
S3_FILES_ACCESS_KEY |
The access key. Arrives through the secret channel. |
S3_FILES_SECRET_KEY |
The secret key. Arrives through the secret channel. |
| Name | What it is |
|---|---|
WEB_ROOT |
Where the live release is inside every container: /var/www/html/current. The directory above it holds every release kept for rollback. |
COMPOSER_ROOT |
The same directory — where composer.json is. |
DRUPAL_ROOT |
/var/www/html/current/web, the document root of a Drupal project. |
VALLIC_LOG_DIR |
/var/log/app, where an application writes log files it wants collected. Anything written here is shipped with the rest of the environment's logs and kept in the machine's own copy. It outlives every release. |
| Name | What it is |
|---|---|
MYSQL_DATABASE |
What the MariaDB image reads to create the database on first start: the same value as DB_NAME. |
MYSQL_USER |
The same value as DB_USER, for the MariaDB image. |
MYSQL_PASSWORD |
The same value as DB_PASSWORD, for the MariaDB image. |
MYSQL_ROOT_PASSWORD |
The same value as DB_ROOT_PASSWORD, for the MariaDB image. |
POSTGRES_DB |
The same value as DB_NAME, for the PostgreSQL image. |
POSTGRES_USER |
The same value as DB_USER, for the PostgreSQL image. |
POSTGRES_PASSWORD |
The same value as DB_PASSWORD, for the PostgreSQL image. |
RABBITMQ_DEFAULT_USER |
The same value as RABBITMQ_USER, for the RabbitMQ image. |
SOLR_CLOUD_PASSWORD |
The same value as SOLR_PASSWORD, for the Solr image: its login, and the digest it signs its ZooKeeper nodes with. |
RABBITMQ_DEFAULT_PASS |
The same value as RABBITMQ_PASSWORD, for the RabbitMQ image. |
Anything beginning VALLIC_ or VC_ is reserved wholesale, so that a variable
the platform adds next year cannot collide with one you added today.
Your variables reach your application: the site's own container, its queue
worker and its workers. They do not reach
the database, the cache or any other service beside it. Those read only the
platform's values above, so a variable you add cannot reconfigure them by
sharing a name with one of their settings. The one exception is a variable a
service needs from you. For example, OpenSMTPD reads RELAY_PASSWORD to log in
to your mail provider.
Every setting the services take, in one place. These are not project variables:
they configure the service itself, so they go under that service in
vallic.yaml rather than on the Variables page.
Service settings says what each one does.
| Service | Variables |
|---|---|
| Go | GOMEMLIMIT, GOMAXPROCS |
| MariaDB | MYSQL_MAX_ALLOWED_PACKET, MYSQL_INNODB_BUFFER_POOL_SIZE, MYSQL_MAX_CONNECTIONS, MYSQL_SLOW_QUERY_LOG, MYSQL_LONG_QUERY_TIME |
| Meilisearch | MEILI_MAX_INDEXING_MEMORY, MEILI_LOG_LEVEL |
| MySQL 8 | MYSQL_MAX_ALLOWED_PACKET, MYSQL_INNODB_BUFFER_POOL_SIZE, MYSQL_MAX_CONNECTIONS, MYSQL_SLOW_QUERY_LOG, MYSQL_LONG_QUERY_TIME |
| Nginx | NGINX_CLIENT_MAX_BODY_SIZE, NGINX_KEEPALIVE_TIMEOUT, NGINX_FASTCGI_READ_TIMEOUT, NGINX_GZIP_COMP_LEVEL, NGINX_STATIC_EXPIRES, NGINX_ERROR_LOG_LEVEL, NGINX_DRUPAL_NOT_FOUND_REGEX, NGINX_WP_NOT_FOUND_REGEX |
| Node.js | NODE_OPTIONS |
| OpenSMTPD | RELAY_HOST, RELAY_PORT, RELAY_PROTO, RELAY_USER, OPENSMTPD_MAX_MESSAGE_SIZE, OPENSMTPD_EXPIRE, OPENSMTPD_BOUNCE_WARN |
| PHP-FPM | PHP_MEMORY_LIMIT, PHP_MAX_EXECUTION_TIME, PHP_POST_MAX_SIZE, PHP_UPLOAD_MAX_FILESIZE, PHP_OPCACHE_MEMORY_CONSUMPTION, PHP_APCU_SHM_SIZE, PHP_FPM_PM_MAX_CHILDREN, PHP_DISPLAY_ERRORS, PHP_MAX_INPUT_VARS |
| PostgreSQL | POSTGRES_MAX_CONNECTIONS, POSTGRES_SHARED_BUFFERS, POSTGRES_WORK_MEM |
| RabbitMQ | RABBITMQ_VM_MEMORY_HIGH_WATERMARK |
| Redis | REDIS_MAXMEMORY_POLICY, REDIS_DATABASES |
| Solr | SOLR_HEAP, SOLR_MODULES |
| Valkey | VALKEY_MAXMEMORY_POLICY, VALKEY_DATABASES |
| Varnish | VARNISHD_PARAM_DEFAULT_TTL, VARNISH_BACKEND_GRACE, VARNISH_CACHE_PER_COUNTRY, VARNISH_MOBILE_SEPARATE_CASH, VARNISH_KEEP_ALL_PARAMS |
Set them under the service in vallic.yaml, not as
project variables — they configure the service itself rather than your
application, and each service page shows the shape.
Anything not listed here is either owned by the platform or decides where a service connects, what it is, or whether it starts. Those are refused on purpose: an application able to set them could break its own environment in ways nothing here would catch.
Read the environment; commit nothing that differs between environments. For
Drupal there is a ready-made settings.vallic.php that
does all of it — the database, the cache, the file paths, the hash salt, which
Host headers to trust — and is the same file on every project.
On the next deploy. Changing a variable does not restart anything on its own — the running containers keep the environment they were started with, which is what makes a variable change something you can prepare and then release rather than something that happens under a live site the moment you hit save.
Storage covers disks, which is the other thing that differs between environments.