Configuring Craft

There are several ways to configure Craft depending on your needs.

# General Config Settings

Craft supports several general config settings. You can override their default values in your config/general.php file.

return [
    'devMode' => true,
];

# Database Connection Settings

Craft supports several database connection settings. You can override their default values in your config/db.php file.

# Guzzle Config

Craft uses Guzzle (opens new window) whenever creating HTTP requests, such as:

  • when checking for Craft updates
  • when sending in a support request from the Craft Support widget
  • when loading RSS feeds from the Feeds widget
  • when working with assets on remote volumes, like Amazon S3

You can customize the config settings Guzzle uses when sending these requests by creating a guzzle.php file in your config/ folder. The file does not support Craft’s multi-environment configuration and should return an array, with your config overrides.

<?php

return [
    'headers' => ['Foo' => 'Bar'],
    'query'   => ['testing' => '123'],
    'auth'    => ['username', 'password'],
    'proxy'   => 'https://myproxy:1234',
];

The options defined here will be passed into new GuzzleHttp\Client instances. See Guzzle’s documentation (opens new window) for a list of available options.

# Aliases

Some settings and functions in Craft support Yii aliases (opens new window), which are basically placeholders for base file system paths and URLs. These include:

The following aliases are available out of the box:

Alias Description
@app The path to vendor/craftcms/cms/src/
@config The path to your config/ folder
@contentMigrations The path to your migrations/ folder
@craft The path to vendor/craftcms/cms/src/
@lib The path to vendor/craftcms/cms/lib/
@root The root project path (same as the CRAFT_BASE_PATH PHP constant)
@runtime The path to your storage/runtime/ folder
@storage The path to your storage/ folder
@templates The path to your templates/ folder
@translations The path to your translations/ folder
@vendor The path to your vendor/ folder
@web The URL to the folder that contains the index.php file that was loaded for the request
@webroot The path to the folder that contains the index.php file that was loaded for the request

You can override these default aliases with the aliases config setting if needed.

We recommend overriding the @web alias if you plan on using it, to avoid a cache poisoning vulnerability.

'aliases' => [
    '@web' => 'https://my-project.tld',
];

If your web root is something besides web/, public/, public_html/, or html/, or it’s not located alongside your craft executable, you will also need to override the @webroot alias, so it can be defined properly for console commands.

'aliases' => [
    '@web' => 'https://my-project.tld',
    '@webroot' => dirname(__DIR__) . '/path/to/webroot',
];

You can define additional custom aliases using the aliases config setting as well. For example, you may wish to create aliases that define the base URL and base path that your asset volumes will live in.

'aliases' => [
    '@web' => 'https://my-project.tld',
    '@webroot' => dirname(__DIR__) . '/path/to/webroot',
    '@assetBaseUrl' => '@web/assets',
    '@assetBasePath' => '@webroot/assets',
],

With those in place, you could begin your asset volumes’ Base URL and File System Path settings with them, e.g. @assetBaseUrl/user-photos and @assetBasePath/user-photos.

If you’d like, you can set the alias values with environment variables, either from your .env file or somewhere in your environment’s configuration:

ASSETS_BASE_URL=https://my-project.tld/assets
ASSETS_BASE_PATH=/path/to/webroot/assets

Then you can pull them into the alias definitions using App::env() (opens new window):

'aliases' => [
    '@assetBaseUrl' => craft\helpers\App::env('ASSETS_BASE_URL'),
    '@assetBasePath' => craft\helpers\App::env('ASSETS_BASE_PATH'),
],

When referencing aliases in your settings, you can append additional segments onto the URL or path. For example, you can set a volume’s base URL to @assetBaseUrl/user-photos.

You can parse aliases in your templates by passing them to the alias() function:

{{ alias('@assetBaseUrl') }}

# URL Rules

You can define custom URL rules (opens new window) in config/routes.php. See Routing for more details.

# Application Configuration

