Variables
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 environment when you apply them, or with the next deploy.
Two places to set them
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.
Secrets
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.
Pasting a .env
Add variable → Bulk takes a pasted .env and lists what it read, one row
per variable, each with its own Secret box. A name containing any of
KEY, SECRET, TOKEN, PASSWORD, PASSWD, PASS, PRIVATE, DSN,
CREDENTIAL or AUTH arrives with the box already ticked — STRIPE_API_KEY,
DATABASE_DSN, SMTP_PASS. It is a match anywhere in the name, so
MONKEY_MODE and PASSPORT_URL are ticked too: untick a row before saving
when its value is safe to show, because once saved as a secret it stays one.
Adding a single variable ticks nothing for you; tick Secret yourself.
Names the platform owns
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.
Where the site is
| 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. |
Secrets
| 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. |
Database
| 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. |
Services in the stack
| 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. |
VARNISH_SECRET |
The secret for Varnish's admin interface (varnishadm, port 6082), for anything that drives the cache that way rather than by HTTP purge. Derived per environment. Arrives through the secret channel. |
SMTP_HOST |
The mail relay. Port 25 from inside the stack, unauthenticated; the relay is what talks to the outside world, through the provider set as its RELAY_HOST on port 587 — direct delivery on port 25 is blocked by most cloud providers. |
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. |
CDN
| Name | What it is |
|---|---|
VALLIC_CDN_PURGE_SOCKET |
The Unix socket to send a purge through. Present only when the project has bought a CDN. |
VALLIC_CDN_PURGE_URL |
The URL to POST a purge to, through that socket. Only its path matters. |
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. |
Files
| 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. |
Paths
| 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. |
Container images
| 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.
Who reads them
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.
What you can change
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 |
| Vinyl Cache (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.
Wiring a site to them
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.
When they take effect
Saving a variable does not restart anything. The running containers keep the environment they were started with, so a change is something you prepare and then release, not something that happens under a live site the moment you hit save. Until it is released, the Variables page says Not applied and names the environments still running on the old values.
It is released in one of two ways:
- Apply variables, on that notice, or
vallic var applyfrom the command line. The site and its workers restart with the new values, which takes a few seconds; the database and other services keep running. From the project's page, or with--scope project, it applies to every environment still behind, and names them. - The next deploy. A deploy sends any changed variables before the new code goes live, so the release starts with them.
Change several at once and apply once: every apply is a restart.
Next
Storage covers disks, which is the other thing that differs between environments.