Also see: https://gist.github.com/lemiorhan/8912188
Here are the simple steps needed to push your local git repository directly to a remote (e.g. prod) server over ssh. This is based on Digital Ocean's Tutorial.
You are developing in a working-directory on your local machine, let's say on the master
branch. Usually people push code to a remote
server like github.com or gitlab.com and pull or export it to a production server. Or you use GitHub's webhooks to send a POST request to a webserver to take appropriate actions such as cloning/checking out a branch on the remote (prod) server.
But here you could simply use a bare
git repository on the production server and publish a branch of your choice (e.g. master
) directly to that server. This remote repo on the server acts upon the push event using a 'git hook' (in this case, the post-receive
git hook) to put the files into a deployment directory on your server. No need for any intermediary such as GitHub.
This creates a scenario where there is no middle-man, high security with encrypted communication (using ssh keys, only authorized people get access to the server) and high flexibility from using a shell script (in the post-receive
hook) for the deployment.
- Know how to use GIT, ssh etc.
- Have a local working-directory ready to deploy, with AT LEAST 2 commits in the
git log
. - Have SSH access to your server using private/public key
-
Have the local workspace dir ready to deploy
-
Create a directory on your remote server to receive the deployment (e.g.
/var/www/html
) -
Add a bare git repository on the remote server
-
Add the
post-receive
hook (shell script) to the bare repository, make it executable -
Add the remote-repository as a 'git remote' to your local git repository
-
Push to the production server, relax.
Nuf said. I assume we are working on master – but you could work on any branch. Ensure there are at least 2 commits.
ssh into your remote (e.g. production) server.
We'll assume that your username is webuser
on server.com
and you access it (for "security-through-obscurity" reasons) over port 234 instead of the usual 22:
$ ssh [email protected] -p234
$ mkdir ~/deploy-dir
(Note: If you ssh in over the default ssh port of 22
, then you can also just use the regular ssh [email protected]
instead of ssh [email protected] -p22
, but let's assume you use port 234
)
Now we'll create a "bare" git repository – one that does not contain any working copy files. It only has the contents of the .git
directory in a normal working copy such as refs
, hooks
, branches
etc. Call it whatever you like, but for our purposes, let's call it bare-project.git
:
$ git init --bare ~/bare-project.git
The post-receive
hook is a shell script that is executed when the push from the local machine has been received. We will write this script so that it deploys the files into required deployment directory (~/deploy-dir
in this example). The post-receive
file is located at this path: ~/bare-project.git/hooks/post-receive
. It must be named exactly as post-receive. Normally, it is not present by default, so use a text editor such as vim
to create and edit it.
The script we will use does check if the correct branch is being pushed (it won't deploy a develop
branch, e.g.)
See the post-receive file for details.
Ensure it is executable: chmod a+x ~/bare-project.git/hooks/post-receive
Now we'll add the bare repository (on the remote server) to your local system as a 'git remote'. For this example, prod
is what we'll call this remote. This could also be called "staging" or "live" or "test" etc if you want to deploy to a different system or multiple systems.
$ cd ~/path/to/working-copy/on-your-local-system/
# assuming you ssh over port 234 instead of 22,
# otherwise if you use the default port (22), you can just omit the `:234` part of the following url:
$ git remote add prod ssh://[email protected]:234/home/webuser/bare-project.git
Make sure bare-project.git
corresponds to the name of the bare repo you used in step 3.
Now you can push the master branch to the remote server:
$ git push prod master
That's it.
You should see something like:
$ git push prod master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 948 bytes | 948.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Ref refs/heads/master received. Deploying master branch on server...
remote: Already on 'master'
To ssh://[email protected]:234/home/webuser/bare-project.git
d2b8c82..ac8be14 master -> master
If you pushed a "bad" deployment to the remote server and need to roll it back, fret not! It's easy to roll-back to an earlier, "good" commit using a forced push:
# on your local machine
# assuming that HEAD~1 is the commit you want to roll-back to
$ git reset --hard HEAD~1 # or git revert if you prefer that
# force push to the remote server
$ git push -f prod master
@shanerigsby The attached script dont have any build process included. You can include build commands like
npm build
accordingly and the command would still work as expected. Just need to make sure that your target machine have node and other necessary packages installed. One thing to note is these commands will be run asgit
user so make sure thatgit
user has the necessary access to run these commands :)