Best practice updating a website - deployment

currently my work-flow is as follows:
Locally on a machine I maintain a git repo on each website I am working on, when the time comes to publish something I compress the folder and upload this single file to the production server via ssh then I decompress, test the changes a move the changes to the live folder and I get rid of the .git folder.
I was wondering if the use of a git repo on the live server was a good idea, seems to be at first but it can be problematic if a change doesn't look the same on on the production server in comparison to the local development machine... this could start a fire...
What about creating a bare repo on some folder on production server then clone from there to the public folder thus pushing updates from local machine to the bare repo and pulling from the bare on the public folder of the production server... may anyone plese provide some feedback.
Later I read about capistrano http://capify.org but I have no experience w/ this software...
In your experience what is the best practice/methodology to accomplish a website deployment/updates?
Thanks in advance and for your feedback.

I don't think that our method can be called best practice, but it has served us well.
We have several large databases for our application (20gb+), so maintaining local copies on each developers computer has never really been an option, and even though we don't develop against the live database, we do need to do the development against a database that is as close to the real thing as possible.
As a consequence we use a central web server as well, and keep a development branch of our subversion trunk on it. Generally we don't work on the same part of the system at once, but when we do need to do that, or someone is making a lot of substantial changes, we branch the trunk and create a new vhost on the dev server.
We also have a checkout of the code on the production servers, so after we're finished testing we simply do a svn update on the production servers. We've implemented a script that executes the update command on all servers using ssh. This is extremely convinient, since our code base is large and takes a lot of time to upload. Subversion will only copy the files that actually have been changed, so it's a lot faster.
This has worked really well for us, and the only thing to watch out for is making changes on the production servers directly (which of course is a no-no from the beginning) since it might cause conflicts when updating.

I never thought about having a repository copy on the server. After reading it, I thought it might be cool... However, updating the files directly in the live environment without testing is not a great idea.
You should always update a secondary environment matching exactly the live one (webserver + DB version, if any) and test there. If everything goes well, then put the live site under maintenance, update files, and go live again.
So I wouldn't make the live site a copy of the repository, but you could do so with the test env. You'll save SSH + compressing time, plus you can check out any specific revision you'd like to test.

Capistrano is great. The default recipes The documentation is spotty, but the mailing list is active, and getting it set up is pretty easy. Are you running Rails? It has some neat built-in stuff for Rails apps, but is also used fairly frequently with other types of webapps.
There's also Webistrano, which is based on Capistrano but has a web front-end. Haven't used it myself. Another deployment system that seems to be gaining some traction, at least among Rails users, is Vlad the Deployer.

Related

Organizing workflow with Mercurial and Netbeans (+ bitbucket.org?)

I've never worked with any version control systems before. Now I'm trying to learn Mercurial, but I'm confused (I've already read about 10-15 articles + hginit.com). I don't know how to organize the workflow.
I have a testing server and a production server. I work from my office computer and from my home laptop. I make changes directly on the testing server, and every week or so copy new code to my production server. I also need wiki/issues/etc. pretty much everything bitbucket.org has. I know that's a bad way of doing things.
Is there any tutorial or articles on how to organize the workflow? I'd also appreciate any schemes/sketches describing the process.
Thank you!
[Edit: Changed based on comments]
Using Bitbucket
Once you have created an account.
You should be able to create a repo with an appropriate url. Then you can clone it to create a local repository.
Check out getting started.
See the following to push the updates to BitBucket.
BitBucket comes with very extensive documentation.
Also there are, other useful tools to work with BitBucket:
BitbucketExtension that allows you to use command line for a number of operations.
Using Mercurial Queues and bitbucket.org
Organizing workflow
You will have to evolve a workflow that suits you. In your case, it looks like you have a testing server and production server.
So , you can setup two repositories, one for the testing server ad one for production. You can make push to testing server automatic so that you can test out the changes immediately. You can tag releases that are then pushed to production server.
Your local repo can be used to publish changes to testing server.
You can push the approved changes, tagged to BitBucket repository.

