A Git Development Environment
Installing and using Git for Drupal and WordPress site development using Ubuntu/Mint and a Hostgator Reseller or VPS account.
By: Andrew Tuline Date: February 7, 2014 Version: 2.0.0
Revisions ... 4
1. Quick Git ... 5
1. Introduction ... 5
2. Conventions ... 5
2. Let’s Get Started ... 6
3. Installing Git ... 6
4. Basic Configuration ... 6
5. Git Repositories ... 6
6. Single User ... 8
7. Gitk ... 8
8. Simple Daily workflow in a non-bare repository ... 10
9. File Status... 11
10. Setup - Cloning From Bare Repository ... 12
11. Setup - Adding to a Bare Repository ... 14
12. Using .gitignore ... 16
13. Apache and Git Directory Structure in Ubuntu ... 17
14. Prior to Downloading Projects ... Error! Bookmark not defined. 15. Downloading Projects From GitHub ... 19
16. Downloading Drupal from GitHub ... 19
17. A Drupal .gitignore ... 21
3. Public Git Repositories ... 26
1. Using bitbucket.org as your master ... 26
2. Using github.com as your master ... 27
4. Sites and Site Components ... 29
5. Site Deployment and Migration ... 31
1. Introduction to Deployment and Migration ... 31
2. Adding a Staging Server ... 31
3. Shell Script Tools ... 32
4. A Simple Deployment ... 36
5. Fix Serialization ... 40
6. Restricting Access to Staging Server ... 42
7. General Site Migration Tips ... 43
8. WordPress Site Migration ... 43
9. Drupal Site Migration ... 43
10. Gitflow ... 44
Revisions
1.04 Long standing combined Development and Git version (in serious need of significant changes).
1. Quick Git
1. Introduction
Git is quickly becoming the version control backbone of team based web site development. This document covers initial configuration of Git and builds upon that in order to develop a basic distributed workflow for WordPress and Drupal. It is not, however, a comprehensive guide to using Git.
To learn more about Git, http://sixrevisions.com/resources/git-tutorials-beginners.
2. Conventions
2. Let’s Get Started
3. Installing Git
On your Ubuntu workstation, if you haven’t already done so, Git can be installed by typing:
dev$ sudo
apt-get
install
git
4. Basic Configuration
Prior to using Git, you should setup your name and email address similar to:
dev$ git
config
--global user.name
"Joe
Blow"
dev$ git
config
--global user.email
"[email protected]"
Review your Git identity and configuration with:
dev$ git
config
-l
# lower case ‘L’
5. Git Repositories
Repository Description
Local repository It’s located on your workstation. Remote repository It’s located elsewhere.
Non-bare repository The repository includes the files you’re working on.
Bare repository The repository has no working files in the directory, just blobs and things you shouldn’t edit.
For a single user environment, you could create a local non-bare repository and just use that for web development. For an open source or distributed environment, you will be using a remote bare repository (preferably on github.com or bitbucket.org) as well as a non-bare local repository for each developer.
For a single user environment, you can create a non-bare local repository by typing:
dev$ cd
~
dev$ git
init
nonbare
dev$ cd
nonbare
dev$ ls
-al
The above command creates a non-bare repository in that the working files are in the ‘nonbare’ directory, while the Git repository is in a
hidden ‘.git’ directory beneath it. This configuration is fine for local use, however, you cannot use this as your ‘Master’ repository in a distributed environment.
You can create a bare/master repository by typing:
dev$ cd
~
dev$ git
init
--bare
barerepo
dev$ cd
barerepo
dev$ ls
-al
This is a completely different directory structure, and you will not see any of your working files here. This could even be the central repository that your team w pull from and push back to. Don’t create files in this directory.
Most web developers work remotely at some point and will need to access the main repository from a remote location. As a result, the master repository should be stored on on a host such as GitHub or BitBucket. DIY’ers could even install their own web enabled Git Hosting with Gitlab locally or on their Hostgator VPS.
6. Single User
In a single user environment, we’ve created a non-bare repository. We can now add files to this directory, and once done, you need to add and commit those updates:
dev$ cd
~/nonbare
dev$ touch
test.txt
dev$ git
add
.
# ‘.’ refers to all files
dev$ git
commit
-m
"Initial commit."
To check the status of the repository:
dev$ git
status
dev# On branch master
nothing to commit (working directory clean)
7. Gitk
dev$ sudo
apt-get
install
gitk
To run gitk, we need to ‘cd’ into a repository with a repository in it. Let’s look at our previous non-bare repository:
dev$ cd
~/nonbare
dev$ gitk
# you must exit before getting the prompt back
or
8. Simple Daily workflow in a non-bare repository
From the previous chapter, we created a non-bare repository. Here’s a simple daily workflow for it:
dev$ cd
~/nonbare
dev$ git
checkout
-b
branch-name
# come up with a name, ‘-b’ creates a branch
DO SOME EDITS
dev$ git
add
.
dev$ git diff
# to see the changes vs previously committed files
dev$ git
commit
-m
"Detailed
message."
# you can go back for some more edits
AT THE END OF A WORK SESSION
dev$ cd ~/nonbare
dev$ git
checkout
master
dev$ git
merge
branch-name
# merge those changes
dev$ git log
dev$ git status
dev$ git
branch
-d
branch-name
# you can then delete that temporary branch
Perform adds/commits in small chunks. At the end of a session, you can then checkout the master and perform a merge. To review the various versions of the repository, type:
dev$ git
log
commit
d7ec9a
9129719759797923742397239472394729
Author: Joe Blow [email protected]
Date: Mon Jan 14 14:03:16 2013 -0800
Added text to a file.
commit cf23669a92948298474297423974239742397423
Author: Joe Blow [email protected]
Date: Mon Jan 14 14:03:16 2013 -0800
Initial commit.
If, for any reason, you have made a mistake in your working files, you can revert back to a previous version with:
dev$ git
reset
--hard
d7ec9a
# use the first several digits of a previous commit hash
OR
dev$ git
reset
--hard
HEAD~
# to go back to the previous commit
Note: We will be using this simple workflow a lot in our upcoming examples.
9. File Status
File Status Description
Untracked You have created a file in your non-bare working directory. Staged/Tracked That file is now tracked via the Git 'add' command.
Committed/Tracked That file has now been committed to the repository with the Git 'commit' command. This is a good place to be.
Not Staged/Tracked A previously tracked file has been further edited, but not re-added or committed.
Once you have performed a successful commit to the non-bare repository, you should see:
dev$ git
status
dev# On branch master
# or branch-name
nothing to commit
# working directory clean
10.
Setup - Cloning From Bare Repository
The following section sets up your environment by first create a bare repository and then cloning it to a working/non-bare repository.
dev$ cd
~
dev$ rm -rf barerepo
# delete our previous repo
dev$ git init --bare barerepo
dev$ cd ~
dev$ rm -rf myproject
dev$ git
clone
barerepo
myproject
# 'myproject' is now a non-bare repository
Cloning into 'myproject'…
warning: You appear to have cloned an empty repository.
done.
dev$ cd
myproject
dev$ touch
text.txt
dev$ git
add
.
dev$ git
commit
-m
"Initial
commit."
dev$ git
push -u origin master
# can do just a 'git push' after first time
At any time, you can check the status of your repository and see the results of your actions with the following commands:
dev$ git
status
dev$ git
log
dev$ gitk
# if you have it installed
Tip: It's important that you pull from the bare repository at the start of your work session and push it back when done. Let’s have a look at the modified daily workflow now that we’re using a non-bare repository:
dev$ cd
~/myproject
dev$ git
pull
dev$ git
checkout
-b
branch-name
#create a branch
dev$ git
add
.
dev$ git diff
dev$ git
commit
-m
"Detailed
message."
# Repeat as required
AT THE END OF A WORK SESSION
dev$ git
checkout
master
dev$ git
merge
branch-name
dev$ git
push origin master
dev$ git log
dev$ git status
dev$ git
branch
-d
branch-name
# Delete the branch when done.
As a reminder, perform edits/adds/commits in small chunks. At the end of a session, you can then checkout the master and perform a merge.
11.
Setup - Adding to a Bare Repository
Rather than clone from a bare repository to start, let’s assume we already have some files and want to setup our repositories for them.
dev$ cd
~
dev$ rm -rf barerepo
# delete the old one, again
dev$ git init --bare barerepo
dev$ rm -rf myproject
# delete the old one
dev$ mkdir myproject
dev$ cd
myproject
dev$ touch
text.txt
dev$ git init
dev$ git
add
.
dev$ git
commit
-m
"Initial
commit."
dev$ git
remote
add
origin
~/barerepo
# add our bare repository
dev$ git
push -u origin master
# only do this the first time
Again, at any time, you can check the status of your repository:
dev$ git
status
Reminder: Don’t forget to pull from the bare repository at the start of your work session and push it back when done.
Our daily workflow will be EXACTLY the same as before in that we: Pull the latest changes
Create a temporary branch Edit the files
Add/commit them Checkout the master Merge the changes Push the changes
12.
Using .gitignore
Sometimes, you will want to exclude various files in your Git respository. These could be log files or files that are unique to each server, such as site configuration files. In order to do so, let’s create a ‘.gitignore’ file on the development workstation:
dev$ cd ~myproject
dev$ vi .gitignore
It could contain:# Site configuration
*.log
.htaccess
Once complete, type:
dev$ git add .
dev$ git commit -m "Added .gitignore"
dev$ git push origin master
. . .
dev$ git status
From now on, any log files as well as the .htaccess file will not be incorporated into the Git repository. Many development houses use different .gitignore files. I’ll include some examples from Github later in the document, but look around the Internet to see what works for you.
13.
Apache and Git Directory Structure in Ubuntu
Let’s starting to develop a basic workflow in a real development directory as shown below:
Development Workstation
Directory Description
/var/www/client1.dev ~ directory for client1’s development tools in Ubuntu.
/var/www/client1.dev/www ~ directory for client1’s web site (Apache points here). It will be a non-bare repository.
~/git Interim home directory for our bare git repositories. We’ll eventually host this elsewhere.
~/git/client1.git Bare repository for client1.
From the previous document, we should not have to use ‘sudo’ in /var/www, as we have already set the permissions to allow the ‘www-data’ group to write to the directories, and have added ‘username’ to that www-data group. In addition, we have set the sticky bit so that the ‘www-data’ group will become the owner of any files/directories created beneath /var/www.
If they don’t already exist, create the git and client1 directories:
dev$ mkdir
/var/www/client1.dev
# development scripts for client1 go in here
dev$ mkdir
/var/www/client1.dev/www
# the actual web site goes here
dev$ cd
/var/www/client1.dev/www
dev$ touch index.html
# let’s create something first
dev$ git
init
# create a non-bare working repository
dev$ git add .
dev$ cd
~
dev$ mkdir
git
# make the git repositories directory
dev$ git
init
--bare ~/git/client1.git
# create a bare repository
dev$ cd
/var/www/client1.dev/www
dev$ git
remote
add
origin
~/git/client1.git
# add our bare repository
dev$ git
push -u origin master
We should already have an Apache host created for client1.dev. As a reminder:
dev$ sudo
vi
/etc/apache2/sites-enabled/client1.dev.conf
Add the following:
<VirtualHost
*:80>
DocumentRoot
"/var/www/client1.dev/www"
ServerName
client1.dev
ServerAlias www.client1.dev
</VirtualHost>
Edit /etc/hosts with vi and add:
dev$ sudo
/etc/init.d/apache2
restart
Your client1.dev web site should now have both a non-bare repository as well as a local bare repository and you can begin development. Don’t forget that you’ll be working in /var/www/client1.dev/www and pushing/pulling from the bare repository located at
~username/git/client1.git.
If you’re downloading Drupal or WordPress, you’ll need to clone it and then re-create your repositories. That’s coming up next.
14.
Downloading Projects From GitHub
Both Drupal and WordPress can be downloaded from a popular repository called GitHub. Rather than start a project from scratch, let’s download a baseline copy and develop our project from there.
In the previous example, we cloned a working directory from an empty bare repository, after which we could make our changes and then push them back.
In the case of Drupal or WordPress, we need to clone from GitHub, and then remove all ties from that source so we can use our own non-bare and bare repositories. For the first examples, we’ll do so on our development workstation. We’ll expand the scope later.
15.
Downloading Drupal from GitHub
The trick with downloading Drupal as well as WordPress from GitHub is that you’re not just downloading the latest version as you would a .zip file. Rather, you’re downloading the entire repository of versions. Let’s download Drupal and then checkout the latest version. Here’s a reference:
http://drupal.org/node/3060/git-instructions/7.x
dev$ rm -rf /var/www/client1.dev/www
# just to be safe
dev$ mkdir /var/www/client1.dev/www
dev$ cd
/var/www/client1.dev/www
dev$ git
clone --branch
7.x
http://git.drupal.org/project/drupal.git
.
# don’t forget the ' .'
OR
dev$ git clone --branch 7.x git://github.com/drupal/drupal.git .
dev$ ls
. . .
dev$ git
branch
-a
# list the branches
dev$ git
checkout
7.19
# or whatever the current release is
We then need to remove the links to GitHub and create our own repositories:
dev$ rm
-rf
.git
# Deletes Git along with everything else except 7.19
This leaves us with a pristine version of Drupal 7.19, and without any version control. Let’s create a non-bare repository for it in this directory, and then create and push it to bare repository as follows:
dev$ cd
~
dev$ rm
-rf
git/client1.git
# remove your old bare repository
dev$ git
init
--bare
git/client1.git
# create an empty bare repository
dev$ cd
/var/www/client1.dev/www
dev$ git
init
# create the non-bare repository
dev$ git
add
.
dev$ git
commit
-m
"Drupal 7.19 initial commit."
dev$ git
status
dev$ git remote add origin ~/git/client1.git
dev$ git push -u origin master
From here, you can now start on your daily workflow (see section Error! Reference source not found.). Note: You can also use ‘drush’ to download Drupal with the following command:
dev$ cd /var/www/client1.dev
dev$ rm -rf www
dev$ mkdir www
dev$ cd www
dev$ drush dl drupal
# which downloads the latest recommended release
# to a directory called drupal-7.19
$ shopt -s dotglob nullglob
# so we can include any hidden files during our mv
# just be careful not to move a .git directory to a non-repository
$ mv drupal-7.19/* .
# moves ALL files to current directory
$ rmdir drupal-7.19
At this point, you can create your database and go through the Drupal installation procedures. Once complete, you can then initialize your local repository.
16.
A Drupal .gitignore
# Ignore configuration files that may contain sensitive information.
sites/*/settings*.php
# Ignore paths that contain user-generated content.
sites/*/files
sites/*/private
.DS_Store
.cvs
*.sql
*.bak
*.swp
*.log
Thumbs.db
You might also want to look at https://github.com/github/gitignore/blob/master/Drupal.gitignore.
17.
Downloading WordPress
As with Drupal, when downloading WordPress from GitHub, you’re not just downloading the latest version as you would a .zip file. You’re downloading the entire repository of versions. In order to develop for a specific version, we need to do the following:
dev$ rm -rf /var/www/client1.dev/www
dev$ mkdir /var/www/client1.dev/www
dev$ cd
/var/www/client1.dev/www
dev$ git
clone http://github.com/WordPress/WordPress.git
.
# don’t forget the ' .'
dev$ ls
# you should see a bunch of WordPress files
Now we need to checkout the latest release of WordPress, in this case version 3.6.1:
dev$ git
branch
-a
# list branches
dev$ git
checkout
3.6.1
# checkout the latest
This leaves us with a pristine version of WordPress 3.6.1, and without any version control. As with Drupal, we could initialize our Git repositories, create the database and install WordPress on the Server.
18.
A WordPress .gitignore
There are numerous .gitignore configurations for WordPress; some include the WordPress core files and some don’t. Here’s one from github:
https://github.com/github/gitignore/blob/master/WordPress.gitignore
.htaccess
wp-config.php
wp-content/uploads/
wp-content/blogs.dir/
wp-content/upgrade/
wp-content/backup-db/
wp-content/advanced-cache.php
wp-content/wp-cache-config.php
sitemap.xml
*.log
wp-content/cache/
wp-content/backups/
sitemap.xml.gz
You might also want to look at http://www.stumiller.me/what-should-be-excluded-in-a-wordpress-gitignore-file/.
WordPress will create a .htaccess file if you change the Permalinks to ‘Post name’ on the wp-admin/options-permalink.php page. These .htaccess files may be slightly different between client1.dev and client1.mycompany.com, so this file has been added to the .gitignore file as well.
19.
Installing WordPress on Ubuntu
We’ve downloaded WordPress, but we haven’t actually ran the install scripts yet.
Go ahead and create a database on the Ubuntu server with either phpMyAdmin or in the terminal. Keep in mind that the database isn’t under version control and will eventually have to be put on the staging server.
Also, remember that your settings files will be located at:
/var/www/client1.dev/www/wp-config.php
This is important to keep in mind, because when you’re configuring WordPress on either your staging server (client1.mycompany.com) or your development workstation (client1.dev), the URL and database settings will be different. You will need to take this into account when using Git by using the .gitignore file as discussed later on.
Go ahead and run the WordPress installation by opening a browser in Ubuntu and typing (I assume you have already added an entry in the hosts table for it):
Here’s some insecure settings:
3. Public Git Repositories
Rather than host our bare master repository locally, we’re going to host it on a public server so that we can access it anywhere.
1. Using bitbucket.org as your master
You should consider using a host such as bitbucket.org or github.com for hosting your master repository. I’m using bitbucket.org, as they provide free hosting for private repositories as long the team has 5 or fewer members.
To do so, create an account on Bitbucket, add your SSH key from your development workstation and then create a bare repository called ‘Client1’.
On your development workstation, you should then be able to:
dev$ cd /var/www/client1.dev
dev$ rm -rf www
dev$ mkdir www
dev$ cd www
dev$ git init
dev$ touch index.html
dev$ git add index.html
dev$ git commit -m "Initial commit"
. . .
# and any other updates
dev$ git remote add origin ssh://[email protected]/mycompany/client1.git
# use SSH and not HTTPS
dev$ git push -u origin master
# initial push
dev$ git push origin master
# all further pushes
The advantages of using Bitbucket are that it provides a web front end to display the status of your repository. It gives you the option to provide an issue tracker and a wiki for your project. You can also share files with your clients.
Note: If you haven’t shared your Ubuntu SSH key, you can use HTTPS and then manually type in your username/password.
2. Using github.com as your master
You can use github.com for your master repository for no charge as long as it is a public repository. Once you have created an account, add your Ubuntu SSH key to github, then create an empty repository on github called client1.git. Then go to your development workstation and:
dev$ cd /var/www/client1.dev/www
dev$ git push -u origin master
# initial push
4. Sites and Site Components
Let’ recap the architecture we’re going to be using. In my Web Development Environment document, we have several servers as follows:
The challenge is that not all of the content will be the same on each. Let’s break this down into separate components and consider how we should manage and deploy them.
Sites www.bitbucket.org Git Repository Bare Repo client1.mycompany.com Staging Server DB client1.dev Devel Workstation Working Repo & Web Site DB www.client1.com Production Server DB Web Site Web Site
A public Git server (www.bitbucket.org) with a bare repository. 3 web sites, each with a database and files
The development workstation has a non-bare repository. Databases
The databases may contain URL’s and file paths unique to each server, which are easy to edit. WordPress databases contain serialized strings, which are not easy to edit.
We won’t include the database in the Git repository. It’s big and doesn’t fit nicely in there. Files
.htaccess may be unique to each server. .gitignore may be unique to each server.
settings.php and wp-config.php are unique to each server. Drupal and WordPress core files should NOT be edited/hacked. User uploaded content is often binary and LARGE.
There will be the core application files.
There will be new/modified themes which should be under version control.
There will be additional/modified modules/plugins which should be under version control. Git Repositories
Only your development environment should use a non-bare Git repository. Use a bare repository for the master repository.
5. Site Deployment and Migration
1. Introduction to Deployment and Migration
As I spent more time studying Git, site deployment and migration, I thought of different ways to do it. At one point, I had almost everything contained in the Git repository, including the database, and thought of using a Git hook to move everything over, including the database, however further reading deemed that not a good idea.
When I go back and think of why we’re using Git in the first place, it’s to track the functionality that we are modifying. Therefore, let’s limit our use of the Git repository as much as possible. When we go to deploy content to a staging or production server, rather than incorporate it into Git and use a ‘git push’ command to deploy content, we’ll use some form of file copy. In this case, we’ll use the the ‘rsync’ command over SSH.
2. Adding a Staging Server
The purpose of adding a staging server is to show your work in progress to your client, while still maintaining full control over it. To add our staging server client1.mycompany.com, we need to create that subdomain in CPanel. In doing so, it will the the ‘~mycompany/client1’ subdirectory. Select ‘Subdomains’:
From there, you should have a directory at ‘/home/mycompany/public_html/client1’ and when browsing to it with http://client1.mycompany.com, you should see:
3. Shell Script Tools
The following files can be downloaded from ‘github.com:atuline/migrate-scripts.git’.
Here’s a number of commands/shell scripts that should come in handy to support file and database migration to the staging server. I keep these in the ‘/var/www/client1.dev’ directory on the development workstation. They include:
copydb.sh Copy a previously dumped and edited .sql file from the development workstation to the staging server.
createdb.sh Create the database on the development workstation. createdb_stg.sh Create the database on the staging server.
dropdb.sh Delete the database on the development workstation. dropdb_stg.sh Delete the database on the staging server.
dumpdb.sh Dump the database on your development workstation to a .sql file. exclude.txt Contains list of files to exclude from the syncfiles.sh script. fix-serialization.php Called by replace.sh to fix serialization strings for a WordPress
database.
fixperms.sh Configures the file/directory permissions for Apache. importdb.sh Import a .sql file to the development workstation database. importdb_stg.sh Import a .sql file to the staging server database. The MySQL
username/password for that database must already exist.
infile.txt URL and directories to be modified when migrating a database from the development workstation to the staging server. It’s used by replace.sh
replace.sh Use this to change the text strings in your development workstation .sql file to that of the staging server. The contents of the existing .sql file will be changed.
syncfiles.sh Use the rsync command to synchronize/copy files from the development workstation to the staging server.
copydb.sh
createdb.sh
#!/bin/sh
mysql -uroot -ppassword "create database client1_dev";
mysql -uroot -ppassword "grant all on client1_dev.* to root@localhost";
createdb_stg.sh
#!/bin/sh
ssh www.mycompany.com.com 'mysql -e "create database mycompany_client1"'
ssh www.mycompany.com 'mysql -e "grant all on mycompany_client1.* to mycompany_client1"'
dropdb.sh
#!/bin/sh
mysqladmin -uroot -ppassword drop client1_dev;
dropdb_stg.sh
#!/bin/sh
ssh www.mycompany.com 'mysqladmin drop mycompany_client1'
dumpdb.sh
exclude.txt
.htaccess
.gitignore
fix-serialization.php
See the github.com source for this.
fixperms.sh
sudo find www -type f -exec chmod 0644 {} \;
sudo find www -type d -exec chmod 2755 {} \;
importdb.sh
#!/bin/sh
mysql -uroot -psierrasys8 client1_dev < client1_dev.sql;
importdb_stg.sh
#!/bin/sh
ssh www.mycompany.com 'mysql mycompany_client1 < /home/mycompany/mycompany_client1.sql'
infile.txt
/var/www/client1/www
/home/mycompany/public_html/client1
replace.sh
See the github.com source for this.
syncfiles.sh
#!/bin/sh
rsync -e 'ssh' -avl --delete --stats --progress --exclude-from '/var/www/client1.dev/exclude.txt'
/var/www/client1/dev/www
www.mycompany
.com:/home/mycompany/public_html/client1
This script copies the files from your development workstation to the staging server with the exeception of the excluded file(s). It uses less bandwidth than a regular ‘scp’ command and will delete files on the remote host if they are no longer in the source.
See: http://articles.slicehost.com/2007/10/9/backing-up-your-files-with-rsync
4. A Simple Deployment
The following section does the following:1. Create a simple site with a non-bare repository on our development workstation at client1.dev. 2. Create a bare master repository called client1.git on bitbucket.org.
3. Create a staging site at client1.mycompany.com.
4. Copy/migrate files and database to client1.mycompany.com.
Central Repository
Hostname bitbucket.org
Git repository name (bare) client1.git
Staging Server
Web hostname client1.mycompany.com
Web directory /home/mycompany/public_html/client1
Development Workstation
Hostname client1.dev
Tools directory /var/www/client1.dev
Git repository directory (non-bare) /var/www/client1.dev/www
Web directory /var/www/client1.dev/www
First, let’s create a simple development site and create a central repository as well as a live site.
dev$ cd /var/www
dev$ rm -rf client1.dev
dev$ mkdir client1.dev
# Our scripts go in here
dev$ mkdir www
# Actual site goes in here
dev$ cd www
dev$ git init
dev$ touch index.html
dev$ git add .
dev$ git commit -m "Initial commit."
# Our dev site is now set up
Let’s now create and push to our main repository at bitbucket.org and import our Ubuntu SSH key into the Bitbucket account. Then, click on the ‘Create’ button to create your ‘client1.git’ repository:
Now, let’s define and push to our master repository:
dev$ cd /var/www/client1.dev/www
dev$ git remote add origin ssh://[email protected]/mycompany/client1.git
dev$ git push -u origin master
# initial push
dev$ git push origin master
# all further pushes
We can pretty well duplicate these steps when creating the live server, so we won’t cover that here. Just give it another name in Git, such as ‘Live’.
But what about the actual staging server web site?
Rather than add the complexity of a Git repository to the staging server, we’ll use a combination of rsync and database scripts in order to update the staging server. Assuming the following:
WordPress is configured and running on the development workstation.
A database user is already configured on the staging server (via phpMyAdmin). Infile.txt is already configured with source/destination text strings.
I would edit for proper naming and use the following scripts (in order):
1. syncfiles.sh - to synchronize all of the files (they may require the group:file owner to be changed on the staging server). 2. dumpdb.sh - to dump the development workstation database to a .sql file.
3. replace.sh - to replace the development workstation URL’s and directories in the database with that of the staging server. 4. dropdb_stg.sh - to remove the outdated database on the staging server.
5. createdb_stg.sh - to create a new database on the staging server 6. copydb.sh - to copy the modified .sql file to the staging server.
7. importdb_stg.sh - to import the modified .sql file on the staging server.
If you get through the above section without any issues, I will be absolutely astounded.
If you had some problems, the next section provides additional background information.
5. Fix Serialization
Let’s look at content unique to the web server in WordPress, and possibly in Drupal if any content has been added.
Data Type Example String Changes Editing it
URL unique to the site client1.dev will be client1.mycompany.com Easy to change Path unique to the site /var/www/client1/www will be /home/mycompany/client1 Easy to change Serialized strings s:11:"client1.dev" will be s:21:"client1.mycompany.com" Difficult to change
I’m going to use a modified copy of ‘Fix-Serialization’ originally from https://github.com/Blogestudio/Fix-Serialization as it doesn’t require you to be running WordPress to perform the database conversion. Fix-Serialization is a combination shell and PHP script which takes a database dump file and:
Changes source URL and directory structure strings to destination URL and directory structures. Fixes any serialized strings that have changed.
Files included:
infile.txt (contains source and destination URL's and directory structures)
replace.sh (run this shell script to swap strings and to call the PHP script)
fix-serialization.txt (a descriptive file)
fix-serialization.php (PHP script to perform serialization fixes)
How to use:
Put a dump of your WordPress database in the current directory, i.e (dumpdb.sh):
mysqldump -uroot -pmypassword client1_dev > client1_dev.sql
Create/modify infile.txt with your source and destination information similar to this:
www.client1.dev
client1.mycompany.com
/var/www/client1/www
/home/mycompany/public_html/client1
Execute the script as follows:
dev$ cd /var/www/client1
# put it in the client1 tools directory
. . .
# dump your database to this directory
dev$ sh replace.sh
# replaces current .sql file with a modified version
https://github.com/azizur/wordpress-oneclick-migration
http://interconnectit.com/products/search-and-replace-for-wordpress-databases/ (a standalone php script) http://wordpress.org/extend/plugins/wp-migrate-db/ (a WordPress module)
http://ithemes.com/purchase/backupbuddy/ (an awesome WordPress plugin) https://github.com/interconnectit/Search-Replace-DB
6. Restricting Access to Staging Server
You might want to modify the .htaccess file on your Hostgator staging server so that visitors must enter a password to view that web site. In order to do so, you’ll require two files. They are:
.htaccess (this may already already exist!)
.htpasswd
In your .htaccess file, add:
AuthType Basic
AuthName "Restricted access"
AuthUserFile /home/mycompany/client1/.htpasswd
# change as appropriate of course
require valid-user
Place your .htpasswd file in the full path of your ‘~’ directory at Hostgator, typically ‘/home/mycompany’. Both files should be set with permissions of 644.
In your .htpasswd file, you’ll need to create a username and password. The password needs to be generated, so see
7. General Site Migration Tips
When migrating your site between hosts, you should take into account:
Keep your account information organized. This includes development, staging, Git and production host names, usernames, password, database names, directories, Drupal/Wordpress usernames and passwords and setting files. Don’t forget domain registrar information, expiry and client contact information as well.
There may be .htaccess, .gitignore and settings file differences between hosts. Changing URL entries in the databases (edit the database dump file).
There may be references to a different directory structure, such as /home/client1 instead of /var/www/client1/www.
WordPress may require you to edit serialized objects, in which case, use a 3rd
party database migration utility. URL and database configuration settings in the site configuration files.
You may also need to change privileges/ownership of directories and files when you migrate files between hosts. There may be different php configurations and versions. Run phpinfo();.
Put site specific files in .gitignore.
Don’t put a .git directory in public_html on a public server.
8. WordPress Site Migration
Changing the site URL in WordPress can be challenging. Follow this URL from the WordPress Codex.
http://codex.wordpress.org/Changing_The_Site_URL
Essentially, you need to edit wp-config.php and change the URL’s. Then there’s the database changes, which we have already covered.
9. Drupal Site Migration
Modifying Drupal to support another URL seems a lot easier than with WordPress. http://drupal.org/node/171998.
Optionally modify the $base_url in sites/default/settings.php. Clear the drupal cache.
10.
Gitflow
Once you have a basic workflow and deployment in place, you’ll want to think about long term use of Git. The following link provides some more in depth examples of developing a more comprehensive Git workflow:
6. Conclusion
Between these two documents, you should have a good idea on how to: 1. setup a LAMP server
2. setup and develop in a Git environment 3. deploy to a staging (or other) server
There are a lot of different methods you can use to accomplish these goals, so feel free to use these as a starting point for your own site development.