Skip to content

Commit

Permalink
Latest and Greatest additions to deploy-site
Browse files Browse the repository at this point in the history
1. Added --no-backup switch
2. Added PORT variable to allow specifying non-standard/special ssh
   ports for your git repository server.
3. Added Apache performance enhancing capabilites (NOTE: Requires
   modifying Apache configuration as outline in the README file.)
4. Miscellaneous other improvements relating to destination file
   permissions, owner/group and acl's.
  • Loading branch information
John W Smith committed Apr 10, 2013
1 parent ef3b7a7 commit 2d15238
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 29 deletions.
49 changes: 40 additions & 9 deletions README.md
Expand Up @@ -21,24 +21,55 @@ Each deploy also creates a database backup. The backups are stored as `/var/dbba

## Server-side configuration

Running `deploy-site` is automatically setup to use the hostname of the Ubuntu server to locate the matching the repository on Github. Hostnames and repositories are standardized by customer.
Running `deploy-site` is automatically setup to use the hostname of the Ubuntu server to locate the matching repository on Github. Hostnames and repositories are standardized by customer.

Take the Big Tube Company as an example, a fictional company. They host their website at http://bigtubeco.com. Their staging and test site FQDN are staging.bigtubeco.com and test.bigtubeco.com. The hostname of their production Ubuntu VM would be named `bigtubeco`, the staging server hostname `bigtubeco-staging`, and test is `bigtubeco-test`.

Continuing the naming scheme, create a Github repository with a complete installation of Drupal 7 in the root of a repository named `bigtubeco`. The name of the organization or the origination of a specific user do not matter since `deploy-site` treats users, their forks, and organizations the same.
Continuing the naming scheme, create a Github repository with a complete installation of Drupal 7 in the root of a repository named `bigtubeco`. The name of the organization or the origination of a specific user does not matter since `deploy-site` treats users, their forks, and organizations the same.

Users are not supposed to login to the Ubuntu server using a shared account; each user should have their own login credentials and can be managed by a service like winbind or centrify.
Users are not supposed to login to the Ubuntu server using a shared account; each user should have their own login credentials and can be managed by a service like winbind, Centrify or Likewise.

The default `/var/www` directory is where `deploy-site` will attempt to deploy files and keep them owned by the www-data user. Users should be granted access to read and write to `/var/www` with filesystem-level ACLs. Users who are all members of a developers group could be granted access with the following:
The default `/var/www` directory is where `deploy-site` will attempt to deploy files and set appropriate owner, group, filesystem permissions and acl's. In our environment, this means owner/group would be www-data, and then we would apply ACL's to allow Developers, Domain Admins and any other AD Group users as required. Users should be granted access to read and write to `/var/www` with filesystem-level ACLs. Example, users who are members of a developers group could be granted access with the following:

```
setfacl -m g:developers:7 /var/www
setfacl -m d:g:developers:7 /var/www
setfacl -R -m g:developers:7 /var/www
setfacl -R -m d:g:developers:7 /var/www
setfacl -R -m g:developers:rwx,d:g:developers:rwx /var/www
```

If you have enough people for role separation, developers would not be granted access to login to or deploy code to the live virtual machine.
If you have enough people for role separation, developers would not be granted access to log on or deploy code to the live systems.

**UPDATE: 04-09-2013**

Recent editions to the deploy site script require a few changes to Apache to fully reap the benefits of the additions, and should increase Apache's performance.

First you will need to modify the default site file (assuming your setup is 1 web site per VM). Change all occurences of "AllowOverride ??????" to be "AllowOverride None". Next, below the <Directory /var/www> ... </Directory> configuration block, add the line "Include htaccess.d/". What you should end up with is something like this:

```
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
<Files ~ "^install.php">
Order deny,allow
Deny from all
</Files>
</Directory>
Include htaccess.d/
```

**__NOTE__**: The above is only a portion of the actual configuration file.

In order to implement the above changes, Apache MUST be restarted. However, if we do this now, our Drupal installation will be broken, as NO .htaccess files will be loaded on access to the site. If we now run the deploy-site script, it will finish up appropriate configuration by adding Includes for each .htaccess file it finds during the deploy to the /etc/apache2/htaccess.d/htaccess.conf file. It will also take care of restarting apache after the new configuration file has been generated.

A new --no-backup switch has also been added. This switch does exactly what it implies, NO database backup will be created prior to deploying the new code. We DO NOT recommend using this switch on your production server! Switch was implemented to shorten the deployment times developers were seeing when deploying test branches of the code, in this situation backups might not be required, or make sense.

A new variable was added to allow special/non-standard ports to be used for your github host. When setting this variable, be sure to include the colon at the beginning (ex: PORT=":7999") would be used for the default configuration if you are using Atlassian's Stash product as your git repository server.

## Client-side configuration

Expand Down
74 changes: 54 additions & 20 deletions deploy-site
Expand Up @@ -5,11 +5,14 @@ SCRIPT=$(basename ${0});
REPOSITORY=$(hostname | cut -d'-' -f 1)
HOSTNAME=$(hostname)
DEFAULTORG="development"
DEFAULTSERVER="github.com"
DEFAULTENVIRON="live"
DOMAIN=$(dnsdomainname)
USERNAME=$(whoami)

###### Destination Server Configuration
DEFAULTSERVER="github.com"
PORT="" ##### Custom ssh ports must include colon (ex. PORT=":7999")

USAGE=$(cat <<EOF_USAGE
USAGE: ${SCRIPT} <options>
Expand All @@ -20,12 +23,13 @@ The following options are supported:
--branch [branch to deploy] : No Default, must specify.
--deployed : Lists information about the currently
: deployed tag for the current server.
--no-backup : Skips creating DB Backup (Not recommended)
--org [org in github] : Defaults to "${DEFAULTORG}".
--repo [name of repository] : Defaults to "${REPOSITORY}".
--server [servername] : Defaults to "${DEFAULTSERVER}".
Default user for all git operations will be the currently
logged in user (${USERNAME}).
Default user for all git operations will be the currently logged in
user (${USERNAME}).
EOF_USAGE
)
Expand All @@ -48,6 +52,9 @@ git config --global user.email
EOF_GITCONFIG
)

# Default to creating a DB Backup
SKIPDB=false

######### Shouldn't need to change anything below #########
NUMARGS="$#"

Expand Down Expand Up @@ -104,6 +111,10 @@ EOF_DEPLOY
# or begins with -- (ie picking another argument)
while [ "${1}" != "" ]; do
case ${1} in
--no-backup)
SKIPDB=true;
shift 1
;;
--branch)
BRANCH=$(assign_value ${2})
shift 2
Expand Down Expand Up @@ -181,7 +192,7 @@ if [ -d /tmp/clone ]; then
sudo rm -rf /tmp/clone
fi

GITURL="git+ssh://${SERVER}/${ORG}/${REPO}.git"
GITURL="git+ssh://${SERVER}${PORT}/${ORG}/${REPO}.git"

echo "Cloning ${BRANCH}..."
mkdir /tmp/clone
Expand Down Expand Up @@ -210,26 +221,26 @@ if [ -r /opt/patches/D${DVERS}-ssl.patch ]; then
elif [ "${DVERS}" == "7" ]; then
# Find the settings file for site
SETTINGSFILE=$(find /var/www -type f -name settings.php 2> /dev/null)

echo "Checking Drupal ${DVERS}.x ${SETTINGSFILE} for previously applied patch..."

# Look for the patch
PATCHED=$(grep -A 15 "^\$databases" ${SETTINGSFILE} | grep "'pdo'")

# was it found?
if [ "${PATCHED}" == "" ]; then
# Nope
echo "${SETTINGSFILE} not previously patched, patching..."

# Define the SSL options for PDO connection
PDOOPTIONS=$(cat << EOF
'pdo' => array ( PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/mysql/ca.crt', PDO::MYSQL_ATTR_SSL_CERT => '/etc/ssl/mysql/${HOSTNAME}.${DOMAIN}.crt', PDO::MYSQL_ATTR_KEY => '/etc/ssl/mysql/${HOSTNAME}.${DOMAIN}.key', ),
'pdo' => array ( PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/mysql/ca.crt', PDO::MYSQL_ATTR_SSL_CERT => '/etc/ssl/mysql/${HOSTNAME}.${DOMAIN}.crt', PDO::MYSQL_ATTR_SSL_KEY => '/etc/ssl/mysql/${HOSTNAME}.${DOMAIN}.key', ),
EOF
)

# Find the location in file to insert PDO SSL options
INSERTPOS=$(( $(grep -A0 -B0 -n1 "^\$databases" ${SETTINGSFILE} | cut -d: -f1) + 1 ))

# Patch the file
sed -i "${INSERTPOS}i${PDOOPTIONS}" ${SETTINGSFILE}
else
Expand All @@ -244,21 +255,26 @@ else
exit 2
fi

echo "Removing old backup DB files..."
find /var/dbbackup/* -mtime +1 -delete
if [[ ! ${SKIPDB} ]]; then
echo "Removing old backup DB files..."
find /var/dbbackup/* -mtime +1 -delete

echo "Creating DB Backup..."
cd /var/www
drush sql-dump --result-file='/var/dbbackup/'${ENVIRON}'-'${TAG}'.sql'
echo "Creating DB Backup..."
cd /var/www
drush sql-dump --result-file='/var/dbbackup/'${ENVIRON}'-'${TAG}'.sql'

echo "Compressing (bzip2) sql backup..."
bzip2 /var/dbbackup/${ENVIRON}-${TAG}.sql
echo "Compressing (bzip2) sql backup..."
bzip2 /var/dbbackup/${ENVIRON}-${TAG}.sql
else
echo "Skipped DB Backup . . ."
fi

echo "Configuring permissions..."
if [ "${ENVIRON}" == "live" ]; then
sudo chown -R www-data:www-data /tmp/clone
USER='-u www-data'
else
sudo chgrp -R www-data /tmp/clone
USER=''
fi

Expand All @@ -270,7 +286,7 @@ for D in `find /tmp/clone -type d`; do
done

echo "Syncing ${BRANCH} to /var/www..."
CMD='sudo '${USER}' rsync -rl --exclude="private" --exclude=".git" --exclude=".gitignore" /tmp/clone/ /var/www/'
CMD='sudo '${USER}' rsync -rpl --exclude="private" --exclude=".git" --exclude=".gitignore" /tmp/clone/ /var/www/'
eval ${CMD}

# Just so we don't throw errors below when bash can't find the /tmp/clone directory
Expand All @@ -292,10 +308,28 @@ DEPLOY="## START DEPLOY INFO
"

# Remove the previous DEPLOY INFO
sed -i '/START DEPLOY INFO/,/END DEPLOY INFO/d' /var/www/.htaccess
sudo sed -i '/START DEPLOY INFO/,/END DEPLOY INFO/d' /var/www/.htaccess

# add the info to the end of the .htaccess file
echo ${DEPLOY} >> /var/www/.htaccess
echo -e "${DEPLOY}" | sudo tee -a /var/www/.htaccess >/dev/null

# Find all .htaccess files and build include for apache
HTACCESS=$(find {/var/www,/var/private,/var/mailinglist,/var/private_files} -name .htaccess 2>/dev/null)

# Loop through the found files and create the include file for apache
HTINCLUDE=""
for F in ${HTACCESS}; do
DIR=$(dirname "${F}")
HTINCLUDE+=$(printf "<Directory %s>\\\n Include %s\\\n</Directory>\\\n" "${DIR}" "${F}")
done

# write the file
echo -e "${HTINCLUDE}" | sudo tee /etc/apache2/htaccess.d/htaccess.conf >/dev/null
sudo chmod 0644 /etc/apache2/htaccess.d/htaccess.conf

# reload apache (gracefully) to load newly created file
echo "Reloading apache..."
sudo apache2ctl graceful 2>/dev/null >/dev/null

echo "Launch complete!"
echo "Template for pasting to a related issue:"
Expand Down

0 comments on commit 2d15238

Please sign in to comment.