This is part 3 of a five-part series:
- Part One has examples for common daily tasks in Git.
- Part Two, similar examples for Rails.
- Part Three, miscellaneous cases.
- Part Four dissects an example of a failed attempt at a useful script.
- Part Five concludes with a brief discussion of when to use Bash as opposed to some other scripting language.
TL;DR for Part 3:
- Use environment variables to make a script portable
- Using
ssh
with--
to pass a string of commands to execute is great for working with remote systems - Know how to use SSH keys
Apache
Some projects aren’t Rails projects. Some are PHP and run on an Apache server. Since you have all your non-sensitive configurations (like rewrite rules) in version control (you do, right? … right?), you need an easy way for devs to start and stop their web server with those configurations.
These scripts doesn’t live in ~/bin
but rather in a bin
directory in the project root.
bin/devctl
#!/bin/bash if [[ -z "$1" ]]; then echo "argument of stop, start, or restart required"; exit 1 fi DEVROOT=$(pwd) \ PHP_SO_LOCATION="/usr/local/Cellar/php56/5.6.30_6/libexec/apache2/libphp5.so" \ apachectl -f "$(pwd)/conf/httpd.conf.dev" -k "$1"
That file’s real name is bin/devctl_example
. There’s a .gitignore
entry for bin/devctl
(just like with your rails database.yml
and secrets.yml
files; then you could use something like link-configs
from Part 2 to manage this).
Anything in the config that might be variable among devs’ environments should be extracted to an environment variable so the script is portable.
The httpd.conf.dev
gets the values for DEVROOT
and PHP_SO_LOCATION
from the environment for lines like
DocumentRoot "${DEVROOT}"
and
LoadModule php5_module ${PHP_SO_LOCATION}.
bin/push-staging
For some projects, deploying is just a matter of pulling down the latest code and restarting Apache. I have scripts like these (and similar scripts for production and other pre-production runways).
#!/bin/bash git push && ssh deploy-user@staging-host -- 'cd /var/www/html/web-root && git branch && git pull && sudo apache2ctl restart'
Being able to pass a command as a string after --
with ssh
is handy for automating a lot of tasks. In this case I’m including git branch
with that list of commands so that I can confirm from the output what branch it’s pulling.
There’s no backslash to continue the lines because the newlines get squashed when the string is sent to the remote system.
Scripts like these are also helpful for projects where we’re collaborating with a client who’s comfortable making markup, style, and even some code changes, but isn’t ready to do their own deploys. We can give them this with simple git pull
and git commit
instructions and say “Then run the bin/push-staging
script to deploy your changes” (after adding their public ssh key to the deploy-user’s authorized_keys).
Multiple Versions of a Server
Since we work with many different clients at beezwax, we might need multiple versions of a given database in our development environments. Differences of even minor versions can mean a big difference in functionality (e.g. the introduction of the jsonb
datatype and its associated functions and operators in Postgres 9.4 and 9.5).
So I have two (similar but not identical) scripts for managing different Postgres servers:
postgres-9.3
#!/bin/bash cmd="$1"; /usr/local/opt/postgresql-9.3/bin/pg_ctl -D /opt/postgresql-9-3-data "$cmd";
and
postgres-9.5
#!/bin/bash cmd="$1"; "$POSTGRES/bin/pg_ctl" -D "$PGDATA" "$cmd";
The 9.5 script uses the $POSTGRES
and $PGDATA
env vars set in my .bash_profile
, while the 9.3 script hardcodes those locations. This makes it easy to stop and start the different versions:
$ postgres-9.3 start server starting LOG: database system was shut down at 2018-06-04 13:47:44 PDT LOG: MultiXact member wraparound protections are now enabled LOG: autovacuum launcher started LOG: database system is ready to accept connections $ postgres-9.5 start server starting LOG: database system was shut down at 2018-06-04 13:47:55 PDT LOG: MultiXact member wraparound protections are now enabled LOG: autovacuum launcher started LOG: database system is ready to accept connections $ postgres-9.3 stop LOG: received smart shutdown request LOG: autovacuum launcher shutting down LOG: shutting down waiting for server to shut down....LOG: database system is shut down done server stopped
Similarly with the psql
clients, the psql
in /usr/local/bin
is a symlink to the 9.5 version. I have an alias psql93
for the 9.3 client.