Time to hand over the reins before Capistrano costs me my youth?
groups.google.com
groups.google.com
The fact that people read this article, and don't feel the need to mention his fear of releasing software just shows how broken things are. It shouldn't be an accepted fact of open source that if you release new code that might be backwards incompatible, you get vitriol for it.
His quote:
... but I too cowardly to release it and make it mainstream, as Im afraid it'll destroy whatever good will for open source I have left when the flood of support questions inevitably comes in, followed by all the people who are unhappy with what I've built and feel obliged to tell me how bad I am at software.
It seems (and this is just entirely my opinion) that it is forgotten that people are doing this out of their own goodwill and are not necessarily being paid for it and really have no contractual obligation to keep doing what they are doing.
It's almost the worst of both worlds. You get all the responsibility for having your open source project be considered at the same level as a commercial solution but without it actually being a commercial solution.
Do you mean to say that the Python community is poisonous? Or that the Ruby community is poisonous from the perspective of a Python community member?
I went ahead and removed the python part, as it didn't really contribute to the message.
https://github.com/zerotier/ZeroTierOne
I got some good feedback, but more than my fair share of "this is the stupidest fucking idea I've ever heard of" and such. Luckily I know to ignore pretty much all that shit.
I'm gonna tell it like it is:
There are a lot of people in tech who don't have great social skills. They're awkward, feel withdrawn, and have trouble dealing with other people generally.
One quick and easy solution some of them hit upon is to just be an asshole. If you're an asshole, people sort of sometimes defer to you or steer clear of you. It creates the illusion of power and influence while shielding a person from having to do any real work to improve themselves in that area.
If you think it's bad online and with OSS projects, try delving into the meat-space startup scene itself.
I'm sick of these two types of assholes, really. The first type is the "I'm an asshole online -- it's my persona. "
The other is the hater / troll.
And I just have to think that both of those kinds of assholes result from a lack of social skills - as in, "I don't know how to get along with other people in society."
Damnit, I just want to code cool stuff and use other people's cool stuff. Can't we all just write cool stuff and help each other out?
1. Focus on what people they actually know and respect think vastly more than anyone they hear from online.
2. Assume that anyone criticizing their effort is an armchair hacker who just likes to be better than others. It's not always true, but is better than assuming that everyone else is better than you.
3. Always be proud of what you've done -- just because we've gone to the moon doesn't mean you shouldn't be proud of making your Arduino blink the LED finally.
I talk about it a bit near the end of this: http://blog.saikoled.com/post/62737468595/entrepreneurship-f...
The greats weren't great because at birth they could paint
The greats were great cause they paint a lot
(Macklemore - Ten Thousand Hours)
It's the tiny steps that bring us forward. A big project starts with a single commit.Even if I could dedicate two hours every single day of the year to becoming an expert at something, I'll be 50+ before I'm an expert in it. If I could dedicate about 15% of my waking life to becoming an expert in new things, there is only enough time in my remaining life to become an expert in two things at most. And that's assuming it doesn't take more hours or become more difficult or even impossible to become an expert in new things when you're much older. And, frankly, what's the use of becoming an expert in something in your mid 60s?! Just in time to finish the last bit of your life.
If only I'd known the value of time much earlier in life, so I could have jumpstarted that in my 30s and focused on more than one thing to become an expert in . . . you only realize that sort of thing when it is too late.
Aaaaaand now I'm bummed out. :)
Why do you do anything, after all? Do you have to be an expert for it to be worth doing? If this were the case, certainly no one would be a parent. It's just a guideline to keep people from claiming expertise that they don't have yet, which is often a problem with people who have been doing things for a very short time.
Or for a specific example, I've been doing karate for 10 years very seriously. Overall, I've probably spent about 4,000 hours doing karate in classes. Of that, I've spent probably about 1,200 hours teaching, which I started doing after only maybe 800 hours of training. I've trained two students from white belt to black belt, and have introduced on the order of 100 students to karate.
But I'm not an expert. According to this rule I need about another 10 years to be one. Does that mean that I don't enjoy doing it? Or that me doing it doesn't contribute to the state of the art? Hardly. Being an expert and being able to contribute are not the same. I'm not going to have karate masters coming to me for advice. But I still have made the world a better place, in a small way, for ~100 people.
My father and mother both started new careers at 40, again at 45, again at 50, and now they're both moving to new things again at 53 (they were young when I was born). Neither of them will probably be experts at what they're working on in a technical sense, but they're still making substantial contributions to the world. Heck, my dad just got his very first journal article published this year in an area that he started working in at 50!
http://america.aljazeera.com/articles/2013/8/8/study-conflic...
In the end, don't do stuff because you want recognition as an expert, do it because you care. Expertise will follow, for the things that are worth it.
I find that in some ways Gladwell's book as the opposite effect of causing me to not not even want to start something due to this "10,000" hour rule.
At the end of the day, we don't need to be an expert in most things to be proficient. Josh's book lays this out in a nice way. On a more practical level, even 1 hour a day on something has tremendous accumulative effect.
I believe the biggest gift we can give ourselves is to not lose our learning mindset. For those of us who have gone through college/university and gained the discipline to study, we tend to throw it out when we are done. In hindsight, that is the best skill that one should retain in their life. The ability to be disciplined and focus on studying/learning/doing new skills is what I am trying to continue to cultivate and I hope that when I am 50 I still have this mindset and discipline.
But its not like you go and spend 10,000 hours and at then at the 10000 hour 1 second you become an expert.
If you are deeply involved in something working day and night. Within an year, you will be close enough to swimming with experts. Often that is all you need.
In case anyone doesn't know it.
"Matz Is Nice So We Are nice." (Matz being the creator of Ruby and generally nice guy.)
... And yeah, it sucks that it feels like it's died a bit. But keep it up anyway; https://twitter.com/tenderlove is a great example to follow. :)
I wrote to him asking if he had any feedback on my project, since I'm about to release it, and because he had a similar project that didn't get much traction. He didn't reply...fair enough, I'm sure he's a very busy guy.
Fast forward a few months, I launch the project and it blows up on HN for a few days, and on twitter for a few weeks. The majority of people love it! But sifting through the feedback online, I'm shocked and disappointed to see is the very person I reached out to trashing my project publicly in comment sections and on his twitter feed. No constructive feedback, only how the project itself was a horrible idea, and the code was disgusting. I was dumbfounded...before, I wasn't worth 2 minutes to reply to in an email, but now I am worth destructive criticism on social media by the same person?
I waited a few months and sent another email asking for advice on maintaining the project. No response still. Yet every now and then, to this day, I still see backhanded comments by him about my project whenever someone mentions it to him on twitter.
Some people are toxic, petty, and childish. I don't really have a lesson from this, but that's my little story.
So when some other human is the source of the bug or blocking issue then we don't take care to be social and delicate. That's broken, that's badly built, hey that sucks. Or just channeling other pent up annoyances onto whoever is around.
I spent so much of my life working on it. I wrote the software behind it, designed the presentation, handled the customer service, mediated disputes, handled the promotion, and helped with user-founded real-world gatherings built around the community on the site.
It required so much of my attention and, unfortunately, often was so hostile and venomous that the only reason I stuck with it for many of the later years was out of a sense of obligation to the community (many people made friendships through the site, met spouses, established real world businesses, and even put themselves through school thanks to the site) and a sense of obligation to myself . . . I put in all of my 20s and part of my 30s dedicated to the site and service. Hours and hours every day. I put in enough time that it was a second full time job -- not counting the $25k of cash I put in over the years.
I had real life stalkers via the site. I had harassment via my email, IM, and even via local authorities (with such a large community, there are bound to be a few crazies). Hell, even just my email inbox was depressing. For the last 3-5 years of the project, I felt sick every time I would visit my own site. Sicker when I would check my own email for it. To the point that I would go months without going to my website . . . and more without checking my email. At one point, it was so bad that my inbox had 1.1m messages (that is AFTER filtering out spam).
The only thing worse was considering shutting it down. It was a part of me. It was probably my biggest accomplishment at the time. A lot of people dream of building such a huge successful community from top to bottom with their own hands for so long, but never get anywhere close to achieving it. How could I give that up, no matter how much grief it caused me?
I'm not exactly sure what pushed me over the edge, but in 2010, I finally shuttered it. I felt bad for it. I still felt obligated to them and to myself . . . but I sensed I had to move on. And since then, I have had this great sense of relief. I have time for myself and time for other potential future projects. I am no longer forced to dismiss other opportunities, because of the obligation I had to this project. I no longer felt sick thinking of my email. I no longer felt like a prisoner. I felt like I had more control over each day of my life and what I did with it.
I have never been one of those people who sticks in a relationship just because leaving it would make all the invested time "feel like it was wasted". When a relationship goes bad, I move on and don't look back or even keep in contact. I'm good with that. This experience, though, gave me a little insight into all the people out there who have a hard time leaving relationships. Even unsatisfactory ones. Life is short and you only have so much time and energy to put into things. When you have given so much into one thing, it can feel like moving on is a bigger loss than sticking around. I totally get that, now.
But, in the end . . . it was a great choice. For him, it might also be the right choice. All of the "if only things were different" thoughts and all of the motivation to take the reign to chance those things in the community are great, but . . . ultimately can become a way of simply keeping you tied down to the very things that make you regret what you're doing. When that becomes clear, the choice to move on has to be at the forefront.
I have a feeling, anything that you offer for free will be often treated as worthless. Its an problem with us humans, we attach quality with price and we think if something is expensive its of superior quality. Going down this line of argument something that comes for free is always going be treated that way.
It also gives a good indication of how a person would spend his time. If you give away your work for free, how do you expect others to pay up or value your time? And look at this way- If you put up with crap, people will assume you are perfectly OK with crap thrown at you.
Take a tough stance and never climb down from there. At times that's harsh and rude to a lot of people. But ultimately that's the only thing that protects you.
http://www.goodreads.com/book/show/82104.How_I_Found_Freedom...
Tangent mode on:
Somebody really, really needs to write the How To Deploy Rails Without Losing Your Sanity handbook. I will buy a copy. It will sell thousands of them.
A lot of the problems with people's interactions with Capistrano are environment/ops problems which have known solutions that work, but which rely on people having a great understanding of arcane trivia which is spread across conference presentations, blog posts, commit messages, and the practical experience of the best Rails teams. Unless you're prepared for an archaeological expedition every time you start a new Rails project, you're going to do something wrong. You should see the bubblegum and duct tape which I came up with, and it mostly works, but I know it is bubblegum and duct tape.
Example:
Non-deterministic deploys of code from (usually) un-tagged source control
I feel lucky in that I was mentored by an engineer who decided to teach me, one day, Why We Tag Shit. But for the Why We Tag Shit discussion, I would be like almost every other intermediate Rails engineer, and be totally ignorant of why that was a best practice until lack of it bit me in the keister, at which point the server is down and one has to rearchitect major parts of the deployment workflow to do things the right way. Why We Tag Shit is only about a 500 word discussion, but it's one piece of organic knowledge of the hundreds you need to do things right, and it is (to the best of my knowledge) not covered in docs/QuickStarts/etc because that seems to be out of the purview of the framework proper (I guess?).
I'm sure that I'm ignorant of several of the hundreds of pieces of things one needs to do to do deployment right, as evidenced by my fear every time I execute my deploy scripts. I, and I must assume many other companies, am willing to pay for an option which gets me to a non-bubblegum and duct tape outcome.
Seriously, folks: there is a product here.
The same reason "why we tag shit" is the reason downloading packages from gem/pip is not enough
Who guarantees that when you do your deploy, the library you need is there? How many times did your build break because it had a glitch downloading the package?
Keep a way of rebuilding and deploying your software. All of it
This happens very infrequently in my experience, but it's simple on most CI servers to restart a build.
In practical terms, this means that you never know whether change X is faulty or simply the world is temporarily faulty.
(Of course, this may or may not be not useful to you to know.)
If the deploy fail for any reason, it's aborted, you just have to run it again.
Good engineering is the attempt to prove that statement wrong.
It's really easy to write these kinds of things off as rare occurrences, but this is exactly the kind of thing that causes us to talk about "fear" when deploying.
Edit: solution was to run 'rvm osx-ssl-certs update all' on OSX, which is unsettling, as it installs certs all over the disk. Then on Ubuntu it was "yum update openssl", I believe.
I remember my first brush with this when Maven first started getting popular. Apache had to move their servers to a new datacenter and the server that had the drives for the main maven repo was lost in transit. It took five days to bring everything back up. During that whole time, nobody could build anything unless they had local copies.
Ever since then, I'm pathological about ensuring that I have a local mirror of all my dependencies.
I'd love to be able to do it without embedding code copies, or at least have a smarter system than that.
Maybe a section on the Server where gems lie, and a section on the hard-drive of your dev computer where gems lie - and then in a build process, it finds the gems with a certain checksum or tag or something similar. That's an interesting idea you have.
If it lives behind a proxy, a web server being able to talk to anything but the proxy server and database is a matter of developer convenience.
The dirty little secret is that these things are trivial to set up. Anyone whose build or deploy has been broken by github, rubygems.org, ruby-lang.org or even rvm.io falling over is Doing It Wrong. While I empathise, I have very little sympathy for people panicking when github gets DDoSed again.
The complexity comes in mirroring the right set of other people's gems, which match the exact combined set of all versions used in all your various projects.
There is not a good "pass-through" gem server that just automatically mirrors what it is asked for from RubyGems. There really, really should be.
Rubygems is a wonderful and powerful tool for getting libraries set up and adding new code. It's not really suited for putting things into production, especially when people think pulling old versions (for whatever reason) is acceptable behavior.
At work we install and set up libraries on development machines using bundler/rubygems, then go in and version lock everything after we know we'll be using it. Building a release-worthy version involves repackaging all of the gems as rpms so they can be installed along with all of our other software when building the new (virtual) server.
It's a pain in the ass, yes, but we have never had library issues crop up in production. I know exactly what is on the system, and fixing anything is an obvious and straightforward process.
You don't have to make things this formal/official, but it's pretty easy to achieve library version updates and know that what's on your server will work correctly at the same time.
P.S. I enjoy reading your comments as do many others, but I feel you hand-wave over important points sometimes, e.g. Why you feel tagging is important. If it truly is a 500 word discussion it shouldn't be hard to synopsise.
Tags, plus sufficiently advanced dependency management and database migrations (n.b. not trivial!), allow you to track and reproduce past states of the deployed software.
For example: A customer reports a problem. You verify the problem exists. The customer reports that the system didn't have the problem last week Tuesday. If you want to know why, tagged releases (and a record of them -- incidentally, another one of the 643 things to know is "All deploys should be recorded somewhere") let you travel in time back to the software in use last Tuesday, verify if the customer's recollection is accurate (well, sorta), and then compare just what has changed rather than trying to run down the bug without any historical context.
Naming things also lets you talk about them, which is helpful, because you'll want to talk about individual releases of the software. (I mean, sure, you could use random hexadecimal numbers, but for whatever reason people find production_release_20131007_3 a bit more informative than 066630de00d242137efab6bf21b8ea04aeee7a1d. One glance at the first one tells you that it's the 3rd deploy from October 7th, assuming you've used the company's naming convention for more than a minute. The second one tells you nothing and is difficult to pull useful information out of without having to manually cross-tabulate it with you git repository, which would be unfortunate if it were e.g. attached to a log file, customer support request, or Wiki article about known-good releases for interacting with external systems.)
FWIW dates in tags are redundant because the tag itself has a time stamp. Re: environment names in tags, IMO they don't belong in the repo.
Thanks for replying.
Having them in the tagname makes it much easier and more visible.
after "deploy:restart", "deploy:tag_release"
desc 'Tag release'
task :tag_release do
`git checkout #{rails_env}`
`git tag #{rails_env}_#{DateTime.now.strftime "%Y_%m_%d-%H_%M"}`
`git push --tags`
`git checkout master`
end
Boom!My code won't be appropriate if you don't use master/staging/production branches, either.
set :branch do
default_tag = `git tag`.split("\n").last
tag = Capistrano::CLI.ui.ask "Tag to deploy (make sure to push the tag first): [#{default_tag}] "
tag = default_tag if tag.empty?
tag
endWhy would you come here to say that? Capistrano is one way to deploy software. Heroku's method is another. Neither is wrong.
This kind of thing is why author's of open source tools like Capistrano get burnt out and just want to run for the hills. Because people with no skin in the game have to come along and shoot their mouth off.
You're probably a really nice person, but when you do things like this, you hurt other people and you make yourself look like an asshole.
In the meantime, and if you're on AWS, check out OpsWorks. It's the cat's pajamas. It both makes much of the hassle of deploying a thing of the past, is extremely flexible, and makes it possible to have Heroku-like "git push" deploys without giving up control (or being forced into Beanstalk's opinionated ways). Amazon made a very smart purchase when they bought Scalarium.
Both Rails and Meteor will let you develop apps at breakneck speed, with their powerful, magic cores and their excellent module ecosystems, but when you get to deploying them you'll sometimes wish you'd stayed on LAMP or (god forbid) ASP.NET. Yes, I really said that.
We're spending $50k-$100k/yr on Linux system administration of all the small and big moving parts that always fall apart and requires constant babysitting.
I want to give MSFT all this money and use MSVS, C#, ASP.NET and Azure for everything. I love MSVS and always loves MSVC (back in the days). I love performance of C{++|#}.
I don't feel inspired to build great SaaS solutions with shitty interpreted languages, forcing to use made-in-the-basement plugins (or gems) and all that trailing crap of sluggishness, upgrades, fixes and weird behaviors that follows.
Now you all may downvote me!
if it's destroying you, leave. go on a long vacation. it's not worth it. there's no shame or guilt in taking a break or passing on your work.
I am yet to look into v3 stuff closely, but if you think it is better why not make maintstream? Is the main reason just community backlash?
Our company also uses Cap extensively and we really appreciate all your hard working building and maintaining it. I totally feel your pain reading responses about bugs, test coverage, etc. I urge you to consider whether you can get a couple of trusted allies or colleagues involved in putting Cap 3 out. I think it could be a huge boon to those of us who like the idea of modularized code and perhaps you can find a buffer or person who is willing to field some or all of the influx of bug reports (directly ask the community if so!)
Tom, if you are on HN, you're the only reason this project has been able to come as far as it has. Thank you.
I mean for something as operationally critical like Capistrano, why dont you seriously raise money on Kickstarter, outsource some of the testcases, etc. and be more productive overall.
And please feel free to raise money to fix RubyGems as well ;)
I'm going to take a closer look into the source code and try to help out with issues. It's something I've been wanting to do for a while so I hope I can at least help out a little bit here
You'll always be the creator of Capistrano and for this your reputation will live on. If you've got clients that love you, your business will also thrive. I think your fear of letting go is probably unwarranted, and in any event your happiness should come first.
Maybe you can find a way to delegate the bits you don't like about maintaining Capistrano so you don't need to directly manage it yourself? This is probably niave and maybe you are doing this already with v3 but it occurs to me if rails is the main cause of the headaches perhaps you can split that part into a cap-rails gem that is separately managed then you could hand over the reigns to someone else?
Anyways, as mentioned, thank you for a great tool - I very much hope you find a solution that helps you feel good about the situation.
As for your comment, "Ruby is pathologically difficult to install correctly on modern Linux distributions", I disagree wholeheartedly with this. It may be more difficult to install than a simple `apt-get`, but if you're used to compiling from source and you know what the hard dependencies are, it's really not a huge problem. ruby-install and ruby-build of course make this easier but those tools don't require the use of RVM or rbenv, especially on a machine where you know there will only be one Ruby. However, you're correct in the assumption that Ruby could be a lot easier to install if the language creators would move towards that. That said, I think there are a lot of people who are unfairly blaming you for their own misunderstandings of what these tools do and how they are used. For example, chruby or rbenv is absolutely vital on my dev machine because I work with projects using different versions of Ruby. But it's just bad practice to have a production box running multiple versions of Ruby, in my opinion.
I really feel that the users you've interacted with may have been frustrated by their own misunderstanding of the tools they're using, because it's really not as hard as a lot of people make it out to be...
Can someone direct me to the common complaints, or outline the common complaints here?
https://gist.github.com/bradland/6861980
That's 9 lines of shell if you exclude comments, and includes the MD5 check. I've updated these commands a few times as Ruby has advanced, but most of the changes come with my distro updates. For example, the Debian 7 release required an update to most of the libs that Ruby depends on. Otherwise, it's been relatively trouble free.
1: It's not really a build script. It's a listing of the shell commands you'd need to install Ruby manually. I extracted them from my build scripts.
Here's my take on using rbenv to have the same kind of environment on your laptop and the server - damn fast : http://www.lambdacurry.com/damn-fast-production-ready-ruby-s...
Why are you forced to use RVM on the server? A great number of the issues people face when trying to deploy Rails apps are environment based. Tools like rbenv and RVM are environment managers. They make all kinds of changes to things like PATH, GEM_HOME, etc.
In a production server environment, you want consistency and simplicity. Yes, you can use tools like rbenv or RVM, you but add layers of environment management on top of the base server environment. When you use these tools to manage Ruby on your server, any process or daemon that needs Ruby will first have to ensure that these tools are loaded and invoked properly. It's a layer of indirection that I feel a strong incentive to avoid.
Don't get me wrong. I'm not saying they're not good tools. Quite the opposite. I'm a huge fan of RVM, rbenv, and chruby. I have a deep appreciation of their contribution to the Ruby ecosystem, but I'm one guy. I have a reasonable understanding of Linux system administration, but the more layers of complexity I add, the deeper the water gets. At some point, I'm in over my head.
There are two really great options for installing Ruby on your production servers:
Note: Most Linux distributions give /usr/local/bin priority in PATH by default, which is why I use it instead of /opt. Using /usr/local/bin means you don't need to modify PATH.
1) Use ruby-build [1]. This is the plugin that rbenv uses to install Ruby, and you can use it without rbenv. Once it is installed, this simple invocation will get you a working Ruby install:
ruby-build '2.0.0-p247' '/usr/local'
Because of the reasons outlined in the note above, this type of Ruby install will "just work", even for utilities that shell out with bare shells like `sh -c 'some command here'`. This is because we installed to paths that work with the bare minimum environment.2) Install from source. In the example above, ruby-build really isn't doing all that much. You still have to have the basic deps (build-essential, zlip, ssl, readline) in place in order to build Ruby, and you have to remain aware of any caveats introduced by new OS or Ruby releases.
I use option 2.
A great way to keep up with what's required to install Ruby on your system is to look at what tools like rbenv and RVM are doing under the hood. These tools act as collectors for the little hacks and workarounds (e.g., ref URL 2 below) that are occasionally required to install Ruby. If you're running a mainstream distro on a recent release, you really shouldn't need much in the way of hacks/workarounds these days. OS X is where a lot of the trouble lies.
1: https://github.com/sstephenson/ruby-build
2: https://github.com/sstephenson/ruby-build/blob/master/bin/ru...
EDIT: Above I said, "[ruby-build] isn't doing all that much", which isn't entirely fair. Ruby-build does do some really nice things like check MD5 hashes. It also checks for common caveats, which I kind of played off. I do the work of looking out for these things, but I'd certainly understand why someone wouldn't want the hassle, and ruby-build does a fantastic job of keeping up with these hassles and automating them away. In short, I want to be crystal clear that I am super appreciative of the work that the rbenv and RVM authors do. They are a tremendous asset to the community.
sudo apt-get install build-essential openssl-dev zlib1g-dev
wget http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz
tar xvfz ruby-2.0.0-p0
cd ruby-2.0.0-p0
./configure && make && sudo make install
This is not hard, and it's never caused me any kind of trouble.Also, if you did that and also did something like "apt-get install chef" or something that installs the system ruby, you will have two copies of ruby installed and need to make sure your $path is correct.
As far as system Rubies go, I try to keep things simple. I use Debian for my systems, so I know that `/usr/local/bin` will always be first in my path, so that's where I install.
This falls far short of "awful" in my opinion. There are many pieces of software that are far more difficult to compile from source.
I don't know what life is like for Rails devs, but just getting Chef up and running is painful enough that it killed any latent interest I might have had in ever diving into Ruby.
In that case, part of the problem was documentation (as far as I can tell in retrospect, I never really needed anything other than the Ruby 1.8.7 I already had installed), but just being exposed to rbenv and the mess of that world left a bad taste in my mouth.
Of course, it's not just Ruby. I have no use for the similar tools for any environment, that purport to let you keep multiple versions installed simultaneously. Whether it's for Python, Groovy, Ruby, whatever. I've come to the conclusion that it's just plain A Bad Idea to do that sort of thing.
Ran "update-alternatives" and set Ruby back to 1.9.3 and now when I try to install the Gems, I get failures like:
"in `require': cannot load such file -- mkmf (LoadError)"
I think I'm making progress, but man, this is frustrating.
To be fair though, the basic Chef install is done and working, and I can run "knife client list" and see my clients. It's just that I'm trying to get through this EC2 tutorial and it has you installing this specific list of Gems, and that's where the problems are now. sigh
If you're not a Rubyist and just wants to use Chef, Chef's own Debian packages work great. You can ignore RubyGems and update-alternatives and other stuff, Chef's Debian packages provide everything you need.
I think that Chef should go through the tutorials and clean up the old things.
I don't have a problem with Ruby, I have a problem with its clusterfuck of programs that reinvent the package management wheel and assume that you're going to send your work over to magicland where all of the Ops wizards will make it into a working product.
The reason it's that way is because most of these people develop on Macs then hand off to someone to deploy on Linux. They don't know anything but web dev, and with PaaS like Heroku, they're never likely to. My warning, though: if the reason you're on a PaaS is because you have no idea of how to deploy, you're going to be paying an ignorance tax. Make Ruby easier to deploy, and PaaS will end up cheaper.
edit: I have no problem with rvm (or virtualenv) as a container to run different versions of a language and dependencies on the same server. To use those tools to run a single system version for a single application would be silly, but since the tools are completely broken for doing that anyway, it's simply impossible to do and to retain dark, lush hair at the same time.
Thanks for all you've done.
Before everyone leaps to conclusions, I'd better clarify - I am not saying there's anything wrong with you - I am not excusing the crass behavior which is getting you down.
What I'm saying is that there are almost certainly skills you can learn which will stop this getting to you. I don't know exactly what they are, and most people here don't either (although they will passionately sell you the hammer which worked for their particular nail). Ask an expert.
Thanks very much for your efforts and I am sorry you feel the need to step down from maintenance.
* Ditch v2 ASAP (seems like you've already decided on this). It's pretty obvious you aren't motivated to work on that codebase anymore. I've looked at v3 and it's much better thanks to relying on Rake tasks.
* Be selfish. It's your project so if you think v3 is the way to go forward, go with it and who cares what the "community" thinks.
* Seems like you already have a few people helping out, so continue and maybe make formal "core" team. There's nothing with yourself taking a step back from the heavy coding. But I believe that Capistrano would be better with your guidance than without it.
codebeaker: There was no mention of Harrow in that post. Are you still working on that? I'd assume that if you were you'd continue work on Capistrano since it's based on it.
Regardless of frameworks, and of technologies and platforms, I believe if I can take the load off myself with Capistrano, by turning it into the open source component of a best-practice company, and build teams of passionate, skilled support engineers, then I'll be where I want to be.
Unfortunatley Harrow would suffer if I give up on Capistrano, as part of the promise of Harrow as a SaaS is that it's all guaranteed to stay compatible, and work as we've all come to expect, just with improved workflow, etc...
([1] http://www.harrow.io, please excuse the missing graphic placeholder I've not updated the landing page in some time as I've been focusing on building the product, and the landing page performs really well without that graphic in place)
Or call the community's bluff. "I think v3 is the way forward, so that's what I'm going to be working on. If you want to stick with v2, you maintain it."
As a result various releases of v2 were buggy. Capistrano is a hard to test application agreed but its test coverage is plainly woeful.
About 6 months back when 2.4.12 release was broken (https://github.com/capistrano/capistrano/issues/434) I suggested to remove asset pre-compilation stuff from Capistrano. Capistrano is a general purpose tool, company where I work we use it for deploying java, php, ruby and all sort of stuff. I don't understand why it should have poorly tested asset pre-compilation things built in.
I don't know what made Lee work on a rewrite. I can only imagine how difficult it must have been for him to work on something so big singlehandedly while running a company.
His last point is very valid about using RVM, rbenv etc in production. I don't know why people do that. Does that make it easier? Aren't people aware of something like - https://launchpad.net/~brightbox/+archive/ruby-ng ?
The rewrite is a ground-up re-think, but it's leaning on the best of what the open source community has come up with in the last 5 years, and leaning heavily on all the best practices we've learned as a community.
The rewrite was also a way for me to say "this isn't a rails tool anymore" (of course, those of us who knew Capistrano well could always cut out the core railsisms and use it for deploying pretty much anything). And a way to say "look, this tool isn't magic, it's an orchestration tool that glues together some other libraries".
Part of the rewrite was to split things into components, so that when people have a version that works for them, bug fixing changes to rvm or rbenv, or other extensions don't have to risk breaking the core functionality. Stability through modularity.
A way for me to pay my envisaged debt to society for the good things that being the custodian of such a widely used project has brought me.
Many of the v2 releases were broken as I tried to let two people help me with maintainer ship, and both of them went a little nuts accepting pull requests, and a lot of things got merged that probably weren't quite upto scratch, or caused subtle problems, which is a huge problem of Capistrano.
I'm grateful to both of them for their bravery, and willingness to try and help, but maintaining it has been such a hard task. A balance between maintaining compatibility, and not breaking people's production environments, and pushing the tool forwards, and improving it.
1) Use multiple parallel Ruby versions for transitions and rollbacks - for example, when we upgraded from Ruby 1.9 to 2.0, we installed 2.0 via RVM, ran our staging environment on 2.0 while production ran on 1.9. The instant-rollback safety net is great, because if we run into some obscure bug on one VM, we just change our RVM environment config var and deploy and we're back to known-good in seconds with no downtime.
2) Run applications that require different Ruby version levels. For example, Puppet 2.7 wasn't compatible with Ruby 1.9+, but our app was running on 1.9. With a single system install, we'd not be able to run both.
The point about stepping out-of-bounds in regards to LTS distros is extremely valid, but at least in our case, it's not about "just effin' compile already!", but rather about flexibility and resilience - by using RVM, we absorb the burden for making sure things work rather than delegating it to our distro, but it's worth it for the things we pick up.
Personally I always try to run ftom apt in production.
I'd suggest Lee runs a Kickstarter type thing and I'd very happily throw in $100. But I don't think he will because it doesn't seem quite right.
So here's a (wild and completely off the cuff) startup idea - a pre-emptive Kickstarter. Someone creates the project "Lee Hambley, continue working on Capistrano." and we all pledge into the pot. If Lee agrees to do it, he gets the money. If not, we don't pay anything.
What you want to do is build a single package of everything your application needs (which includes the application code and all dependencies -- libc and up), then copy that package to the production servers.
It shouldn't matter if your application server has Ruby 1.9.3 and you need 2.0.
It shouldn't matter if the last deploy of your app needs Nokogiri compiled against libxml 2.8 and you now need 2.9.
It shouldn't matter if you are running 5 different apps with 5 completely different set of dependencies on the same machine.
It shouldn't matter if you need to use the asset pipeline.
It shouldn't matter if github or rubygems drops out half-way through the deploy process.
All the production server should get is a single package of all that your application needs, then a 'restart application' command.
Docker should be able to handle all this simply.
If I had a Mac I'd skip the ad-hoc Ruby environment switchers and skip straight to Vagrant.
Then one day a rare instruction set on our colocated server (so not something super standard like linode) was specified during the compilation step of ruby and (due to an extremely subtle co-bug between ruby and the compiler). It took us fucking weeks to find this hisenbug that was somehow causing workers to drop, but only during times of very high load.
Probably lost $500k worth of customers, dev time, and company moral.
Now I have a different view. Keep things as simple and as "normal" as possible. That way you can always upgrade to the next version, you don't hit weird bugs when you libraries assume that Time.now is second-accurate, instead of sub-second accurate (MRI vs Enterprise Ruby).
RVM is made for production (http://stackoverflow.com/a/6282260/384700) and it saves a lot of headaches to just go with the flow. As for mac dev, I agree that it is a waste of time compared to working out of Ubuntu, but designers like photoshop and Vagrant is non-trivial for them to set up, especially for people that work on multiple projects.
Simple and normal, to me, means "use packaged Ruby." Chasing the bleeding edge and compiling the interpreter at every release is exactly the sort of practice that introduces edge-case heisenbugs.
If you need a nonstandard compile-time option you go to work on the package source, make the change, put your custom package up in your private apt/yum repo, and leave things alone until the next security update comes down the pike.
Me, I consider hosting to be entirely fungible. I'd rather change vendors than mess about with custom packaging big chunks of the stack to work around weirdness.
Wherever I have encountered Phusion's REE I have ripped it out, with good results.
I think most people that uses rbenv or RVM in production is only compiling new versions if the specified version isn't there already.
No.
3pt14159 said that he used to use distro-packaged Ruby, but stopped because his distro used a compile-time option that didn't play well with his vendor's hardware.
3pt14159's solution was to start using rvm on production boxes.
I think that is a bad idea, and that either:
1. 3pt14159 should just pull down the package source, change the compile time option, rebuild the package, and use the mildly customized package in production.
2. 3pt14159 should not waste time working around hardware weirdness, and just switch to a vendor that doesn't have these problems.
chruby (probably also rbenv, haven't used it) is easier to understand and trivial to set up with non-interactive shells.
export PATH=$PATH:/usr/local/rvm/bin/rvm
. /usr/local/rvm/scripts/rvm
. $REPO/.rvmrc
. $(rvm jruby-$JRUBY_VERSION do rvm env --path)
cd $REPO
bundle exec torquebox deploy
Definitely not ideal and I spent a large amount of hours figuring out how to use it non-interactively. I'm still somewhat worried that some things might go wrong if some of the code I didn't write in this repo attempts to call binaries directly. Basically with bundle exec --deployment, all gems are stored in $CODE/.vendor which is necessary to allow users to install their own gems, with the root installation. Bundle exec has to be used, I messed around with RVM wrappers, but they don't work with the --deployment bundler use. source /usr/local/rvm/environments/$BUILD
You can put it in a wrapper script if you like. It will unset all conflicting environment variables first.Maybe rvm/rbenv is not the best solution, but some solution is needed. You can either invent one yourself, or adapt something that's already been built. We're using rvm, and while I'm not a huge fan of it and would rather switch to rbenv, I've managed to tame it so that it's not such a huge beast, using various wrappers so that non-interactive Ruby programs work start up in the correct environment.
If it's more arcane than that, it sounds like kvm or lxc is the answer.
If you really really need to run two pieces of software with differing ruby interpreters on the same machine, then your real problem is technical debt. One fix would be to update the ancient software so that it can use modern Ruby. Another fix would be to re-architect the solution so that the greater system could operate across multiple OS instances. The least attractive option would be to use packaged Ruby for the modern stuff, and a hand-compiled Ruby for the legacy stuff.
Why?
Why can't you have a stable app using Ruby 1.9 that hasn't need any updates (other than security) in three years running on the same machine that also runs another newer application which uses Ruby 2.0 and Rails 4?
To me, that's not "technical debt".
I wouldn't want to worry about dynamic library loading flags.
Sometimes it is the list of default gems that is different (like how fedora packages bignum as a gem), and sometimes it is the distro packaged gems that just doesn't look like the stock versions. I've seen examples of gems split into two gems, as well as gems that has had their version dependencies altered. things like that easily makes either rubygems or bundler very unhappy.
The thing about distro packaged software is that you have to trust the distro to do the right thing, and it only takes so many examples of them doing something stupid before that trust is lost.
RHEL used to be notorious for breaking their Perl 5 dists. The first rule of Perl was to compile your own the server.
> hey exist to allow developers on Macbooks to sync their version of Ruby with whatever is packaged in the Linux distro or BSD variant that runs in production.
Or to allow developers who run ubuntu to develop multiple projects which need conflicting versions of the Gem and interpreters seamlessly. Also, I sometimes deploy multiple projects on same production box where the 2 might need different interpreters, and they almost always need separate gemsets. I can manage the interpreters and LOAD_PATH manually, but then I will end up creating an unholy mess which will somewhat resemble rvm.
I am curious. What are your reasons for "rvm doesn't belong in production"?
Yeah, sure, you can have multiple versions of Ruby and the Nokogiri gem on the same box. libxml2, borrowed from the GNOME project, is the C library that is doing all of the heavy lifting underneath. If the version of libxml2 on your dev machine is different than the version in prod, it doesn't much matter if you've got the same version of Ruby and the same version of Nokogiri.
Use Vagrant. You will get a complete Linux VM for each different project that will match up perfectly with whatever the prod environment looks like.
Use Vagrant to spin up Linux VMs locally so that you can have a dev environment that matches production.
I don't work in a Ruby shop anymore, but I'd look at Bundler if I was looking to manage multiple gemsets on the same installation. As I point out in the above thread, maintaining multiple gemsets on the same machine is an antipattern that points to technical debt.
Ruby 1.8 is over. EOL. You need to port everything forward or suffer the consequences.
False dichotomy. There is no technical debt. Both Ruby 1.9.3 and Ruby 2 are functional and used in production. It will take some time to totally move to 2, and when that happens, there will be applications on different release versions of 2. I don't want to wait for os packaging to use a new ruby release, and I don't want to be forced by the packaging to use a particular version(older or newer).
> I don't work in a Ruby shop anymore, but I'd look at Bundler
Um. I use Bundler along with rvm.
> maintaining multiple gemsets on the same machine is an antipattern that points to technical debt.
Having a restriction of not more than one app on one machine is as stupid as it gets.
How does rvm fix that?
Superior package management is the reason that small teams of ops people can manage huge deployments.
In the bad old days of early Linux or traditional UNIX one had to hand-build and deploy those dozens of libraries that go scrolling by when you "apt-get install libxml2". Worse, the only way to really figure out the dependency tree was a recursive operation that involved picking a library, downloading it, attempting to build it, waiting for it to fail, figuring out what other library was missing, downloading that library, attempting to build it, waiting for it to fail, figuring out what library was missing...
Inevitably, the grad student that wrote one of the libraries somewhere in this dependency soup would have moved on, and the web page at http://morlock.iscs.random.edu/~gradguy would disappear. The next step would be to fire up an ftp client and start digging around sunsite.unc.edu and some surviving yggdrasil mirror in Australia with a banner that said "PLEASE DO NOT USE THIS SERVER IF YOU ARE OUTSIDE OF AU/NZ, WE ARE PAYING $10 PER MEGABYTE ACROSS INTERNATIONAL LINKS."
Once the software was compiled you then had to subscribe to every mailing list for each piece of software and keep an eye for security notices. If the project didn't have a mailing list you had to keep an eye on the relevent USENET groups where something might get mentioned. If the project had neither you just had to visit the FTP site every so often and see if there was a new version. If the project had a changelog you could read that and hopefully make a decision as to whether it was necessary to upgrade. If it didn't have a changelog you had to diff the old source and the new source and try to figure out what the implications were.
Package management put an end to this insanity. The Linux Filesystem Standard was an important part of this, as well.
rvm turns its back on 20 years of progress and goes takes us back to ad-hoc what-the-fuckery.
A proper Linux distribution is an exercise in distributed responsibility. Instead of saddling every sysadmin in the world with the individual responsibility of making all of these decisions, expertise is allowed to accrete with the individual packagers. The operator evaluates the quality of the distribution and trusts the packagers to do the right thing.
So what do you do if the specific Ruby version you need isn't packaged?
What's that I hear? Compile from source? How exactly is that any better than RVM? Every single piece of criticism you shouted against RVM applies just as much, if not MORE, to tarball compilation.
What if the distro only provides 1.9 but you need 2.0 features?
It sure is easy to wave your hands and accuse people of being insane.
I'm also of the opinion that compiling assets in production as a part of your deployment process is insane, there's so much magic in the Rails asset pipeline that it's not uncommon to turn up bugs where tables don't exist, and the rails app can't initialize, or some javascript runtime environment isn't found which can leave your deployment in a broken state.
I'm firmly of the opinion that assets should be compiled and checked in, but then of course you run into problems with rails serving those in development mode, rather than the development files.
All these issues are fixable, but they're all indicative of tools that aren't quite mature yet, and as Capistrano sits on the boundary of where these problems come to light, it seems to fall to us to deal with it, and to educate people on what they ought to be doing.
Education is no problem, I really believe that the de-facto standardisation of Rails-like deploys (i.e timestamped releases, with common linked directories, and a symlink to the current active timestamp) is an excellent result for knowing what to expect in an environment where there's hundreds of ways to get Rails apps running, but it's still not as smooth a process as it could be.
I'm familiar with at least one project that's been re-written in Scala and Java because the previous version was prohibitively difficult to deploy as it was in RoR. (GrayLog2, to namedrop them)
> some javascript runtime environment isn't found
This is a very familiar pain point for me. IMHO many problems with RoR deployment stem from the fact that Ruby depends on so many native code extensions. It's pathetically easy to break things like therubyracer or nokogiri because some .so file was updated or is not installed. I'm guessing that this is done for performance issues with the Ruby interpreter, but wow, it really makes for portability nightmares. Add RVM on top of this and it's just insane.As someone coming from Java (I largely switched from Java to Rails about a year ago) I find this tendency toward native code deps incredibly painful. Turns out there's a really good reason to demand "100% pure Java" libraries. One can always throw rocks at Maven or CLASSPATH hell, but I find that Ruby deploys tend to be much more problematic than Java.
Whatever you decide on I hope you get some relief. FWIW I have benefited greatly from your work on Capistrano, and sincerely appreciate your efforts.
This is one of the pain points for me. Even when everything is setup, the asset compilation churns the disks and takes way too much cpu. I would rather do that on my local machine than disrupt the production server. I do a simple workaround for that:
namespace :deploy do
namespace :assets do
desc 'Run the precompile task locally and rsync to shared'
task :precompile, :roles => :web, :except => { :no_release => true } do
run_locally "rake assets:precompile"
run_locally 'rsync -e "ssh -i production.pem" --recursive --times --rsh=ssh --compress --human-readable --progress public/assets #{user}@#{host}:#{shared_path}'
run_locally "rake assets:clean"
end
end
end # Dont recompile assets unless they hange
task :precompile, :roles => :web, :except => { :no_release => true } do
from = source.next_revision(current_revision)
if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
else
logger.info "Skipping asset pre-compilation because there were no asset changes"
end
end
I'm not entirely happy with it and don't even know if it's something I should be doing. I rarely change my assets, so this at least allows me to do quick deploys until an asset change comes. (shrug) It feels incredibly hacky.For me, the more important thing was not compiling on a production box. Compiling on production box does lots of io and uses way too much cpu. I am ok with a slight delay in deploy due to assets compilation happening on my local machine.
I see a lot of people in this thread criticizing the assets pipeline. But I think it's a good idea with an implementation which is yet to mature. For now, it needs some work on my part(do I check in the assets, do I compile on production box, how do I ensure assets are only compiled when changed etc etc), but overall I am quite happy with the way it works.
I have used Capistrano a lot, I built my "default" setup, compiled it into a gem, and released it here: https://github.com/kaspergrubbe/simple-capistrano-unicorn and moved on with my life as a developer.
I know of at least two bigger organizations that depend on Capistrano (and my gem) for their deploys. I feel like Capistrano is the way to go if you manage your own servers, and need to deploy to them.
Capistrano started my Rails experience, and I am very grateful for the work put into it. But I never wrote and said "Thank you" or "Great job", maybe we need to be more vocal to the people that put in time and energy to build the software that we use a lot.
If your tool sees any sort of uptake, it suddenly no longer is yours. The community suddenly expects you to not only to continue to modify the base code to improve functionality, but to also adhere to a sort of backwards compatability so that everything they know and loved about your baby never changes.
I can't imagine how much more taxing this would be once the tools you built become integral part of other team's workflow. The burden and stresses of keeping "the world" afloat would cause many a sleepness night for people of strong constitution.
At our company, we develop multiple RoR apps and we've run into many of these issues (mostly related to the asset pipeline), yet none of them actual problems with Capistrano. Since it's the bridge between so many things, I can imagine why it's easy for it to become cannon fodder.
We've tried to standardize many of our recipes such as local asset precompilation into a single cohesive gem (https://github.com/innvent/matross). That has saved us the trouble of debugging the same issues over and over when they inevitably pop up across applications.
I believe when you said that PAAS will go, only reason I use heroku and dokku(from docker) is due to its easy deployment.. and for no other reason than deployment..
https://gist.github.com/kaspergrubbe/5792356
Is this an issue with Graphite? Because I feel this setup is quite elaborate compared to using Rubygems and bundler.
sudo apt-get --assume-yes upgrade
in it. But to your point, I think most of the easy_install packages could be handled by pip. The apt packages look like almost all non-python major components like rabbitmq, apache, sqlite, etc which are best provided that way.I'm not sure about Graphite itself, but at a quick glance it's not clear why it's all 'sudo python setup.py' rather than in a package.
Graphite is both a good and bad example. Good because it is really complex and documentation is a little sketchy. I've written a fabric script[1] that automates the process, and it's far from trivial. Bad example, because it's not really a single app, but a system - a collection of tools with dependencies. Even if we discount the web server (nginx or apache?), it includes things like the core "database" (whisper), the event listener (carbon, which in itself is complex depending on your setup), the graphic and processing libraries, and then graphite which is a pretty involved django app with its own sub-components.
So when you say graphite, it's really a full-blown system with lots of moving parts that need to fit in together. I can't think of an equivalent example in the rails world, but any rails app with a db, caching layer, and a few other external components won't be much easier to get set up and running.
However, when dealing with projects that are closer to pure python, and/or less complicated, workon proj && pip install < requirements.txt has almost never failed me.
More and more I find myself moving to Ansible. So good.
I'm not sure, I just think it's worth discussing.
Me I run Rails on Linode and it's fine, but yes, it's unfortunate Ruby/Rails never reached LAMP-level simplicity on virtual hosts.
$ play dist
$ unzip app-name.zip
$ cd app-name
$ ./bin/start
Can dist on build server and copy archive to prod if that option is available (or upload from local dev machine).
It's ridiculously simple, and all generated at compile time.
I don't understand hand wringing deployments, is Rails _that_ good?
I mean, outside of MVC, RESTful routing, form validation, AR, migrations, etc. functionality that exists in other frameworks/libraries, what does Rails actually bring to the table that is unique?
Is it the gem ecosystem, where you can find x,y,z functionality that exists nowhere else, or some cutting edge Rails feature? I don't know, just asking, spent a year on a Rails clone, Grails, and was not really taken, tracking runtime MOP errors is no joy, give me a static compiler any day over that.
Need versioned assets? Need multiple versions of assets in prod? Play doesn't do it out of the box.
Need a specific version of the JVM? Play can't help you there.
Need to change your start script to do something different (ports, SSL, JVM config). Play can't do it.
Play is very far from deploy script.
Just turn off assets entirely as the Capistrano author does with Rails. Running Bower + GruntJS here, snappy fast, well happy working with tools designed for the job.
Not sure about multiple asset versions, I just have front end web server handle inbound /assets/img/foo.timestamp.png request as /assets/img/foo.png. It's not too difficult to create an asset helper trait to append timestamp at container start up to asset paths.
> Need a specific version of the JVM? Play can't help you there.
This is hardly a strike against Play, installing Java is not exactly an overwhelming task ;-)
> Need to change your start script to do something different (ports, SSL, JVM config). Play can't do it.
Excuse me?
./bin/start -server -Xms128m -Xmx512m -Dhttp.port=9001 -Dhttp.address=172.16.53.1 -Dlogger.file=${HOME}/logger.xml -Dconfig.file=conf/prod.conf
Kudos. It takes a lot of courage to admit your baby is not going to fulfill the future you had initially imagined.
[1] http://ruby.awsblog.com/post/Tx2AK2MFX0QHRIO/Deploying-Ruby-...