The best practice for Docker is to run one process per container, deliberately making it hard to write Dockerfiles that run multiple services.
Docker Compose solves the problem by giving you the tools you need to run multiple containers (running one service each) rather than a single container running multiple services.
You might use Compose to set up a stack like this:
version: '2'
services:
redis:
image: 'redis'
ports:
- '6379:6379'
nginx:
image: 'nginx'
ports:
- '80:80'
mongodb:
image: 'mongo'
ports:
- '27017:27017'
app:
build: .
ports:
- '3000:3000'
After running docker-compose up the library images for redis, nginx and mongo will be pulled from Docker hub.
Then it will try and build a container from the Dockerfile in the same directory as your docker-compose.yml file.
If you're building a node app, it might look something like this:
FROM node
COPY . /app
RUN npm install
CMD ["npm", "start"]
Docker Compose also configures the network so that each of your composed services gets a descriptive host mapped to the container's ip addresses.
So for example, if you were connecting to Redis from your node app, you won't find it running on localhost (because that's your container). Instead, it'll be at redis:6379.
It's written for Python, but the getting started article is very good.