You can customize Craft’s entire Yii application configuration (opens new window) from config/app.php. Any items returned by that array will get merged into the main application configuration array.

You can also customize Craft’s application configuration for only web requests or console requests from config/app.web.php and config/app.console.php.

Craft’s default configuration is defined by src/config/app.php (opens new window), app.web.php (opens new window), and app.console.php (opens new window). Refer to these files when you need to override existing application components.

# Cache Component

By default, Craft will store data caches in the storage/runtime/cache/ folder. You can configure Craft to use alternative cache storage (opens new window) by overriding the cache application component from config/app.php.

Make sure that your config/app.php file is setting a unique id for your application, like new Craft projects are doing (opens new window). If not, add that missing line, and run the following command to add a unique APP_ID environment variable to your .env file:

php craft setup/app-id

# Database Cache Example

If you want to store data caches in the database, first you will need to create a cache table as specified by yii\caching\DbCache::$cacheTable (opens new window). Craft provides a console command for convenience:

php craft setup/db-cache-table

Once that’s done, you can set your cache application component to use craft\cache\DbCache (opens new window).

<?php
return [
    'components' => [
        'cache' => function() {
            $config = [
                'class' => craft\cache\DbCache::class,
                'defaultDuration' => Craft::$app->config->general->cacheDuration,
            ];

            return Craft::createObject($config);
        },
    ],
];

If you’ve already configured Craft to use yii\caching\DbCache (opens new window) rather than craft\cache\DbCache (opens new window), you can safely switch to the latter if you remove your cache table’s dateCreated, dateUpdated, and uid columns.

# APC Example

<?php

use craft\helpers\App;

return [
    'components' => [
        'cache' => function() {
            $config = [
                'class' => yii\caching\ApcCache::class,
                'useApcu' => true,
                'keyPrefix' => Craft::$app->id,
                'defaultDuration' => Craft::$app->config->general->cacheDuration,
            ];

            return Craft::createObject($config);
        },
    ],
];

# Memcached Example

<?php

use craft\helpers\App;

return [
    'components' => [
        'cache' => function() {
            $config = [
                'class' => yii\caching\MemCache::class,
                'useMemcached' => true,
                'username' => App::env('MEMCACHED_USERNAME'),
                'password' => App::env('MEMCACHED_PASSWORD'),
                'defaultDuration' => 86400,
                'servers' => [
                    [
                        'host' => 'localhost',
                        'persistent' => true,
                        'port' => 11211,
                        'retryInterval' => 15,
                        'status' => true,
                        'timeout' => 15,
                        'weight' => 1,
                    ],
                ],
                'keyPrefix' => Craft::$app->id,
                'defaultDuration' => Craft::$app->config->general->cacheDuration,
            ];

            return Craft::createObject($config);
        },
    ],
];

# Redis Example

To use Redis cache storage, you will first need to install the yii2-redis (opens new window) library. Then configure Craft’s cache component to use it:

<?php

use craft\helpers\App;

return [
    'components' => [
        'redis' => [
            'class' => yii\redis\Connection::class,
            'hostname' => 'localhost',
            'port' => 6379,
            'password' => App::env('REDIS_PASSWORD') ?: null,
        ],
        'cache' => function() {
            $config = [
                'class' => yii\redis\Cache::class,
                'keyPrefix' => Craft::$app->id,
                'defaultDuration' => Craft::$app->config->general->cacheDuration,
            ];

            return Craft::createObject($config);
        },
    ],
];

# Database Component

If you need to configure the database connection beyond what’s possible with Craft’s database config settings, you can do that by overriding the db component.

This example configures read/write splitting by defining read replicas. The writer will be whatever’s configured in config/db.php.

<?php

use craft\helpers\App;

