Reputation: 1
I've got two services that I wish to spin up in Docker. According to Docker's documentation, the general rule of thumb is that you should spin up each service within its own container. I understand the reasoning behind this.
However, my two services both require the same basic setup. Having two Dockerfiles for the respective services seems wasteful, especially as all that would differ is what the CMD
is that runs.
My question: using docker-compose
and Dockerfile
s, how can I build a "common" image (where all dependencies are installed), before each CMD
can be run in a separate container, using the "common" image as a starting point? I could build the "common" image and push it to a (private?) registry (from what I understand), but would multi-stage builds be the solution here?
For example, something like:
FROM python:3.8-alpine AS builder
RUN apk add --update --no-cache \
gcc \
libc-dev \
libffi-dev \
libressl-dev \
musl-dev \
&& mkdir /usr/app/
COPY ./testproject /usr/app/testproject/
COPY ./requirements.txt /usr/app/requirements.txt
WORKDIR /usr/app
RUN pip install -r requirements.txt
~~~~
FROM python:3.8-alpine AS wss
WORKDIR /usr/app/testproject
CMD ["wsserver", "-b", "0.0.0.0", "-p", "8001", "testproject.asgi:application"]
~~~~
FROM python:3.8-alpine AS http
WORKDIR /usr/app/testproject
CMD ["httpserver", "-b", "0.0.0.0", "-p", "8000", "testproject.asgi:application"]
Obviously, this doesn't work -- I don't know how to bring the Docker artefacts over to wss
or http
from builder
. Or I may be barking up the wrong tree. Basically, I want to be able to spin up wss
or http
as individual services in my docker-compose.yml
file.
Indeed, in my docker-compose.yml
file, documentation suggests that I could then use target: http
to build the http
image for that service, as an example.
Still getting the hang of Docker-ing. Thanks for any advice!
Upvotes: 0
Views: 35
Reputation: 158812
You can easily override CMD
when you run the image. In Compose, you'd use the command:
setting:
version: '3.8'
services:
wss:
build: .
command: wsserver -b 0.0.0.0 -p 8000 testproject.asgi:application
ports: ['8001:8000']
http:
build: .
command: httpserver -b 0.0.0.0 -p 8000 testproject.asgi:application
ports: ['8000:8000']
I wouldn't use a multi-stage build here; if you do, though, you can use the AS
name from a previous stage in the FROM
line of a later stage, so say FROM builder AS ...
in the last two stages. (Multi-stage builds are a little better suited to building a single final artifact, and I might argue that even having two images is a little bit overly complex.)
Upvotes: 1