Docker with Docker Toolbox for Windows Tutorial
This tutorial walks you through the basics of using a Java app server (WildFly) via a Linux container, running on Windows with Docker Toolbox. We have been testing this tutorial on Windows 7 and 8.1, you will notice that the screenshots come from either of those versions as this document has been tested and maintained.
There are notes for people running on Macs as well.
First follow installation steps for Docker Toolbox:
Install all the components.
Mac: The docker binaries are in
/usr/local/binwhich you can access from your terminal.
Windows: The docker binaries lands in
C:\Program Files\Docker Toolboxfor Windows
Tip 1: Where does the boot2docker VM ISO land on a Windows?
Tip 2: Where does the docker-machine default instance land on Windows installation of VirtualBox?
Tip 3: Window Size Width 160 - docker ps is best displayed with lots of width.
You can make this change on the
Docker Quickstart Terminal command window as well
Tip 4: VirtualBox before any
VirtualBox installed prior to Docker Toolbox has no mention of any docker-machine until we create any docker-machine host. Also, if you have previously installed Docker Toolbox, you can often use
docker-machine upgrade <docker host name>to simply update to the latest version.
Look for and select the
Docker Quickstart Terminalmenu option in your Start Menu
Or use start.sh to launch the command prompt (not the normal Windows command prompt)
You should be able to double-click on start.sh in C:\Program Files\Docker Toolbox
If you successfully launch start.sh, it will execute
ip, therefore you can skip to step 8 below. Do make note of the IP address that is printed out, you will need it later.
You might also execute docker-machine commands from the Windows (DOS) Command Prompt aka "cmd.exe" and type
You should see the docker host called default listed in VirtualBox Manager
docker-machine status default
Note: When it is time to shutdown, run
docker-machine stop default
This will show all environments variables needed to connect to the docker-machine host called default
docker-machine env --shell cmd default
Alternatively you can specify which type of shell you are using. So the proper instructions for environments variables will be created.
From this point forward, you will be inside of a Linux shell, using Linux commands
docker run centos /bin/echo "Hello World"
This will take some time if this is the first run of the "centos" image (size: 200 MB).
If you run the same command again, you will notice that is runs immediately, no download required. A Docker container starts incredibly fast when compared to traditional virtual machine technology.
To prove that point, run the same command again.
Note: the container stops as soon as it finishes the /bin/echo command
On Windows, with docker-machine, the Users directory is shared as
On Mac the Users directory is shared as
This shared folder will allow you to add and edit files using your traditional Windows tools instead of having to learn vi or nano.
Using your File Explorer, create a
demosub-directory to your home directory and then use a
ls -lto see it via the boot2docker-vm (in this example
Burris the username):
ls -l /c/Users/<your_username>/demo
ls -l /Users/<your_username>/demo
In this screenshot, I already some sample projects in my C:\Users\Burr\demo directory
Note: We won't be using "demo" in this tutorial, the goal here was to let you see the connection between /c/Users and C:\Users
docker run -i -t centos /bin/bash
-i means interactive and -t allows your keyboard input
You can also use
-itas well as
-i -t. Remember this trick - if you have an app server failing to start, you can see the console output and review the logs by using "-it"
If this is your first time running the centos image, it may take over a minute to download.
You are now running inside of the Centos-based container, to prove that point, use the following command
exitto leave the container and drop back into the boot2docker-vm shell.
docker ps -a
but there have been previously run containers
docker pull centos/wildfly
Docker Hub contains a large number of pre-configured images that are ready to use via a simple "pull" e.g. https://registry.hub.docker.com/u/centos/wildfly/
rundoes an implicit "pull" if the image is not already downloaded
Docker images are typically identified by two words
centos/wildflyimage includes nice documentation on how to use it - we will be following several of those steps next.
docker run -it centos/wildfly
tis important so you can
Ctrl-Cto stop wildfly and the container.
Ctrl-Cand run a
docker psto see that the container has been stopped.
In this particular case, the WildFly instance does not expose any ports to the outside world, so we don't have any access to WilFly. let's try enabling external access next.
docker run -it -p 8080:8080 centos/wildfly
-p <host_port>:<container_port>flag exposes the container port to the docker host machine
default. The first port
8080relates to the docker host machine port, and the second parameter
8080port relates to the container port that will be exposed.
Each docker container process runs inside the docker host called
defaultcreated by docker-machine previously. To get the ip of the docker host, just open another CMD.exe terminal and type
docker-machine ip default.
Ctrl-Cto terminate the WildFly container.
docker history centos/wildfly
Modify the image and provide our own custom Java application
If you remember way back to
ls /c/Users/<your_username>/demo, the
Usersdirectory on your Windows host is shared with the docker
defaulthost (thanks to VirtualBox Guest Additions). In your home directory, create a directory called
docker_projectsthat is a sibling of
demo. You can create the directory from within the docker-machine host
defaultwith the following command (or just use File Explorer).
Use your home directory name in place of "Burr"
and then create a sub-directory called
You can create the "myapp" directory via Windows Explorer or the boot2docker-vm shell
and then change to the directory, it is important that you do this inside of the boot2docker-vm shell
myappdirectory, create a text file called
Dockerfile, with no extension.
On Windows you might use the Atom editor from Atom.io for text editing.
Edit the newly created
Dockerfileand add the following two lines:
FROM centos/wildfly COPY javaee6angularjs.war /opt/wildfly/standalone/deployments/
Note: On Macs, we have seen Wildfly have a permissions problem with the .war. The workaround is to switch to Root and use chown to make the ajustment to the .war file by adding the following two lines:
USER root RUN chown wildfly:wildfly /opt/wildfly/standalone/deployments/javaee6angularjs.war
The trailing "/" does matter
You can find
javaee6angularjs.warat https://github.com/burrsutter/docker_tutorial/blob/master/javaee6angularjs.war?raw=true Download the war and copy it to the
Back in the boot2docker ssh session
docker build --tag=myapp .
the trailing "." is important
Use the docker
docker imagescommand to see if the image was created
Let's see if that worked
docker run -it -p 8080:8080 myapp
you should see the deployment of
javaee6angularjs.warin the wildfly console logging
And test the app via your browser http://192.168.99.100:8080/javaee6angularjs
The IP address in my screenshots change from time to time as this document has been maintained. Just make sure to remember YOUR IP address as seen via
docker-machine ip default
Now it is time for a victory dance around the room! You have your first Java EE application deployed as part of a Docker container. Remember, Ctrl-C to shut down the app server.
You could also use a
-itto run the container detached, in the background
docker run -d -p 8080:8080 myapp
If detached, you will need to use
docker psto see the active containers and then use
docker stop CONTAINER_IDand
docker rm CONTAINER_ID
Note: Docker automatically generated the name "agitated_hawking" which you can use instead of the CONTAINER_ID. Each time that you execute
docker runcommand, it will create a different (and funny) name for your container.
Adding a --name=some_name allows you to give override the default name of agitated_hawking or whatever was randomly assigned to your container by Docker
docker run --name=myapp_is_running -d -p 8080:8080 myapp
docker logs myapp_is_running
and you can
docker stop myapp_is_runningwhen it is time to shutdown the -d detached app server container
Dive into a live container
docker exec -it myapp_is_running bash cd /opt/wildfly/standalone/log tail server.log
This is a very useful technique if you find things are misbehaving and you wish poke around inside the running container.
OPTIONAL - Clean Slate: If you wish to completely clean up and run through the above steps again:
Remove/Delete all containers
docker rm `docker ps -a -q`
the back ticks are important! You might also need to "stop" or "kill" any containers that are running and will not remove.
docker ps -a docker stop CONTAINER_ID docker kill CONTAINER_ID
Replace CONTAINER_ID with the id seen in the
Remove/Delete all images
docker rmi `docker images -a -q`
watch those back ticks again
You will probably see some scary error messages. You can ignore it since it's caused because there's dependencies between certain docker images. This bulk command doesn't follow the dependencies order.
Check out the follow-on tutorial for adding MySQL. https://github.com/burrsutter/docker_mysql_tutorial