New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping volumes should be supported for Docker for Mac #12

Open
jurisk opened this Issue Jan 10, 2017 · 22 comments

Comments

Projects
None yet
@jurisk

jurisk commented Jan 10, 2017

README.md for mssql-server-linux states:

Current Limitations: Mapping volumes is not supported for Docker for Mac.

Could this limitation be resolved?

@manngo

This comment has been minimized.

Show comment
Hide comment
@manngo

manngo Feb 16, 2017

I would certainly like to know at least what is the technical reason it doesn’t (yet) work.

manngo commented Feb 16, 2017

I would certainly like to know at least what is the technical reason it doesn’t (yet) work.

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft Feb 16, 2017

Collaborator

Smart engineer on our team says...

SQL Server requires underlying filesystems to support the O_DIRECT file option so that we can use asynchronous I/O. It appears that Docker's OS X volume mapper doesn't support this.
We also require O_DIRECT because SQL Server expects unbuffered I/O to the disk.

Collaborator

twright-msft commented Feb 16, 2017

Smart engineer on our team says...

SQL Server requires underlying filesystems to support the O_DIRECT file option so that we can use asynchronous I/O. It appears that Docker's OS X volume mapper doesn't support this.
We also require O_DIRECT because SQL Server expects unbuffered I/O to the disk.

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft Feb 16, 2017

Collaborator

BTW - you can use data container volumes for persistence when using Docker for Mac. That doesnt help you share files between the macOS host and the container but it does give you data file persistence for your DB files in /var/opt/mssql/data.

https://docs.docker.com/engine/tutorials/dockervolumes/#/creating-and-mounting-a-data-volume-container

Collaborator

twright-msft commented Feb 16, 2017

BTW - you can use data container volumes for persistence when using Docker for Mac. That doesnt help you share files between the macOS host and the container but it does give you data file persistence for your DB files in /var/opt/mssql/data.

https://docs.docker.com/engine/tutorials/dockervolumes/#/creating-and-mounting-a-data-volume-container

@gigatexal

This comment has been minimized.

Show comment
Hide comment
@gigatexal

gigatexal Feb 16, 2017

On the Mac one could do all their docker work in a Linux VM and get around the limitations of the Mac file system.

gigatexal commented Feb 16, 2017

On the Mac one could do all their docker work in a Linux VM and get around the limitations of the Mac file system.

@gigatexal

This comment has been minimized.

Show comment
Hide comment
@gigatexal

gigatexal Feb 16, 2017

Thinking out loud here: would a compliant file system using FUSE (not sure this even works on OS X) on OS X work? You could use a file system on this FUSE thing to pass the -v for mappings. Maybe ZFS on OSX? https://openzfsonosx.org/

gigatexal commented Feb 16, 2017

Thinking out loud here: would a compliant file system using FUSE (not sure this even works on OS X) on OS X work? You could use a file system on this FUSE thing to pass the -v for mappings. Maybe ZFS on OSX? https://openzfsonosx.org/

@manngo

This comment has been minimized.

Show comment
Hide comment
@manngo

manngo Feb 16, 2017

@twright-msft Thanks for the suggestion about Data Container Volumes, and the link.

I had trouble getting this to work, as I was unclear about the correct syntax.

The following worked well:

docker create -v /var/opt/mssql --name mssql microsoft/mssql-server-linux /bin/true

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Test@123' -p 1433:1433 --volumes-from mssql -d --name sql-server microsoft/mssql-server-linux

This worked through successive restarts of Docker, so this is a workable solution.

manngo commented Feb 16, 2017

@twright-msft Thanks for the suggestion about Data Container Volumes, and the link.

I had trouble getting this to work, as I was unclear about the correct syntax.

The following worked well:

docker create -v /var/opt/mssql --name mssql microsoft/mssql-server-linux /bin/true

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Test@123' -p 1433:1433 --volumes-from mssql -d --name sql-server microsoft/mssql-server-linux

This worked through successive restarts of Docker, so this is a workable solution.

@adilsoncarvalho

This comment has been minimized.

