Dockerize a React app
mentorcruise.com
mentorcruise.com
Why are we containerizing a React app? It’s literally just a bundle of JavaScript. I have to spin up a whole container just to run `npm start` locally?
I guess it’s kind of cool that they show how to put it behind Nginx? But it really makes me question the target audience here. You’re advanced enough to need your app behind a reverse proxy, but not advanced enough to know how to put some static files in a Docker container?
What if we just stripped away the Docker and nginx stuff? That would be how you do this “easily”.
I'm pretty sure that the intent there is to make your bundled JS/HTML/CSS be ready for deployment, not that you have to use the approach locally (outside of maybe checking whether the containers are built correctly and all of the assets are served).
If you have a container cluster that has your back end APIs and your DBs running in it, you can deploy your front end alongside those, with the web server running inside of the container that will serve the files.
Not the only way to do it, of course, but if you are already using containers (and perhaps appreciate the 12 Factor App principles), then this approach is rather pleasant. I can see myself linking a tutorial like that to someone, should I want to introduce them to the approach.
The frontend team will also likely need to tweak various HTTP headers, but in a lot of organizations the internet facing reverse proxy is controlled by an operations team, not the frontend team.
Sure, in each individual case going bare-metal is easier - but once you get to N=2 (multiple languages, multiple versions of the same language installed side-by-side) I find containers to be a net positive.
(If we were in a world where every language was able to output reproducible static binaries with embedded assets I think I would prefer that, but alas we aren’t there)
There's plenty of people coming from a more traditional sysadmin background with close familiarity with bare-metal systems but not so much familiarity with the docker ecosystem, which is really its own thing, fairly sprawling and not entirely obvious to reason about.
> spin up a whole container just to...
A container is closer to a chroot jail than it is a VM. It's not something you need to spin up, unless you're on some convoluted cluster orchestration system... It's not intrinsic to containers.
I think the deployment story for for React apps is monopolized by all the at-the-edge startups, and they don't run containers(?). Even Fly.io doesn't run containers (you make a Docker image as your "deployment artifact", and Fly creates a Firecracker-friendly VM from it).
Like, for example, why would you do this? It's a good question for someone who's looking to do this to ask themselves before doing it, and therefore a good question to try to answer. Like for example, if I'm trying to deploy to a service like Fly.io or into a Kubernetes cluster, then this may very well be the right thing to do.
However, if I'm a n00b and I just know people deploy things with Docker, I might miss that it'd actually be much easier to just push this stuff to Cloudflare Pages, Vercel, Netlify or another static pages hosting tool/CDN.
Some people read articles like this without having much of a basis for why you would want to add all of this complexity, and it leads them to think it's the right choice when it isn't necessarily. Generally the answer for why to do this, in my mind, is something along the lines of uniformity; having everything be an OCI image is convenient, and in the case of a PaaS or existing container cluster setup, it might be necessary if you want your frontend deployment to go alongside your other containers. It also has the benefit of being easier to test exactly how it will run locally, whereas with something like Cloudflare Pages you might need to play around to figure out how things like redirect rules will wind up working when you actually deploy it.
I'm also a bit surprised. This is the kind of deployment you can hack together in 30 minutes if you know almost nothing about React builds, nginx, or Docker. It's one of the more trivial Docker tasks out there.
But having a container to deploy makes more sense than telling people to just use Vercel or cloudflare. Default to cloud isn't a good mindset.
Cloud can be bad, but in this case it's barely any different from what people used to do with cPanel hosting back in the day. The point is to just drop some files somewhere and have someone else's HTTP server host them.
Yes but I don't think we should be outraged over posts that discuss deploying with an HTTP server. If anything, the concern should be over the focus on specific platforms like Vercel/Next.js, or Cloudflare Workers limiting broader understanding and options.
Other than the obvious edge benefits of a CDN, this would seem to open up issues around asset versioning. EG it's pretty standard to include asset/build hashes as part of urls, to ensure that the base app page and JS requests all get the correct build. You want JS to be cached between normal refreshes, but that to be busted on a new build.
If you were to deploy a new docker container with this pattern, you'd lose the old hashes, so potentially getting weird intermittent failures if someone's operating the old app in their browser, but the accompanying assets are no longer available due to a new build having gone out? If you don't do hashes, how do you ensure a new page load doesn't use a cached asset? ETAGS?
I think the article is a decent presentation of "docker 101" but left me with more questions than answers on what it actually means to try and do an dockerized ngnix static asset server rather than a CDN.
It is standard to have a sunsetting period. You don't just wake up and don't have infra.
Improvements:
- use lock file and npm ci mode
- don't run under root
- add security headers
- add ssl
- caching
- sendfile on
- gzip
- why the hell is the builder container named prod?
having seen sufficient images with npm install followed by a npm start, this guide is still relevant (for apps that don't do SSR anyway).
inb4: take your kubernetes complaints elsewhere.
I just wish I knew what to make