Andrew Welch · Insights · #craftcms #cli #devops

Published , updated · 5 min read ·


For more tools, technologies, and techniques, check out the devMode.fm podcast!

Exploring the Craft CMS 3 Console Command Line Interface (CLI)

Craft CMS 3 comes with many use­ful com­mands that can save you time, and make your life eas­i­er. In this arti­cle, you’ll learn how to stop wor­ry­ing and love the CLI

Craft-cms-3-console-command-line-interface

Craft CMS 3 comes with a won­der­ful con­sole com­mand line inter­face (CLI), but some peo­ple fear CLI’s in gen­er­al, and oth­ers may not ful­ly appre­ci­ate what the Craft CLI can do for you. For­tu­nate­ly, the best way to over­come both is through understanding.

This arti­cle goes into depth explain­ing what the Craft CLI is, and details the com­mands that are avail­able to you. So let’s dive right in!

Link When might we want to use the Craft CLI?

To ful­ly appre­ci­ate why the Craft CLI can be so use­ful, we need to under­stand a bit about how it works, and how reg­u­lar web requests work.

Learning-how-things-work

For a reg­u­lar web request, the web serv­er han­dles the request, hand­ing off the pro­cess­ing of PHP to a sep­a­rate process (usu­al­ly php-fpm). Craft CMS is writ­ten in PHP, and also the Twig tem­plates we write are com­piled down to PHP.

So suf­fice it to say that for any giv­en web request, there will typ­i­cal­ly be a fair bit of PHP that ends up run­ning on our web serv­er. Since web requests are exter­nal, untrust­ed requests there is a memory_​limit and a max_​execution_​time for each request, so that our serv­er is not overwhelmed.

While this is nor­mal­ly won­der­ful, when we need to per­form inten­sive oper­a­tions like mul­ti­ple image trans­forms, re-sav­ing of entries, and espe­cial­ly Craft CMS & plu­g­in updates, it can become a hin­der­ance. Time­outs hap­pen, queue jobs fail, and it’s no fun for anyone.

Addi­tion­al­ly, when we have occa­sion to run tasks at reg­u­lar inter­vals or when we deploy changes to our web­site, doing things like going in and clear­ing caches by hand gets old quick.

The Craft CMS con­sole com­mand line inter­face to the rescue:

  • Tasks run via CLI typ­i­cal­ly have no memory_​limit or max_​execution_​time, because they are run by an inter­nal, trust­ed source, so you they won’t time­out or run out of memory
  • CLI tasks can eas­i­ly be trig­gered at reg­u­lar inter­vals (per­haps via cron) or trig­gered when cer­tain events hap­pen, in an auto­mat­ed way that doesn’t require any user intervention

So for any time con­sum­ing or mem­o­ry inten­sive process, as well as when­ev­er we need tasks to hap­pen in an auto­mat­ed way, the CLI is our friend.

Link What exactly is the Craft CLI?

Now that we know when we might want to use the Craft CLI, let’s have a peek behind the cur­tains to see exact­ly what it is.

Craft-cms-console-command-line-interface-explained

When we set up a new Craft CMS 3 project, there are a cou­ple of curi­ous files that are placed in the project root directory:

-rwxr--r--  1 vagrant vagrant     501 Nov 17  2017 craft
-rwxr--r--  1 vagrant vagrant     330 Apr 15  2017 craft.bat

The craft.bat file is just a wrap­per for run­ning Craft CLI on Win­dows, it ends up run­ning the craft com­mand in the end. So let’s have a look at what the craft com­mand is, exactly:

#!/usr/bin/env php
<?php
/**
 * Craft console bootstrap file
 */
// Set path constants
define('CRAFT_BASE_PATH', __DIR__);
define('CRAFT_VENDOR_PATH', CRAFT_BASE_PATH.'/vendor');
// Load Composer's autoloader
require_once CRAFT_VENDOR_PATH.'/autoload.php';
// Load dotenv?
if (file_exists(CRAFT_BASE_PATH.'/.env')) {
    (new Dotenv\Dotenv(CRAFT_BASE_PATH))->load();
}
// Load and run Craft
define('CRAFT_ENVIRONMENT', getenv('ENVIRONMENT') ?: 'production');
$app = require CRAFT_VENDOR_PATH.'/craftcms/cms/bootstrap/console.php';
$exitCode = $app->run();
exit($exitCode);

The first line #!/usr/bin/env php is called a she­bang (this was a thing long before Ricky Mar­tin) which essen­tial­ly just tells the con­sole that the script is PHP, and to exe­cute in the cur­rent environment.

The rest of the code is very sim­i­lar to what is in our web/index.php, which makes sense, because we’re run­ning Craft in both cas­es. Just think of the craft com­mand as the CLI equiv­a­lent of the web’s index.php. Both boot­strap Craft, and run it.

Link Running things in the Craft CLI

To exe­cute the Craft CLI in its sim­plest form, make sure you’re in the root direc­to­ry of your project in your con­sole (per­haps using the cd com­mand) and type:

./craft

The odd look­ing ./ is a Unix-ism that means in this cur­rent direc­to­ry”. I know, I know. You’re already in that cur­rent direc­to­ry, why doesn’t it know this already? Just accept it and let it hap­pen, because if we don’t use it we’ll see:

vagrant@homestead ~/sites/craft3 $ craft
-bash: craft: command not found

It’s a long sto­ry as to why this is the case, but it has to do with how Unix paths work. Typ­ing just ./craft on its own just lists all of the avail­able com­mands (tech­ni­cal­ly this is the same as ./craft help).

If you see a Permission denied error like this:

vagrant@homestead ~/sites/craft3 $ ./craft
-bash: ./craft: Permission denied

This just means that the craft script doesn’t have exe­cutable per­mis­sions. You can fix that with the following:

chmod a+x craft

For more infor­ma­tion about Unix and Craft per­mis­sions, check out the Hard­en­ing Craft CMS Per­mis­sions article.

So assum­ing we’ve typed it suc­cess­ful­ly, we’ll see some­thing like this:

vagrant@homestead ~/sites/craft3 $ ./craft

This is Yii version 2.0.16.

The following commands are available:

- backup                                           Creates a new database backup
    backup/db (default)                            Creates a new database backup
    
- cache                                            Allows you to flush cache.
    cache/flush                                    Flushes given cache components.
    cache/flush-all                                Flushes all caches registered in the system.
    cache/flush-schema                             Clears DB schema cache for a given connection
                                                   component.
    cache/index (default)                          Lists the caches that can be flushed.

- clear-caches                                     Clear caches via the CLI
    clear-caches/all                               Clear all caches
    clear-caches/asset                             Asset caches
    clear-caches/asset-indexing-data               Asset indexing data
    clear-caches/compiled-templates                Removes all of a directory’s contents recursively.
    clear-caches/cp-resources                      Control Panel resources
    clear-caches/data                              Deletes all values from cache.
    clear-caches/index (default)                   Lists the caches that can be cleared.
    clear-caches/temp-files                        Removes all of a directory’s contents recursively.
    clear-caches/template-caches                   Deletes all the template caches.
    clear-caches/transform-indexes                 Asset transform index

- gc                                               Garbage collector.
    gc/run (default)                               Runs garbage collection.

- help                                             Provides help information about console commands.
    help/index (default)                           Displays available commands or the detailed
                                                   information
    help/list                                      List all available controllers and actions in machine
                                                   readable format.
    help/list-action-options                       List all available options for the $action in machine
                                                   readable format.
    help/usage                                     Displays usage information for $action.

- index-assets                                     Re-indexes assets in volumes.
    index-assets/all                               Re-indexes assets across all volumes.
    index-assets/one (default)                     Re-indexes assets from the given volume handle
                                                   ($startAt = 0).

- install                                          Craft CMS CLI installer.
    install/craft (default)                        Runs the install migration
    install/plugin                                 Installs a plugin

- migrate                                          Manages Craft and plugin migrations.
    migrate/all                                    Runs all pending Craft, plugin, and content
                                                   migrations.
    migrate/create                                 Creates a new migration.
    migrate/down                                   Downgrades the application by reverting old
                                                   migrations.
    migrate/fresh                                  Truncates the whole database and starts the migration
                                                   from the beginning.
    migrate/history                                Displays the migration history.
    migrate/mark                                   Modifies the migration history to the specified
                                                   version.
    migrate/new                                    Displays the un-applied new migrations.
    migrate/redo                                   Redoes the last few migrations.
    migrate/to                                     Upgrades or downgrades till the specified version.
    migrate/up (default)                           Upgrades the application by applying new migrations.

- project-config                                   Manages the project config.
    project-config/rebuild                         Rebuilds the project config.
    project-config/sync                            Syncs the project config.

- queue                                            Manages application db-queue.
    queue/exec                                     Executes a job.
    queue/info (default)                           Info about queue status.
    queue/listen                                   Listens db-queue and runs new jobs.
    queue/retry                                    Re-adds a failed job(s) to the queue.
    queue/run                                      Runs all jobs from db-queue.

- resave                                           Bulk-saves elements
    resave/assets                                  Re-saves assets.
    resave/categories                              Re-saves categories.
    resave/entries                                 Re-saves entries.
    resave/tags                                    Re-saves tags.
    resave/users                                   Re-saves users.

- serve                                            Runs PHP built-in web server.
    serve/index (default)                          Runs PHP built-in web server.

- setup                                            Craft CMS setup installer.
    setup/db                                       Alias for setup/db-creds.
    setup/db-creds                                 Stores new DB connection settings to the .env file.
    setup/index (default)                          Sets up all the things.
    setup/security-key                             Generates a new security key and saves it in the .env
                                                   file.
    setup/welcome                                  Called from the post-create-project-cmd Composer
                                                   hook.

- update                                           Updates Craft and plugins.
    update/composer-install                        Installs dependencies based on the current
                                                   composer.json & composer.lock.
    update/info                                    Displays info about available updates.
    update/update (default)                        Updates Craft and/or plugins.


To see the help of each command, enter:

  craft help <command-name>

Phew, that’s a lot! These are all of the built-in CLI com­mands as of Craft CMS 3.1.21; there may be more added lat­er, and plu­g­ins can add their own CLI com­mands too!

We’ll cov­er what each one does, but the sin­gle most impor­tant CLI com­mand is:

./craft help <command-name>

If we use the ./craft help com­mand for a top lev­el com­mand, we might see some­thing like this:

vagrant@homestead ~/sites/craft3 $ ./craft help update

DESCRIPTION

Updates Craft and plugins.


SUB-COMMANDS

- update/composer-install  Installs dependencies based on the current composer.json & composer.lock.
- update/info              Displays info about available updates.
- update/update (default)  Updates Craft and/or plugins.

To see the detailed information about individual sub-commands, enter:

  craft help <sub-command>

But if we’re a bit more spe­cif­ic with it, and sup­ply the full sub-com­mand such as ./craft help update/composer-install we’ll see a whole lot more help on that spe­cif­ic com­mand, the para­me­ters it takes, etc.:

vagrant@homestead ~/sites/craft3 $ ./craft help update/composer-install

DESCRIPTION

Installs dependencies based on the current composer.json & composer.lock.


USAGE

craft update/composer-install [...options...]


OPTIONS

--appconfig: string
  custom application configuration file path.
  If not set, default application configuration is used.

--color: boolean, 0 or 1
  whether to enable ANSI color in the output.
  If not set, ANSI color will only be enabled for terminals that support it.

--help, -h: boolean, 0 or 1
  whether to display help information about current command.

--interactive: boolean, 0 or 1 (defaults to 1)
  whether to run the command interactively.

I con­sid­er the help com­mand to be the most impor­tant com­mand, because we can use it to fig­ure out how to use all of the oth­er commands!

Let’s check out the avail­able com­mands, and what we might use them for.

Link backup

Yes! As of Craft CMS 3.1.21, you can now back up the data­base via a con­sole com­mand! Have a look at some of the exam­ples that Bran­don not­ed in the FR:

# create backup in the given folder
./craft backup ./backups

# create backup in working directory with custom filename
./craft backup backup.sql

# create backup in specific location
./craft backup ./backups/backup.sql

# create backup in the storage/backups/ folder
./craft backup

This can be a great addi­tion as a cron job or oth­er auto­mat­ed exe­cu­tion to back up the Craft database!

Link cache

You’re prob­a­bly not going to use this com­mand much, if at all. It’s actu­al­ly com­ing from Yii2 and deals specif­i­cal­ly with the Yii2 data cache, which isn’t used for much of any­thing in Craft (though many plu­g­ins do lever­age it).

It has noth­ing to do with what you prob­a­bly think of in terms of caching & Craft, which is the {% cache %} tag. For more on that, check out the The Craft {% cache %} Tag In-Depth article.

In addi­tion, the clear-caches com­mand (see below) can clear the Yii2 data cache any­way so… noth­ing to see here, move along.

Link clear-caches

The clear-caches com­mand is one that PR’d to the Craft core. It is exact­ly anal­o­gous to the Clear Caches Util­i­ty; any­thing you can clear from the CP, you can now clear from the CLI.

This is espe­cial­ly use­ful if you want to clear caches when you deploy changes to the web­site, for exam­ple. See the Com­pos­er Scripts sec­tion below for more on this.

Pro tip: If you see the error Error clearing cache Control Panel resources it’s because for CLI requests, you need to tell Craft where your /cpresources direc­to­ry is in your general.php file:

'resourceBasePath' => dirname(__DIR__) . '/web/cpresources',

You can find a dis­cus­sion about the above on this GitHub issue.

Link gc

The gc com­mand is a bit on the obtuse side, so it’s like­ly only in cer­tain cir­cum­stances that you’ll have a use for it. If you use Craft 3.1’s new Soft Deletes fea­ture, and you want to run garbage col­lec­tion man­u­al­ly or on a fixed time sched­ule, this is the com­mand for you.

What garbage col­lec­tion does is it per­ma­nent­ly deletes any­thing that was soft delet­ed and has expired. Instead of it hav­ing a chance of run­ning on any giv­en web request (and thus poten­tial­ly slow­ing down the web request), you can con­trol when and how it runs.

Link help

We’ve talked about this.

Link index-assets

The index-assets is a PR from Ryan McQuen and does the same job as the Asset Index­es Util­i­ty, but it does so via the CLI.

This can be espe­cial­ly handy because asset index­ing can take a long time, and will run more reli­ably via the CLI than web request because it won’t time out or run out of mem­o­ry dur­ing indexing.

Link install

The install com­mand can be used to install Craft itself (which runs the install migra­tion that sets up the data­base struc­ture) or to install a plu­g­in. To install a plu­g­in, it needs to already be in your composer.json, but this gives you a way to do it from the CLI, per­haps as part of your boil­er­plate setup.

If you want to install Craft as part of some larg­er auto­mat­ed process, you can run it non-inter­ac­tive­ly, for example:

./craft install \
    --interactive=0 \
    --email="admin@example.com" \
    --username="admin" \
    --password="secret" \
    --siteName="Craft3" \
    --siteUrl="$SITE_URL" \
    --language="en"

N.B.: the \ in the above exam­ple isn’t unique to the ./craft install com­mand, it’s a gener­ic way to have a mul­ti-line com­mand in Unix shells.

Check out the Set­ting up a New Craft CMS 3 Project arti­cle for more on set­ting up your own Craft CMS boil­er­plate setup.

Link migrate

The migrate com­mand gives you CLI con­trol over your migra­tions. The most com­mon use-case here is to run migra­tions as part of your auto­mat­ed build deploy­ment, so you aren’t hav­ing to race to the /admin CP to run the migra­tions when you push updates to Craft CMS or plu­g­ins into production.

In this con­text, a migra­tion” means a set of data­base com­mands that Craft and/​or plu­g­ins run to change the struc­ture of the data­base. This is need­ed from time to time as fea­tures are added, or bugs are fixed.

Your web­site won’t be avail­able to the pub­lic until migra­tions are run, if Craft or plu­g­ins have pend­ing migrations.

There’s no way to pre­dict when Craft or plu­g­ins will need to do a migra­tion, so it’s best done in an auto­mat­ed way every time you do updates. See the Com­pos­er Scripts sec­tion below for more on this.

Link project-config

The project-config/sync is again a com­mand that you’ll most like­ly run as part of your deploy­ment process, if you’re using Craft CMS 3.1’s new Project Con­fig feature.

Your web­site won’t be avail­able to the pub­lic until Project Con­fig is synced, if you’re using Project Con­fig with Craft 3.1 and changes to the project.yaml have been pushed.

Avoid the pulse-quick­en­ing race to the /admin CP to ensure that your project.yaml changes are applied in pro­duc­tion when you push them. See the Com­pos­er Scripts sec­tion below for more on this.

Also new in Craft CMS 3.1.20 is the project-config/rebuild com­mand which will rebuild your project.yaml from the data­base in the event that some­thing has got­ten out of sync.

Link queue

The queue com­mand allows you to inter­act with the Craft CMS queue and queue jobs via the CLI. If you’re hav­ing issues with stuck queue jobs (which run via web requests, as dis­cussed above), check out the Work­er start­ing con­trol article.

You can then turn off the run­QueueAu­to­mat­i­cal­ly general.php con­fig set­ting, and have the queue run in the back­ground via the CLI via ./craft queue/listen

If you don’t want to go to these lengths, the Async Queue plu­g­in from Oliv­er Stark can give you the same results.

Link resave

The resave com­mand is the newest Craft CMS CLI com­mand. It once again allows you to run the lengthy and mem­o­ry inten­sive Re-sav­ing Ele­ments” task via the CLI. See this GitHub issue for context.

I think we’re see­ing a pat­tern here with the CLI being use­ful for lengthy and/​or mem­o­ry inten­sive operations.

Link serve

The serve com­mand is a PR from Mark Huot that ensure the Yii2 serve com­mand works with Craft CMS. What does that mean? 

It means that with zero local devel­op­ment envi­ron­ment, you can start serv­ing Craft up from a giv­en host/​port. Handy for get­ting things up and run­ning in a jiffy!

Link setup

The setup com­mand allows you to set up your .env file for envi­ron­ment-spe­cif­ic set­tings, includ­ing data­base set­tings, and oth­er secrets” or things that vary from envi­ron­ment to environment.

This is cov­ered in detail in the Craft Instal­la­tion instruc­tions, and is a nice inter­ac­tive way to fill in what’s need­ed with­out hav­ing to cre­ate & edit the .env file direct­ly with an editor.

Link update

The update com­mand is a way to ease the pain of run­ning Com­pos­er via the CP as Pix­el & Ton­ic works on their Update Ser­vice. This one deserves men­tion­ing what the sub-com­mands do explicitly:

  • update/update — this does the exact same thing as click­ing on the Update but­ton in the CP, but run­ning it via the CLI so you don’t have to wor­ry about Com­pos­er tim­ing out or run­ning out of memory
  • update/composer-install — this is some­thing you’re use when you deploy Craft CMS, effec­tive­ly doing the same thing as composer install but for serv­er setups where Com­pos­er is not installed.

These com­mands are use­ful if you don’t have Com­pos­er installed local­ly or on your serv­er (or just don’t want to deal with Com­pos­er), but have run into issues with updat­ing via the CP.

It’s also use­ful if you want the deploy­ment process to be auto­mat­ed as dis­cussed in the DEPLOY­MENT sec­tion of the Set­ting up a New Craft CMS 3 Project arti­cle, but again, don’t have Com­pos­er avail­able to you. 

Link Composer Scripts

You can run these com­mands direct­ly as part of your deploy­ment process via a shell script or the like, but you can also lever­age Composer.

Com­pos­er has a con­cept of Scripts that can be exe­cut­ed when var­i­ous things hap­pen. For exam­ple, let’s say that you update your Craft CMS site in local devel­op­ment, and then push the composer.lock file to production.

On pro­duc­tion, you’d then run the composer install com­mand, and exact­ly what you installed & test­ed in local devel­op­ment will then be installed on production.

You might add some­thing like this to the "scripts" sec­tion of your composer.json:

"scripts": {
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php craft setup/welcome"
        ],
        "post-update-cmd": [
            "@php craft migrate/all",
            "@php craft project-config/sync",
            "@php craft clear-caches/all"
        ],
        "post-install-cmd": [
            "@php craft migrate/all",
            "@php craft project-config/sync",
            "@php craft clear-caches/all"
        ]
    }

What this means is that any time composer update or composer install are run, it will run Craft CLI com­mands to:

  • Run all pend­ing migrations
  • Sync your project.yaml changes
  • Clear all caches

Boom, instant auto­mat­ed deploy­ment. The nice part about this is that it’ll run in local dev, too.

Pro tip: if you do your composer install inside of a buddy.works con­tain­er or the like, where you don’t want migra­tions to be run (there may be no data­base at all), you can use:

composer install --no-scripts

In this way, your composer install will hap­pen, but none of the Com­pos­er scripts will be run in an envi­ron­ment where they may not exe­cute properly.

Link Wrapping up

That’s all she wrote! Hope­ful­ly this arti­cle has helped demys­ti­fy the Craft CMS CLI a bit, and giv­en you some ideas of how it can make your devel­op­ment and deploy­ment process better.

Have-no-fear-of-the-cli

Have no fear… the CLI is here! Embrace it where it can help auto­mate things for you, and make your life easier.

Hap­py deploying!