straightforward single developer deployment with mercurial and netbeans?

I am coding a website using the Codeigniter PHP framework.
I am using mercurial for version control.
I have 3 systems I work with. I do my coding on a Windows 7 machine using Netbeans 6.9.1. I am occasionally making commits, and pushing to a repository at Bitbucket.org, purely for the purposes of backup and version control.
I have a "beta" website (on a shared Linux box with it's own dedicated IP address) that I upload to using FTP, where I can test that everything is working as intended on an actual site running Linux.
Once I'm happy with that, I upload to my "live" site, which is on it's own dedicated server. Again I'm just using FTP to upload the files from my development server.
I realize that this is all kinds of wrong. For one thing I have to go in and change some things on the beta and live machines so that they're referring to the correct domain name, instead of localhost. For another, I'm not making use of mercurial at all to help with this. I assume instead of uploading from FTP, I could be using mercurial to "grab" a particular revision that I've marked as ready to deploy. I also think I could possibly be doing something in Netbeans differently to make the process easier.
What I want to do is have some very smoothe way to control all this, and hopefully one that knows how to deal with the issue of a slightly different configuration setup for the beta and live sites from the localhost.
Is there a standard way to do what I'm looking for? I've seen references to some third party apps for "continuous integration" but I'm not sure I need anything like that.
I'm a little lost as to what would be the SIMPLEST thing for me to do that would make my life easier....any help greatly appreciated :) Thanks!
It depends on how different the setup for each site is, and if there are secrets involved, which should not be visible on a public place (I assume you use a public bitbucket repository).
If the changes are not sensitive, then you can add two additional branches for your test and production servers, where only the configuration changes are applied. Every time you change something in default and deploy it to test, you would simply merge default on top of test, and mercurial fill in the different configuration settings in the process. Then the server deployment wold be a call to hg archive within the correct branch.
A typical change history would look like this:
O----o-o-o-o-o-o-o-o---o default
\ \ \
T1--------T2-----------T3 test
\ \
P1---------------------P2 production
where in T1 and P1 the parameters for test and production are filled in. You also can use this branch setup to mature the development of your site, where you hack in default, and only propagate stable changes into test and production.
If the changes are sensitive, you can create a non-versionized deploy script (or better a versionized deployment script and a not versionized configuration file), which patches the output of hg archive.
You should use deployment scripts anyway, which handles the packaging of the product and deploy an the target in an automated and standardized way. Within this script you can also embed information about the source revision into the final archive.
Note that this model works fine for an environment, where no changes are made on the server. If you do changes to the product on the server, you need to copy the files from the server back into your development environment(at the correct revision), to check what was changed on the server. When you want to make changes also on the server, you might want to install mercurial also there.

Deployment with CakePhp

I have a CakePhp Website that is currently live. I would like to keep working on the site, without impacting the deployed site.
What is the best way to keep a production version separate from a deployed version, and then merging the two when appropriate?
Currently, I am using Git for version control.
Thanks!
First thing, get to know a version control system Subversion, Git, Bazaar, Mercurial are some examples. They are a safety net that can save your bacon because they save EVERY change to EVERY file in your fileset.
Then, typically I have a local development server and also a subdomain (staging.example.com) on the production server. I then do my heavy development on the local development server. Then I use SVN to archive all my site changes. Then, using a shell account on the production server I check out the new version of the software to the staging subdomain. If it works ok there, I can then update the live site using just a single SVN check out.
I've also heard of people placing a symbolic link in the location where the site root should be (/var/www/public_html) that points to the live directory (/var/www/site_ver_01234) , then set up the new version in a parallel directory (/var/www/site_ver_23456). Finally, just recreate the symbolic link pointing to the new version's directory. The switch is instantaneous and transparent. I'm sorry I'm not more clear on this method though, I read about it a while back but never tried it myself though.
I've also looked at Bazaar (another version control system) that has a plugin that automatically ftps any changed files to a given server every time a version is checked in.
The general idea, first of all, is to use a version control system. Using this, you're developing your site on your local machine or with several people, having a central repository somewhere.
When you're happy with a certain revision and would like to deploy it, you "tag" it. That means you freeze the state of that revision and separate it from the continually evolving "trunk". What that means specifically depends on your version control system.
You then take that tagged revision and copy it to the live server. Possibly you may copy it to a "staging server" before to test it in another environment. This copying can be as simple as overwriting all existing files using FTP, or it can involve automated deployment systems which will take care of the details for you and allow you to roll back an unsuccessful deployment. If a database is involved as well, you're probably also looking at database schema migration scripts that need to be run.
Each of these steps can be done in many different ways, and you'll have to figure out what's the best approach for you. If you're not doing so already, start using a version control system such as SVN or git. Do it now! Then you might want to google or search on SO about different techniques to tag and branch using that system. For serious deployment, start with a keyword like Capistrano or one of its PHP clones.

Managing a dev vs production environment for a web app?

I have finished developing the core of a web application I have been working on. Since I was the only developer I just developed locally (lamp stack) without using version control (probably stupid but anyway..). Now that it is getting close to production ready, I have a couple other developers working with me so I set up a repository for my code.
This is my question: I still want to be able to test any changes locally first before posting to production. How do I manage this with a repository without having to maintain 2 versions of my code (that I have to synch up manually)? For one, the production code has a few differences here in there (such as database constants etc.). I'd like to be able to change my code in my local repository, test it on my local apache server, then check the code directly into production (is this even possible using eclipse)?
I am using eclipse and subversion (php code). I know I asked many questions but hopefully you get the idea of what I am trying to do...and I assume its rather common. Thanks.
In addition to the excellent answers you've gotten already, I'd like to emphasize that if there are differences between your dev and production code, you're adding risk. You should be using the same, well-tested code in both locations; any difference between the environments should be expressed in configuration files. Any configuration files in source control should be samples only; your deployment script should not push new configuration files to production.
This, in combination with tagged releases and a staging environment that mimics production, should help you promote your code smoothly to the production environment.
I would suggest a few things
Use tags/branches in SVN. When the code is production ready, tag it with a unique name.
Set up a staging area for integration testing. After a release is tagged for staging, yank it from your vcs and copy it into the staging area. This can be as simple as a different directory tree or a second install of your server.
Put constants into separate files that can copied/merged over into the staging and deployment directories
Test the staged version against dev to insure everything works as it did in your dev environment. I would point staging to production databases when I am sure it is working and ready to be promoted. Test that it also works against prod.
Once everything works in staging, update the production copy. I would suggest you create a clean deployment directory then copy that entire deployment over to the production server after copying/merging config settings.
This was my approach is dealing with perl/cgi many years ago and it worked pretty well. SVN handles tags/branching much better so it should be easier to deal with. We had very few production problems once we started staging the files before pushing to prod.
It sounds like you haven't created any branches or tags, and probably have a "trunk" that isn't labeled as such. Best practices would dictate that you have a trunk for the current stable code, branches that you develop against, and tags that are actually used on the production site. There is a short description and diagram on Wikipedia.
Of course, that's just best practice. Your project sounds small enough that you could get away with splitting your code into a development/ directory and a production/ directory in your code repository. Checkin code to the development directory, and once a change is fully tested, merge it into the production directory.
Whether you do it the right way or the easy way, it's important to do something to separate your development code from your production code. As you add more developers, it will be increasingly unlikely that the development code base is stable because people are checking in code that hasn't been fully tested, isn't complete, whatever. Spending a little extra time on managing two branches of code will save you a lot of headaches later on.

How can I use subversion to deploy web applications?

We are a small team of 4 developers working on a web application. We use trac+svn on a shared server for version control and ticketing and we are happy and satisfied with this. The same shared server also hosts our web application. The application itself is a Perl CGI application that uses CGI::Application and a moderate number of standard (CPAN) and custom Perl modules that are installed in the usual (/usr/lib/perl...) and a few unusual locations (/home/user/lib/perl..). While the broad details might be irrelevant, the most important point is that the location/layout of libraries on our development machines is different from that on the production (shared) server. We have to live with this as a given. The library layout is identical on all development machines though.
Here is a typical, but clearly sub-optimal work-cycle that my colleagues and I follow:
Code and test on development machines
Checkout/Commit/Update our code onto the SVN
Periodically "svn export" onto the appropriate DocumentRoot of the server
Hand edit the exported tree to set the library includes match the library layout on the server
Test application on live server, raise tickets for each other
Go to 1
Clearly there must be a better way and would appreciate hearing from others who might be handling this better than we are. For example is there a way to svn export and fix the library locations in an automated way? Or is there some completely different way to handle this situation than we have been doing so far.
Thank you for your attention
You should have scripts that do this for you that can be run from a local box. Mine always look something like:
$> checkout from source or copy from working
$> run sed/perl -pi/copy to convert configs to the production values
(ie cp production.config myconfig)
$> upload to web server (rsync/ssh/ftp/etc)
$> ssh $SERVER migrate_db, set permissions, run unit tests, etc
The last one requires ssh access which I always look for but everything else can be done locally. You'd usually have a set of dev configs and a set of production configs (or a script to convert from dev to production
One step uploads are always a really good idea.
Keep a config file (e.g. config.pl) that stores all the system-dependant paths and variables. Then set the svn:ignore property on this file so that it is never commited. This will allow you to easily keep a local configuration script per system that is separate from the commited tree.
If you don't have the possibility of mirroring your development server in production, why can't you mirror your production server in development? That might take some reconfiguring, but what's the risk? Everything's checked into svn.
But maybe that really, really isn't an option for you. My preference for deploying web applications is to do an svn checkout and then run a symlinking script. The idea is that you write a system of rules that logically maps the contents of one folder to the contents of another. Of course, if you drop folder symlinks in your document root, you have to tell Apache to follow them.
Frankly, the absolute safest scenario would be to set up a virtual machine that you can configure exactly like your production machine. This way you can actually test the contents of your deployment script and submit tickets. Then, when the problem is discovered, you modify the script to make it more likely that development deployment will follow the new and improved procedure.
And, as a side note: I much prefer to use svn checkouts in place rather than svn exports. It shouldn't be hard (especially if you use a deployment script) to make sure that apache or whatever your web server is doesn't have permission on the .svn folders. Ideally, anything you can do to make an svn rollback a one-line command is absolutely key.
If this is a Linux box you could write a cron job to take care of this for you. You could use sed/awk to replace the needed strings in the code and svn export works fine from a cron job. You would need to maintain the script but it seems faster than doing it by hand every time.
For the hand-editing part, I would have a separate branch in Subversion for the local modifications you need. The developers commit into trunk and when you need to deploy, use 'svn merge' or svnmerge.py to merge changes from trunk to the branch.
After creating the branch the first time, make your local modifications in there.
On the servers, have the directories in DocumentRoot and /usr/lib/perl and /home/user/lib/perl be Subversion working copies checked out from the branch.
Do not use svn export, just have a checkout so you can 'cd /usr/lib/perl; svn up'.
The one thing to be careful about is not exposing your .svn directories in DocumentRoot, use this:
# Prevent any access to .svn directories.
<DirectoryMatch "^/.*/\.svn/">
Options None
AllowOverride None
Order allow,deny
Deny from all
</DirectoryMatch>
Having working copies deployed in DocumentRoot is also nice, if you need to rollback a change, just 'svn up -r PREV'.
Codesion offers enterprise grade subversion and trac on demand. In addition, we now have the ability to one-click publish / deploy your code via ftp, scp, rsync and many other methods. This will be an easy and quick way for you to accomplish what you are trying to do.
See our Codesion Publisher features:
https://help.codesion.com/View.jsp?procId=01fabe5e83381dda4edda959b97b2c5b