DEV Community 👩‍💻👨‍💻

Matthias Andrasch
Matthias Andrasch

Posted on

Separate content from config in Statamic

Before we continue with the deployment, we need to make some adjustments. As stated before, my goal is to separate content from config as much as possible. Therefore I will not rely on Statamics Git Automation. Let's see how far I can push this as a Statamic newbie!

🚧 This article is work in progress. 🚧

Technical approach

My approach: User editable content (markdown files, media assets in content/) should only be stored on the production server, they shouldn't be tracked in the git repository.

Only configuration files should be tracked and pushed via git, always from local to production in a one-way-street.

I don't want to handle git merge conflicts on a live server. I simply don't ;-)

Update: I found out that CraftCMS described the approach perfectly in the CraftCMS deployments docs. This is the approach I would love to implement in Statamic:

Screenshot CraftCMS Docs Deployment, linked below

Screenshot CraftCMS Docs allowAdminChanges, linked below

But how do we get the production content data to the local development environment to play and develop with it? I'll use use DDEVs pull feature and get the content via SSH/rsync from the production server later in this series.

Change storage of collection definitions

Usually the collection yaml definitions are stored in content/collections next to the markdown files. But we can change this. We need to change content/collections to resources/collections in config/stache.php, these are the important lines:

'collections' => [
            'class' => Stores\CollectionsStore::class,
            'directory' => base_path('resources/collections'),
        ],
Enter fullscreen mode Exit fullscreen mode

The full config/stache.php file:

<?php

use Statamic\Stache\Stores;

return [

    /*
    |--------------------------------------------------------------------------
    | File Watcher
    |--------------------------------------------------------------------------
    |
    | File changes will be noticed and data will be updated accordingly.
    | This can be disabled to reduce overhead, but you will need to
    | either update the cache manually or use the Control Panel.
    |
    */

    'watcher' => env('STATAMIC_STACHE_WATCHER', true),

    /*
    |--------------------------------------------------------------------------
    | Stores
    |--------------------------------------------------------------------------
    |
    | Here you may configure the stores that are used inside the Stache.
    |
    | https://statamic.dev/stache#stores
    |
    */

    // separate collections from entries
    'stores' => [

        'collections' => [
            'class' => Stores\CollectionsStore::class,
            'directory' => base_path('resources/collections'),
        ],

        'entries' => [
            'class' => Stores\EntriesStore::class,
            'directory' => base_path('content/collections'),
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Indexes
    |--------------------------------------------------------------------------
    |
    | Here you may define any additional indexes that will be inherited
    | by each store in the Stache. You may also define indexes on a
    | per-store level by adding an "indexes" key to its config.
    |
    */

    'indexes' => [
        //
    ],

    /*
    |--------------------------------------------------------------------------
    | Locking
    |--------------------------------------------------------------------------
    |
    | In order to prevent concurrent requests from updating the Stache at
    | the same and wasting resources, it will be "locked" so subsequent
    | requests will have to wait until the first has been completed.
    |
    | https://statamic.dev/stache#locks
    |
    */

    'lock' => [
        'enabled' => true,
        'timeout' => 30,
    ],

];
Enter fullscreen mode Exit fullscreen mode

Afterwards you need to move content/collections/pages.yaml to resources/collections/pages.yaml.

And we need to remove and add the content/-directory to .gitignore:

# add to .gitignore:
/content
Enter fullscreen mode Exit fullscreen mode

Since these files are already tracked, we need to remove the whole folder from the project and commit these git changes.

ddev exec rm -rf content/
Enter fullscreen mode Exit fullscreen mode

The missing piece: Permissions based on environment

To avoid confusion it shouldn't be possible to edit configuration things in the control panel on production sites.
This should only be done in the local dev environment and then be committed from there to the git repository.

Screenshot of edit collection menu item

See this twitter discussion for the current state. I guess I need to implement different permission sets for the local as well as the production site. 🤔

I opened a GitHub discussion about this:
Implement a config option like "allowAdminChanges" - override permissions dynamically based on APP_ENV? #6289

Disclaimer: I'm a Statamic newbie, maybe they are some more challenges to this approach.

Acknowledgements

Thanks very much to Jonas Siewertsen for helpful advice on twitter. He also held a great talk about zero-downtime deployment and offers statamictutorials.com for free. Thanks so much!

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.