0

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

2
  • Since you need to run two commands, the original form with two separate single-process containers is probably better. The ENTRYPOINT lines are probably causing problems, and if you can consistently only use CMD that might simplify things. What problem are you having with the two-container setup that you're trying to solve? When you say "it doesn't work", what specific problem are you running into? Commented Feb 3, 2024 at 0:03
  • @DavidMaze Actually, I have no problem with running 2 containers. Rather, I want it to depend on only one image for subsequent executions after the Docker build process. In other words, the second image (created in the second service) covers the main image (the first service), if it is possible to make the first service refer to the second image, then the main image file can be deleted and Occupies less storage space. But I think impossible, because of different ENTRYPOINT . Commented Feb 3, 2024 at 0:13

1 Answer 1

1

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, and docker images will 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/or entrypoint: for each of the containers as well. The base image splits the ENTRYPOINT and CMD in 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's ENTRYPOINT/CMD unmodified

FROM freqtradeorg/freqtrade:develop_plot
RUN pip install jupyterlab "prompt-toolkit<=3.0.36" jupyter-client --user --no-cache-dir

Now in your Compose file, specify the same build: option for both containers. Omit image: (unless you're planning to push the built image to a registry somewhere).

services:
  freqtrade:
    build: .
    # actually arguments to the `freqtrade` command
    command: trade ...
  jupyter:
    build: .
    # replaces the `freqtrade` command entirely
    entrypoint: jupyter lab ...

One other consideration here, though: a Dockerfile FROM line 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 its image: as the base image, and a second builds its Dockerfile FROM the same image, the total space required is only the size of the base image plus the content added by the RUN line. 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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your reply. I'll test it. About your last consideration: When I check images size (using: docker images) I see : ft_ft_jupyterlab:latest 1.3GB and freqtradeorg/freqtrade:develop_plot 1.18GB . Do you say total size is 1.3GB not 2.48GB ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.