Skip to content
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

Container from Dockerfile different than manually created #12795

Closed
suchja opened this issue Apr 26, 2015 · 10 comments
Closed

Container from Dockerfile different than manually created #12795

suchja opened this issue Apr 26, 2015 · 10 comments

Comments

@suchja
Copy link

suchja commented Apr 26, 2015

Description of problem:
Not sure whether this is an issue with docker, but there is a difference when executing commands inside a container versus executing the same commands from a Dockerfile.
So far I have only experienced this issue with wine. I have an image with wine installed (see here). The next step is to initialise the wine prefix. Therefore I start a Container from the image with docker run --rm -it --entrypoint /bin/bash wine:latest. Inside the container I type the commands as follows:

$> wine wineboot --init
$> winetricks --unattended dotnet40

You can see now that winetricks is downloading and installing .NET 4.0 framework.

Now trying to move wine wineboot --init into a new dockerfile like this:

FROM wine:latest

RUN wine wineboot --init

After building an image from that Dockerfile, starting a container from it and trying to run the second command: winetricks --unattended dotnet40, I do get an error from wine.

So why is there a difference between running wine wineboot --init interactively in the container versus running it from the Dockerfile?

docker version:
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.1
Git commit (client): a8a31ef
OS/Arch (client): darwin/amd64
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.4.1
Git commit (server): a8a31ef

docker info:
Containers: 9
Images: 277
Storage Driver: aufs
Root Dir: /mnt/sda1/var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 295
Execution Driver: native-0.2
Kernel Version: 3.18.5-tinycore64
Operating System: Boot2Docker 1.5.0 (TCL 5.4); master : a66bce5 - Tue Feb 10 23:31:27 UTC 2015
CPUs: 4
Total Memory: 1.961 GiB
Name: boot2docker
ID: BY2Q:R6SQ:E7DY:E3QD:TMAL:BFM5:DNVZ:GI3D:FG2M:DZK6:YDBD:TPJ5
Debug mode (server): true
Debug mode (client): false
Fds: 23
Goroutines: 26
EventsListeners: 0
Init Path: /usr/local/bin/docker
Docker Root Dir: /mnt/sda1/var/lib/docker

uname -a:
Darwin MacBook-Pro.fritz.box 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

Environment details:
boot2docker with VirtualBox 4.3.26

@suchja suchja changed the title Container from Dockerfile different than manually cretaed Container from Dockerfile different than manually created Apr 26, 2015
@suchja
Copy link
Author

suchja commented Apr 26, 2015

I updated to version 1.6.0, which seems not to make any difference.

@duglin
Copy link
Contributor

duglin commented Apr 26, 2015

I know nothing about 'wine' but let me ask some questions...

  • what's the error message you get ?
  • does 'wine boot --init' persist anything that might not get saved when docker creates an image from that container?
  • what happens if you modify your Dockerfile to say:
RUN wine wineboot --init && winetricks --unattended dotnet40

@suchja
Copy link
Author

suchja commented Apr 27, 2015

Sorry for the vague and lengthy problem description so far.

what's the error message you get?

The error message I get is this:

wine cmd.exe /c echo '%ProgramFiles%' returned unexpanded string '%ProgramFiles%' ... can be caused a corrupt wineprefix, an old wine, or by not owning /home/xclient/.wine

does 'wine boot --init' persist anything that might not get saved when docker creates an image from that container?

After scrolling through tons of trace messages from wine it seems that indeed more stuff is written to files in the interactive approach compared to the dockerfile approach. When doing wine wineboot --init from the dockefile the last output from wine is trace:wineboot:main Operation done before docker removes the intermediate container.
When executing wine wineboot --init interactively on the command line, the line trace:wineboot:main Operation done is followed by tons of additional trace output indicating that more stuff is written to different files. In this case immediately after trace:wineboot:main Operation done I can see a bash prompt and then the additional trace message. Small excerpt:

trace:wineboot:ProcessRunKeys done
trace:wineboot:main Operation done
xclient@b81d0dae2b13:~$ trace:file:RtlDosPathNameToNtPathName_U (L"C:\\windows\\system32\\winedevice.exe",0x33f5f8,(nil),(nil))
trace:file:RtlGetFullPathName_U (L"C:\\windows\\system32\\winedevice.exe" 520 0x33f3a8 (nil))

