Six ways to run multiple processes in one Docker container, from GNU Parallel and Foreman to a custom entrypoint script, Supervisord, and tmux, with trade-offs.
Debugging a Rails app from VSCode while the Rails server itself needs to keep running is a common case: the container has to run rdbg, the Ruby debug listener, and rails server at the same time. CMD and ENTRYPOINT only take one process, so something has to manage the rest. Here’s what each option actually costs you.
Simple, but it’s one more dependency for something that doesn’t need a job-parallelization tool: Parallel is built for fan-out batch work, not for supervising two long-running services.
The natural choice in a Ruby project: it’s already part of the ecosystem, and it gives you unified, prefixed logs for both processes with no extra configuration.
A custom entrypoint script
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bashset-e
rdbg -n--open--host 0.0.0.0 --port 12345 &
rails server -b 0.0.0.0
# Wait for any process to exitwait-n# Exit with status of process that exited firstexit$?
1
2
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
No extra dependency, and full control over startup order and exit behavior, at the cost of a script you now own and have to keep correct. That’s usually the right trade when the process logic is genuinely simple, as it is here.
Supervisord
1
RUN apt-get update && apt-get install -y supervisor
Supervisord restarts processes automatically and centralizes logging, which is what you want in production. For a local debugging setup, that’s more process than the problem needs.
Useful if you actually want an interactive terminal into the container, less useful if you just want both processes running in the background. Not something to ship to production.
Docker Compose
Not a way to run multiple commands in one container, but often the better answer to the underlying problem: give the debugger and the server their own containers.
1
2
3
4
5
6
7
8
9
10
11
12
version:'3'services:debugger:image:your-rails-imagecommand:rdbg -n --open --host 0.0.0.0 --port 12345ports:-"12345:12345"web:image:your-rails-imagecommand:rails server -b 0.0.0.0ports:-"3000:3000"
1
docker-compose up
Which one to actually use
For the VSCode-plus-rdbg case specifically, a custom entrypoint script or Foreman covers it with the least added complexity. Reach for Supervisord only once this is running in production and needs automatic restarts. tmux and Docker Compose solve different problems, interactive access and container separation, not “run two commands in one container” as such.