Now, instead of pushing changes to the system, let's build a distributed system; where runners push successfully tested changes to special Git branches; and environments pulls changes from its respective Git.
We'll just use the Prod environment. Let's set up the deploy-to-prod job to push to the "prod" branch in Git; and let's set up the Prod environment to pull from the "prod" branch (while development continues on the "master" branch).
Addition of feature 'b' triggers CI/CD
\
a---b---c---d branch 'master'
|
v
branch 'prod'
CI/CD pushes 'b' code to 'prod' branch
Let's initialize the "prod" branch and ensure Prod can pull from it.
Initialize "prod" branch (off "master"):
sudo su - gitlab-runner
GIT_SSH_COMMAND="ssh -i ~gitlab-runner/.ssh/push_to_git" git clone [email protected]:root/www.git
cd www
git checkout -b prod
GIT_SSH_COMMAND="ssh -i ~gitlab-runner/.ssh/push_to_git" git push origin prod
cd ..
rm -rf www
exit
Check that Prod can pull from "prod" branch:
sudo su - root -c "GIT_SSH_COMMAND='ssh -i ~/.ssh/pull_from_git' git archive [email protected]:root/www.git prod | tar -t"
You should see the list of file in the "prod" branch:
ubuntu@ip-172-31-23-12:~$ sudo su - root -c "GIT_SSH_COMMAND='ssh -i ~root/.ssh/pull_from_git' git archive [email protected]:root/www.git prod | tar -t"
.gitlab-ci.yml
Hello.php
HelloTest.php
README.md
index.php
ubuntu@ip-172-31-23-12:~$
Go ahead and install the files once manually, just to make sure it all works:
sudo su - root -c 'GIT_SSH_COMMAND="ssh -i ~root/.ssh/pull_from_git" git archive [email protected]:root/www.git prod | tar -xv -C /var/www/prod-html --exclude=.gitlab-ci.yml'
Example output:
ubuntu@ip-172-31-23-12:~$ sudo su - root -c 'GIT_SSH_COMMAND="ssh -i ~root/.ssh/pull_from_git" git archive [email protected]:root/www.git prod | tar -xv -C /var/www/prod-html --exclude=.gitlab-ci.yml'
Hello.php
HelloTest.php
README.md
index.php
ubuntu@ip-172-31-23-12:~$
Set up Production environment to track the "prod" branch with a root
cron job:
echo '* * * * * root GIT_SSH_COMMAND="ssh -i ~root/.ssh/pull_from_git" git archive [email protected]:root/www.git prod 2>/dev/null| tar -xv -C /var/www/prod-html --exclude=.gitlab-ci.yml 2>/dev/null' | sudo tee -a /etc/crontab
-
You may want to look into a tool like dpl which can deploy to a wide variety of service providers.
-
The way CFEngine's contrib/masterfiles-stage.sh handles Git is, it stages the changes in a side directory, validates them, and then does the tablecloth pull trick where it swaps out the old content and swaps in the new (with two back-to-back calls to
mv
) so you never get half old and half new. -
Next best thing after that is instantiating a new environment with the new code.