Auto deployment with Git and Rails, How does it wo

2019-05-14 14:54发布

I have a Git repository in bitbucket and another on my live rails server, How can I make it so whenever i push to bitbucket it, the live server pull it from bitbucket as well?

I found this snippet online, and i put it on my live server's git hooks as post-receive, but i don't know what to do next:

#!/bin/sh
name=$1
if [ -z "$name" ] ; then
        echo "need to give name of checkout dir on command line"
        exit 1
fi

dir=/srv/web/$name
if [ ! -d $dir ] ; then
        echo "the directory $dir does not exist"
        exit 1
fi

cd $dir
env -i git pull
rake db:migrate
touch $dir/tmp/restart.txt

Can anyone point out what should i do to make this happen? I've seen post hooks on bitbucket (similar to github) but i'm not sure what to do.

2条回答
成全新的幸福
2楼-- · 2019-05-14 15:25

Analysis

BitBucket has a number of service hooks, but none of the ones I've used are explicitly for triggering deployment scripts. You could role your own using the BitBucket broker API, but this is generally not the right thing to do.

The received wisdom is to use deployment scripts from continuous integration, so that you're only deploying successful builds. Note that I said "deploying," not "pushing," because you can't push to a repository with a working tree.

However, it's certainly possible to trigger a Rails update without continuous integration, post-receive hooks, or deployment tools such as Capistrano. Polling is one alternative.

Solution

While a post-receive or service hook can trigger an arbitrary action on commits, the simplest thing to do is just to poll Git from your web server. For example, you could run a cron job every minute to pull the current master branch into a working tree under your web root.

First, install and test your polling script. I generally use a variation of this:

#!/bin/bash
# Script:
#     git_poll.sh <appname>
# Purpose:
#     Poll your Rails repository for changes.

set -e

WEBROOT='/var/www'
MY_RAILS_APPNAME="$1"
shift

# Use the flock(1) utility to guard against long-running fetch or merge
# operations using the flock(2) system call. On Debian-based systems,
# this tool is found in the util-linux package.
(
    flock -n 9 

    cd "$WEBROOT/$MY_RAILS_APPNAME"
    git fetch origin master

    # Check if heads point to the same commit.
    if ! cmp --quiet <(git rev-parse master) <(git rev-parse origin/master)
    then
        git pull --force origin master
        touch "$WEBROOT/$MY_RAILS_APPNAME/tmp/restart.txt"
    fi
) 9> "/var/lock/polling4${MY_RAILS_APPNAME}"

This script assumes you're using Phusion Passenger. If you're using something else, you may need to modify the script to take some other action after Git pulls from the remote repository.

Next, make sure the script is executable. chmod 755 /usr/local/bin/git_poll.sh should do it.

Finally, update your Rails user or system crontab with something similar to the following:

* * * * * /usr/local/bin/git_poll.sh example_app

Since we're using exclusive locking in the script, polling every minute should be fine. If you don't use locking, or want to reduce load on your systems, then set a longer polling interval in your crontab.

That's it! Now when you push to origin from development or QA, your Rails server should update itself within a minute or so. That's usually sufficient for most purposes, and hopefully yours as well.

查看更多
你好瞎i
3楼-- · 2019-05-14 15:30

If you want things to happen when you push to bitbucket i think you need to use their brokers support somehow. Maybe post the updated refs to some service on your server that pull, resets etc.

But if you push directly to your own server you can use the standard git post-receive hook.

查看更多
登录 后发表回答