Skip to content

Instantly share code, notes, and snippets.

@francoisromain
Last active February 16, 2024 15:08
Show Gist options
  • Star 59 You must be signed in to star a gist
  • Fork 35 You must be signed in to fork a gist
  • Save francoisromain/58cabf43c2977e48ef0804848dee46c3 to your computer and use it in GitHub Desktop.
Save francoisromain/58cabf43c2977e48ef0804848dee46c3 to your computer and use it in GitHub Desktop.
A bash script to create a Git post-receive hook to deploy after a Git push
#!/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`
# - project-name is mandatory
# 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="/srv/tmp/"
DIR_WWW="/srv/www/"
DIR_GIT="/srv/git/"
DIR_ENV="/srv/env/"
if [ $# -eq 0 ]; then
echo 'No project name provided (mandatory)'
exit 1
else
echo "- Project name:" "$1"
fi
GIT=$DIR_GIT$1.git
TMP=$DIR_TMP$1
WWW=$DIR_WWW$1
ENV=$DIR_ENV$1
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 "users", on the directories
sudo chgrp -R users .
# 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
sudo touch post-receive
# 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
@rajeshisnepali
Copy link

Why did you create DIR_WWW="/srv/www/"? I've nginx server and the default location is in /var/www/html.

Will my project run when I install my project in /srv/www location?

@Cogitri
Copy link

Cogitri commented Mar 1, 2019

Why did you create DIR_WWW="/srv/www/"? I've nginx server and the default location is in */var/www/html.

Changing that is one a matter of setting root correctly, see http://nginx.org/en/docs/beginners_guide.html

@jonaswebdev
Copy link

I got an error on the git push from my local machine, the directory "ENV" no was created via script, so I created manually and worked... it's ok?

@jonaswebdev
Copy link

Nevermind, I adapted this script to my use, thanks for sharing :)

@francoisromain
Copy link
Author

@rajeshisnepali @Cogitri @jonaswebdev sorry I didn't receive any notification. I just saw your comments now.
@jonaswebdev you're right, it was missing the block to add the env directory. I just fixed it

@ddacunha
Copy link

ddacunha commented Jul 4, 2019

May I suggest that the URL of this gist be added inside the script for credit and future references?

@francoisromain
Copy link
Author

francoisromain commented Jul 4, 2019

@ddacunha good idea. done! I also add a link to project-delete.sh to undo what this script is doing.

@palansher
Copy link

Hello!
Understood nothing.. you made function dir_create() and never used it in your script. What a purpose of that?

@nrjdalal
Copy link

I've created an easy to understand script for SSH live deployment to my Siteground server. You guys can check it out and do manual edits as per your needs.
https://github.com/nrjdalal/ssh-git-connect

@francoisromain
Copy link
Author

@palansher you're perfectly right. I updated the gist to remove the unused method.

@palansher
Copy link

I've created an easy to understand script for SSH live deployment to my Siteground server. You guys can check it out and do manual edits as per your needs.
https://github.com/nrjdalal/ssh-git-connect
page 404

@jdmacdiarmid
Copy link

I'm currently using SiteGround. Is there a way to configure this for a shared host account? I want to set up my site on a subdomain. When I log into the backend using ssh, I get dropped into the home folder for "baseos | @SiteGround". In this folder, I have access to 2 folders: tmp and www. There are other domains and subdomains in the www folder. I was reading the artcle at . If I create a separate staging subdomain to push changes then copy the files from staging to the production subdomain, would that work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment