Skip to content

[Messenger] Added section about "Consuming Messages in Docker" #15340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: 4.4
Choose a base branch
from

Conversation

Basster
Copy link
Contributor

@Basster Basster commented May 13, 2021

Like announced on the syfomy-devs slack, some hints and tipps about running messenger:consume in a container environment.

My fork was heavy out of sync, so I needed three approaches for this PR 😉

@Warxcell
Copy link

The approach I use is to run container for each queue.

FROM MyPHPContainer

USER www-data

ENTRYPOINT ["php", "bin/console", "messenger:consume", "--limit=10"]

CMD ["main"]

@Basster
Copy link
Contributor Author

Basster commented May 19, 2021

The approach I use is to run container for each queue.

You have to re-build a container for each queue on each deployment. Having a parameterized entrypoint in the same image makes much more sense. You only want to build one image for all environments per release (following twelve-factor-app concept).

@Warxcell
Copy link

The approach I use is to run container for each queue.

You have to re-build a container for each queue on each deployment. Having a parameterized entrypoint in the same image makes much more sense. You only want to build one image for all environments per release (following twelve-factor-app concept).

Yes, you build one image for all environments - one image for messenger and one for app.
As per https://docs.docker.com/config/containers/multi-service_container/

It is generally recommended that you separate areas of concern by using one service per container. That service may fork into multiple processes (for example, Apache web server starts multiple worker processes). It’s ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application.

@Basster
Copy link
Contributor Author

Basster commented May 19, 2021

Image to container is like class to instance.

As long as the consumer is no seperate application but baked into your symfony website application, there should be no separate image, only another runtime configuration (entrypoint, env vars, etc).

@Warxcell the articel you've linked, explicitly describes multi-service containers, running multiple prozesses in parallel. That's exactly, what I try to avoid with this tipps.

@javiereguiluz
Copy link
Member

In Symfony Slack there was a very active thread about this Pull Request. See https://symfony-devs.slack.com/archives/C8WHX21K7/p1621414331044800

Hopefully we can agree on some changes and propose them here? Thanks!

@Basster
Copy link
Contributor Author

Basster commented May 21, 2021

To pick this up from the Symfony Slack:

no need at all to define custom entrypoint, simply custom command is enough

If the inherited entrypoint of the base image doesn't support arguments, changing the command does nothing but handing over "wrong" parameters to a binary/script.
Fortunately most official image entrypoints support overwriting the whole thing, but they don't do neccessarily.

ENTRYPOINT is the font-facing binary.
CMD are the arguments to that binary.

Source: https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact

Mostly ENTRYPOINT is a shell like /bin/bash or a custom one that overwrites the whole "logic" of the entrypoint if non supported CMD is given (e.g. https://github.com/docker-library/php/blob/81ceb39449dc0d42fcecf455b6f372b0b5f3f426/8.0/buster/cli/docker-php-entrypoint)

As we cannot be sure whether the base image each and everyone uses supports entrypoint overwrite with simple CMD change, I'd like to promote having a separate (and very specific) entrypoint for this purpose.

It also follows single responsibility principle, by providing a separate and specific bootstrapping for the consumer process.

As long as the consumer is no seperate application but baked into your symfony website application, there should be no separate image, only another runtime configuration (entrypoint, env vars, etc).

If you build a separate consumer application, feel free to use whatever (single) entrypoint you like.

@mleczakm
Copy link
Contributor

Basically, as you wrote - there is completely no need of using custom entrypoint for commands using standard approach, so I see no point for writing docs that says something different. KISS. Instead of this two paragraphs you can simply cover base usecase with CMD overwrite.

Same with limits tbh. It is something completely user-specific and there is no point in requiring from someone to restart their workers every N messages/every M minutes because it is only waste of resources. Only soft memory limit should be mentioned as obligatory in production environment, because not having it properly set up will result in app crash. But having it same as php native memory_limit won't help and won't prevent errors - you need to handle memory peeks during handling events, so this value must be php memory_limit decreased by peek memory usage during message handling.

@Basster
Copy link
Contributor Author

Basster commented May 25, 2021

Basically, as you wrote - there is completely no need of using custom entrypoint for commands using standard approach, so I see no point for writing docs that says something different. KISS. Instead of this two paragraphs you can simply cover base usecase with CMD overwrite.

Fair enough. Maybe I'm going to add a hint about ENTRYPOINT vs CMD.

Same with limits tbh. It is something completely user-specific and there is no point in requiring from someone to restart their workers every N messages/every M minutes because it is only waste of resources

I don't understand why restarting is a waste of resources (it frees them), but anyways.

The existing part about Deploying to Production tells axaclty that: "Don’t Let Workers Run Forever", so I've picked it up for Docker usage, as well. And as seamless restarting should be in the lifecycle of every containerized application, I shouldn't bother.

But having it same as php native memory_limit won't help and won't prevent errors

But having a too low memory_limit and wondering why the consumer crashes with OOM is also not fun to debug.

@Warxcell
Copy link

Warxcell commented Nov 1, 2021

New insights from my side: if your use single image with FPM and Messenger, you cannot gracefully restart messenger, since FPM image overrides STOPSIGNAL SIGQUIT, so when you run same image with php bin/console messenger:consume $queue, you cannot stop it gracefully. You would need to use hacks to achieve that, or manually add a listener for SIGQUIT.

Filled also a issue for it, in case symfony decides to handle that case aswell.

@Warxcell
Copy link

Warxcell commented Nov 3, 2021

New insights from my side: if your use single image with FPM and Messenger, you cannot gracefully restart messenger

It would happen if you use single container and run two processes inside - but no one is proposing it. You can use single fpm image with multiple containers.

That's exactly what I do. I have SINGLE image, and I run MULTIPLE containers from it. Did I ever said that I'm running 2 processes within single container? Did you even read what I wrote? I will quote myself

so when you run same image with php bin/console messenger:consume

which basically mean "run another container from same image, but different command which is php bin/console messenger:consume"

@OskarStark
Copy link
Contributor

Symfony 4.4 is not supported anymore, you may want to rebase on top of 5.4 branch, otherwise please close the PR.

Thank you

@wouterj wouterj modified the milestones: 4.4, 5.4 Jul 1, 2024
@xabbuh xabbuh modified the milestones: 5.4, 6.4 Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants