This section will go over what you need to install PyroCMS and how to do it.

Heads Up: Looking for documentation on developing with PyroCMS? Have a look at documentation for Pyro's engine, the Streams Platform.

Server Requirements

PyroCMS has a few system requirements:

  • PHP >= 7.0 (5.6.4 for v3.3)
  • PDO PHP Extension
  • cURL PHP Extension
  • SQLite PHP Extension
  • OpenSSL PHP Extension
  • Mbstring PHP Extension
  • Fileinfo PHP Extension
  • Tokenizer PHP Extension
  • GD Library (>=2.0) OR Imagick PHP extension (>=6.5.7)

Server Configuration

This section will go over a few basics of setting up your server for a Laravel application like PyroCMS.

NGINX Example

Below is an example NGINX configuration:

Notice: The web root should be set to your installation's public directory.
# --------------------------
# Redirect non-www > www
# --------------------------

server {
    listen      80;
    listen      443 ssl;
    return 301$request_uri;

# --------------------------
# Redirect to HTTP > HTTPS
# --------------------------

#server {
#    listen      80;
#    server_name;
#    return      301$request_uri;

server {
    listen      80;
    listen      443 ssl;


    access_log /var/log/nginx/example.com_access_log combined;
    error_log /var/log/nginx/example.com_error_log error;

    index  index.php index.html;

    charset utf-8;

    root /var/www/vhosts/;

    ssl_certificate      /var/www/vhosts/;
    ssl_certificate_key  /var/www/vhosts/;

    gzip on;
    gzip_static on;
    gzip_http_version 1.0;
    gzip_disable "MSIE [1-6].";
    gzip_vary on;
    gzip_comp_level 9;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;

    fastcgi_intercept_errors off;
    fastcgi_buffers 8 16k;
    fastcgi_buffer_size 32k;
    fastcgi_read_timeout 180;

    # Remove trailing slashes
    rewrite ^/(.*)/$ /$1 permanent;

    expires $expires;

    location / {
        try_files $uri $uri/ /index.php?$args;

    location ~ \.php$ {

        fastcgi_pass unix:/var/run/php-fpm-default.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        include        fastcgi_params;

    location ~ /\.ht {

        access_log off;
        log_not_found off;

        deny all;

    location ~* \.ico$ {

        expires 1w;
        access_log off;

    location ~* \.(?:jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {

        try_files $uri $uri/ /index.php?$query_string;

        access_log off;
        log_not_found off;

    location ~* \.(?:css|js)$ {

        try_files $uri $uri/ /index.php?$query_string;

        access_log off;
        log_not_found off;

    add_header "X-UA-Compatible" "IE=Edge,chrome=1";

Installing PyroCMS

PyroCMS utilizes Composer to manage its dependencies. So, before using PyroCMS, make sure you have Composer installed on your machine.

Heads Up: Do not create a .env file just yet - Pyro's installer will generate one for you.

Via Installer

First, download the PyroCMS installer using Composer:

composer global require "pyrocms/installer"

Make sure to place the $HOME/.composer/vendor/bin directory (or the equivalent directory for your OS) in your $PATH so the pyro executable can be located by your system.

Once installed, the pyro new command will create a fresh PyroCMS installation in the directory you specify.

For instance, pyro new will create a directory named containing a fresh Pyro installation with all of Pyro's dependencies already installed:

pyro new

You can specify a specific version with the tag option and also include VCS sources with the dev option.

pyrocms new --tag=3.2.0 --dev

Via Composer

You may install PyroCMS by issuing the Composer create-project command in your terminal:

composer create-project pyrocms/pyrocms

If you are using a Windows environment, you might run into issues with the length of paths when unzipping packages. To avoid this issue, use the --prefer-source flag.

Host Configuration

When you setup your web host be sure to point the web root to Pyro's public directory. Just as you would a normal Laravel installation.

Directory Permissions

After installing, you may need to configure some permissions in order to proceed. Directories within the storage, public/app, and the bootstrap/cache directories should be writable by your web server. If you are using the Homestead virtual machine, these permissions should already be set.

If, when trying to access the installer below, you get a white screen. Your permissions are misconfigured.

Running the Installer

After downloading and installing PyroCMS and it's dependencies, you will need to install the software in order to get started. By this time you should be able to visit your site's URL which will redirect you to the installer:

Using the CLI Installer

Pyro comes with a CLI installer you can use if you like by running the following command:

php artisan install

You will be prompted for details in order to proceed with the installation process.

Automating the CLI Installer

You can automate the installer by creating your own .env file with something like this:

[email protected]

Then run the installer and indicate that the system is ready to install:

php artisan install --ready
Heads Up! The APP_KEY must be exactly 32 characters in length.
Using the cURL Installer

Pyro also comes with a cURL installer you can use by executing the following CLI command:

curl -L --max-redirs 100 ""

If desired you can make a browser request to the same URL and append &verbose=true to load the installer directly without a GUI.

Post Installation

Upon logging in the first time after installation you will notice the suggestion to delete the Installer module. To do this simply remove the "anomaly/installer-module" requirement from your project's composer.json file and run composer update.

If you are not using composer going forward you can simply delete /core/anomaly/installer-module from your Pyro installation.

Installing Addons

Pyro comes with a few different ways you can include additional addons in your project.

Installing Addons Manually

You can manually install addons by copying the addon folder into the appropriate vendor folder in addons/{APPLICATION_REF}/{VENDOR} for a specific application or addons/shared/{VENDOR} to allow all applications access to the addon.

Installing Addons with Composer

Addons can be installed with Composer by including the addon in your root composer.json file like a normal package.

Addons installed this way will be considered a core component of your core project and as such will be downloaded to the core directory.

    "require": {
        "anomaly/repeater-field_type": "~1.2.0"

Installing PRO Addons with Composer

You can install PRO and private addons in general with Composer as well. Simply add the repository to your root composer.json file as well as the require line:

"require": {
    "anomaly/forms-module": "~1.1.0",
    "anomaly/standard_form-extension": "dev-master",

If your installation is older or otherwise does not already have included then you can add it now or use the older approach using VCS type repositories:

"repositories": [
        "type": "vcs",
        "url": ""
        "type": "vcs",
        "url": ""
GitHub Authentication for Composer

When deploying PRO addons to servers using composer you will need to authorize Composer to access PRO addons on your behalf. To do this you will need to create a new personal access token and install it on your remote:

composer config -g <oauthtoken>


This section will go over how to contribute to PyroCMS, addons, and it's components.

Bug Reports

To encourage active collaboration, pull requests are strongly encouraged, not just bug reports. "Bug reports" may also be sent in the form of a pull request.

However, if you file a bug report, your issue should contain a title and a clear, detailed description of the issue. You should include as much relevant information as possible and a code sample or link to your repository that demonstrates the issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix quickly.

Remember, bug reports are created in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the bug report will automatically see any activity or that others will jump to fix it. Creating a bug report serves to help yourself and others start on the path of fixing the problem you are experiencing.

Please submit all bug reports to the [](PyroCMS repository). All pull requests must be submitted to the applicable addon repository.

When submitting bug reports for other addons to the PyroCMS repository please prefix the repository the bug report is for by prefixing it with the application addon.

[streams-platform] Your bug report title here.

Development Discussion

Discussion regarding bugs, new features, and implementation of existing features should take place on the [](PyroCMS forum). Discussion can also be had in the PyroCMS Slack team. Ryan Thompson, the lead developer, is typically present in the channel on weekdays from 10am-4pm (UTC-06:00 or America/Chicago).

Which Branch?

*All** bug fixes should be sent to the latest stable branch. Bug fixes should never be sent to the master branch unless no develop branch exists for whatever reason.

Minor features that are fully backwards compatible with the current release may be sent to the latest stable branch.

Major new features should always be sent to the develop branch, which contains upcoming releases.

If you are unsure if your feature qualifies as a major or minor, please ask ryanthompson in the #general PyroCMS Slack channel.

Security Vulnerabilities

If you discover a security vulnerability within PyroCMS, please send an e-mail to Ryan Thompson at [email protected]. All security vulnerabilities will be promptly addressed.

Coding Style

Streams Platform and all addons follow the PSR-2 coding standard and the PSR-4 autoloading standard.


This section will go over the general application structure of PyroCMS.

The application structure of PyroCMS is nearly identical to the application structure of Laravel.

The Addons Directory

The addons directory is where all addons not included in the composer.json file should be kept.

Note: Typically addons in the addons directory are committed to your project repository.

Addon Directory Structure

Just like composer packages PyroCMS addons have a vendor slug that is included in their path. Addons also include the site's application reference and the addon's type in it's full path.


An example could be:


Sharing Addons Between Applications

All addons in the composer.json file will be available for all applications in your PyroCMS installation.

You can also share addons by placing them in the addons/shared folder.


The App Directory

The app directory can be used just like in a native Laravel application. While it is recommended to bundle your application logic in addons the app directory can be used all the same.

For more information on using the app folder for application services please refer to Laravel documentation.

The Bootstrap Directory

The bootstrap directory contains files that bootstrap the framework and configure autoloading. This directory also houses a cache directory which contains framework generated files for performance optimization such as the route and services cache files.

You will notice the bootstrap/app.php file also replaces the console kernel and http kernel with Pyro's own.

The Config Directory

The config directory, as the name implies, contains all of your application's configuration files. It's a great idea to read through all of these files and familiarize yourself with all of the options available to you.

You will notice a streams.php configuration file that can be used to alter the boot process of the Streams Platform, the engine of PyroCMS.

For configuring addons and the Streams Platform further please refer to [#configuration](configuration section).

The Core Directory

The core directory contains any addon required by your composer.json file. Any file contained in the composer.json dependencies is considered part of your website or application's core dependencies.

Warning: It is not advised to commit your core directory!

The Database Directory

The database directory works exactly the same as a native Laravel application. Because most migrations and seeds are within addons, it can be helpful to put miscellaneous seeds and migrations in the database directory.

The Public Directory

The public directory contains the index.php file, which is the entry point for all requests entering your application. This directory also houses your assets such as images, JavaScript, and CSS.

The Asset service in the [/documentation/streams-platform](Streams Platform) also uses the public directory to cache images and assets from various themes and addons. Cached assets can be found in the public/app/{application}/assets directory.

The Resources Directory

The resources directory contains Laravel views as well as raw, un-compiled Laravel assets such as LESS, SASS, or JavaScript. This directory also houses all of your language files.

While you can use the resources directory exactly like you would in a native Laravel application you are encouraged to bundle language files, assets, and views in their respective addons that you are developing for your website or application.

Note: It is highly encouraged to bundle your resources into their respective addons that you develop.

The resources directory will also contain override files for addon config, views, and language files. You will be published to the resources/{application}/addons directory then when running the corresponding Artisan commands.

The Routes Directory

The routes directory contains all of the route definitions for your application. By default, three route files are included with Laravel: web.php, api.php, and console.php.

Note: It is highly encouraged to bundle your routes into their respective addons that you develop.

The web.php file contains routes that the RouteServiceProvider places in the web middleware group, which provides session state, CSRF protection, and cookie encryption. If your application does not offer a stateless, RESTful API, all of your routes will most likely be defined in the web.php file.

The api.php file contains routes that the RouteServiceProvider places in the api middleware group, which provides rate limiting. These routes are intended to be stateless, so requests entering the application through these routes are intended to be authenticated via tokens and will not have access to session state.

The console.php file is where you may define all of your Closure based console commands. Each Closure is bound to a command instance allowing a simple approach to interacting with each command's IO methods. Even though this file does not define HTTP routes, it defines console based entry points (routes) into your application.

Pro Tip: These routes are loaded FIRST. This means that duplicate subsequent routes will override them by name and route path.

The Storage Directory

The storage directory contains your compiled Twig and Blade templates, file based sessions, file caches, and other files generated by the framework. This directory is segregated into app, framework, logs, and streams directories. The app directory may be used to store any files generated by your application. The framework directory is used to store framework generated files and caches. The logs directory contains your application's log files. And finally, the streams directory contains your stream generated entry models, addon caches, and private storage (non-public uploads for example).

The storage/app/public directory may be used to store user-generated files, such as profile avatars, that should be publicly accessible. You should create a symbolic link at public/storage which points to this directory. You may create the link using the php artisan storage:link command.

The Vendor Directory

The vendor directory contains your Composer dependencies.


This section will describe how configuration works in PyroCMS and how to access it. For the most part configuration in PyroCMS works exactly the same as [](configuration in Laravel).

Accessing Configuration

You may easily access your configuration values using the global config helper function from anywhere in your application. The configuration values may be accessed using "dot" syntax, which includes the name of the file and option you wish to access. A default value may also be specified and will be returned if the configuration option does not exist:

$value = config('app.timezone');

To set configuration values at runtime, pass an array to the config helper:

config(['app.timezone' => 'America/Chicago']);

Streams Platform Configuration

The Streams Platform contains it's own configuration. You may easily access configuration values for the Streams Platform just the same as you would any other configuration. Configuration values for the Streams Platform have a streams:: prefix:

$value = config('streams::locales.default');

To set configuration values at runtime, pass an array to the config helper:

config(['streams::assets.paths.my_path' => 'my/example/path']);

Publishing streams configuration

In order to configure the Streams Platform without modifying core files you will need to publish the Streams Platform with the following command:

 php artisan streams:publish

You can then find the Streams Platform configuration files in resources/{application}/streams/config.

Addon Configuration

Addons contain their own configuration. You may easily access configuration values for addons just the same as you would any other configuration. Configuration values for addons have a vendor.type.slug:: prefix based on their dot namespace:

$value = config('anomaly.module.users::config.login');

To set configuration values at runtime, pass an array to the config helper:

config(['anomaly.module.users::config.login' => 'username']);

Publishing addon configuration

In order to configure addons without modifying core files you will need to publish the addon with the following command:

 php artisan addon:publish vendor.type.slug

You can then find the addon configuration files in resources/{application}/{vendor}/{slug}-{type}/config.

Errors & Logging

When you start a new PyroCMS project, error and exception handling is already configured for you through Laravel's default provisions.

For logging, Laravel utilizes the Monolog library, which provides support for a variety of powerful log handlers. Laravel configures several of these handlers for you, allowing you to choose between a single log file, rotating log files, or writing error information to the system log.


This section will describe how to configure error logging for Pyro.

Error Detail

The debug option in your config/app.php configuration file determines how much information about an error is actually displayed to the user. By default, this option is set to respect the value of the APP_DEBUG environment variable, which is stored in your .env file.

For local development, you should set the APP_DEBUG environment variable to true. In your production environment, this value should always be false. If the value is set to true in production, you risk exposing sensitive configuration values to your application's end users.

Log Storage

Out of the box, PyroCMS supports writing log information exactly like Laravel. You can write to single files, daily files, the syslog, and the errorlog. To configure which storage mechanism Laravel uses, you should modify the log option in your config/app.php configuration file. For example, if you wish to use daily log files instead of a single file, you should set the log value in your app configuration file to daily:

'log' => 'daily'

Maximum Daily Log Files

When using the daily log mode, PyroCMS will only retain five days of log files by default. If you want to adjust the number of retained files, you may add a log_max_files configuration value to your app configuration file:

'log_max_files' => 30

Log Severity Levels

When using Monolog, log messages may have different levels of severity. By default, PyroCMS writes all log levels to storage. However, in your production environment, you may wish to configure the minimum severity that should be logged by adding the log_level option to your app.php configuration file.

Once this option has been configured, Laravel will log all levels greater than or equal to the specified severity. For example, a default log_level of error will log error, critical, alert, and emergency messages:

'log_level' => env('APP_LOG_LEVEL', 'error'),

Monolog recognizes the following severity levels - from least severe to most severe:

  • debug
  • info
  • notice
  • warning
  • error
  • critical
  • alert
  • emergency

Custom Exceptions

By default PyroCMS load the corresponding view from the Streams Platform matching the error code thrown when debugging is disabled.

For example if the system throws a 500 error and is not in debug mode then the streams::errors/500 view will be loaded.

You can override these views a few different ways.

Publishing Streams Views

You can publish the entire Streams Platform resources by running the following command:

php artisan streams:publish

You can then customize the resources/views/errors views to accommodate your needs.

Overriding from your theme

Your theme can override views manually and automatically. To automatically override error views in your theme simply create / copy the error views from Streams Platform to resources/views/streams/errors.

Defining theme overrides

Lastly you can define view overrides manually within your theme class by defining the $overrides property:

protected $overrides = [
    'streams::errors/500' => 'example.theme.test::custom/errors/500',
Pro Tip: You can override any view in the same fashion as above.