Show comment
Hide comment
@adilsoncarvalho

adilsoncarvalho Mar 4, 2017

Thanks a lot folks! This thread is very helpful!

For those using docker-compose, I created a gist to make it work with your other services.

https://adilsoncarvalho.com/using-mssql-on-linux-using-docker-for-mac-a5d4ac81e57f

adilsoncarvalho commented Mar 4, 2017

Thanks a lot folks! This thread is very helpful!

For those using docker-compose, I created a gist to make it work with your other services.

https://adilsoncarvalho.com/using-mssql-on-linux-using-docker-for-mac-a5d4ac81e57f

@julielerman

This comment has been minimized.

Show comment
Hide comment
@julielerman

julielerman Apr 22, 2017

Contributor

checking in ...is there any movement on this issue? Thanks.

Contributor

julielerman commented Apr 22, 2017

checking in ...is there any movement on this issue? Thanks.

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft Apr 24, 2017

Collaborator

@julielerman Sorry, no, not yet. We're focusing on some of the other issues at the moment having to do with configuration of SQL Server in containers. Targeting CTP 2.1 for those improvements and then we'll take a look at the next batch of issues. This is certainly one of the higher priority issues.

Collaborator

twright-msft commented Apr 24, 2017

@julielerman Sorry, no, not yet. We're focusing on some of the other issues at the moment having to do with configuration of SQL Server in containers. Targeting CTP 2.1 for those improvements and then we'll take a look at the next batch of issues. This is certainly one of the higher priority issues.

@barspi

This comment has been minimized.

Show comment
Hide comment
@barspi

barspi Apr 26, 2017

I spent hours last night (being a docker newbie and all) trying different combinations.

I can confirm that creating a "data volume container", and then using the --volumes-from parameter works fine.

I can also confirm that the (new, as of Docker 1.9+?) option of creating a plain "data volume" works. You can either pre-create it using docker volume create myvolname and then using the -v myvolname:/var/opt/mssql option when running docker run..., or you can go ahead and just use -v myvolname:/var/opt/mssql and it will create a volume "on the spot" if it doesn't exist.
Then you can re-use/share that volume with other containers.

Now, one thing that baffles me is that everybody is talking about the need to have persistent volumes because when you stop your containers everything will be lost. However, in my experiments with the mssql linux image/containers, I can stop and start and restart the container all I want, and my filesystem changes are still there (of course they won't be there if I remove the container, but nobody is expecting that.) Do I have something "different" in my Docker setup? Is this a "feature" of Docker for Mac? Has Docker changed its behaviour in the latest versions? (I'm using the latest Docker for Mac Community Edition Version 17.03.1-ce-mac5 (16048))

barspi commented Apr 26, 2017

I spent hours last night (being a docker newbie and all) trying different combinations.

I can confirm that creating a "data volume container", and then using the --volumes-from parameter works fine.

I can also confirm that the (new, as of Docker 1.9+?) option of creating a plain "data volume" works. You can either pre-create it using docker volume create myvolname and then using the -v myvolname:/var/opt/mssql option when running docker run..., or you can go ahead and just use -v myvolname:/var/opt/mssql and it will create a volume "on the spot" if it doesn't exist.
Then you can re-use/share that volume with other containers.

Now, one thing that baffles me is that everybody is talking about the need to have persistent volumes because when you stop your containers everything will be lost. However, in my experiments with the mssql linux image/containers, I can stop and start and restart the container all I want, and my filesystem changes are still there (of course they won't be there if I remove the container, but nobody is expecting that.) Do I have something "different" in my Docker setup? Is this a "feature" of Docker for Mac? Has Docker changed its behaviour in the latest versions? (I'm using the latest Docker for Mac Community Edition Version 17.03.1-ce-mac5 (16048))

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft May 24, 2017

Collaborator

@barspi - you have a correct understanding. You can stop/start/restart your containers all day long and as long as you don't remove the container the changes made inside the container will remain. It's like a VHD file. You can stop/start/restart the VM all day long and all the changes will be persisted in the VHD file, but if you delete the VHD file then all is lost.

