views:

211

answers:

6

I'm a Unix sysadmin-turned-programmer, and because this is near and dear to my heart at present, wanted to hear about some best- and worst-practices, in terms of writing software so that it is easy to deploy, upgrade, and maintain long-term. I'm not talking about the long-term maintenance of the code itself; rather, what guidelines do you use to keep your software from turning into an un-installable mess?

My current pet peeve is hard-coded configurations. I'm in the process of working with our development team at my full-time job to simplify the deployment of our applications, so that I can totally automate every step of the deployment process. A large chunk of the configuration for these apps is actually hard-coded, either at build time or in the codebase, which makes the process of actually setting the software up on a server very, very painful.

Fortunately, the team at my full-time gig is talented and wants to see this fixed as much as I do, so things are moving along smoothly.

As for a 'best practice', from a Unix perspective, I really like it when software is, or can be, self-contained. So, I should be able to install an application into a directory, and then be able to move that directory around without causing the app to go utterly haywire. This doesn't really take much more than a bit of startup path-detection, and it makes my life as a sysadmin so much nicer.

What are some ways that you simplify the deployment process (on both Windows and Unix) for server-type applications, and likewise, what are some things you've run into that have turned into a real nightmare when it came time to push the code out the door?

+1  A: 

1-Manage your external depedancies - If you assume a file must be at x, make x configurable. Or use relative pathing as one example.

2-Do not hard code configuration.

3-Avoid binary dependancies (COM & DLL Hell Days from Windows)

4-Automate it or make it so simple a brain dead monkey could do it in their sleep. For example now all I have to do is unzip a file and my web app is deployed, I have one sql script that needs running and the DB is handled. It shouldn't take more then a few clicks...and no absolutley no configuration changes should need to be done this should all be scripted.

JoshBerke
+1  A: 

I suggest you to check a pet project of mine: Chestnut Package Manager

It is a utility to handle executables and resource files in a transparent, platform independent and relocatable way. Its concept is similar to Apple bundles and Java archives. It is implemented in Python.

Maybe it does not solve your problem completely, but you can get some ideas, and most of all, you can give me suggestions if you find it useful, so I can try to implement your needs.

Stefano Borini
One of the reasons I'm doing a lot of dev work in Groovy is for the deployment infrastructure provided by the JVM, but I'd love to be able to use Python or Ruby. I'll definitely have a look at your project; thanks!
Don Werve
+1  A: 

Follow the Filesystem Hierarchy Standard. Having the app be completely self contained (binaries, config, headers, libs all in one directory) breaks that standard, which makes many things more painful to deal with.

./configure, make, make install (or an appropriate variant if you need a different build system) should be the steps to install your program. configure should find any dependencies, enable or disable any optional features, and allow setting --prefix (and exec-prefix, bindir, etc) to select appropriate install locations for the various components. See the GNU Coding Standards for more information (I don't agree with all of the GNU coding standards, but the advice for how configure should work is good).

Include man pages describing all of the command line options your programs take. You can have better documentation elsewhere (info, HTML, whatever), but I should be able to use man as a quick reference for command line options. Don't be like GNU and put just stubs in some man pages, with pointers to the info docs for more info.

Brian Campbell
A: 

The software design and the stability of the environment both contribute heavily to how deployable software is. Each application should be configurable and make it a habit for applicaitons to have a startup script that validates its environment and produces meaningful error messages. Control access to the servers and insist that teams modifying those servers have done due testing in a stable test environment. Be a champion of the test environment. The changes the applications teams make should be scripted when possible and include an implementation plan, a validation plan, a backout plan, and a backout validation plan. Provide a place where temp files and artifacts get automatically get cleaned up. /u/spool/01 gets cleaned each and every day. /u/spool05 gets cleaned each five days. /u/spool30 gets cleaned every thirty days. Consier statically linking shared code if many applications share the same server. Avoid rats nests of links. Avoid shared mounts. Champion logging standards. Isolate your test systems from your production systems. Create standards to not write outside of the current directory or a fixed set of directories. Create a clear linkage between the binary deployed and the source management system it came from. Monitor your servers for runaway processes, filling disks, and network connectivity. Be draconian about permission bits. Figure out a way to reward system uptime.

ojblass
A: 

I recommend you treat both deployment and maintenance as scenarios that need to be tested, in exactly the same way you would test the operational aspects of the software.

When a bug is found, one should create a regression test, and perhaps unit tests. In exactly the same way, when a customer has a problem with the deployment or maintenance of the software, and if it is more a software problem than a documentation or training problem, then a test should be added to the test plan to make sure the problem does not happen again.

Of course, to the extent that these tests can be automated, they should run at least after every nightly build; at best on every Continuous Integration build. At the very least, the product's installation script or installer program should be run when it's time to deploy the application to the QA machines it will be tested on.

John Saunders
A: 

Confession: I clicked on this question thing it read "How to write deplorable software?" But now I'm here, I ought to take a shot...

I wonder if taking a leaf from the Agile book might help? Work in short iterations (one to four weeks, say) and ensure that you deploy no less than at the end of every iteration. That way, you are driven to get really good at deploying your app - if it takes too long you won't get anything else done. Problems with the deployed app feed back from the user community as they are encountered and can be prioritised for action over subsequent iterations.

Mike Woodhouse