Testing and deploying TYPO3 using GitLab, GitLab CI, Capistrano and TYPO3 Console
In this article, I’ll show you how to setup automated testing and continuous deployment of a TYPO3 website using GitLab , GitLab CI, Capistrano and TYPO3 Console. The main purpose of the article is to give you a _ starting point_ for automated testing and continuous deployment.
With the setup described in this article, I want to make sure, that
- tests are executed automatically on every commit
- pushes to master branch will automatically be deployed to the production server
- deployment will only execute, when tests pass
I tried to keep write the article as simple as possible, so please note, that some features / processes of real life automated deployment scenarios are not covered.
Prerequisites:
- A composer based TYPO3 website with a basic site package
- At least one TYPO3 extension with tests
- A working GitLab server (I’m using an own instance of the Community Edition)
- A GitLab CI runner
- A SSH account on the webspace, where you want the TYPO3 website to be deployed
- Ruby version 1.9.3 or newer on your local machine (required for capistrano)
GitLab.com offers free private repositories and also access to GitLab CI runners, so I’m pretty sure, that the setup I described here may even work using the GitLab.com infrastructure.
1. Structure of the composer based TYPO3 website
The TYPO3 website used for this blogpost is a really simple composer based TYPO3 website. It contains a sitepackage with TypoScript and a Fluid template and it contains the TYPO3 extension sf_yubikey, which is used in this example to execute some unit tests. Also the TYPO3 website contains the TYPO3 extension typo3_console, which will be used in the deployment process.
Unit tests can be executed on CLI with the command shown below:
My composer.json file contains the following contents:
Note, that I use helhum/typo3-console (not from TER), which on install makes the typo3cms command available in the _ vendor/bin_ directory.
The TYPO3 installation also contains a backend user named _cli_lowlevel, which is required to execute CLI commands.
2. Move all sensitive data and local settings out of the LocalConfiguration.php
You should never commit any sensitive data (like passwords or API keys) to a Git repository, so I move those settings out of from LocalConfiguration.php to the file AdditionalConfiguration.php, which also is located in the typo3conf/ folder.
The local AdditionalConfiguration.php file used in this blogpost looks like shown below:
Besides all sensitive data from the LocalConfiguration.php, the AdditionalConfiguration.php file should include all settings, that should not be shared across deployment stages.
3. Modify the default .gitignore, so some TYPO3 directories will not be included in the git repository
For the TYPO3 website in this blogpost, I extended the default .gitignore file, so contents of some TYPO3 directories and files do not get committed to the git repository (e.g. fileadmin, uploads or all extensions installed by composer)
4. Commit the TYPO3 website to a git repository
The .gitignore file is ready, so now I create a new git repository and add / commit all files to it. Finally, I create a new project on the GitLab server and add the repository as a remote for the local git repository and finally push the repository to the remote.
5. Configure deployment of TYPO3 website with capistrano
5.1 SSH setup for deployment to webserver
First, I add my public SSH RSA key to the .ssh/authorized_keys file in the home-directory of the SSH user on the webserver, so I’m able to login by using SSH key authentication. This step is not required, but makes deployment from my local machine to the webserver easier.
Next I create a new SSH RSA key on the webserver (like shown here), so the SSH user will be able to pull from the remote git repository on the GitLab server I created in step 4. This SSH RSA Key will be the deployment key and must not contain a password.
The new SSH public key must now be added to the git repository on the GitLab server. In order to do so, I add it as Deployment Key for the project (see screenshot below)
5.2 Initialize and configure capistrano
I have chosen capistrano as the deployment tool for the TYPO3 website, because it is well documented, has a large user base and is easy to use/extend. If you do not like capistrano, it should be easy to replace capistrano with the deployment tool of your choice (e.g. TYPO3 surf, Deployer, Magallanes, …)
In the project root of my local composer based TYPO3 website, I now initialize a new capistrano config with the following command:
First of all, I remove everything in the file config/deploy/production.rb and add the following content:
Next, I create a really basic deployment in config/deploy.rb, which mainly executes composer install and executes some TYPO3 tasks using TYPO3 console.
You may note the file AdditionalConfiguration.php in the linked_files section of the deployment configuration. This is required in order to get TYPO3 running, when I’m doing a deployment from my local machine.
The linked_dirs section contains the folders web/fileadmin and web/uploads, which I want to share across deployments, since users will upload files to it.
5.3 Manual steps before first deployment
Before the first deployment can be executed, there are some steps, that need to be done manually on the webserver.
5.3.1 Initial shared folder setup
I copy the contents of the directories fileadmin/ and uploads/ from my local TYPO3 website to the directory ** shared/web** in the deployment path (see “deploy_to” in the deploy.rb file). The final directory structure is as shown below (Note: .htaccess files are not shown).
The shared folder does also contains the typo3conf/ directory, where I add the AdditionalConfiguration.php and modify the settings (e.g. database credentials, GraphicsMagick path, …) to match the server configuration.
5.3.2 Initial database setup
Since there is no initial TYPO3 database on the webserver, I create a local dump of the TYPO3 database and restore it to the remote database on the webserver.
5.4 Initial deployment
Now it is time to do the first deployment form my local machine, so I execute the deployment with the following command
Capistrano now executes the deployment and after finishing, I have a fully working copy of my local TYPO3 website on the remote webserver.
Capistrano creates the directories current/, releases/, repo/ and shared/. The current version of the deployed TYPO3 website is available in the current/ directory, so I adjusted the webserver to load the website from that directory.
5.5 Commit deployment configuration
Finally I commit the deployment configuration to the git repository, so it later can be used for the automated deployment.
6. Configure automated test execution on GitLab server
In an automated deployment process, you need to make sure, that only working versions of your website will be deployed to the production server. In this example, I simply run the unit tests of a TYPO3 extension to demonstrate, how automatic test execution can be a part of a deployment process. In real life scenarios, you can for example use unit, functional or acceptance tests to make sure, that your website will run smoothly after deployment.
In my local project, I create the file .gitlab-ci.yml and add the following contents to it:
I add and commit the file to the git repository and push the changes to the remote. Now GitLab CI will start a PHP 7.0 docker container, install all dependencies and finally run the configured unit tests.
Nice, the build passed….
…and unit tests have been executed on the GitLab CI runner.
You may notice, that the build took 3:16 minutes to finish, which is pretty long just for unit test execution. To reduce the build time, I suggest to create your own docker image with all dependencies included.
If you want to receive e-mail notifications on builds (or only for failed builds), you can enable this feature in the service section of the GitLab project.
7. Configure automated deployment on GitLab server
As a final step, I want to automate the deployment of the website, when commits are made to the master branch and if tests passed. Since the GitLab CI runner will do the deployment, it must be able to SSH to the production website.
I create a new SSH RSA key (with no password), which will be used for the deployment from the GitLab CI runner to the production webserver. After adding the SSH public key to the ssh/authorized_keys file of the SSH user on the webserver, I create a new variable in the GitLab project and add the new private key to it.
Next, I extend the .gitlab-ci.yml to use the SSH_PRIVATE_KEY variable in the docker container, that will do the deployment. Detailed instructions can be found in the GitLab CI documentation. The final configuration file looks like shown below:
Since capistrano is a ruby application, I use a docker container with ruby for the deployment.
Finally, after committing the changes to the repository, the GitLab CI runner runs the build and deploys the TYPO3 website to the production server.
And that’s it, the automated testing and continuous deployment setup for TYPO3 is up and running.
Outlook and conclusion
There are for sure some things that can be improved in the process I described in this post. For example, you could also add the AdditionalConfiguration.php file as a secret variable to the GitLab project and use the GitLab CI Mutli-Runner to deploy it to the production server. Also you can automate TYPO3 related tasks using TYPO3 console (e.g. database updates on new extension installation with typo3cms database:updateschema, update reference index, …).
I hope the post will give you a good point of how/where to start with automating tests and continuous deployment of a TYPO3 website. The shown technique is just one way of how to setup and automate the process - feel free to build your own configuration with the tools of your choice and please share your knowledge :-)