The reason that people make such a big deal about persistence is that historically a few years ago containers didnt have persistence at all. They were designed to be completely ephemeral.

It also just comes from a bit of paranoia about people that dont know what they are doing potentially losing data. Just like most things in life there are risks if you dont know what you are doing. :)

Collaborator

twright-msft commented May 24, 2017

@barspi - you have a correct understanding. You can stop/start/restart your containers all day long and as long as you don't remove the container the changes made inside the container will remain. It's like a VHD file. You can stop/start/restart the VM all day long and all the changes will be persisted in the VHD file, but if you delete the VHD file then all is lost.

The reason that people make such a big deal about persistence is that historically a few years ago containers didnt have persistence at all. They were designed to be completely ephemeral.

It also just comes from a bit of paranoia about people that dont know what they are doing potentially losing data. Just like most things in life there are risks if you dont know what you are doing. :)

@mysticmind

This comment has been minimized.

Show comment
Hide comment
@mysticmind

mysticmind Jun 7, 2017

I had the same problem running a microsoft/mssql-server-linux Docker image (Sql Server 2017) container on a Ubuntu 16.06 VirtualBox VM host.

When Docker command with a volume param is run

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<YourStrong!Passw0rd>' -p 1433:1433 -v /var/opt/mssql:/var/opt/mssql -d microsoft/mssql-server-linux

Execution will get stuck at Recovery is complete. This is an informational message only. No user action is required. and won't move forward to completion. Using data container volumes as suggested by @twright-msft solved the problem.

In summary, this problem is there in Linux environment as well.

mysticmind commented Jun 7, 2017

I had the same problem running a microsoft/mssql-server-linux Docker image (Sql Server 2017) container on a Ubuntu 16.06 VirtualBox VM host.

When Docker command with a volume param is run

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<YourStrong!Passw0rd>' -p 1433:1433 -v /var/opt/mssql:/var/opt/mssql -d microsoft/mssql-server-linux

Execution will get stuck at Recovery is complete. This is an informational message only. No user action is required. and won't move forward to completion. Using data container volumes as suggested by @twright-msft solved the problem.

In summary, this problem is there in Linux environment as well.

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft Jun 8, 2017

Collaborator

@mysticmind - Can you please tell me more about your environment? Were you running macOS with Virtual Box on it and then an Ubuntu VM on Virtual Box with Docker Engine inside of it?

Collaborator

twright-msft commented Jun 8, 2017

@mysticmind - Can you please tell me more about your environment? Were you running macOS with Virtual Box on it and then an Ubuntu VM on Virtual Box with Docker Engine inside of it?

@mysticmind

This comment has been minimized.

Show comment
Hide comment
@mysticmind

mysticmind Jun 8, 2017

@twright-msft Windows 10 running a VirtualBox Ubuntu 16.04 VM with Docker inside it

mysticmind commented Jun 8, 2017

@twright-msft Windows 10 running a VirtualBox Ubuntu 16.04 VM with Docker inside it

@kspearrin

This comment has been minimized.

Show comment
Hide comment
@kspearrin

kspearrin Oct 2, 2017

@twright-msft Is this still an issue in GA?

kspearrin commented Oct 2, 2017

@twright-msft Is this still an issue in GA?

@twright-msft

This comment has been minimized.

Show comment
Hide comment
@twright-msft

twright-msft Oct 3, 2017

Collaborator

@kspearrin - Yes, it is likely still a problem.

Collaborator

twright-msft commented Oct 3, 2017

@kspearrin - Yes, it is likely still a problem.

@peschkaj

This comment has been minimized.

Show comment
Hide comment
@peschkaj

peschkaj Oct 6, 2017

Could this be documented on Docker Hub to prevent duplicate bugs being raised?

peschkaj commented Oct 6, 2017

Could this be documented on Docker Hub to prevent duplicate bugs being raised?

@kinosang

This comment has been minimized.

Show comment
Hide comment
@kinosang

kinosang Nov 24, 2017

it's still an issue in 2017-latest.

create a docker volume or data container volume works as charm, but not a final solution, is there any plan to solve it?

