- Created with simplicity and ease of use in mind, inspired by magento cloud pipeline
- Emphasis on zero downtime during deployment, must have at least 2 nodes for this
- Separate root to build application changes without affecting mage root
- State checking flow for optimized build of pipeline/server/application related changes
- Simple deploy summary for pipeline/server/application section in tabular format during each deployment
- Support to sync nginx, php, logrotate and magento env changes directly from repository to golden server
- Composer auto update flow when last update run exceeds 30 days during deployment even without any changes
- Patches install complete flow to auto apply, revert and delete relevant changes
- Aws cli integration to create image, update launch configuration and start/wait for instance refresh
- Part of static
pub/static
on efs causes massively slow static deployment so it should not been kept on efs - Part of static
var/view_preprocessed
will be on efs due to entirevar
being efs, so custom configuration will be done later on to remedy massively slow static deployment - Part of static
pub/static/_cache
should for now be in efs as it generates only on demand and not sharing it breaks layout static cache bug - Crontab for
root
andubuntu
user will be auto deleted on auto scaling nodes to avoid conflicting cron runs, this effectively allows golden server to be also used as a dedicated cron server. It is achieved using launch configuration user data. - Logrotate config has
*.cfsaved
extenstion so regular cron skips it and we can define custom schedule usingroot
user'scrontab
as required
# Magento log rotation
45 20 * * * /usr/sbin/logrotate /etc/logrotate.d/magento.cfsaved -s /var/lib/logrotate/magento.status
- Project sequence diagram
- Pre-Requistices
- Configure repository and user for deployment
- Configure gitlab server
- Configure golden server
- Usage of pipeline and extra information
- Proper credentals/vpn to ssh into staging/production ec2 servers
- Magento 2 existing project installed and running on staging/production ec2 server
- These folders mounted on efs
app/etc
,var
andpub/media
in ec2 server mage root - All services endpoint accessible from staging/production ec2 server
- Proper credentals to ssh into gitlab hosted server
- Gitlab installed/running, magento repository configured in gitlab and two gitlab shell runner configured
- Access to all relevant aws credentals and aws cli installed and configured in gitlab/staging/production server
- Ssl configured using
ssl termination
externally from loadbalancer side
- Clone this repository in your pc and cd into it
- Follow steps below to configure repository for existing and cloud
- Follow steps below to configure a new new user for deployment
- Add the config samples to your existing magento repository, replace
$path_to_your_project
with your project path
cp .gitlab-ci.yml.dis $path_to_your_project/.gitlab-ci.yml
cp .gitignore.dis $path_to_your_project/.gitignore
cp .rsyncignore.dis $path_to_your_project/.rsyncignore
cp -r .ec2.dis $path_to_your_project/.ec2
- Modify
.gitignore
file as needed .ec2/shared
has config samples which will be shared between staging/production, modify as needed- The php logs path has been modified to
/var/log/php/php*.log
, recommended to do similar in your server php fpm config .ec2/production
has config samples for production only, replace$domain_name
with your domain name in file names and file contents- Replace all
$variable
in.ec2/production/magento/env.php
file with production services information .ec2/staging
has config samples for staging only, replace$domain_name
with your domain name in file names and file contents- Replace all
$variable
in.ec2/staging/magento/env.php
file with staging services information - Commit changes and push to your existing magento respository, pipeline will be skipped as it's restricted to specefic branches.
- Create a new repository preferably with
cloud
suffix to your existing repository name, examplecompany-magento-cloud
- Delete default
master
branch and create two new branches asstaging
andproduction
- Clone your updated existing magento repository into these two new branches
- Keep
production
branch as default/protected,staging
branch can be left unprotected to allow force pushes - Restrict the two gitlab runner created to this project and add
production
in tags to one andstaging
in tags to another - Configure production gitlab runner to only run on pipelines triggered on protected branches for security
- Create a new user in gitlab with username
deployer
and fullname preferably asAws Cloud
- Give this user access to the new repository created for cloud
- Create two ssh keypair and add the public keys to
ssh keys
in user setting namedec2 production
andec2 staging
- Copy the private key of ssh kepair to respective ec2 production/staging server
~/.ssh
folder and rename asgitlab
- The deployer user and keypair will later be used for paswordless git operations over ssh.
- Follow steps below to configure gitlab-runner user, ssh and this repository
- Setup a password for
gitlab-runner
user and add it tosudo
group, all operations in gitlab server will use this user by default - Login into gitlab server using
gitlab-runner
user and created password - Copy your vpn file to
/etc/openvpn/client
and add this entry in sudoders file for passwordless commands for openvpn
# Passwordless sudo commands
gitlab-runner ALL=NOPASSWD: /usr/sbin/openvpn, /usr/bin/pkill
- Create a ssh
config
file in~/.ssh
and add these entries, replace$host_ip
with ssh ip of each servers and$key_name
with key name
Host production_golden
User ubuntu
HostName $host_ip
IdentityFile ~/.ssh/$key_name.pem
Host staging_golden
User ubuntu
HostName $host_ip
IdentityFile ~/.ssh/$key_name.pem
- Start the vpn using
sudo openvpn $cloud_aws
and make sure vpn is connected and did not require sudo password - Ssh into each of the ssh alias created above manually firstime to cache the fingerprint, replace
$ssh_alias_name
with host alias from above
ssh $ssh_alias_name
- Once ssh into every server is working and cached, close the vpn using
sudo pkill openvpn
and make sure it did not require sudo password
- Clone this repository in home folder of user
- Add some variables in
/etc/environment
for pipeline commands alias, replace$vpn_name
with your own
# Aws Openvpn config
cloud_aws="--config /etc/openvpn/client/$vpn_name.ovpn"
# Root path
scripts_root="/home/gitlab-runner/gitlab-aws-magento2-deploy/scripts/gitlab"
- Cd into
$scripts_root
and create two .env file for staging and production from sample env file
cp -a .env.dis .env.prod
cp -a .env.dis .env.stag
- Edit each of the
.env
file and addproduction
orstaging
aws related details
- Redo these steps for each golden server
production
andstaging
- Follow steps below to configure mage/build root and ssh and this repository
- Checkout the specefic instance branch
production
/staging
from the repository created for cloud in yourmage root
- Create an additional local only deploy branch named
deploy
in yourmage root
which will allow build stage to be retryed with changes - Create a ssh
config
file in~/.ssh
and add these entry, replace$gitlab_domain
with your own,$host_ip
with it's ip and$key_name
with key name
Host $gitlab_domain
HostName $host_ip
IdentityFile ~/.ssh/$key_name.pem
- Cd into your current
mage root
and change the git remote to ssh one instead of https, now all git commands should work through ssh - Create a new folder in
/var/www/html
asbuild
and copy over.git
and.gitignore
from mage root - Run
composer install
inbuild
folder to install all packages, make sureconfig.php
is also present inapp/etc
if not already - Magento build operations can be done without any services connection so
env.php
is not required inapp/etc
- Create a symbolic link for
view_preprocessed
outsidevar
to non-efs folder inbuild
folder
rm -rf var/view_preprocessed
mkdir -p symlinks/view_preprocessed
cd var && ln -snf ../symlinks/view_preprocessed .
- Modify
pub/index.php
section to use customview_preprocessed
as follows
$tmpMaterializationDir = dirname(__DIR__, 1).'/symlinks/view_preprocessed/pub/static';
$params = $_SERVER;
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive(
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? [],
[
DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
DirectoryList::TMP_MATERIALIZATION_DIR => [DirectoryList::PATH => $tmpMaterializationDir]
]
);
- Remove these files from current
mage root
, they can be left undeleted but serves no purpose in this pipeline frommage root
rm -r .ec2 .git .gitignore .gitlab-ci.yml
- Rsync your
build root
changes tomage root
sudo rsync -a --exclude-from=".rsyncignore" $build_root/ . --delete
- Since
var
andsymlinks
is skipped for rsync, create a symbolic link forview_preprocessed
outsidevar
to non-efs folder inmage root
as well
rm -rf var/view_preprocessed
mkdir -p symlinks/view_preprocessed
cd var && ln -snf ../symlinks/view_preprocessed .
- Clone this repositrory in home folder of user
- Add some variables in
/etc/environment
for pipeline commands alias, replace$domain_name
with your project domain name
# Root path
mage_root="/var/www/html/$domain_name"
build_root="/var/www/html/build"
scripts_root="/home/ubuntu/gitlab-aws-magento2-deploy/scripts/ec2"
- Cd into
$scripts_root
and create two .env file for staging and production from sample env file
cp -a .env.dis .env.prod
cp -a .env.dis .env.stag
- Edit each of the
.env
file and addproduction
orstaging
aws/magento related details
- After setting up everything from previous steps, make some changes in previous already existing repository, commit and push changes
- Clone the new repository for cloud in seperate isolated folder and pull changes of previous repository in one of the branches preferably
staging
- Push the changes to relevant branch, the pipeline should trigger, run it's operations and complete if everything was setup up properly
- Symbolic linked
view_preprocessed
invar
will be used bystatic deployment
command while modifiedview_preprocessed
inpub/index.php
will be used bynginx
- Admin configuration
Enable Symlinks
does not need to be enabled, it's only needed for read operations while write operations can be done safetly with this disabled - To force application build even without changes use the web ui
run pipeline
and setFORCE_APPLICATION_BUILD
to1
or set this variable to1
during git push
git push origin $branch_name -o ci.variable="FORCE_APPLICATION_BUILD=1"