Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@rajeshisnepali rajeshisnepali commented Feb 28, 2019

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

This comment has been minimized.

Copy link

@Cogitri 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

This comment has been minimized.

Copy link

@jonaswebdev jonaswebdev commented Apr 2, 2019

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

This comment has been minimized.

Copy link

@jonaswebdev jonaswebdev commented Apr 11, 2019

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

@francoisromain

This comment has been minimized.

Copy link
Owner Author

@francoisromain francoisromain commented May 8, 2019

@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

This comment has been minimized.

Copy link

@ddacunha 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

This comment has been minimized.

Copy link
Owner Author

@francoisromain 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

This comment has been minimized.

Copy link

@palansher palansher commented May 1, 2020

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

@nrjdalal

This comment has been minimized.

Copy link

@nrjdalal nrjdalal commented May 23, 2020

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

This comment has been minimized.

Copy link
Owner Author

@francoisromain francoisromain commented Jul 8, 2020

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

@palansher

This comment has been minimized.

Copy link

@palansher palansher commented Jul 8, 2020

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

This comment has been minimized.

Copy link

@jdmacdiarmid jdmacdiarmid commented Oct 21, 2020

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