kinosang commented Nov 24, 2017

it's still an issue in 2017-latest.

create a docker volume or data container volume works as charm, but not a final solution, is there any plan to solve it?

@pablocarreraest

This comment has been minimized.

Show comment
Hide comment
@pablocarreraest

pablocarreraest Jan 23, 2018

2018, any news at this? love feedback

pablocarreraest commented Jan 23, 2018

2018, any news at this? love feedback

@t-oster

This comment has been minimized.

Show comment
Hide comment
@t-oster

t-oster Feb 14, 2018

Is O_DIRECT the same thing missing in ZFS which prevents using ZFS filesystems as volumes #13 ?

t-oster commented Feb 14, 2018

Is O_DIRECT the same thing missing in ZFS which prevents using ZFS filesystems as volumes #13 ?

@BretFisher

This comment has been minimized.

Show comment
Hide comment
@BretFisher

BretFisher Jul 18, 2018

Based on a discussion with @julielerman, I thought I'd post some guidelines I give to my students and clients around this issue. The TL;DR is:

Don't use bind-mounts on Docker Desktop (macOS/Windows) for database persistence. It's an anti-pattern.

In essence, you're asking the database engine in the container to span operating systems to a remote file system, which at best will be much slower, and at worst just won't work. mssql isn't alone here. I've seen various disk I/O issues and container startup issues for most other sql, nosql, and key/value storage systems when trying to use bind-mounts on macOS and Windows. Sometimes it's a file permissions mis-match, sometimes it's disk driver I/O features, and others are just performance related.

If you're on macOS, I recommend you get savy on the Docker for Mac file sharing features/concerns, as well as how to performance tune it. On Windows, it's much worse because I believe it still uses SMB networking protocols to bind-mount, which almost never works with db files.

I don't think we should expect Docker Desktop to solve all those low level OS issues, and I've helped my clients ensure they don't need a workflow for local test/dev that requires mounting a db file on host into a running db container. In all cases so far it was just a workflow issue that had a different solution.

Methods I've seen used:

Yes named volumes work great, and is what should be used to store db's. The challange usually comes when people want 1. sample/seed data or 2. a large database that they don't want to re-import.

For sample/seed data, that should be part of a custom ENTRYPOINT script that you put in compose files just for local development. This way you customize the local dev startup expirence without changing the Dockerfile. The script can/should be smart enough to detect if the data needs to be re-imported on container startup. The seed data gets stored in the repo with code usually so its schema can be matched to db schema changes. The mssql image doesn't have a default ENTRYPOINT script yet, but you can see great examples on other database images, like the mysql official image, where it will create users, set passwords, and more during container startup, and then restart the database in the CMD stanza.

For large datasets where you don't want the delay of import every time, you'll need to get your pre-created files into the container. Options include:

  1. Once the container is running with the named volume, you can use docker cp to copy the files from host path to container path where you've mounted the named volume. To my knowledge, this can't be automated (that I know of) for easy local development setup with docker-compose up, which is always my goal for new dev environment setup.

  2. My prefered if you have multi-gig db files: You could still bind-mount the directory with data in it on host, but the goal isn't to mount those files directly in mssql, but to rather have a ENTRYPOINT script that checks for their existance in the volume location, and if missing, copy them over from bind-mount location, before passing control to CMD where they'll get mounted by mssql. Sorry I don't have an example, but it should just be a few lines of bash to get working.

Note that none of this is recommended for servers or production obviously, but then those setups won't have bind-mount issues across OS's either.

I hope that helps.

BretFisher commented Jul 18, 2018

Based on a discussion with @julielerman, I thought I'd post some guidelines I give to my students and clients around this issue. The TL;DR is:

Don't use bind-mounts on Docker Desktop (macOS/Windows) for database persistence. It's an anti-pattern.

In essence, you're asking the database engine in the container to span operating systems to a remote file system, which at best will be much slower, and at worst just won't work. mssql isn't alone here. I've seen various disk I/O issues and container startup issues for most other sql, nosql, and key/value storage systems when trying to use bind-mounts on macOS and Windows. Sometimes it's a file permissions mis-match, sometimes it's disk driver I/O features, and others are just performance related.

If you're on macOS, I recommend you get savy on the Docker for Mac file sharing features/concerns, as well as how to performance tune it. On Windows, it's much worse because I believe it still uses SMB networking protocols to bind-mount, which almost never works with db files.

I don't think we should expect Docker Desktop to solve all those low level OS issues, and I've helped my clients ensure they don't need a workflow for local test/dev that requires mounting a db file on host into a running db container. In all cases so far it was just a workflow issue that had a different solution.

Methods I've seen used:

Yes named volumes work great, and is what should be used to store db's. The challange usually comes when people want 1. sample/seed data or 2. a large database that they don't want to re-import.

For sample/seed data, that should be part of a custom ENTRYPOINT script that you put in compose files just for local development. This way you customize the local dev startup expirence without changing the Dockerfile. The script can/should be smart enough to detect if the data needs to be re-imported on container startup. The seed data gets stored in the repo with code usually so its schema can be matched to db schema changes. The mssql image doesn't have a default ENTRYPOINT script yet, but you can see great examples on other database images, like the mysql official image, where it will create users, set passwords, and more during container startup, and then restart the database in the CMD stanza.

For large datasets where you don't want the delay of import every time, you'll need to get your pre-created files into the container. Options include:

  1. Once the container is running with the named volume, you can use docker cp to copy the files from host path to container path where you've mounted the named volume. To my knowledge, this can't be automated (that I know of) for easy local development setup with docker-compose up, which is always my goal for new dev environment setup.

  2. My prefered if you have multi-gig db files: You could still bind-mount the directory with data in it on host, but the goal isn't to mount those files directly in mssql, but to rather have a ENTRYPOINT script that checks for their existance in the volume location, and if missing, copy them over from bind-mount location, before passing control to CMD where they'll get mounted by mssql. Sorry I don't have an example, but it should just be a few lines of bash to get working.

Note that none of this is recommended for servers or production obviously, but then those setups won't have bind-mount issues across OS's either.

I hope that helps.

reviewtypo3org pushed a commit to TYPO3/TYPO3.CMS that referenced this issue Jul 22, 2018

[TASK] Enable functional tests on microsoft sql server again
Executing functional tests on mssql has been disabled a while
ago since the daemon crashed frequently: The server can not
run on tmpfs volumes that we usually use to speed up database
operations. sql server uses O_DIRECT i/o system calls which
tmpfs does not support. Find details at
Microsoft/mssql-docker#12

We now run mssql tests on hard disks again, but enable them
only as nightly since they are too slow as pre-merge tests.

Change-Id: Iefc61670dcf74012fcdaada8e5b771538e7cf8c3
Resolves: #85614
Releases: master
Reviewed-on: https://review.typo3.org/57641
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>

TYPO3IncTeam pushed a commit to TYPO3-CMS/core that referenced this issue Jul 22, 2018

[TASK] Enable functional tests on microsoft sql server again
Executing functional tests on mssql has been disabled a while
ago since the daemon crashed frequently: The server can not
run on tmpfs volumes that we usually use to speed up database
operations. sql server uses O_DIRECT i/o system calls which
tmpfs does not support. Find details at
Microsoft/mssql-docker#12

We now run mssql tests on hard disks again, but enable them
only as nightly since they are too slow as pre-merge tests.

Change-Id: Iefc61670dcf74012fcdaada8e5b771538e7cf8c3
Resolves: #85614
Releases: master
Reviewed-on: https://review.typo3.org/57641
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
@psoares

This comment has been minimized.

Show comment
Hide comment
@psoares

psoares Sep 7, 2018

Same issue happens when running in the latest docker with kubernetes enabled and trying to run mssql through the stable helm chart at https://github.com/helm/charts/tree/master/stable/mssql-linux

psoares commented Sep 7, 2018

Same issue happens when running in the latest docker with kubernetes enabled and trying to run mssql through the stable helm chart at https://github.com/helm/charts/tree/master/stable/mssql-linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment