18 ms·
Rails on Docker
- laneystroup 4y agoI still use Capistrano. In fact, I like Capistrano so much that I have full Load Balancing, Auto-Scaling, and End-to-End encryption enabled for my projects on AWS via the elbas gem. My primary use case for this is PCI Compliance. While PCI DSS and/or HIPAA do not specifically rule out Docker, the principle of isolation leans heavily twoard the principle that web hosts must be running on a private virtual machine. This rules out almost all docker based-PaaS (including Fly.io, Render.com, AWS App Runner, and Digital Ocean), as these run your containers on general Docker hosts. In fact, the only PaaS provider that I can find advertising PCI compliance is Heroku, which now charges +$1800/month plus for Heroku Private to achieve it. I would love to share my configuration with anyone that needs it.
- deleted 4y ago[deleted]
- amarshall 4y agoDid you read the OP? > Fly.io doesn't actually run Docker in production—rather it uses a Dockerfile to create a Docker image, also known as an OCI image, that it runs as a Firecracker VM
- atmosx 4y agoFly.io will convert your docker image to a firecracker[^1], a microVM engine based on KVM. [^1]: https://firecracker-microvm.github.io/ https://firecracker-microvm.github.io/
- dylanz 4y agoIf you could share your configurations that would be great! (see email in my profile). I used Capistrano for many, many, years but haven't kept up with it in quite a while. I've had to tackle HIPAA deployments in k8s and it's quite the ordeal for a small team. I miss the days of "cap deploy".
- laneystroup 4y agoWill do! I will post a link later today.
- laneystroup 4y agoOK, I see now that fly.io uses Firecracker, not Docker (thanks for the catch!). And I see that flyio (and AWS App Runner) have updated their docs regarding PCI and HIPAA, as well, since I last looked at their site. Pretty smart actually. By the same token, I think this reinforces the point that Docker itself is not considered PCI Compliant, unless we are simply treating it's config files as a DSL. And in that case, if you want PCI Compliance and go with the Docker DSL, then you are locked into providers that offer this same "transmorgification" from Docker to Firecracker. Happy to hear that there are still other Capistrano users out there! I will push up my config later today.
- deleted 4y ago[deleted]
- nickjj 4y agoIf anyone is looking for a complete guide I put together this last month: https://nickjanetakis.com/blog/a-guide-for-running-rails-in-docker https://nickjanetakis.com/blog/a-guide-for-running-rails-in-... It includes running Rails and also Sidekiq, Postgres, Redis, Action Cable and ties in esbuild and Tailwind too. It's all set up to use Hotwire as well. It's managed by Docker Compose. The post also includes a ~1h hour ad-free YouTube video. The example app is open source at https://github.com/nickjj/docker-rails-example https://github.com/nickjj/docker-rails-example and it's optimized for both development and production. No strings attached. The example app has been maintained and deployed a bunch over the years.
- deleted 4y ago[deleted]
- cvccvroomvroom 4y agoThanks but I already have my own containers and infrastructure for dev and prod Rails. It's fine for people who are just starting out or want a repeatable environment. Also, if you want stability and fewer headaches long-term: - use a RHEL-derived kernel and customize the userland (container or host) quay.io has a good cent 9 stream. Ubuntu isn't used at significant scale for multiple reasons, and migrating over later is a pain. - consider podman over docker - use packaging (nix, habitat, or rpms) rather than make install (and use site-wide sccache) - container management (k8s or nomad) - configuration management (chef) because you don't always have the luxury of 12factor ephemeral instances based on dockerfiles and need to make changes immediately without throwing away a database cluster or zookeeper ensemble - Shard configuration and app changes, with a rollback capability - Have CI/CD for infrastructure that runs before landing - Monitoring and alerting - Don't commit directly to production except for emergencies. Require a code review signoff by another engineer. And be able to back out changes. - Have good, tested backups that aren't replication - Don't sweat the small stuff, but get the big stuff right that doesn't compound tech debt
- 023984398 4y agoThis is awesome and I'm glad Rails is adding something official here. Unfortunately if you want to use the Dockerfile in development with docker-compose you will need to make some changes/additions. Most notably: only precompile assets if deploying, not during development
- josephshaw92 4y ago[flagged]
- jupp0r 4y agoWill it be called "Ruby on Whales"? Joke aside, it's trivial to write your own Dockerfile and this still is what nontrivial apps will do, due to customization.
- adamors 4y agoIt's trivial to write a Dockerfile, it's not trivial to write a good one.
- benced 4y agoAs someone who doesn’t know rails at all, what’s the innovation here? Surely Rails has had Dockerfiles written for it before?
- garfieldnate 4y agoHow on earth did Rails not have an official Dockerfile until now? Have people been deploying like it's 2010?
- e12e 4y agoFor some more (too many?) in-depth tricks for rails and docker, see also: "Ruby on Whales: Dockerizing Ruby and Rails development" https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development https://evilmartians.com/chronicles/ruby-on-whales-docker-fo... Previously posted to hn - but without any comments.
- jchw 4y ago> 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". Removing the files in another command will work, but it does nothing to decrease the overall image size: as far as whatever filesystem driver you're using is concerned, deleting files from earlier layers is just masking them, whereas deleting them before creating the layer prevents them from ever actually being stored.
- viraptor 4y agoIf 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 https://github.com/viraptor/cruftspy
- cvccvroomvroom 4y agoEvery command in a dockerfile creates a layer, and most Dockerfile builders cache each if that line hasn't changed. Dynamic callouts to run updates or check things on the web won't rerun.
- mattficke 4y agoThe older “Docker without Docker” blogpost linked from there goes into that, it’s one of the best deep dives into containers (and honestly one of the best pieces of technical writing full stop) I’ve come across. https://fly.io/blog/docker-without-docker/ https://fly.io/blog/docker-without-docker/
- emerongi 4y agoIf you only care about the final image size, then `docker build --squash` squashes the layers for you as well.
- jchw 4y agoDefinitely, although it's worth noting that while the image size will be smaller, it will get rid of the benefits of sharing base layers. Having less redundant layers lets you save most of the space without losing any of the benefits of sharing slices. I think that is the main reason why this is not usually done.
- brundolf 4y agoI used to think I hated Docker, but I think what I actually hate is using Docker locally (building/rebuilding/cache-busting images, spinning containers up and down, the extra memory usage on macOS, etc etc). I don't need all that for development, I just want to run my dang code But I've been really enjoying it as a way of just telling a PaaS "hey here's the compiler/runtime my code needs to run", and then mostly not having to worry about it from there. It means these services don't have to have a single list of blessed languages, while pretty much keeping the same PaaS user experience, which is great
- kugelblitz 4y agoI 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 standards and different setups; I don't want to switch the language and the yarn or npm versions or the Postgres or MySQL versions and remember each one. Some might use RabbitMQ, another Elasticsearch. Docker helps me tremendously here. Additionally, I add a Makefile for each project as well and include at least "make up" (to start the whole app), "make down", "make enter" (to enter the main container I'll be working with), "make test" (usually phpunit) and perhaps "make prepare" (for phpunit, phpstan, php-cs-fixer, database validate) as a final check before adding a new commit. Locally, I had additional aliases on my shell. "t" for "make test", "up" for "make up". So now I just have to go to a project folder, write "up" and am usually good to go!
- brundolf 4y agoSure, 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 have an upgrade model where you should never need an older version of the compiler/runtime; you just keep updating to the latest and everything will work. I find that when circumstances allow me to use one of these languages/toolsets, most of the reasons for using Docker just disappear. [0] Examples include Rust/cargo, Go, Deno, Node (to an extent)
- agtorre 4y agoThis 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.
- grk 4y agoThe default Gemfile now bundles Puma in, so yeah it's production ready
- e12e 4y agoPuma is certainly fine as the app server - but normally you'd still have a proxy/load balancer/tls terminator/"ingress server" in front. Something like traefik, nginx, haproxy or caddy. If (one of the) front-facing servers do regular http caching (a good idea anyway to play nice with rails caching[1])", you can probably "serve" the static assets straight from rails and let your proxy serve them from cache (if you don't have/need a full cdn). [1] https://guides.rubyonrails.org/caching_with_rails.html#conditional-get-support https://guides.rubyonrails.org/caching_with_rails.html#condi...
- dewey 4y agoYes, usually you still serve your asset (images,...) directory through nginx or something similar, though.
- ye-olde-sysrq 4y agoThis 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.
- ginzunza 4y agoThis is a manual using that image with Redis and Postgres: https://medium.com/@gustavoinzunza/rails-redis-pg-with-docker-compose-in-2023-64ebb6d25de1 https://medium.com/@gustavoinzunza/rails-redis-pg-with-docke...
- alberth 4y agoAm I the only person who struggles to deploy Rails apps. It's a super productive framework to develop in, but deploying an actuals Rails apps - after nearly 20 years of existance, still seems way more difficult than it should be. Maybe it's just me.
- berkes 4y agoNot just you. Whenever you've covered your bases, Rails grows in complexity. Probably necessary complexity to keep up with modern world. Solved asset pipeline pain? Here's we packer. No, let's swap that out for jsbundle. Finally tamed the timing of releasing that db migration without downtime? Here's sidekiq, requiring you to synchronize restarts of several servers. Oh, wait, we now ship activejob. Managed to work around threads eaten by websocket connections in unicorn? Nah, puma is default now. Oh, and here's ActionCable you may need to fix all your server magic. Rails is opinionated. And that is good at times. But it also means a lot of work on annoying plumbing having to be rebuilt for a new, or shifted opinion. Work on plumbing, that is not work on your actual business core.
- viraptor 4y ago> Finally tamed the timing of releasing that db migration without downtime? Here's sidekiq, requiring you to synchronize restarts of several servers To be fair, this was already an issue whenever you have more than one instance of anything. Whether it's an extra sidekiq or two web servers or anything else, you have a choice of: stop everything and migrate, or split the migration into prepare, update code, finalise migration.
- berkes 4y agoYes. It was. But async workers have the tendency to be busy on long running processes, whereas a web server typically has connections that last at most seconds. Their different profile makes restarting just a tad harder.
- jillesvangurp 4y agoNo, it's not. I've observed the same in the Python community where there is a bit of a disconnect between developers and operations people. Docker has been the obvious way to package up code for close to a decade now. I believe, I started using it around 2014 or so and I actually dockerized a jruby app at the time as well (sinatra not rails). With Ruby and Python, most instructions for getting something going is just a series of "install this or that", "modify this file over there", "you could do this or that", "call this, than that, and then that", etc. These instructions tend to be developer focused. Virtual environments are usually left as an exercise to the reader and failing to use those leaves you with a big mess on your filesystem. Just pretend your production server is a snowflake developer laptop and you'll be fine seems to be the gist of it. Except of course that doesn't quite work like that anymore in many places and you need to take some steps to prevent that. I spend some time face palming myself through the Apache Air (python) documentation trying to figure out a sane way to get that on a production environment. As it turned out that involved jumping through quite a few hoops. My conclusion was that whoever wrote that, was not used to dealing with production environments. So, good that they are tackling this in the rails community. Stuff like this should not be an afterthought. With docker, you don't really need any virtual environments anymore. And you can also use them for development. That actually simplifies getting started instructions for both developers and operations people. Just use this container for development and run this command to push your production ready image to your docker registry of choice. No venvs, no gazillions of dependencies to install, etc.
- rcarmo 4y ago> RAILS_SERVE_STATIC_FILES - This instructs Rails to not serve static files. ...but... it's set to True....
- bradgessler 4y agoOpen a PR! This will fix the problem if its a bug/oversight or if its intended to be that way, force somebody to comment on it for a future person who is puzzled by this choice.
- byroot 4y agoIt's intended. Yes serving static files from Ruby is slower than from nginx or whatever, but you'd need to embed nginx in the image and run both processes etc. The assumption here is that there is a caching proxy in front of the container, so Rails will only serve each assets once, so performance isn't critical.
- jrochkind1 4y agoI am not sure which they intended, but the problem is that the comment doesn't match the code: > RAILS_SERVE_STATIC_FILES="true" > RAILS_SERVE_STATIC_FILES - This instructs Rails to not serve static files That is not what it does when you put `="true"`, nope. In fact both, settings are common. On heroku you typically use `RAILS_SERVE_STATIC_FILES="true"` but put a CDN in front. But other people do false and have eg nginx serving them. If this is what fly.io means you to do... where is the nginx, not mentioned in the tutorial? Whichever they intend to do, their code does not match their narrative of what it does.
- byroot 4y agoI was answering to the person saying to open a PR (on Rails I presume). That comment isn't in the Rails dockerfile, it was added by the OP. https://github.com/rails/rails/blob/4f3af4a67f227ed7998fed570b9aa671e1b74117/railties/lib/rails/generators/rails/app/templates/Dockerfile.tt#L28 https://github.com/rails/rails/blob/4f3af4a67f227ed7998fed57...
- deleted 4y ago[deleted]
- bploetz 4y agoIt's been a while since I've done any Ruby/Rails development, but just curious why they chose to use a Debian/Ubuntu based image in the default Dockerfile instead of an Alpine based image?
- bradgessler 4y agoThe dockerfile is optimized for “works for the most number of people out of the box”. There was debate over using the ruby v ruby-slim image. Ultimately it was decided to go with the larger image to maximize compatibility. That said, keep using Alpine! There’s no reason for folks to stop doing what they’re already doing if it’s working for them. The new dockerfile is meant more for people who are just getting started that aren’t familiar with Docker or Linux.
- faebi 4y agoI assume because Debian/Ubuntu works more likely out of the box. I tried to use Alpine but ran into various issues in our sad big corporate setup. Additionally, ruby provides base docker images in these too.
- freedomben 4y agoAlpine has some razor edges in it. I would never default to it. Always test your app thoroughly. musl doesn't implement everything that glibc does and some of the differences can cause big problems. This is not purely theoretical. I once spent a week deugging a database corruption issue that happened because of a difference in musl's UTF-8 handling. Use Alpine liberally for local images if you like, but don't use it for production.
- bploetz 4y ago"Use Alpine liberally for local images if you like, but don't use it for production." We take the exact opposite approach: default to Alpine based images, only use another base OS if Alpine doesn't work for some reason. The majority of our underlying code base isn't C-based, so maybe that's why Alpine has been successful for us, but as always, everyone's situation is different and YMMV.
- thrownaway561 4y agoThough this is a great step... you still have to edit the Dockerfile if you are using Postgres and Redis.
- bradgessler 4y agoI have a proposal out for making the deployment story even easier by providing RubyGems a way to describe the packages they depend on to operate properly at https://community.fly.io/t/proposal-declare-docker-images-dependencies-via-the-ruby-slim-docker-packages-key-in-gemspec-metadata/9979/11 https://community.fly.io/t/proposal-declare-docker-images-de... The idea is I could run a command like `bundle packages --manager=apt` and get a list of all the packages `apt` should install for the gems in my bundle. Since I know almost nothing about the technicalities and community norms of package management in Linux, macOS, and Windows, I'm hoping to find people who do and care about making the Ruby deployment story even better to give feedback on the proposal.
- regularfry 4y agoOne problem you're likely to run into is that systems using the same packaging lineage cut the same dependency up in different ways. The "right name" for a dependency can change between Ubuntu and Debian, between different releases of Ubuntu, and different architectures. It very quickly gets out of hand for any interesting set of dependencies. Now it might be that there's enough stability in the repositories these days that that's less true than it was, but I remember running into some really annoying cases at one point when I had a full gem mirror to play with. This is one of those problems that sounds easy but gets really fiddly. I had a quick run at it from a slightly different direction a looooong time ago: binary gems (https://github.com/regularfry/bgems https://github.com/regularfry/bgems although heaven knows if it even still runs). Precompiled binary gems would dramatically speed up installation at the cost of a) storage; and b) getting it right once. The script I cobbled together gathers the dependencies together into a `.Depends` file which you can just pipe through to the package manager, and could happily use to strap together a package corresponding to the dependency list. I've never really understood why a standard for precompiled gems never emerged, but it turns out it's drop-dead simple to implement. The script does some linker magic to reverse engineer the dpkg package dependency list from a compiled binary. I was quite pleased with it at the time, and while I don't think it's bullet-proof I do think it's worth having a poke at for ideas. Of course it can only detect binary dependencies, not data dependencies or anything more interesting, so there's still room for improvement.
- _odey 4y agoI have my own local development Rails setup and template files that could be dropped in any project with minimal changes (mostly around configuring the db connection) - https://gitlab.com/sdwolfz/docker-projects/-/tree/master/rails https://gitlab.com/sdwolfz/docker-projects/-/tree/master/rai... Haven't spent the time to document it. But the general idea is to have a `make` target that orchestrates everything so `docker-compose` can just spin things up. I've used this sort of thing for multiple types of projects, not just Rails, it can work with any framework granted you have the right docker images. For deployment I have something similar, builds upon the same concepts (with ansible instead of make, and focused on multi-server deploys, terraform for setting up the cloud resources), but not open sourced yet. Maybe I'll get to document it and post my own "Show HN" with this soon.
- dewey 4y agoThis is long overdue. Rails got very nice updates in the past years to make it easier to handle JS and other assets. Deploying it was still always a hassle and involved searching for existing Dockerfiles and blog posts to cobble together a working one. At the beginning I always thought I'm doing something wrong as it's supposed to be easy and do everything nicely out of the box. And dhh apparently agrees (Now at least: https://dhh.dk/posts/30-myth-1-rails-is-hard-to-deploy https://dhh.dk/posts/30-myth-1-rails-is-hard-to-deploy) as there's now a default Dockerfile and also this project he's working on, this will make things a lot nicer and more polished: https://github.com/rails/mrsk https://github.com/rails/mrsk
- cromulent 4y agoGreat name. I wonder if Maersk (the Danish shipping container company) will note the hat-tip, and if it will annoy their lawyers.
- iamflimflam1 4y agoWhat 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.
- the_gastropod 4y ago(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 https://lamby.custominktech.com
- bradgessler 4y agoYou might try caching bootsnap in the Docker image. I didn’t realize this was possible until I saw it in the Dockerfile that Sam and DHH cranked out recently.
- gls2ro 4y agoI dont think Rails is fit for this. It is a full app so I think by design it does not fit into Cloud Run architecture of cloud functions. May I suggest you take a look at Roda or Hanami?
- regularfry 4y agoWhile I've not tried it personally, Django can be run like this. It being a "full app" doesn't preclude it from having a fast enough startup to allow for cloud function deployment.
- freedomben 4y agoI dislike that too. I've started using Sinatra for ruby apps instead of rails. You end up writing a lot more boilerplate but startup times are near instant and the API is great. Also it's highly stable. I haven't had to update my Sinatra apps (beyond updating dependent gems) in many years.
- quest88 4y agoBut how does this work when talking to dev databases on my machine?
- zeroxp 4y agoDockerized applications can still reach services on the localhost, but you may want to take a look at docker compose so you get your application and backing systems in one place. It makes your local development environment incredibly resilient.
- quest88 4y agoDo you have an example how that would work? I unsuccessfully spent quite a while trying to get a docker container running rails to talk to a docker container running postgre. And I wanted to postgre container to persist to the host's disk so I could save state between runs. Maybe that wasn't the best way to do it though?
- perlwle 4y agoDB data can be stored in volume and persisted. There are a lot of dockerfile / compose examples on github. * https://github.com/docker/awesome-compose https://github.com/docker/awesome-compose * https://github.com/jessfraz/dockerfiles https://github.com/jessfraz/dockerfiles
- bradgessler 4y agoThe Dockerfile is not optimized for a development environment. It might work for some cases, but this default file is really all about “how can the probability of a successful production deployment be improved out of the box?” Getting a Docker compose dev env working is another can of worms. Maybe I should write about that next?
- wefarrell 4y agoI 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 Gemfile and there would be occasional inconsistencies between environments.
- viraptor 4y agoThis experience is mostly about how you see docker used, not any specific property of it. Both Capistrano and Docker can be used for deploys with or without interruptions. Both can be immediate or take minutes. The tool itself won't save you from bad usage.
- 5e92cb50239222b 4y agoWhy are using Docker then? I have little experience with Ruby, but for PHP projects we're still using ye olde way. Deploys are hot and do not interrupt requests, just as you described (it pretty much comes down to running `composer install && rsync` in CI — there are more complicated solutions like capistrano, which I've also used, but they don't seem to provide enough features to warrant increased complexity).
- freedomben 4y agoI 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.
- laneystroup 4y agoI 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.
- marcopicentini 4y agoDeploying with Cloud66 is a lot easier. Just git push. I can chose my hosting provider and switch each other.
- revskill 4y agoThis is a really good news. And to be fun, the easiest way to become mainstream, is to have a guide on how to deploy a Rails application in 1 click, for any cloud hosting service.
- hit8run 4y agoI use dokku. Works really well.
- ezekg 4y agoIIRC, Dokku can only manage 1 server, so it's essentially useless for anything except small side projects that don't need to scale horizontally.
- hit8run 4y agoHow do you define small side projects? One potent server is enough to serve multiple thousand of requests per second…
- ezekg 4y agoSmall side project, meaning anything that's fine with occasional downtime. You should run at least 2 servers for redundancy, regardless of size. You just can't lean on a single server, even if you can squeeze thousands of RPS out of it (big doubt). It will inevitably fail, and you will have downtime.
- josegonzalez 4y agoMaintainer of Dokku here: We support Kubernetes and Nomad as deployment platforms, and folks are welcome to build their own builder plugins if they need to support others.
- dieselgate 4y agoI've found the "Docker for Rails Developers" book by Rob Isenberg [1] to be a great resource for getting started using Rails and Docker. It's only a couple years out of date at this point but should still be highly relevant for anyone trying to get started. The only issue I've had with Rails and Docker is serving the container on a 1gb d.o. droplet - the node-sass gem is usually a sticking point for a lot of people and believe the 1gb droplet to be just too small to host a dockerized rails app. But the benefits of using docker for Development is still overwhelmingly worth the effort of containerizing things. It's super cool rails 7.1 is including the Dockerfile by default - not that rails apps need more boilerplate though.. [1]: https://pragprog.com/titles/ridocker/docker-for-rails-developers/ https://pragprog.com/titles/ridocker/docker-for-rails-develo...
- throwaway23942 4y agoI use FROM scratch. The app itself is built with a binary packer that is copied in. Still, I'd much rather use Nix/Guix over Dockerfile.