When you need to build a website, there are quite a few things that need to be considered. Some of them are more abstract, like how you're going to market the site, and some are more technical. In this article you'll be learning about one of the technical aspects of using a CMS for your website: versioning it with Git.
When using a headless CMS like Strapi, it can quickly become a confusing task to version it properly. How does it handle changes? How can you collaborate with others using common workflows? How does it handle different environments?
Let's dive in and answer those questions.
When you want to use a CMS with Git, you first need to decide what workflow you want to use. There are a few different workflows typically used in engineering teams. You can have a single main
branch, which everyone commits to. This is typically how most Git beginners start, but it's not widely used; you can easily end up with conflicts and a main
branch that's filled with bugs.
There are three workflows that you'll typically find used in production:
GitHub flow is what you'll find in most open-source projects, and for good reason. It strikes a balance between being easy to follow but allowing for code reviews before merging into main
. Essentially, you create a branch where you make changes to the code. This can either be a feature, a hotfix, a bug, or something else. When you want the code merged, you open a pull request that gets reviewed and merged if approved.
Then you have Gitflow. It's an extension to GitHub flow in a sense, even though it was developed a year before. Instead of merging directly into main
, you first merge into a develop
branch. When you're ready to release a new version, you merge develop
into main
—as a result, main
always contains the latest version of your code.
Feature branching is the last one, and it's seeing less and less use. While it's a solid workflow, it creates a lot of overhead. You create a branch for a feature, work on that feature, and create a pull request when the feature is ready. But because a feature can take weeks or months to develop, merging can be a daunting task.
For these reasons, you'll be using GitHub flow while going through this article. It strikes a great balance between being easy to work with while providing a solid history and easy collaboration.
You've now decided on the workflow you want to use, and it's time to get started with the application itself.
First, you need to make sure that you've installed the latest version of NPM. You can do this easily by utilizing the nvm tool. Once you've got NPM installed, make sure you have npx
by running npm install -g npx
.
Now it’s time to create the app. Run the following command, replacing strapi-workflow
with the name of your app, or use the same name if you're just following along.
Note: If you’d rather just follow along without creating the app yourself, here is a GitHub repo with the finished code.
$ npx create-strapi-app strapi-workflow
When running the command, you'll have to go through a few prompts. The first is choosing whether you want a quickstart installation or a custom one. For this tutorial, you can choose quickstart. You can read more about the installation process here.
After choosing quickstart, you're asked if you want to choose templates. Going for a simple installation here, press Enter to say yes. Finally, you need to choose what template you want, and if you're following along with this tutorial, choose Blog. Wait a minute or two, and your Strapi app is up and running!
A new tab should open in your browser automatically. If not, go to http://localhost:1337/admin
. This is where you'll find the admin panel. Here you'll be prompted to make an administrator account for your app, as you can see below.
Fill in your details and click Let's Start to enter your Dashboard. At this point, you should be making your first commit to your Git project. You can do this in your terminal by placing your shell in the folder of the project, and entering the following commands:
$ git init && \
git add . && \
git commit -m 'Initial Commit'
Now that you've got the application set up, it's time to learn how it all fits together with Git. While Strapi does store all data in a database, whether that be a local SQLite or a hosted MySQL solution, there are many things you can configure in code—like when you're making a new route for your frontend to use.
All routes are saved as files, meaning it's easy to version! Let's take a look at how this works in practice.
Open up your Strapi Dashboard. In the sidebar under Plugins, click Content-Types Builder. Here you can create various things, including new collection types
. A collection type
in Strapi is one of the ways you can create routes for your API.
Click + Create new collection type and follow these steps:
restaurant
as Display name.name
as Name.description
as Name.Strapi will restart the server because it’s updating your files and creating new routes.
You can see that changes have been made by writing git status
in your terminal. You can see the changes by writing git add . && git diff main
(or master
if that's your default branch). You’ll note that a bunch of different files has been added.
If you go to http://localhost:1337/restaurants
, you can see that the route has been created. Right now it will give you a 403 error because you haven't made the route publicly accessible. Fixing permissions is not the focus of this article, but you can see the solution by following the official starter guide here.
Now it's easy to collaborate with your team members, as you can simply open a pull request with the changes, and they can be reviewed. An example of this can be seen here.
Another example of how this approach works well in a Git scenario is when you want to work with multiple different environments. While it's possible to set your environment based on environment variables, Strapi enables you to create configuration files for each environment.
To do this you need to create files following the ./config/env/{env}/{filename}
structure, for example, ./config/env/production/server.js
. When starting Strapi, you need to set the correct variable for the file it should use, like so:
NODE_ENV=production npm run start
An example of where this can be relevant is the IP that you're binding Strapi to when starting. By default the host is set to 0.0.0.0
, meaning that any host will be able to access it.
This may be what you want when deploying to production, but perhaps you only want your own machine to be able to access your development environment when working on it. This can be achieved by making the following change to ./config/server.js
:
1module.exports = ({ env }) => ({
2 host: env('HOST', '127.0.0.1'),
3 ...
4});
And then creating ./config/env/production/server.js
with the following contents:
1module.exports = ({ env }) => ({
2 host: env('HOST', '0.0.0.0'),
3});
You can read more about this functionality here.
Now you know more about how you and your team can start working with Strapi, and how it can easily integrate with a typical Git workflow, whether that be using GitHub flow as in this article, or something else.
Changes in Strapi are written as normal JSON and JavaScript files, making it easy to version just like anything you would write yourself. That can’t be said for many other CMSes, which will typically be using some form of proprietary structure.
As a DevOps enthusiast and general lover of learning, Kasper is used to working with a variety of exciting technologies, from automating simple tasks to CI/CD to Docker.