GIT is the new FTP
coderwall.com
coderwall.com
That's not even a sufficient professional scenario for anything but the simplest of non-essential website. Hell, this won't even do for the simplest of WordPress sites.
BTW, who on earth still uses FTP?
Does sftp[0] count?
I am currently trying to figure out a more clever way to deploy my code. I would love if you would share some thoughts on some general strategy and possible tools. I am using jenkins and git.
Ofcourse it would be cool if all of our clients would host on a PAAS platform like Orchestra or PHPFog but that's not the case by a long shot i'm afraid.
Each file was carefully FTP'd from the shared development area to the live site, and then marked off on the sheet with the date that it had been deployed, and with what feature.
Each new deployment meant either adding a new set of rows to the spreadsheet for a new feature, or for updates to existing features going back and finding an earlier instance of the file in the list and bumping the date on that.
Because of the shared nature of the CMS across different websites, we couldn't svn up in the CMS directory without destroying the current known state of the site. We also couldn't svn up outside of the subdirectory we were working on, as everyone else working on that site was working off the same network share. Everything was done very gingerly.
The day one of the developers came up with a method to take a list of files from the spreadsheet, tar them up and FTP them to the server for later extraction, he was overjoyed and very, very proud.
I got out of there, swore off PHP and its community entirely. I got tired of checking for a baseline of automated deployment, automated testing, version control, and individual dev systems at every single job I applied for; Ruby people don't look at you funny when you mention these things.
Addendum: I personally know a developer currently working for a famous local radio brand who directly works on the live website network via an FTP plugin. He has to contend with other developers dumping the contents of archives directly into his public folder.
(For context, this is all in Sydney, Australia.)
virtualenv/rvm are the standard, using git is the standard, fabric/capistrano for pushing/provisioning is standard.
This is not the case for PHP, the vast majority are using graphical FTP clients to manually overwrite files.
I got tired of checking for a baseline of automated deployment, automated testing, version control, and individual dev systems at every single job I applied for; Ruby people don't look at you funny when you mention these things.
It's about expectations. I tried really hard to find a place that had all these in the PHP world. In the Ruby world (for example), it's a given.
(I have only ever encountered one PHP shop during my rounds interviews that did automated testing... But they used CVS for version control. The very first Ruby shop I interviewed had all of the above, and treated it like they were no big issue.)
Oh the horror! A proven source-code control system.
M-x My-lawn-remark$
* Track renames of files.
* Track changes to the repository as a whole, instead of per file. I care most about stepping through revisions of a project; inspection of the history of a particular file is a secondary concern for me, but is all that CVS can do. A "project" for me is usually a set of files that are interdependent to greater and lesser degrees.
The best you get with CVS for tracking the versions of all the files in a repository is manually creating tags all the time. With Git, Subversion, Mercurial, Bazaar, etc you get this for free; it's how these tools work.
(As an aside, DOS is also a proven operating system. For varying values of "proven".)
First, class loading is more granular than JAR files. From what I can tell, the JARs are just repositories (if you will) for the actual class data. Once a class has been loaded from a JAR, it is distinct from it, and there is no need to keep the whole JAR in memory.
Second, there are many class loaders at play, not just one. At the least, there will be one class loader for Tomcat and one class loader for each web app. This is necessary to keep web apps from breaking each other (and Tomcat!) by loading incompatible versions of classes.
Third, once a class is no longer used (i.e. there exist no objects that are instances of it) it can be garbage collected, and will be if more PermGen space is needed.
Fourth, once a web app is unloaded, its class loader is no longer needed, and it too can be garbage collected (along with any memory it was using to store the aforementioned JAR files, although presumably that memory would be outside of PermGen).
Taking all of this into account, one might (like me) naively presume that once you unload a web app, all of its objects will no longer be referenced, and this will propagate up the tree of references (servlet -> object -> ... -> object -> class) until nothing from that app remains.
HOWEVER, this assumes that references exist in a tree. A singleton class would cause problems: it stores a reference to an object of its own type. This creates a circular reference pattern (class X -> object -> class X) and keeps both class and object in memory.
A possible solution might be to associate each class with the web app that loaded it, then when you unload a web app, you can walk through all of the classes it loaded and null out all of their static fields. This will allow the referenced objects to be garbage collected, and in turn, the classes of those objects.
But this is probably much easier said than done (it may even be impossible due to limitations on the JVM), and there are probably other issues I'm not even aware of and thus not considering. Never mind JNI, which just adds even more fun to the mix.
So ultimately I must agree with the recommendation to restart Tomcat when you're deploying web apps. From a developer perspective, I would also recommend eliminating static data in your libraries and web apps as much as possible.
I use Transmit to FTP updated files to my web server. Then I send smoke signals to my colleagues to inform them of the changes, and document the updates on a papyrus using quill and ink. Should I be doing it differently?
I've also found that using parchment makes updates more durable as they weather better.
I think it's useful to have deployment integrated with your SCM. You have a complete history of deployments. You can easily roll back to any version. You can deploy from any machine which has your SCM tool installed.
Sometimes this matters:
http://stackoverflow.com/questions/6554910/i-am-failing-to-r...
(Yes, it's a hack.)
But this doesn't work for Mule; for some directories it autodetects and attempts to run it (whatever that means for that directory).
So in my case, rsync looks better than git at deployment. I can't imagine a scenario where the reverse is true. Does someone have a counterexample?
[1] My home-made Jekyll clone: http://loup-vaillant.fr/projects/ussm/
My website is stored in mercurial currently, and when I push to the server it runs bundle and compiles the site.
Anyhow, this scheme sort of old hat for Git users. Most of us require a build to deploy code, which generally results in SCM-polling continuous integration solutions like Jenkins to fully automate the preparations required to run new code.
This blog post sort of suggests a WordPress crowd's version of continuous integration. Go ahead and use it for a blog theme, or a set of assets. If you're doing this for a web application, you're probably doing something wrong.
Thank you Kerrick Long
> First, create a directory on your server and initialize an empty git repository.
The number of people who deploy sites via FTP who also have SSH access and the ability to install Git on their hosting is small. Most people deploying to the web do not control their own servers.
As other have said, deployment should really be done by continuous integration server, and preferably using a protocol that's designed for transmitting files, not version control.
I didn't really write this as a tutorial as much as an easy way for me to look back and find the commands when I have a forgetful moment. That's why it doesn't go into explaining how or why things work, explaining how to set up git, explaining how to set up your web server to serve files from a directory, or other preliminary information.
Had similar problem with a site called TVCatchup. They stream free TV in the UK. Their player sits in the middle of the page and that is surrounded by an advertising border. Nothing else on the page of consequence. What I found was that I found it very hard to focus on the player in the middle. Often I would get a headache watching. Told the admins, who didn't want to know. Basically I got an angry "Foxtrot Oscar". Ended up using an ad blocker until they found a way to defeat that. Now I don't use the site any more.
As a photographer, this is quite annoying, because it's hard to predict what something will look like. I'll try to find a photograph of mine that'll stand up to being "hipsterized" better.
> SFTP is not FTP run over SSH, but rather a new protocol designed from the ground up by the IETF SECSH working group.
ssh username@from_server "tar czf - directory_to_get" | tar xzvf - -C path_to_save
rsync -avz somehost:/path/to/src /path/to/dest rsync -avz --delete src dest
This assumes there are no files you want to keep on the destination, of course. You can exclude them or reorganize to keep them safe. rsync -avz --exclude '*.swp' --delete site/ $(WEBUSER)@$(WEBHOST):site/
This way I'm only putting the necessary files on the server and transferring changes is incredibly fast and secure (ssh is used by default).In rare cases where I need to deploy from a repo on the server, I'll clone it to the remote host and use rsync locally to copy the files. But I still avoid serving directly out of the repo. There's too much sensitive information in version control to even risk exposing it during a misconfiguration.
I typically deploy with a similar setup that you described, but instead of rsync'ing the files locally I just make a clone of the repo and serve that. Though it is another step to fetch/merge, it stops me from losing any changes that someone did to production without telling me.
I only recently used Capistrano to deploy a project and it was very satisfying, so I'm gravitating towards that as my default deployment method.
+1. Secrets should not be in your VCS repo. I'd guess the parent is talking about user/pass or pub/priv key creds.
I really wish "we" had better tools for passing around config, and secrets in particular. Chefs data bags are close, but I still don't want the master knowing my secrets.
This allows me to update my code locally, push to github and have my server automatically download the changes (using girror[3]) and update the code, all with zero downtime.
What I like most about it is that it's all nicely contained inside the same code as my application!
[1] https://github.com/LearnBoost/up [2] https://github.com/LearnBoost/up-hook [3] https://github.com/node-migrator-bot/node-girror
As it is to run git on windows you, best case, have to install a lightweight nix OS. Cygwin mingw,whatever. I think we techies and power users don't realize how messed up that is if you want git to be more than a program for programmers. Ftp was a protocol, you could make a native client for everything. Git is a great tool, but not yet comparable to ftp.
git init --bare fatal: core.bare and core.worktree do not make senseWhen we click the build button, a small Python script is called that rsyncs over ssh the already built artifact (pulled in from the existing TC build) over to the environment, which runs JBoss, and gets auto-deployed.
For our developers, our build process amounts to committing their code, getting an email from TeamCity when the build completes, then clicking the Deploy button. The tools take care of the rest, and we end up with a nice trail of logs available in case anything goes wrong, and a clear rollback strategy.
We also don't get an ever-growing git repository, or have to maintain a bunch of FTP configuration. Everything is done over ssh via passwordless pki. Best of all, it didn't take long at all to set up (the longest part was probably writing the python deployment script, which has some basic logic to know which environments live at which addresses, and also how to run some post-deploy commands for the 1 non-JBoss deployed .jar based service we have).
It's not perfect - we don't have an automated database migration mechanism right now, though in a distributed system like ours I'm not entirely sure one would work at this point (and we've got other plans to deal with that weakness anyway). I'd also like to move to Hudson or Jenkins at some point, as there is a real attraction to the rich ecosystem there (TeamCity is a commercial product).
I would recommend looking into continuous integration over this method. I've been using TeamCity for just over a year and it is fantastic for a staging environment.
Using this workflow, if you break your site, reverting would require either a) fixing the bug and then doing another push or b) looking up and typing in the hash of the last known good commit. Neither of these are as fast and easy as "git push".
Our solution is to deploy with tags. Every push to production gets its own tag, and that is what we checkout into production. If the site breaks, you just checkout the previous tag name and you're reverted. This way reverting is exactly as easy and fast as pushing new code.
If you (or an unfortunate client) are using a cheap shared host that only provides you with FTP, this approach at least guarantees that the only code on the site is what exists in your VCS.
Springloops has a useful deploy-by-ftp feature. When you commit a change using their Subversion host it automatically pushes it out to the development or production server.
It's easy for designers to use since they can update a jpg or two for a client, commit a change, then hit refresh on the live site and it shows up.
I know it's not perfect, but for small web shops and non-technical people, it works great.
1. All assets are under version control.
2. Committing code of any sort (HTML, CSS, Javascript, Ruby, Python, PHP, ...etc) triggers the unit tests and a failure of the unit tests prevents the commit from completing. #unit tests should take n < 3 seconds
3. Pushing the code to the deploy repo (or branch) triggers the acceptance tests (behavior driven tests that look at the functionality of the site overall, account creation, login, profile_view, checkout) failure of the acceptance tests sends an email to the whole team. Code changes affecting security sensitive modules should be considered failing until they have been manually qualified (e.g. anything touching passwords or money).
4. If the acceptance tests pass and no critical modules were affected by the commit, that commit gets deployed into the production environment. That fact is recorded on the dashboard and emailed to the team.
This is difficult to achieve but once reached, it's like being over the step on a boat that hydroplanes; friction is reduced and you get greater velocity for the power expended.
So for us, git is an important part of our deployment process, though there's more that goes on especially for production deployments.
Isn't that what FTP is most known for - being insecure?
<Files ~ "^\.">
Order allow,deny
Deny from all
</Files>vc: metadata (permissions) are irrelevant. dep: metadata is critical
vc: version everything by default (explicitly exclude) dep: version by explicit inclusion
I've have a doc with numerous links and notes that I should share sometime.
The actual deploying and testing was all done with Fabric, but the idea was the same.
I think that's a pretty good case for using a CI system like Jenkins, especially because it's really easy to set up. It didn't support Git by default, but there was a plugin that was both easy to install and fairly comprehensive.
I'd be great they explain how to know which code is live (ie. tag "releases"), how to revert to a previous version (ie. something went wrong), potentially something needs to be restarted, etc.
mkdir ~/www/example.com && cd !$
!$ is the last argument of the preceding commandhttp://www.gnu.org/software/bash/manual/bashref.html#Word-De...
(I'm running OS X, FWIW)
&& in OS X seems to put the left side into history and works as I described, but it didn't work when I tried it in Ubuntu 10. $_ works in both.
mkcd() { mkdir "$1" && cd "$1" }You can do a one-liner with git archive but I don't think it's as easy.
and asuming you don't just use git for deployment but also for it's core purpose version control you should setup the origin to the actual origin and name the remote where you push to accordingly (production, dev, test, staging) and you shouldn't set it as the default push, to avoid excedently deploying when you just wanted to checkin the code to the origin repo!
Correct me if I am wrong, I would really love to replace ftp with git.
But the post is about deployments and not about transferring files.
GIT is the new RSYNC