Three steps to configure the deployment process:
- Create an empty Git repo on the server
- Write a Git Hook to deploy the code
- Deploy from the local computer
On the remote server
Add two files project-create.sh and project-delete.sh to /www directory
project-create.sh:
#!/bin/bash
# source: https://gist.github.com/francoisromain/58cabf43c2977e48ef0804848dee46c3
# and another script to delete the directories created by this script
# project-delete.sh: https://gist.github.com/francoisromain/e28069c18ebe8f3244f8e4bf2af6b2cb
# Call this file with `bash ./project-create.sh project-name [service-name]`
# - project-name is mandatory
# - service-name is optional
# This will creates 4 directories and a git `post-receive` hook.
# The 4 directories are:
# - $GIT: a git repo
# - $TMP: a temporary directory for deployment
# - $WWW: a directory for the actual production files
# - $ENV: a directory for the env variables
# When you push your code to the git repo,
# the `post-receive` hook will deploy the code
# in the $TMP directory, then copy it to $WWW.
DIR_TMP="/var/tmp/"
DIR_WWW="/var/www/"
DIR_GIT="/var/git/"
DIR_ENV="/var/env/"
DIR_HTML="/public_html"
if [ $# -eq 0 ]; then
echo 'No project name provided (mandatory)'
exit 1
else
echo "- Project name:" "$1"
fi
if [ -z "$2" ]; then
echo '- Service name (optional): not provided'
GIT=$DIR_GIT$1.git
TMP=$DIR_TMP$1
WWW=$DIR_WWW$1$DIR_HTML
ENV=$DIR_ENV$1
# Create $WWW parent directory
sudo mkdir -p "$DIR_WWW$1$DIR_HTML"
cd "$DIR_WWW"
sudo chown -R www-data:www-data "$1"
sudo chmod -R g+rwX "$1"
else
echo "- Service name (optional):" "$2"
GIT=$DIR_GIT$1.$2.git
TMP=$DIR_TMP$1.$2
WWW=$DIR_WWW$1$DIR_HTML/$2
ENV=$DIR_ENV$1/$2
fi
echo "- git:" "$GIT"
echo "- tmp:" "$TMP"
echo "- www:" "$WWW"
echo "- env:" "$ENV"
export GIT
export TMP
export WWW
export ENV
# Create a directory for the env repository
sudo mkdir -p "$ENV"
cd "$ENV" || exit
sudo touch .env
# Create a directory for the git repository
sudo mkdir -p "$GIT"
cd "$GIT" || exit
# Init the repo as an empty git repository
sudo git init --bare
# Define group recursively to "www-data", on the directories
sudo chgrp -R www-data .
# Define permissions recursively, on the sub-directories
# g = group, + add rights, r = read, w = write, X = directories only
# . = curent directory as a reference
sudo chmod -R g+rwX .
# Sets the setgid bit on all the directories
# https://www.gnu.org/software/coreutils/manual/html_node/Directory-Setuid-and-Setgid.html
sudo find . -type d -exec chmod g+s '{}' +
# Make the directory a shared repo
sudo git config core.sharedRepository group
cd hooks || exit
# create a post-receive file
sudo tee post-receive <<EOF
#!/bin/bash
# The production directory
WWW="${WWW}"
# A temporary directory for deployment
TMP="${TMP}"
# The Git repo
GIT="${GIT}"
# The Env repo
ENV="${ENV}"
# Deploy the content to the temporary directory
mkdir -p \$TMP
git --work-tree=\$TMP --git-dir=\$GIT checkout -f
# Copy the env variable to the temporary directory
cp -a \$ENV/. \$TMP
# Do stuffs, like npm install
cd \$TMP || exit
# Replace the content of the production directory
# with the temporary directory
cd / || exit
rm -rf \$WWW
mv \$TMP \$WWW
# Do stuff like starting docker
cd \$WWW || exit
# docker-compose up -d --build
EOF
# make it executable
sudo chmod +x post-receive
Above is an edited copy made for my server.
Gist: https://gist.github.com/francoisromain/58cabf43c2977e48ef0804848dee46c3
project-delete.sh:
#!/bin/bash
# source: https://gist.github.com/francoisromain/e28069c18ebe8f3244f8e4bf2af6b2cb
# and another script to create the directories deleted by this script
# project-create.sh: https://gist.github.com/francoisromain/58cabf43c2977e48ef0804848dee46c3
# Call this file with `bash ./project-delete.sh project-name [service-name]`
# - project-name is mandatory
# - service-name is optional
# This will delete 4 directories
# - $GIT: a git repo
# - $TMP: a temporary directory for deployment
# - $WWW: a directory for the actual production files
# - $ENV: a directory for the env variables
DIR_TMP="/var/tmp/"
DIR_WWW="/var/www/"
DIR_GIT="/var/git/"
DIR_ENV="/var/env/"
function dir_delete() {
sudo rm -rf "$1"
}
if [ $# -eq 0 ]; then
echo 'No project name provided (mandatory)'
exit 1
else
echo "- Project name:" "$1"
fi
if [ -z "$2" ]; then
echo '- Service name (optional): not provided'
GIT=$DIR_GIT$1.git
TMP=$DIR_TMP$1
WWW=$DIR_WWW$1
ENV=$DIR_ENV$1
else
echo "- Service name (optional):" "$2"
GIT=$DIR_GIT$1.$2.git
TMP=$DIR_TMP$1.$2
WWW=$DIR_WWW$1/$2
ENV=$DIR_ENV$1/$2
fi
echo "- git:" "$GIT"
echo "- tmp:" "$TMP"
echo "- www:" "$WWW"
echo "- env:" "$ENV"
dir_delete "$GIT"
dir_delete "$ENV"
dir_delete "$WWW"
dir_delete "$TMP"
Gist: https://gist.github.com/francoisromain/e28069c18ebe8f3244f8e4bf2af6b2cb
Update both files to be unix encoded:
dos2unix /var/www/project-create.sh
dos2unix /var/www/project-delete.sh
Before executing the file, lets check a few things.
Check members of group www-data:
grep 'www-data' /etc/group
If user you’ll use on Git (the ssh key you need to load) is not part of group, then add like this:
usermod -a -G www-data christine
Create a new project on the server:
bash /var/www/project-create.sh <your-project>
Change the directory owner and group (having chris as the user breaks keeps christine user blocked out):
sudo chown www-data:www-data /var/www
On your local computer
In Bitbucket create a new repo as usual. Clone it to a new project folder under sites. Add a test file and commit it.
Open the Git terminal now and write this:
# Add your server as a Git remote called 'deploy'
git remote add deploy ssh://christine@35.192.41.230/var/git/<your-project>.git/
# Push your code and deploy
git push deploy master
Change remote url if things changed:
git remote set-url deploy ssh://chris@35.192.41.230/var/git/<your-project>.git/
git remote set-url deploy https://github.com/USERNAME/REPOSITORY.git
Add SSH key to Git
# Lists already added identities (‘ssh keys’)
ssh-add -l
#Run SSH Agent
eval `ssh-agent -s`
# Add a new identity (you'll see name of file when you showed the list)
ssh-add ~/.ssh/id_rsa
#Password is 57575757aA
Open id_rsa.pub under C:\Users\Christine.ssh. Check Google Compute under Metadata to see if this SSH key has been added already.
Note: Trying to load ppk files didn’t work.. I’d create new ones and I couldn’t get past the password when trying to add them to Git. Think Git will only accept id_rsa.
Getting error:
Okay now Git says its moved but I don’t see that on the server!!
Look into these:
https://help.github.com/en/articles/changing-a-remotes-url