what happens if you modify your Dockerfile to say RUN wine wineboot --init && winetricks --unattended dotnet40

Then the error message is gone and winetricks is executed. However, it does not properly install dotnet40 as it is expected. I guess this is because wine wineboot --init did not properly prepare the wine environment.

ASSUMPTION: When using the dockerfile approach, docker assumes the command is finished after trace:wineboot:main Operation done, but wine is still running more commands in the background, which can then not be completed.

Is there any way to tell docker to wait a little longer?

@suchja
Copy link
Author

suchja commented Apr 27, 2015

Further investigation shows that wine wineboot --init starts several processes which are not completed once wine wineboot --init command is completed.

I tried the following command while working interactively in the container: wine wineboot --init && ps aux. This gave me output (only focusing on the lines for ps aux):

trace:wineboot:main Operation done
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
xclient      1  0.0  0.1  18180  3348 ?        Ss   08:59   0:00 /bin/bash
xclient    169 31.1  0.3  29936  6992 ?        Ss   09:26   0:05 /usr/bin/wineserver
xclient    173  0.5  0.2 2646048 5772 ?        Ssl  09:26   0:00 C:\windows\system32\services.exe                                      
xclient    179  0.3  0.3 2648712 8192 ?        Ss   09:26   0:00 C:\windows\system32\explorer.exe /desktop                                      
xclient    209  0.0  0.3 2646648 6360 ?        Sl   09:26   0:00 C:\windows\system32\winedevice.exe MountMgr                                      
xclient    217  0.0  0.4 3832628 8268 ?        S    09:26   0:00 C:\windows\system32\winemenubuilder.exe -a -r                                      
xclient    219  0.0  0.2 2643948 5304 ?        Ssl  09:26   0:00 C:\windows\system32\services.exe                                      
xclient    222  0.0  0.1  15572  2176 ?        R+   09:26   0:00 ps aux
xclient@b81d0dae2b13:~$ trace:file:RtlDosPathNameToNtPathName_U (L"C:\\windows\\system32\\winedevice.exe",0x33f5f8,(nil),(nil))
trace:file:RtlGetFullPathName_U (L"C:\\windows\\system32\\winedevice.exe" 520 0x33f3a8 (nil))

After that tons of additional trace messages are following. Once trace message output stops another ps aux only shows PID 1 and ps aux processes running.

So any idea how to handle this in a dockerfile?

@suchja
Copy link
Author

suchja commented Apr 29, 2015

Finally found a way how to wait. Basically I'm waiting on the core process wineserver to be terminated by this script:

#!/bin/sh

# inspired by http://stackoverflow.com/a/10407912

echo "Start waiting on $@"
while pgrep -u xclient "$@" > /dev/null; do 
        echo "waiting ..."
        sleep 1; 
done
echo "$@ completed"

The question is how does this fit with automated builds on docker hub? Will I get a reliable build with it? What's best practice for such an issue anyway? Is there a place where this can be properly documented?

@duglin
Copy link
Contributor

duglin commented Apr 29, 2015

For better or worse I think you're stuck with this type of solution, unless you can find a way to make wine wineboot --init block until its done with all of its work.
Yes I think it should be reproducible on docker hub.
re: docs - you interested in creating something for: https://docs.docker.com/articles/dockerfile_best-practices/ ?

@suchja
Copy link
Author

suchja commented Apr 29, 2015

re: docs - Will try to add a few lines to section one process per container. Do you know which repository to fork?

@duglin
Copy link
Contributor

duglin commented Apr 29, 2015

docker itself. All docs are under the "docs" dir.

@duglin
Copy link
Contributor

duglin commented May 7, 2015

@suchja I'm going to close this issue. If you do update the docs you can open a PR for that. Hope that's ok.

@SmartDeltaRaymon
Copy link

Hi, joining in the discussion a bit late here (specially signed in for this response with my work github account due to the lack of a private one).

Wanted to let you know these insights helped me a great deal in fixing a very similar issue I have been having for a long time now.

What I did was run "wineserver -w" as last command after "wine wineboot --init". "wineserver -w" cleanly waits for all wine related processes in the current wineprefix to finish (as you can read in wineserver --help).

This worked for me, just thought I'd share it here in case anyone ever reads back these old questions.

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

No branches or pull requests

4 participants