I've got two multi-tiered web applications running in docker containers that I'm trying to start using docker compose
rather than docker run
. I hope the diagram below conveys the setup but I wonder if it's done properly.
Let's take just one as example, the simpler galleries application on the right. I can probably figure out the recipes application if I get the galleries right. It has two images:
It has a Dockerfile and ng build
creates the image. I was about to create a compose.yml when I realized I probably shouldn't have one for each image but rather somehow use compose to orchestrate startup of multiple images, dependencies and volumes.
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY /dist/ca.footeware.ng.web /usr/share/nginx/html
This is where I started to use compose. It's a maven build with a Dockerfile and a compose.yml. mvn clean package
creates the docker image and docker compose up
starts it as a container. I can test it locally using curl and deploy on server when fit.
FROM amd64/eclipse-temurin:22-jre
ARG JAR_FILE
ADD ${JAR_FILE} /opt/rest.galleries/app.jar
EXPOSE 8000
ENTRYPOINT ["java","-jar","/opt/rest.galleries/app.jar"]
services:
rest_galleries:
image: rest.galleries:3.5.0
container_name: rest.galleries
restart: unless-stopped
ports:
- 8000:8000
volumes:
- /opt/rest.galleries/galleries:/opt/rest.galleries/galleries
- /opt/rest.galleries/logs:/opt/rest.galleries/logs
So after all that I'm trying to decide the next move. Do I create a compose.yml in the ng.galleries project in vscode? If I do, I'd have to describe that it depends_on
the rest.galleries service. Then when all looks right, I can log onto the server and start using another compose.yml? One tailored to starting the two galleries containers? I can see if both angular and rest service were developed in the one IDE, it might be easier but that's not the case and it's clear as mud to me.
Where do you keep your compose.yml's and what would they look like given the above diagram?
I would create one Compose file per application. In the initial diagram you show two logical applications ("recipes" and "galleries") and at the bottom of that diagram one compose.yml
file for each, and that model makes sense to me.
(It seems like you're asking if you should create one Compose file per service. This is harder to manage, and there are complexities in trying to make different Compose files on the one hand talk to each other, and on the other hand not conflict from accidentally using the same names.)
The natural place to put the Compose file is the parent directory of the projects it includes, like
src/
+-- galleries/
+-- docker-compose.yml
+-- ng.galleries/
| +-- Dockerfile
| +-- package.json
| ...
+-- rest.galleries/
+-- Dockerfile
+-- pom.xml
...
Then the Compose file lists the individual services.
version: '3.8'
services:
ng:
build: ./ng.galleries/
restart: unless-stopped
ports: ['3000:3000']
rest:
build: ./ng.rest/
restart: unless-stopped
ports: ['8000:8000']
volumes:
- galleries:/opt/rest.galleries/galleries
volumes:
galleries:
(I've removed the "logs" volume from the setup; configure your application to write to stdout instead of a log file, and docker-compose logs rest
will show the logs. I've converted the local storage to a Docker named volume as well, which can avoid some permission-related problems but can also add some complexity around backing up content.)
You can individually start one service or the other if you need to
# start only the frontend
docker-compose up -d ng
You can have a similar setup for the other project. Assuming the other project is in a differently-named top directory, Compose uses that directory name to generate a project name. The various objects Compose creates are internally labelled with that project name, and objects in different projects won't conflict. It's not a problem if both applications contain Compose services named rest
, for example, since Compose will keep the two projects' Docker objects separate.