return [
    'components' => [
        'db' => function() {
            // Get the default component config
            $config = App::dbConfig();

            // Use read/write query splitting
            // (requires Craft 3.4.25 or later)

            // Define the default config for replica DB connections
            $config['replicaConfig'] = [
                'username' => App::env('DB_REPLICA_USER'),
                'password' => App::env('DB_REPLICA_PASSWORD'),
                'tablePrefix' => App::env('DB_TABLE_PREFIX'),
                'attributes' => [
                    // Use a smaller connection timeout
                    PDO::ATTR_TIMEOUT => 10,
                ],
                'charset' => 'utf8',
            ];

            // Define the replica DB connections
            $config['replicas'] = [
                ['dsn' => App::env('DB_REPLICA_DSN_1')],
                ['dsn' => App::env('DB_REPLICA_DSN_2')],
                ['dsn' => App::env('DB_REPLICA_DSN_3')],
                ['dsn' => App::env('DB_REPLICA_DSN_4')],
            ];

            // Instantiate and return it
            return Craft::createObject($config);
        },
    ],
];

# Session Component

In a load-balanced environment, you may want to override the default session component to store PHP session data in a centralized location.

The session component should be overridden from app.web.php so it gets defined for web requests, but not console requests.

# Redis Example

// config/app.php
<?php

use craft\helpers\App;

return [
    'components' => [
        'redis' => [
            'class' => yii\redis\Connection::class,
            'hostname' => 'localhost',
            'port' => 6379,
            'password' => App::env('REDIS_PASSWORD') ?: null,
        ],
    ],
];
// config/app.web.php
<?php

use craft\helpers\App;

return [
    'components' => [
        'session' => function() {
            // Get the default component config
            $config = App::sessionConfig();

            // Override the class to use Redis' session class
            $config['class'] = yii\redis\Session::class;

            // Instantiate and return it
            return Craft::createObject($config);
        },
    ],
];

# Database Example

First, you must create the database table that will store PHP’s sessions. You can do that by running the craft setup/php-session-table console command from your project’s root folder.

<?php
return [
    'components' => [
        'session' => function() {
            // Get the default component config
            $config = craft\helpers\App::sessionConfig();

            // Override the class to use DB session class
            $config['class'] = yii\web\DbSession::class;

            // Set the session table name
            $config['sessionTable'] = craft\db\Table::PHPSESSIONS;

            // Instantiate and return it
            return Craft::createObject($config);
        },
    ],
];

The session component must be configured with the craft\behaviors\SessionBehavior (opens new window) behavior, which adds methods to the component that the system relies on.

# Mailer Component

To override the mailer component config (which is responsible for sending emails), do this in config/app.php:

<?php
return [
    'components' => [
        'mailer' => function() {
            // Get the stored email settings
            $settings = craft\helpers\App::mailSettings();

            // Override the transport adapter class
            $settings->transportType = craft\mailgun\MailgunAdapter::class;

            // Override the transport adapter settings
            $settings->transportSettings = [
                'domain' => 'my-project.tld',
                'apiKey' => 'key-xxxxxxxxxx',
            ];

            // Create a Mailer component config with these settings
            $config = craft\helpers\App::mailerConfig($settings);

            // Instantiate and return it
            return Craft::createObject($config);
        },
    ],
];

Any changes you make to the Mailer component from config/app.php will not be reflected when testing email settings from SettingsEmail.

# Queue Component

Craft’s job queue is powered by the Yii2 Queue Extension (opens new window). By default Craft will use a custom queue driver (opens new window) based on the extension’s DB driver (opens new window), but you can switch to a different driver by overriding Craft’s queue component from config/app.php:

<?php
return [
    'components' => [
        'queue' => [
            'class' => yii\queue\redis\Queue::class,
            'redis' => 'redis', // Redis connection component or its config
            'channel' => 'queue', // Queue channel key
        ],
    ],
];

Available drivers are listed in the Yii2 Queue Extension documentation (opens new window).

Only drivers that implement craft\queue\QueueInterface (opens new window) will be visible within the control panel.

If your queue driver supplies its own worker, set the runQueueAutomatically config setting to false in config/general.php.

# Modules

You can register and bootstrap custom Yii modules into the application from config/app.php as well. See How to Build a Module for more info.

# Environmental Configuration

Some settings should be defined on a per-environment basis. For example, when developing locally, you may want your site’s base URL to be http://my-project.test, but on production it should be https://my-project.com.

# Control Panel Settings

Some settings in the control panel can be set to environment variables (like the ones defined in your .env file):

  • General Settings
    • System Name
    • System Status
    • Time Zone
  • Sites
    • Base URL
  • Sections
    • Preview Target URIs
  • Asset Volumes
    • Base URL
    • File System Path (Local)
  • Email
    • System Email Address
    • Sender Name
    • HTML Email Template
    • Username (Gmail and SMTP)
    • Password (Gmail and SMTP)
    • Hostname (SMTP)
    • Port (SMTP)
    • Use authentication (SMTP)
    • Encryption Method (SMTP)

To set these settings to an environment variable, type $ followed by the environment variable’s name.

A site’s Base URL setting

Only the environment variable’s name will be stored in your database or project config, so this is a great way to set setting values that may change per-environment, or contain sensitive information.

Plugins can add support for environment variables and aliases in their settings as well. See Environmental Settings to learn how.

# Using Aliases in Control Panel Settings

Some of these settings—the ones that store a URL or a file system path—can also be set to aliases, which is helpful if you just want to store a base URL or path in an environment variable, and append additional segments onto it.

For example, you can define a ROOT_URL environment variable that is set to the root URL of your site:

# -- .env --
ROOT_URL="http://my-project.tld"

Then create a @rootUrl alias that references it:

// -- config/general.php --
'aliases' => [
    '@rootUrl' => craft\helpers\App::env('ROOT_URL'),
],

Then you could go into your User Photos volume’s settings (for example) and set its Base URL to @rootUrl/images/user-photos.

# Config Files

You can set your general config settings, database connection settings, and other PHP config files to environment variables using Craft’s App::env() (opens new window) function:

# -- .env --
CP_TRIGGER="secret-word"
// -- config/general.php --
'cpTrigger' => craft\helpers\App::env('CP_TRIGGER') ?: 'admin',

# Multi-Environment Configs

Craft’s PHP config files can optionally define separate config settings for each individual environment.

// -- config/general.php --
return [
    // Global settings
    '*' => [
        'omitScriptNameInUrls' => true,
    ],

    // Dev environment settings
    'dev' => [
        'devMode' => true,
    ],

    // Production environment settings
    'production' => [
        'cpTrigger' => 'secret-word',
    ],
];

The '*' key is required here so Craft knows to treat it as a multi-environment key, but the other keys are up to you. Craft will look for the key(s) that match the CRAFT_ENVIRONMENT PHP constant, which should be defined by your web/index.php file. (Your server’s hostname will be used as a fallback.)

Make sure your key(s) are sufficiently unique! Craft reads your array of config settings from top to bottom, applying config settings wherever the CRAFT_ENVIRONMENT value contains the key.

By default, new Craft 3 projects will define the CRAFT_ENVIRONMENT constant using an environment variable called ENVIRONMENT, which is defined in the .env file:

# -- .env --
ENVIRONMENT="dev"
// -- web/index.php --
define('CRAFT_ENVIRONMENT', craft\helpers\App::env('ENVIRONMENT') ?: 'production');

# PHP Constants

Your web/index.php and craft files can define certain PHP constants Craft’s bootstrap script will check for while loading and configuring Craft.

Constants you set in web/index.php will be used for web-based requests, while any you set in your root craft file will be used for console requests.

# CRAFT_BASE_PATH

The path to the base directory that Craft will look for config/, templates/, and other directories within by default. (It is assumed to be the parent of the vendor/ folder by default.)

// Tell Craft to look for config/, templates/, etc., two levels up from here
define('CRAFT_BASE_PATH', dirname(__DIR__, 2));

# CRAFT_COMPOSER_PATH

The path to the composer.json file. (It is assumed to live within the base directory by default.)

define('CRAFT_COMPOSER_PATH', 'path/to/composer.json');

# CRAFT_CONFIG_PATH

The path to the config/ folder. (It is assumed to live within the base directory by default.)

# CRAFT_CONTENT_MIGRATIONS_PATH

The path to the migrations/ folder used to store content migrations. (It is assumed to live within the base directory by default.)

# CRAFT_CP

Dictates whether the current request should be treated as a control panel request.

// Tell Craft that this is a control panel request
define('CRAFT_CP', true);

If this isn’t defined, Craft will treat the request as a control panel request if either of these are true:

  • The baseCpUrl setting is set, and the request URL begins with it (plus the cpTrigger setting, if set).
  • The baseCpUrl setting is not set, and the request URI begins with the cpTrigger setting.

# CRAFT_ENVIRONMENT

The environment name that multi-environment configs can reference when defining their environment-specific config arrays. (The craftcms/craft (opens new window) starter project sets this to the value of an ENVIRONMENT environment variable, or falls back to production if it’s not defined.)

// Set the environment from the ENVIRONMENT env var, or default to 'production'
define('CRAFT_ENVIRONMENT', craft\helpers\App::env('ENVIRONMENT') ?: 'production');

# CRAFT_EPHEMERAL

When set to true, Craft will skip file system permission checks and operations that are not available in an environment with ephemeral or read-only storage.

# CRAFT_LICENSE_KEY

Your Craft license key, if for some reason that must be defined by PHP rather than a license key file. (Don’t set this until you have a valid license key.)

// Tell Craft to get its license key from a `LICENSE_KEY` environment variable
define('CRAFT_LICENSE_KEY', craft\helpers\App::env('LICENSE_KEY'));

# CRAFT_LICENSE_KEY_PATH

The path that Craft should store its license key file, including its filename. (It will be stored as license.key within your config/ folder by default.)

# CRAFT_LOG_PHP_ERRORS

Can be set to false to prevent Craft from setting PHP’s log_errors (opens new window) and error_log (opens new window) settings, leaving it up to whatever’s set in php.ini.

// Don’t send PHP error logs to storage/logs/phperrors.log
define('CRAFT_LOG_PHP_ERRORS', false);

# CRAFT_SITE

The Site handle or ID that Craft should be serving from this index.php file. (Only set this if you have a good reason to. Craft will automatically serve the correct site by inspecting the requested URL, unless this is set.)

// Show the German site
define('CRAFT_SITE', 'de');

# CRAFT_STORAGE_PATH

The path to the storage/ folder. (It is assumed to live within the base directory by default.)

Make sure you set this to a valid folder path, otherwise it will be ignored.

# CRAFT_STREAM_LOG

When set to true, Craft will additionally send log output to stderr and stdout. PHP fatal errors will be sent to stderr.

# CRAFT_TEMPLATES_PATH

The path to the templates/ folder. (It is assumed to live within the base directory by default.)

# CRAFT_TRANSLATIONS_PATH

The path to the translations/ folder. (It is assumed to live within the base directory by default.)

# CRAFT_VENDOR_PATH

The path to the vendor/ folder. (It is assumed to live 4 directories up from the bootstrap script by default.)

# Mutex Configuration

Craft uses a file-based mutex driver by default, which should be switched to a different driver in load-balanced environments (opens new window).

A NullMutex (opens new window) driver is used when Dev Mode is enabled, since mutex drivers aren’t necessary for local development and we’ve seen issues with mutex in some Windows and Linux filesystems.

You can configure a custom mutex driver by configuring the mutex component’s nested $mutex property:

// Use mutex driver provided by yii2-redis
return [
    'components' => [
        'mutex' => [
            'mutex' => 'yii\redis\Mutex',
        ],
    ],
];

Notice we’re modifying the nested mutex property and leaving the main mutex component in place.