Docker Containers Clustering

- 1 answer

I was using laravel homestead solution for development but now i would like to migrate to docker. The question is how "bloated" should be my containers. When I say "bloated" I mean how much modules/service should be per container. For example i created four custom containers like this:

  -> php-fpm
  -> composer
  -> memcached
  -> redis
  -> mysql

The question is, if this is right clustering or should i create separate container let say for grunt, bower, memcached etc.? How to decide what goes together and what to separate container? Are there any rules? Should be development the same as production?



How you factor app components into containers depends on what your goals are. Is your goal to make your server easier to manage/administer? Are you primarily interested in how to scale your app successfully as it gets more traffic? Here are some suggestions if scaling is your primary concern:

  1. Putting nginx into its own container makes sense because its primary role is to function as a load balancer. For the most part, all nginx does is to pass requests off to your PHP service for handling. Since it's likely your app needs to handle sessions, and since you don't want your containers to share session data, you should use the ip_hash strategy for delegating requests. That way you won't run into the problem of nonces and CSRF tokens not being recognized.
  2. Since your PHP containers will be doing most of the work, you should probably keep them in containers by themselves. If latency becomes a problem, you can always just spin up a new PHP container and add it to your virtual cluster to help shoulder the load. Anything related to session management, like Redis or memcached, could also be put into this container. That way each container has all of the tools it needs to reduce latency, and open up bottlenecks.
  3. You'll want to put your actual Laravel app files into a single container, and make its volumes shared across your other containers. That way, if your app does things like handle file uploads, you won't have to copy those files to multiple containers. You might want to put composer and artisan here, as the tasks these programs handle are primarily related to maintaining the files in your Laravel app. Dylan Lindgren suggests putting artisan and composer into their own containers.
  4. Since your data is also shared across the entire app, you should also probably have a separate container for your database. I guess you might consider bundling your database with your Laravel app files, but it's probably easier not to do this since you'll be able to find pre-configured containers for various kinds of databases relatively easily.
  5. As for node, you may not even need this on your production server. Since the node/npm-based components are typically only used for combining and compressing resources (JS and CSS) prior to deployment, you could just do all of the preprocessing of assets on your dev machine and make the compressed/minified CSS/JS files a part of your Laravel container. Since all of the CSS/JS related processing happens on the client side, they can essentially be treated as static files.

Here is a diagram to represent this:

enter image description here

Note that you can add as many PHP/Redis/Memcached containers as you would like to handle additional server load as necessary. These containers don't even necessarily have to be on the same physical server, which is where you get added memory and processing power.

If you don't expect the load on your app to be such that you need all of this to manage it, it might just be easier to stick with the traditional approach. Docker is still relatively new and not truly recommended for production environments, although, like me, you're probably really interested in figuring out how it can be useful.

One of the cool things about Docker is that you develop your containers locally and can deploy them "as is" into the cloud. So, locally you'd have all of these containers (and you could even swap out some of them, say your DB and/or server), and then deploying just becomes a matter of running a new instance of your container on the production server.

I hope this helps you understand better how you might come up with a strategy for factoring the pieces of your app into containers. Docker is still relatively new to the Laravel space, and so I'm sure these practices will change rapidly over the next year or two, and probably eventually become automated.