Live data from Hacker News

Rails on Docker

fly.io

131–140 of 228 posts

Re: Rails on Docker

#131

Earlier quoted context omitted.

I work a lot on modernizing codebases. Many times it will be codebases without any proper testing, different versions of frameworks and programming languages, etc. Currently, I'm working in 3 projects at once + my own. Even though it's all PHP, the projects are PHP 8.1 / Symfony 6.2, PHP 8.2 / Symfony 6.2, PHP 8.1 / Laravel 8 and the newest project I joined is PHP 7.4 / Symfony 4. I have to adhere to different standa…

Sure, but that feels like a band-aid on an existing problem. And sometimes a band-aid is what you need, especially with legacy systems, so I'm not judging that. But I think for a new project, these days, it's a mistake to plan on needing Docker from the outset. Modern languages with modern tooling can automatically take care of dependency management, running your code cross-platform, etc [0]. And several of them even…

How do you mean?

If the new project without any tests with a PHP 7.2 and MySQL installation and I need to upgrade it to PHP 8.2, I first need to write tests and I can't use PHP 8.2 features until I've upgraded.

Composer is the dependency manager, but I still need PHP to run the app later on. And a PHP 7.2 project might behave differently when running on PHP 7.2 or PHP 8.2. And sometimes PHP is just one part of the equation. There might be an Angular frontend and a nginx / php-fpm backend, maybe Redis, Postgres, logging, etc. They need to be wired together as well. And I'm into backend web development and do a bit of frontend development, but whoa, I get confused with all the node.js, npm, yarn versioning with corepack and nvm and whatnot. Here even a "yarn install" behaves differently depending on which yarn version I have. I'd rather have docker take care of that one for me.

I feel like "docker (compose)" and "make" are widely available and language-agnostic enough and great for my use cases (small to medium sized web apps), especially since I develop on Linux.

Something language-specific like pyenv might work as well, but might be too lightweight for wiring other tools. I used to work a lot with Vagrant, but that seems to more on the "heavy" side.

Edit: I just saw your examples, unfortunately I've only dabbled a bit with Go and haven't worked with Rust yet, so I can't comment on that, but would be interested to know, how they work re: local dev setup.

Re: Rails on Docker

#132

I do miss the pre-docker days of using capistrano to deploy rails projects. Most deploys would take less than two minutes in the CI server and most of that was tests. The deploys were hot and requests that happened during the deploy weren't interrupted. Now with Docker I'm seeing most deploys take around ten minutes. The downside of capistrano was that you'd be responsible for patching dependencies outside of the Gem…

I hear you, I love(d) capistrano and do miss it quite a bit. That said, the cap approach was easy for a static target, but a horizontally scalable (particularly with autoscale) was an utter nightmare. That's where having docker really shines, and is IMHO why cap has largely been forgotten.

I still use Capistrano and have full Load Balancing and Autos-scaling implemented via the elbas gem. I would be happy to share my configuration if anyone needs it.

Re: Rails on Docker

#133
post #46
post #5

This is really cool. Is the Rails server production ready? I was always under the impression you had to run it with Uvicorn or similar, although I haven't been following Rails development recently.

Yes, usually you still serve your asset (images,...) directory through nginx or something similar, though.

This has been my experience too, and I've never even used Rails at scale. Puma will struggle to serve "lots" (tens on a single page) of (for example) static images (though the actual user experience varies across browsers - safari does okay but firefox chokes and chromium is in the middle). This is with puma on a decent intel prosumer CPU (an i7 iirc) using x-sendfiles through nginx. So puma isn't even actually pushing the image bytes here.

I replaced it with nginx intercepting the image URLs to serve them without even letting puma know and it was instantly zippy. I still use sendfile to support when I'm doing dev and not running nginx in front of it, and I'm not happy with the kind of leaky abstraction there, but damn are the benefits in prod too difficult to ignore.

Re: Rails on Docker

#134
post #100
post #84

Earlier quoted context omitted.

Unfortunately this syntax is not generally supported yet - it's only supported with the buildkit backend and only landed in the 1.3 "labs" release. It was moved to stable in early 2022 (see https://github.com/moby/buildkit/issues/2574 ), so that seems to be better, but I think may still require a syntax directive to enable. Many other dockerfile build tools still don't support it, e.g. buildah (see https://github.com…

And AFAIK buildkit is still a real pain to troubleshoot, as you can't use intermediate stages :/ You can put stuff in a script file and just run that script too.

You can! It's experimental but https://github.com/docker/buildx/pull/1168

Tracking for this: https://github.com/docker/buildx/issues/1104

Re: Rails on Docker

#135
post #102
post #99

Earlier quoted context omitted.

How so? I just tested a build, and it used the cache for every layer including the builder layers.

You did this on the same machine, right? In a CI setting with no shared cache you need to rely on an OCI cache. The last build image is cached with the inline cache, but prior images are not

I never got around to implementing it but I wonder how this plays with cross-runner caches in e.g. Gitlab, where the cache goes to S3; there's a cost to pulling the cache, so it'll never be as fast as same-machine, but should be way faster for most builds, right?

Re: Rails on Docker

#136
post #67

Earlier quoted context omitted.

There are however temporary files being downloaded for the apt installation, and while in this case it's simple enough to remove them in one step that's by no means always the case. Depending on which gems you decide to rely on you may e.g. also end up with a full toolchain to build extensions and the like, so knowing the mechanism is worthwhile.

How would you go about copying something you installed from apt in a build container? Say `apt install build-essential libvips` from the OP, it's not obvious to me what files libvps is adding. I suppose there's probably an incantation for that? What about something that installs a binary? Seems like a pain to chase down everything that's arbitrarily touched by an apt install, am I missing some tooling that would tame…

Run "dpkg -L libvips" to find the files belonging to that package. This doesn't cover what's changed in post install hooks, but for most docker-relevant things, it's good enough.

Re: Rails on Docker

#137

Earlier quoted context omitted.

Sure, but that feels like a band-aid on an existing problem. And sometimes a band-aid is what you need, especially with legacy systems, so I'm not judging that. But I think for a new project, these days, it's a mistake to plan on needing Docker from the outset. Modern languages with modern tooling can automatically take care of dependency management, running your code cross-platform, etc [0]. And several of them even…

How do you mean? If the new project without any tests with a PHP 7.2 and MySQL installation and I need to upgrade it to PHP 8.2, I first need to write tests and I can't use PHP 8.2 features until I've upgraded. Composer is the dependency manager, but I still need PHP to run the app later on. And a PHP 7.2 project might behave differently when running on PHP 7.2 or PHP 8.2. And sometimes PHP is just one part of the eq…

I do work with Go and it doesn’t preclude the utility of containers in development for out-of-process services.

Re: Rails on Docker

#138

Earlier quoted context omitted.

Sure, but that feels like a band-aid on an existing problem. And sometimes a band-aid is what you need, especially with legacy systems, so I'm not judging that. But I think for a new project, these days, it's a mistake to plan on needing Docker from the outset. Modern languages with modern tooling can automatically take care of dependency management, running your code cross-platform, etc [0]. And several of them even…

How do you mean? If the new project without any tests with a PHP 7.2 and MySQL installation and I need to upgrade it to PHP 8.2, I first need to write tests and I can't use PHP 8.2 features until I've upgraded. Composer is the dependency manager, but I still need PHP to run the app later on. And a PHP 7.2 project might behave differently when running on PHP 7.2 or PHP 8.2. And sometimes PHP is just one part of the eq…

> and I can't use PHP 8.2 features until I've upgraded

Yeah- so in Rust, the compiler/tooling never introduces breaking changes, as (I think) a rule. For any collection of Rust projects written at different times, you can always upgrade to the very latest version of the compiler and it will compile all of them.

The way they handle (the very rare) breaking changes to the language itself is really clever: instead of a compiler version, you target a Rust "edition", where a new edition is established every three years. And then any version of the Rust compiler can compile all past Rust editions.

Node.js isn't quite as strict with this, though it very rarely gets breaking changes these days (partly because JavaScript itself virtually never gets breaking changes, because you never want to break the web). Golang similarly has a major goal of not introducing breaking changes (again, with some wiggle-room for extreme scenarios).

> I get confused with all the node.js, npm, yarn versioning with corepack and nvm and whatnot. Here even a "yarn install" behaves differently depending on which yarn version I have.

Hmm. I may be biased, but I feel like the Node ecosystem (including yarn) is pretty good about this stuff. Yarn had some major changes to how it works underneath between its major versions, but that stuff is mostly supposed to be transient/implementation-details. I believe it still keys off of the same package.json/yarn.lock files (which are the only things you check in), and it still exposes an equivalent interface to the code that imports dependencies from it.

nvm isn't ideal, though I find I don't usually have to use it because like I said, Node.js rarely gets breaking changes. Mostly I can just keep my system version up to date and be fine, regardless of project

Configuring the Node ecosystem's build tools gets really hairy, but once they're configured I find them to mostly be plug and play in a new checkout or on a new machine (or a deployment); install the latest Node, npm install, npm run build, done. Deno takes it further and mostly eliminates even those steps (and I really hope Deno overtakes Node for this and other reasons).

> maybe Redis, Postgres, logging, etc. They need to be wired together as well

I think this - grabbing stock pieces off the shelf - is the main place where Docker feels okay to use in a local environment. No building dev images, minimal state/configuration. Just "give me X". I'd still prefer to just run those servers directly if I can (or even better, point the code I'm working on at a live testing/staging environment), but I can see scenarios where that wouldn't be feasible

Re: Rails on Docker

#139
post #2

> Everything after that removes the manifest files and any temporary files downloaded during this command. It's necessary to remove all these files in this command to keep the size of the Docker image to a minimum. Smaller Dockerfiles mean faster deployments. It isn't explicitly explained, but the reason why it must be in this command and not separated out is because each command in a dockerfile creates a new "layer"…

If you want to check your images for some common leftover files in all the layers, I made an app for that: https://github.com/viraptor/cruftspy

Re: Rails on Docker

#140

What kills rails for me at the moment is the time it takes to start up. I'd love to be able to use on top of things like cloud run where resources ramp down to zero when there are no requests, but the startup time makes this very difficult.

(I have not actually used this myself). The folks over at CustomInk maintain Lamby, a project to run Rails in a quickly-bootable Lambda environment. Might be worth checking out, if you otherwise do enjoy working with Rails: https://lamby.custominktech.com
Post reply on HN