Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: How do you deploy a simple web project?
10 points by doc4t on July 17, 2012 | hide | past | favorite | 13 comments
I ask here as this kind of question would most likely be closed on SO...

Recently I have been setting up my own development environment using git and Jenkins. I have so far managed to initiate build and test upon committing. Now the final step is to deploy to the web server.

I don't have a single .war file or similar. I have hundreds of small files like graphics, php files, js files for node and apache configuration files.

I keep almost everything in git but I do not want everything pushed to the web. My initial thought was to just zip a folder, upload it and unzip. But this requires me to keep some sort of list for the files which are used in production and those who are not (like reference images or modules which are temp. disabled).

1) Both the js files and the php files have require directives which would let me derive which files to include. Images are referenced as well so these I could also get. Putting code together for this is however pretty time consuming so maybe one of you clever guys (and girls) could give me a pointer about where to begin?

2) How do I go about replicating/syncing DB changes from the beta DB to the production DB? I am using postgres and don't have very much experience with DBA.




If you're living inside the PHP world, I'd take a look at Phing ( http://www.phing.info/trac/ ). It's very similar to Apache Ant and uses a XML file to describe the build tasks (include/exclude files, copy, tar, SCP, run PHPUnit tests, etc.) and can easily be extended using PHP (we use the rsync extension). It takes a little while to get everything up and running, but once you've got it (and well tests) it'd pretty much bulletproof.

Also worth taking a look at WePay's blog post on how they do deployments: http://blog.wepay.com/2010/11/30/weploy-wepays-deployment-to...


My tip for using Jenkins (or CI in general): have your build script produce a single-file artifact. You don't have a .war file, but what you can do is simply tar or zip your project. I recommend having a source directory and a build directory, and writing your build script such that the source directory is untouched and the output files are placed in the build directory. At the end, zip up that build directory and call it your artifact. You don't HAVE to do this but that's my piece of advice.. it will make your life easier.

Once you've got a stable artifact-builder, you can write a nice script that takes that file and deploys it to the location of your choice.

As you point out, some work needs to be done to determine which files are copied in the build process. I'm not familiar with PHP, but I am involved in an HTML application that has a similar need. We're using RequireJS <http://requirejs.org/docs/optimization.html#wholeproject>..., which has the ability to do all of the copying and optimization in one step. In our build.js file, we specify some patterns to control which files are included and excluded.


I deploy a simple project of mine using a horrible PHP script I wrote: https://github.etsycorp.com/gist/391780

My site is just static files, but it wouldn't actually be that much more complicated if it wasn't. The only thing I'd really need to add would be a line that runs database migrations. You can google "PHP database migrations" to find a handful of libraries that do this, or honestly just make a dummy rails project, and use theirs: http://guides.rubyonrails.org/migrations.html.

Note that the script I wrote is for a site of mine that gets literally zero traffic (although I'm hoping to get more to it eventually.) If it was something more important, I would probably start moving in the direction of Chef or Capistrano, which are more structured, and have things like error-handling.

Regarding stuff you don't want pushed to the site, it sounds like you need to fix your directory structure. It should be something like this:

  project/
  ..app/
  ....controller.php
  ....database.php [etc]
  ..public/
  ....index.php
  ....images/
  ......some_img.jpeg
  ....css/
  ......styles.css
and then the only directory that should be accessible from the internets is project/public. You deploy the project dir, and serve the site from project/public (so if I go to project.com/index.php, that corresponds to project/public/index.php on the file system.)

If you have multiple apps in one repo, you would just have them under project1, project2, then follow the same structure. If you have stuff that doesn't get deployed, it could sit alongside project in a different directory that you don't deploy.

For your requires and so on, you should be using relative paths, so that shouldn't be a problem. If you're not using relative paths, you're crazy and you should fix that. (First the being crazy part, then the relative paths part. You should also use an autoloader, so that you're not really manually requiring stuff that much.


Have you considered using fabric[1]? It's awesome!

[1] http://fabfile.org


Thanks. Having a look


Do you know of ServerFault? The reason you shouldn't ask this on StackOverflow is that it is on-topic on sister-site ServerFault. Either you'll find a similar question, or you'll have the opportunity to ask yours.


Every question I ever asked on the SE network have been closed by over zealous mods that doesn't want debatable questions...which makes it kind of useless for generic discussion. But I'll give it a try once more.


A simple web project? svn export, mysqldump, kick apache


Ok then - a not so simple web project.

1) I can't just pull from git. The repo contains files which should not be on the production server

2) I'm using postgres - not mysql. How do you incrementally change schemas? How do you roll back in case of failure without data loss?


1. Like what?

2. I know, but you did ask. I wouldn't bother incrementally changing the schema for such a small project - I'd just throw the dumps in version control. I'd roll back in the same fashion.

I guess we have different definitions of 'simple web project.' I'm thinking a 100-200 hour project that's going to see 5k visits per day, max. What are you thinking?


1. Like modules which are temp. disabled for instance. You could argue of course that these modules should then not exist in the production branch. Also reference images, project notes etc.

2. I could do that but I'm trying to learn how to do it properly...as in I imagine there would be a better way for this. When the DB (hopefully )grows to a considerable size then I take it this approach is not feasible.

The project is ongoing and I lost track of the hours many years ago. 5K users! Ha - I wish :) I was thinking about my general project setup which is described in the initial question...I'm just wondering whether there would not be a more structure way to solve this problem.


you fork the branch and have one that is 'deployable'. every time you want to do a deployment, tag it with an incrementing version number.

checkout said tag into apache's webroot.

for managing migrations, I don't have specific experience w/ PG but this looks decent: http://www.liquibase.org/home


1. Move those into another repo? Delete them afterward?

2. Use a migration tool. South is one for example that works with Django, there are many others.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: