I am working with a docker-compose file from freqtrade project. I made a docker-compose file with Dockerfile dependency.
docker-compose.yml :
---
version: '3'
services:
freqtrade:
# image: freqtradeorg/freqtrade:stable
# image: freqtradeorg/freqtrade:develop
# Use plotting image
image: freqtradeorg/freqtrade:develop_plot
# # Enable GPU Image and GPU Resources (only relevant for freqAI)
# # Make sure to uncomment the whole deploy section
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# Build step - only needed when additional dependencies are needed
# build:
# context: .
# dockerfile: "./docker/Dockerfile.custom"
restart: unless-stopped
container_name: freqtrade
volumes:
- "./user_data:/freqtrade/user_data"
# Expose api on port 8080 (localhost only)
# Please read the https://www.freqtrade.io/en/stable/rest-api/ documentation
# for more information.
ports:
- "127.0.0.1:8000:8080"
# Default command used when running `docker compose up`
command: >
trade
--logfile /freqtrade/user_data/logs/freqtrade.log
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
--config /freqtrade/user_data/config.json
--strategy SampleStrategy
ft_jupyterlab:
build:
context: .
dockerfile: docker/Dockerfile.jupyter
restart: unless-stopped
container_name: ft_jupyterlab
ports:
- "127.0.0.1:8888:8888"
volumes:
- "./user_data:/freqtrade/user_data"
# Default command used when running `docker compose up`
command: >
jupyter lab --port=8888 --ip 0.0.0.0 --allow-root --NotebookApp.token=''
Dockerfile.jupyter :
FROM freqtradeorg/freqtrade:develop_plot
# Pin prompt-toolkit to avoid questionary version conflict
RUN pip install jupyterlab "prompt-toolkit<=3.0.36" jupyter-client --user --no-cache-dir
# Empty the ENTRYPOINT to allow all commands
ENTRYPOINT []
It works fine. Just I want some improvement.
As you see, in docker-compose.yml there are 2 services: freqtrade , ft_jupyterlab. freqtrade is identical to image: freqtradeorg/freqtrade:develop_plot
and ft_jupyterlab build from Dockerfile.jupyter that uses image: freqtradeorg/freqtrade:develop_plot, so both services use same image.
I want to merge 2 services as a single. Before I describe my modifications, you must know the base image freqtradeorg/freqtrade:develop_plot built from a another Dockerfile that has these lines at the end of it:
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]
So, I made modifications in both docker-compose.yml and Dockerfile.jupyter file as below:
docker-compose.yml :
---
version: '3'
services:
freqtrade:
build:
context: .
dockerfile: docker/Dockerfile.jupyter
restart: unless-stopped
container_name: freqtrade_jupyterlab
volumes:
- "./user_data:/freqtrade/user_data"
# Expose api on port 8080 (localhost only)
# Please read the https://www.freqtrade.io/en/stable/rest-api/ documentation
# for more information.
ports:
- "127.0.0.1:8000:8080"
- "127.0.0.1:8888:8888"
# Default command used when running `docker compose up`
command: >
sh -c "trade
--logfile /freqtrade/user_data/logs/freqtrade.log
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
--config /freqtrade/user_data/config.json
--strategy SampleStrategy
& jupyter lab --port=8888 --ip 0.0.0.0 --allow-root --NotebookApp.token=''"
Dockerfile.jupyter :
FROM freqtradeorg/freqtrade:develop_plot
# Pin prompt-toolkit to avoid questionary version conflict
RUN pip install jupyterlab "prompt-toolkit<=3.0.36" jupyter-client --user --no-cache-dir
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]
But it doesn't work when I run docker-compose up -d
It's usually more manageable to have two containers running a single process, than to try to run two processes in a single container.
You clarify in a comment that your major concern is around disk space, and you'd like both containers to use the same image. So long as they both have the same
build:block, you'll get this effect. It will look like Docker runs through the image-build sequence twice, anddocker imageswill list two images, but the second build will come entirely from the build cache and be very quick, and there will only actually be one copy of the image on disk.You can separately override the
command:and/orentrypoint:for each of the containers as well. The base image splits theENTRYPOINTandCMDin a way that's a little tricky to work with here. Possibly what I'd do is to build a derived image with Jupyter installed, but leave the base image'sENTRYPOINT/CMDunmodifiedNow in your Compose file, specify the same
build:option for both containers. Omitimage:(unless you're planning to push the built image to a registry somewhere).One other consideration here, though: a Dockerfile
FROMline doesn't actually make a copy of the base image, but instead just keeps a pointer to the base image's layers. If one container directly declares itsimage:as the base image, and a second builds its DockerfileFROMthe same image, the total space required is only the size of the base image plus the content added by theRUNline. That is, it's possible that your original setup is actually already using the minimum required space, and there's not actually duplication in Docker's internal storage.