Skip to content

[Docker Desktop] Improve Mac File system performance #7

Closed

Description

@nebuk89

Update Feb 6, 2024 - Released as part of Docker Desktop 4.27 - https://www.docker.com/blog/announcing-synchronized-file-shares/

Update Nov 9, 2023 - As announced in June, Docker has acquired Mutagen IO, Inc.. We are hard at work integrating it into Docker Desktop and working to roll it out as part of a limited early access program.

Update: we are now looking at using GRPCFuse rather than mutagen as a simpler path for perf improvement.

Tell us about your request
Integrate the mutagen pluggin within Docker Desktop to provide users with a file caching option to improve performance on modern web frameworks like PHP Symphony

Which service(s) is this request for?
Desktop

Tell us about the problem you're trying to solve. What are you trying to do, and why is it hard?
File system performance is big issue on Mac,our goal improve web page refresh for web languages like PHP from 2.8 seconds to 0.2 seconds

Are you currently working around this issue?
N/A
Additional context
N/A
Attachments
docker/for-mac#77

Activity

  1. changed the title [-][Docker Desktop][/-] [+][Docker Desktop] Improve Mac File system performance[/+] on Mar 6, 2020
  2. daveisfera commented on Mar 26, 2020

    @daveisfera

    These issue are still happening, so can they be added to this or new cards made to include them?
    docker/for-mac#1592
    docker/for-mac#1899
    docker/for-mac#2417
    docker/for-mac#3186

  3. leehambley commented on Apr 6, 2020

    @leehambley

    I hope leaving a note here is not unwelcome to highlight a particular difficulty in booting Rails applications in Docker on macOS.

    Between Rails hot code reloading, which has a semi-hard dependency on working filesystem events (the polling alternative can eat as much as 20% of system CPU) and Bootsnap, which is a caching loader which tries to speed up booting Rails by bypassing the parsing step (and caching compiled btyecode on disk) which means that booting a Rails app with bootsnap loaded writes as many file as it reads (sometimes), but other times (e,g warm start) has a very different read/write ratio.

    None of the existing methods account for this very well, even the relatively new mount options to try and performance boost either reads or writes don't particularly help because of the relative symmetry under certain configurations.

    Most places I know are still using NFS, with polling, and trying to tune the fsattr cache times to get a reasonable balance of developer experience (speed of code reloading) vs. performance (outright speed), but it's a tightrope.

  4. nebuk89 commented on Apr 6, 2020

    @nebuk89
    ContributorAuthor

    hey @daveisfera we haven't got this quite out onto edge yet :) once we do we will move this over to developer/preview and update this ticket. Hopefully then people on those tickets should see some movement!

  5. mbrioski commented on Apr 6, 2020

    @mbrioski

    @nebuk89 could u clarify caching? Because at the moment the problem is the slow sync from host machine to docker containers

  6. Jean85 commented on Apr 6, 2020

    @Jean85

    @mauri-brioschi With PHP/Symfony apps sometimes the reverse happens: the app itself rewrites a bunch of files in its own var/cache dir, where it dumps a lot of stuff (container definitions, configuration...) and this slows a lot the machine. You could try to ignore that folder from the sync, but you would lose some IDE functionality that relies on that folder.

  7. mbrioski commented on Apr 6, 2020

    @mbrioski

    @Jean85 i know the problem and it happens more with "Frameworks" like Magento where there is "generated" code. Usually i exclude these directories so there's not need for sync.
    Caching these directories really solve the problem? At the end if u flush the cache and u are synchronizing your volumes, your folder must be sync again.

  8. markshust commented on Apr 6, 2020

    @markshust

    Artifacts and caching directories like var/cache, generated, node_modules, vendor, etc. should basically persist on the container, however the issue that @Jean85 pointed out that you miss IDE functionality is definitely valid. As a developer you want assets like these to be generally available, and don't want to have to worry about this folder becoming "out of sync" with the host. I wrote a blog post about all of this at https://markshust.com/2018/12/30/docker-mac-filesystem-volume-mount-approach-performance/ which may be useful to others dealing with filesystem performance issues. Magento 2 seems to be an ideal use-case to test the folder sync issues.

    Mutagen offers different modes https://mutagen.io/documentation/synchronization and ideally we should have access to all of these modes. I believe the "one way" is more performant than "two way" since it only needs to check the filesystem changes in one direction. We'd also need to control whether the host or container is alpha or beta. Consistency also probably isn't required for these artifacts directories, it just needs to be "generally there". Being able to control volume mounts on these different modes is crucial to achieving maximum performance.

  9. mbrioski commented on Apr 6, 2020

    @mbrioski

    What's about mounting NFS volumes? It is the only working solution i have found, i.e. for Magento2.
    No configuration is required and you can still use delegated, cache ...

  10. markshust commented on Apr 6, 2020

    @markshust

    @mauri-brioschi osxfs is (much) more performant than nfs in my experience. i haven't had any issues with osxfs as long as i am strategic in the volumes i mount.

  11. strayer commented on Apr 6, 2020

    @strayer

    I'd like to add that in our case it is important to not sync folders like node_modules or Elixirs build and deps folders back to the host especially because of IDE support. Elixirs folders contain architecture-specific compiled files that will break IDE functionality because many plugins need to execute these files. While file system performance is one of our most prominent Docker dev issues, the requirement of being able to exclude folders from syncing is very important too.

    The obvious workaround would be to simply mount another volume on top of the shared app volume for node_modules and such, but we encountered strange issues with that too. There are filed issues for those problems, but I can't find them right now. I think the issue was the the volumes for node_modules and so on suddenly didn't mount anymore.

  12. rfay commented on Apr 6, 2020

    @rfay

    Just a note that all the docker-sync approaches we've tried have failed, and I'd be very suspicious of mutagen. Although the performance was great, the reliability was zero.

  13. mbrioski commented on Apr 6, 2020

    @mbrioski

    @markshust i'm following this issue docker/for-mac#1592 since a while, and NFS is definitely not slower than Osxfs... we are using it in all Magento2 projects and performances are not comparable at all. We save minutes with NFS.

  14. cweagans commented on Apr 6, 2020

    @cweagans

    @mauri-brioschi it depends on what you're using it for. For PHP projects that all have a zillion tiny files that need to be read every time you send a request, osxfs is definitely not as good. IIRC, for small numbers of files, it does pretty well.

  15. 839 remaining items

  16. franck-grenier commented on Jan 26, 2024

    @franck-grenier

    Synchronized file shares is available for customers with a Docker Pro, Team, or Business subscription.

    Could it be a mistake in the documentation ? :trollface:

  17. NiklasBr commented on Jan 26, 2024

    @NiklasBr

    Huh. This was not what I was expecting.

    You can use a .syncignore file at the root of each file share, to exclude local files from your file share instance. It supports the same syntax as .dockerignore files and excludes, and/or re-includes, paths from synchronization. .syncignore files are ignored at any location other than the root of the file share.

    Some example of things you might want to add to your .syncignore file are:

    • Large dependency directories, for example node_modules and composer directories (unless you rely on accessing them via a bind mount)

    From my perspective hose directories are very important to make available both in the container and host. In multiple containers (e.g. cron and frontend) for execution, and in the host so that the IDE can detect classes for code autocomplete and ilntellisense-style help.

    It seems the new, fourth way, to share files in Docker is still not a good help for Composer-based PHP projects, or am I thinking abut this wrongly?

  18. xenoscopic commented on Jan 26, 2024

    @xenoscopic

    Hi @NiklasBr, if those directories are critical to your workflow, then there's no need to ignore them. We only recommend excluding them if you don't need them and you want to save space within the VM (since they'll be duplicated there when synced). We actually hope this functionality will be particularly effective for PHP projects, so by all means feel free to include their dependencies in the sync!

  19. NiklasBr commented on Jan 26, 2024

    @NiklasBr

    Because you recommend ignoring those directories, what use cases would they be ignored in? I can't find any description on how to deal with multiple projects side by side using compose.yaml files where can I find that documentation? E.g. We have well a twenty parallel full PHP projects, do every engineer manually have to configure all this?

  20. xenoscopic commented on Jan 26, 2024

    @xenoscopic

    Hi again @NiklasBr, great question! It's typically useful to ignore files via .syncignore in cases where you want to create only a single Synchronized File Share for your whole project but you have large assets or dependencies that you don't want to sync into the VM. The other option is to create individual Synchronized File Syncs for each location within a project that you want to bind mount, but even in those cases it can occasionally be useful to exclude contents.

    For example, you might have graphic assets (such as .psd files) that aren't used as part of your build but are stored in a mono repo. Or you might have a frontend component to your app that its built on the host system and not in a container, so there wouldn't be a need to sync the (potentially large) node_modules directory in that case.

    Another case would be where you have dependencies that include native code (e.g. node_modules dependencies that compile in C code). In those cases, you might want separate copies of the dependencies on the host and in the VM, allowing you to run code using those dependencies in both places.

    In general, however, if you need to synchronize the dependencies directories (be they from npm, Composer, Cargo, go mod vendor, etc.), then feel free to do so! The only additional cost is the cost of storing those items in the VM, but that's typically relatively minor.

    I'm not sure exactly what you mean with regard to the side-by-side projects using compose.yaml. If you're asking if it's possible to enable this functionality from Compose, not at the moment - the only mechanism to enable it currently is via the settings panel. However, if all of your PHP projects exist in some directory (such as /Users/yourname/Projects/php), then you can create a single Synchronized File Share for that top-level directory and then any Compose projects that you start up from within that directory will use the functionality.

    We're still collecting feedback on this functionality, so if there's a mechanism that would be easier for enabling this (such as Compose integration, CLI control, etc.), please feel free to provide your feedback!

  21. NiklasBr commented on Jan 26, 2024

    @NiklasBr

    I'm not sure exactly what you mean with regard to the side-by-side projects using compose.yaml. If you're asking if it's possible to enable this functionality from Compose, not at the moment - the only mechanism to enable it currently is via the settings panel. However, if all of your PHP projects exist in some directory (such as /Users/yourname/Projects/php), then you can create a single Synchronized File Share for that top-level directory and then any Compose projects that you start up from within that directory will use the functionality.

    We pretty much need to be able to do this automatically, manually is too fraught with issues and time-consuming.

    Consider this (simplified version) of our project folder structure with three side-by-side projects:

    ~/workspace/project_foo/
        - docker-compose.yaml
        - php-backend/
            - src/
            - vendor/
        - frontend/
            - node_modules/
        - templates/
        - data/
        - dockerfiles/
    
    ~/workspace/project_bar/
        - docker-compose.yaml
        - php-backend/
            - src/
            - vendor/
        - frontend/
            - node_modules/
        - templates/
        - data/
        - dockerfiles/
    
    ~/workspace/project_baz/
        - docker-compose.yaml
        - php-backend/
            - src/
            - vendor/
        - frontend/
            - node_modules/
        - templates/
        - data/
        - dockerfiles/
    
    ...and so on
    

    These have separate Composer and Node dependencies and are wholly separate customer projects with their own docker images and own repositories. One might work on project_foo one day and the next day project_baz and the next week project_bar.

    Some projects may be ElasticSearch, some may not, others may need a frontend pre-renderer, other may not, some projects may use Vue, others React... While they are often built on the same basic tech stack, and have a standardised folder structure and standardised docker volumes in their compose files they may wildy differ in the versions of dependencies, they cannot in reality share any data such as the vendor and node_modules or sync in-between one another.

    The need to set up shares quickly without manual steps either via configuration via docker-compose.yaml or at lease an installation script is doubly important for our colleagues in the support department who need more than I to quickly juggle between a lot of different projects to respond to customer needs.

  22. xenoscopic commented on Jan 26, 2024

    @xenoscopic

    Thanks for the clarification. I think the best suggestion I can offer at the moment would be to create a Synchronized File Share for ~/workspace, which would cause bind mounts for anything under ~/workspace to be replaced. It might be necessary to increase the Docker Desktop disk size, depending on the size of ~/workspace.

    With regard to future automation and/or Compose integration, I don't have anything I can share or promise at the moment, but this is definitely something we'll be looking into, so please do keep an eye on future releases.

  23. NiklasBr commented on Jan 29, 2024

    @NiklasBr

    Thanks @xenoscopic I'll try it as soon as I can find a solution for this issue docker/for-mac#6956 (comment) right now I have to go back to 4.26.1

  24. piotrsmykaj commented on Jan 29, 2024

    @piotrsmykaj

    macbook pro 16, i9 + 32GB Ram, amd radeon 5500m + 2 external monitors + Docker with VirtioFS. After upgrading Docker to one of the recent versions (I don't know exactly which one introduced the issue), my fans are going up to 5600 rpm all the time when containers are up. It's uncomfortable to work in a loud office and feel like on the airport. I downgraded Docker to recommended here 4.14.1 and it's way better. Now my fans go to 5600 rpm only when I use and put a load on my containers, but in the idle fans go down to 3500-4000 rpm.

  25. smnovick commented on Feb 6, 2024

    @smnovick
    Collaborator

    We have completed our integration of the Mutagen plugin with Docker Desktop and released it as Synchronized File Shares in Docker Desktop 4.27. You can read more here: https://www.docker.com/blog/announcing-synchronized-file-shares/

    Given the original request here was to "Integrate the mutagen plugin with Docker Desktop", we will be closing this issue.

  26. locked as resolved and limited conversation to collaborators on Feb 6, 2024
  27. removed their assignment
    on Feb 6, 2024
  28. moved this to Shipped! Enjoy! in docker-roadmapon May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docker_desktopImprovements or additions to Docker Desktop

    Type

    No type

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions