Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Ogala/labs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: docker/labs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.

Commits on Feb 8, 2018

  1. Apply minor formatting

    Aaron Arney authored Feb 8, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    911a276 View commit details

Commits on Mar 24, 2018

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    3f9957d View commit details

Commits on Apr 2, 2018

  1. Merge pull request docker#405 from mariosnikolaou/patch-1

    Fix markdown code formatting and link
    Mano Marks authored Apr 2, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d7f3430 View commit details
  2. Merge pull request docker#402 from ocularrhythm/patch-2

    Apply minor formatting
    Mano Marks authored Apr 2, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f1ee16e View commit details
  3. Copy the full SHA
    17aa3cf View commit details
  4. Merge pull request docker#406 from ManoMarks/master

    adding messages directing contributions to training.play-with-docker.com
    Mano Marks authored Apr 2, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1146edb View commit details
  5. fixing link syntax (docker#407)

    * fixing link syntax
    
    * fixing missing bracket
    Mano Marks authored Apr 2, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f241308 View commit details

Commits on May 7, 2018

  1. Copy the full SHA
    2ca8c07 View commit details

Commits on May 18, 2018

  1. Changed command to stop the container (docker#411)

    Vimal-Raghubir authored and Mano Marks committed May 18, 2018
    Copy the full SHA
    be77fa1 View commit details

Commits on Jun 11, 2018

  1. Copy the full SHA
    ebe2932 View commit details

Commits on Jun 20, 2018

  1. Merge pull request docker#414 from OrenBochman/master

    A suggested bug fix for code lab issue docker#413
    spara authored Jun 20, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8024c32 View commit details

Commits on Jul 18, 2018

  1. Changed buzzfeed url to current format. (docker#408)

    kjonnala authored and Mano Marks committed Jul 18, 2018
    Copy the full SHA
    56972e4 View commit details

Commits on Jul 24, 2018

  1. Update package-lock.json

    Mano Marks authored Jul 24, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    90b06dc View commit details

Commits on Jul 30, 2018

  1. Copy the full SHA
    5749578 View commit details

Commits on Aug 9, 2018

  1. Update package-lock.json

    Mano Marks authored Aug 9, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d24b692 View commit details

Commits on Aug 28, 2018

  1. Copy the full SHA
    16cc1ce View commit details

Commits on Sep 11, 2018

  1. Update to latest SQL images

    sixeyed committed Sep 11, 2018
    Copy the full SHA
    8c217ea View commit details

Commits on Sep 17, 2018

  1. Update ISSUE_TEMPLATE

    Mano Marks authored Sep 17, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6c807ef View commit details

Commits on Sep 30, 2018

  1. Fix expansion of BYOL (docker#428)

    Signed-off-by: Kislay Kishore <kislay.kishore2003@gmail.com>
    kislaykishore authored and Mano Marks committed Sep 30, 2018
    Copy the full SHA
    0fab3d4 View commit details

Commits on Oct 16, 2018

  1. Fix typo (docker#431)

    mgrachev authored and Mano Marks committed Oct 16, 2018
    Copy the full SHA
    6b70e30 View commit details

Commits on Feb 4, 2019

  1. Copy the full SHA
    e952389 View commit details

Commits on Feb 6, 2019

  1. Update to Windows Server 2019

    Signed-off-by: Elton Stoneman <elton@sixeyed.com>
    sixeyed committed Feb 6, 2019
    Copy the full SHA
    f9b8a44 View commit details
  2. Merge pull request docker#450 from sixeyed/master

    Update Getting Started to Windows 2019
    sixeyed authored Feb 6, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    84ac7fa View commit details
  3. Update readme.md

    sixeyed authored Feb 6, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    462358f View commit details

Commits on Aug 13, 2019

  1. Bump bootstrap

    Bumps bootstrap from 3.0.0 to 3.4.1.
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Aug 13, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a18076f View commit details
  2. Bump flask from 0.10.1 to 1.0 in /beginner/flask-app

    Bumps [flask](https://github.com/pallets/flask) from 0.10.1 to 1.0.
    - [Release notes](https://github.com/pallets/flask/releases)
    - [Changelog](https://github.com/pallets/flask/blob/master/CHANGES.rst)
    - [Commits](pallets/flask@0.10.1...1.0)
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Aug 13, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9fd92af View commit details

Commits on Sep 10, 2019

  1. Merge pull request docker#471 from docker/dependabot/pip/beginner/fla…

    …sk-app/flask-1.0
    
    Bump flask from 0.10.1 to 1.0 in /beginner/flask-app
    justincormack authored Sep 10, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c0acb82 View commit details
  2. Merge pull request docker#470 from docker/dependabot/nuget/dockercon-…

    …us-2017/windows-modernize-aspnet-dev/v1-src/ProductLaunch/ProductLaunch.Web/bootstrap-3.4.1
    
    Bump bootstrap from 3.0.0 to 3.4.1 in /dockercon-us-2017/windows-modernize-aspnet-dev/v1-src/ProductLaunch/ProductLaunch.Web
    justincormack authored Sep 10, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    48ac9fe View commit details

Commits on Nov 12, 2019

  1. Bump spring-data-jpa in /developer-tools/java-debugging/app

    Bumps spring-data-jpa from 1.3.0.RELEASE to 1.11.23.RELEASE.
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored Nov 12, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    dcd42c6 View commit details
  2. Merge pull request docker#476 from docker/dependabot/maven/developer-…

    …tools/java-debugging/app/org.springframework.data-spring-data-jpa-1.11.23.RELEASE
    
    Bump spring-data-jpa from 1.3.0.RELEASE to 1.11.23.RELEASE in /developer-tools/java-debugging/app
    justincormack authored Nov 12, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    cf093d0 View commit details

Commits on May 23, 2020

  1. Update Spring to work with Spring Data JPA

    The Dependabot bumped Spring Data JPA to the last major revision of 1.x. This created a dependency issue with Spring. Spring Data JPA 1.11.23 requires Spring 4.3.25 to operate. Additionally, adding the SLF4J Simple dependency provides logging that aids in debugging application startup via `docker logs`.
    timothystone authored May 23, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    55b6ac1 View commit details
  2. Merge pull request docker#1 from timothystone/timothystone-spring-fra…

    …mework
    
    Update Spring to work with Spring Data JPA
    timothystone authored May 23, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    59e648e View commit details

Commits on Jun 15, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ed5f6a8 View commit details

Commits on Jul 1, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    97cc045 View commit details

Commits on Oct 15, 2020

  1. Merge pull request docker#505 from docker/dependabot/maven/developer-…

    …tools/java-debugging/app/mysql-mysql-connector-java-8.0.16
    
    Bump mysql-connector-java from 5.1.21 to 8.0.16 in /developer-tools/java-debugging/app
    justincormack authored Oct 15, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6d4968d View commit details
  2. Merge pull request docker#504 from docker/dependabot/maven/developer-…

    …tools/java-debugging/app/org.hibernate-hibernate-validator-5.3.5.Final
    
    Bump hibernate-validator from 4.2.0.Final to 5.3.5.Final in /developer-tools/java-debugging/app
    justincormack authored Oct 15, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a75b306 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5ccda1f View commit details
  4. Merge pull request docker#512 from docker/dependabot/maven/developer-…

    …tools/java-debugging/app/org.hibernate-hibernate-validator-5.3.6.Final
    
    Bump hibernate-validator from 5.3.5.Final to 5.3.6.Final in /developer-tools/java-debugging/app
    justincormack authored Oct 15, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    12b50ab View commit details

Commits on Mar 21, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4b41cad View commit details

Commits on Apr 18, 2022

  1. Merge pull request docker#503 from timothystone/master

    Spring Data JPA Update for Java Dev Tools Debugging App
    justincormack authored Apr 18, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1bcbb14 View commit details
Showing with 369 additions and 480 deletions.
  1. +1 −45 .github/ISSUE_TEMPLATE
  2. +3 −0 README.md
  3. +2 −2 beginner/chapters/votingapp.md
  4. +48 −33 beginner/chapters/webapps.md
  5. +1 −1 beginner/flask-app/requirements.txt
  6. +1 −1 contribute.md
  7. +83 −71 developer-tools/java-debugging/app/pom.xml
  8. +1 −1 developer-tools/java-debugging/docker-compose.yml
  9. +2 −2 developer-tools/java-debugging/registration-database/Dockerfile
  10. +1 −1 developer-tools/java/chapters/ch01-setup.adoc
  11. +1 −1 developer-tools/java/chapters/ch10-monitoring.adoc
  12. +4 −4 developer-tools/nodejs-debugging/app/package-lock.json
  13. +1 −1 developer-tools/ruby/README.md
  14. +2 −2 dockercon-us-2017/README.md
  15. +1 −1 dockercon-us-2017/docker-cloud/README.md
  16. +2 −2 dockercon-us-2017/docker-enterprise/README.md
  17. +1 −1 dockercon-us-2017/securing-apps-docker-enterprise/README.md
  18. +1 −1 ...ercon-us-2017/windows-modernize-aspnet-dev/v1-src/ProductLaunch/ProductLaunch.Web/packages.config
  19. +1 −1 security/apparmor/README.md
  20. +2 −2 security/apparmor/wordpress/zues/zues-framework/libraries/customizer/README.md
  21. +1 −1 security/capabilities/README.md
  22. +4 −4 security/cgroups/README.md
  23. +1 −1 security/scanning/README.md
  24. +2 −2 security/trust/README.md
  25. +1 −1 windows/readme.md
  26. +2 −15 windows/sql-server/Dockerfile.builder
  27. +21 −6 windows/sql-server/Dockerfile.v1
  28. +21 −6 windows/sql-server/Dockerfile.v2
  29. +55 −36 windows/sql-server/Initialize-Database.ps1
  30. +12 −10 windows/sql-server/part-3.md
  31. +2 −2 windows/sql-server/part-4.md
  32. +23 −36 windows/windows-containers/MultiContainerApp.md
  33. +52 −8 windows/windows-containers/README.md
  34. +0 −27 windows/windows-containers/Setup-AWS.md
  35. +0 −30 windows/windows-containers/Setup-Azure.md
  36. +0 −55 windows/windows-containers/Setup-Server2016.md
  37. +0 −18 windows/windows-containers/Setup-Win10.md
  38. +0 −13 windows/windows-containers/Setup.md
  39. +13 −36 windows/windows-containers/WindowsContainers.md
46 changes: 1 addition & 45 deletions .github/ISSUE_TEMPLATE
Original file line number Diff line number Diff line change
@@ -1,45 +1 @@
** PLEASE ONLY USE THIS ISSUE TRACKER TO SUBMIT ISSUES WITH THE DOCKER LABS TUTORIAL CONTENT **

* If you have a bug working with Docker itself, not related to these labs, please file the bug on the [Docker repo](https://github.com/moby/moby) *
* If you would like general support figuring out how to do something with Docker, please use the Docker Slack channel. If you're not on that channel, sign up for the [Docker Community](http://dockr.ly/MeetUp) and you'll get an invite. *
* Or go to the [Docker Forums](https://forums.docker.com/) *

Please provide the following information so we can assess the issue you're having

**Which lab is it that you're having issues with?**

<!--
Title or URL of the lab
-->
**Description**

<!--
Briefly describe the problem you are having in a few paragraphs.
-->

**Steps to reproduce the issue, if relevant:**
1.
2.
3.

**Describe the results you received:**


**Describe the results you expected:**


**Additional information you deem important (e.g. issue happens only occasionally):**

**Output of `docker version`:**

```
(paste your output here)
```

**Output of `docker info`:**

```
(paste your output here)
```

**Additional environment details (AWS, Docker for Mac, Docker for Windows, VirtualBox, physical, etc.):**
At this time we are not actively adding labs to this repository. Our focus is on training.play-with-docker.com where new lab and workshop oriented content is being added. We welcome fixes to existing content. For any new content you wish to contribute, please use this repository:https://github.com/play-with-docker/play-with-docker.github.io. Issues filed against the repo may or may not be fixed.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Docker Tutorials and Labs

> At this time we are not actively adding labs to this repository. Our focus is on [training.play-with-docker.com](https://training.play-with-docker.com) where new lab and workshop oriented content is being added. We welcome fixes to existing content. For any new content you wish to contribute, please use this repository:[https://github.com/play-with-docker/play-with-docker.github.io](https://github.com/play-with-docker/play-with-docker.github.io).

This repo contains [Docker](https://docker.com) labs and tutorials authored both by Docker, and by members of the community. We welcome contributions and want to grow the repo.

#### Docker tutorials:
4 changes: 2 additions & 2 deletions beginner/chapters/votingapp.md
Original file line number Diff line number Diff line change
@@ -164,7 +164,7 @@ Take a look at the file again. You'll see it starts with
```
version: "3"
```
It's important that you use version 3 of compose files, as `docker stack deploy` won't support use of earlier versions. You will see there's also a `services` key, under which there is a separate key for each of the services. Such as:
It's important that you use [version 3](https://docs.docker.com/compose/compose-file/) of compose files, as `docker stack deploy` won't support use of earlier versions. You will see there's also a `services` key, under which there is a separate key for each of the services. Such as:
```
vote:
image: dockersamples/examplevotingapp_vote:before
@@ -186,7 +186,7 @@ The `image` key there specifies which image you can use, in this case the image

Much like `docker run` you will see you can define `ports` and `networks`. There's also a `depends_on` key which allows you to specify that a service is only deployed after another service, in this case `vote` only deploys after `redis`.

The `deploy` key is new in version 3. It allows you to specify various properties of the deployment to the Swarm. In this case, you are specifying that you want two replicas, that is two containers are deployed on the Swarm. You can specify other properties, like when to restart, what [healthcheck](https://docs.docker.com/engine/reference/builder/#healthcheck) to use, placement constraints, resources.
The [`deploy`](https://docs.docker.com/compose/compose-file/#deploy) key is new in version 3. It allows you to specify various properties of the deployment to the Swarm. In this case, you are specifying that you want two replicas, that is two containers are deployed on the Swarm. You can specify other properties, like when to restart, what [healthcheck](https://docs.docker.com/engine/reference/builder/#healthcheck) to use, placement constraints, resources, etc.

#### Test run

81 changes: 48 additions & 33 deletions beginner/chapters/webapps.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ Let's start by taking baby-steps. First, we'll use Docker to run a static websit

The image that you are going to use is a single-page website that was already created for this demo and is available on the Docker Store as [`dockersamples/static-site`](https://store.docker.com/community/images/dockersamples/static-site). You can download and run the image directly in one go using `docker run` as follows.

```
```bash
$ docker run -d dockersamples/static-site
```

@@ -28,14 +28,15 @@ First, stop the container that you have just launched. In order to do this, we n

Since we ran the container in detached mode, we don't have to launch another terminal to do this. Run `docker ps` to view the running containers.

```
```bash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7a0e504ca3e dockersamples/static-site "/bin/sh -c 'cd /usr/" 28 seconds ago Up 26 seconds 80/tcp, 443/tcp stupefied_mahavira
```

Check out the `CONTAINER ID` column. You will need to use this `CONTAINER ID` value, a long sequence of characters, to identify the container you want to stop, and then to remove it. The example below provides the `CONTAINER ID` on our system; you should use the value that you see in your terminal.
```

```bash
$ docker stop a7a0e504ca3e
$ docker rm a7a0e504ca3e
```
@@ -44,7 +45,7 @@ $ docker rm a7a0e504ca3e
Now, let's launch a container in **detached** mode as shown below:

```
```bash
$ docker run --name static-site -e AUTHOR="Your Name" -d -P dockersamples/static-site
e61d12292d69556eabe2a44c16cbd54486b2527e2ce4f95438e504afb7b02810
```
@@ -59,7 +60,7 @@ In the above command:

Now you can see the ports by running the `docker port` command.

```
```bash
$ docker port static-site
443/tcp -> 0.0.0.0:32772
80/tcp -> 0.0.0.0:32773
@@ -69,17 +70,18 @@ If you are running [Docker for Mac](https://docs.docker.com/docker-for-mac/), [D

If you are using Docker Machine on Mac or Windows, you can find the hostname on the command line using `docker-machine` as follows (assuming you are using the `default` machine).

```
```bash
$ docker-machine ip default
192.168.99.100
```
You can now open `http://<YOUR_IPADDRESS>:[YOUR_PORT_FOR 80/tcp]` to see your site live! For our example, this is: `http://192.168.99.100:32773`.

You can also run a second webserver at the same time, specifying a custom host port mapping to the container's webserver.

```
```bash
$ docker run --name static-site-2 -e AUTHOR="Your Name" -d -p 8888:80 dockersamples/static-site
```

<img src="../images/static.png" title="static">

To deploy this on a real server you would just need to install Docker, and run the above `docker` command(as in this case you can see the `AUTHOR` is Docker which we passed as an environment variable).
@@ -88,19 +90,20 @@ Now that you've seen how to run a webserver inside a Docker container, how do yo

But first, let's stop and remove the containers since you won't be using them anymore.

```
```bash
$ docker stop static-site
$ docker rm static-site
```

Let's use a shortcut to remove the second site:

```
```bash
$ docker rm -f static-site-2
```

Run `docker ps` to make sure the containers are gone.
```

```bash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
```
@@ -111,7 +114,7 @@ In this section, let's dive deeper into what Docker images are. You will build y

Docker images are the basis of containers. In the previous example, you **pulled** the *dockersamples/static-site* image from the registry and asked the Docker client to run a container **based** on that image. To see the list of images that are available locally on your system, run the `docker images` command.

```
```bash
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockersamples/static-site latest 92a386b6e686 2 hours ago 190.5 MB
@@ -132,15 +135,15 @@ For simplicity, you can think of an image akin to a git repository - images can

For example you could pull a specific version of `ubuntu` image as follows:

```
```bash
$ docker pull ubuntu:12.04
```

If you do not specify the version number of the image then, as mentioned, the Docker client will default to a version named `latest`.

So for example, the `docker pull` command given below will pull an image named `ubuntu:latest`:

```
```bash
$ docker pull ubuntu
```

@@ -159,6 +162,7 @@ Another key concept is the idea of _official images_ and _user images_. (Both of
- **User images** are images created and shared by users like you. They build on base images and add additional functionality. Typically these are formatted as `user/image-name`. The `user` value in the image name is your Docker Store user or organization name.

### 2.3 Create your first image

>**Note:** The code for this section is in this repository in the [flask-app](https://github.com/docker/labs/tree/master/beginner/flask-app) directory.
Now that you have a better understanding of images, it's time to create your own. Our goal here is to create an image that sandboxes a small [Flask](http://flask.pocoo.org) application.
@@ -187,29 +191,30 @@ Start by creating a directory called ```flask-app``` where we'll create the foll
Make sure to ```cd flask-app``` before you start creating the files, because you don't want to start adding a whole bunch of other random files to your image.

#### app.py

Create the **app.py** with the following content:

```
```python
from flask import Flask, render_template
import random

app = Flask(__name__)

# list of cat images
images = [
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-1376-1381846217-0.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3391-1381844336-26.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-29111-1381845968-0.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3409-1381844582-13.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr02/15/9/anigif_enhanced-buzz-19667-1381844937-10.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-18774-1381844645-6.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif",
"http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif"
]
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-1376-1381846217-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3391-1381844336-26.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-29111-1381845968-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3409-1381844582-13.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr02/15/9/anigif_enhanced-buzz-19667-1381844937-10.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-18774-1381844645-6.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif"
]

@app.route('/')
def index():
@@ -219,16 +224,20 @@ def index():
if __name__ == "__main__":
app.run(host="0.0.0.0")
```

#### requirements.txt

In order to install the Python modules required for our app, we need to create a file called **requirements.txt** and add the following line to that file:

```
Flask==0.10.1
```

#### templates/index.html

Create a directory called `templates` and create an **index.html** file in that directory with the following content in it:

```
```html
<html>
<head>
<style type="text/css">
@@ -257,7 +266,9 @@ Create a directory called `templates` and create an **index.html** file in that
</body>
</html>
```

### 2.3.2 Write a Dockerfile

We want to create a Docker image with this web app. As mentioned above, all user images are based on a _base image_. Since our application is written in Python, we will build our own Python image based on [Alpine](https://store.docker.com/images/alpine). We'll do that using a **Dockerfile**.

A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a text file that contains a list of commands that the Docker daemon calls while creating an image. The Dockerfile contains all the information that Docker needs to know to run the app &#8212; a base Docker image to run from, location of your project code, any dependencies it has, and what commands to run at start-up. It is a simple way to automate the image creation process. The best part is that the [commands](https://docs.docker.com/engine/reference/builder/) you write in a Dockerfile are *almost* identical to their equivalent Linux commands. This means you don't really have to learn new syntax to create your own Dockerfiles.
@@ -272,6 +283,7 @@ A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a text file
```

2. The next step usually is to write the commands of copying the files and installing the dependencies. But first we will install the Python pip package to the alpine linux distribution. This will not just install the pip package but any other dependencies too, which includes the python interpreter. Add the following [RUN](https://docs.docker.com/engine/reference/builder/#run) command next:

```
RUN apk add --update py2-pip
```
@@ -293,6 +305,7 @@ A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a text file
```

4. Specify the port number which needs to be exposed. Since our flask app is running on `5000` that's what we'll expose.

```
EXPOSE 5000
```
@@ -410,7 +423,7 @@ If you don't have the `alpine:3.5` image, the client will first pull the image a
### 2.3.4 Run your image
The next step in this section is to run the image and see if it actually works.

```
```bash
$ docker run -p 8888:5000 --name myfirstapp YOUR_USERNAME/myfirstapp
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
```
@@ -426,29 +439,30 @@ Now that you've created and tested your image, you can push it to [Docker Cloud]

First you have to login to your Docker Cloud account, to do that:

```
```bash
docker login
```

Enter `YOUR_USERNAME` and `password` when prompted.

Now all you have to do is:

```
```bash
docker push YOUR_USERNAME/myfirstapp
```

Now that you are done with this container, stop and remove it since you won't be using it again.

Open another terminal window and execute the following commands:

```
```bash
$ docker stop myfirstapp
$ docker rm myfirstapp
```

or

```
```bash
$ docker rm -f myfirstapp
```

@@ -463,6 +477,7 @@ Here's a quick summary of the few basic commands we used in our Dockerfile.
* `COPY` copies local files into the container.

* `CMD` defines the commands that will run on the Image at start-up. Unlike a `RUN`, this does not create a new layer for the Image, but simply runs the command. There can only be one `CMD` per a Dockerfile/Image. If you need to run multiple commands, the best way to do that is to have the `CMD` run a script. `CMD` requires that you tell it where to run the command, unlike `RUN`. So example `CMD` commands would be:

```
CMD ["python", "./app.py"]
2 changes: 1 addition & 1 deletion beginner/flask-app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Flask==0.10.1
Flask==1.0
2 changes: 1 addition & 1 deletion contribute.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ Thank you so much for your interest in contributing to [Docker](https://docker.c

Just a few quick things to be aware of before you get started.

We welcome issues and pull requests for either adding a new tutorial, or fixing a problem with an existing tutorial. This is a repository for tutorials that use Docker based projects as much as possible. So if there’s a Docker tool for what you’re describing, please use that.
We welcome issues and pull requests for fixing a problem with an existing tutorial. We are not accepting new tutorials. If you want to contribute new tutorials, please consider contributing to [training.play-with-docker.com](https://training.play-with-docker.com) in this repository: [https://github.com/play-with-docker/play-with-docker.github.io](https://github.com/play-with-docker/play-with-docker.github.io).

Anything you contribute will be under an Apache license. Docker will choose which tutorials to accept and reject, and will be able to take any tutorials here and put them in Docker documentation. Likewise, anything posted here may be forked by anyone on GitHub.

154 changes: 83 additions & 71 deletions developer-tools/java-debugging/app/pom.xml
Original file line number Diff line number Diff line change
@@ -1,72 +1,84 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.docker</groupId>
<artifactId>UserSignup</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>UserSignup Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.3.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>UserSignup</finalName>
</build>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.docker</groupId>
<artifactId>UserSignup</artifactId>
<packaging>war</packaging>
<version>0.0.2-SNAPSHOT</version>
<name>UserSignup Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.release}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.release}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.release}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.23.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.release>4.3.25.RELEASE</spring.release>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<finalName>UserSignup</finalName>
</build>
</project>
2 changes: 1 addition & 1 deletion developer-tools/java-debugging/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -30,4 +30,4 @@ services:
- "8000:8000"
restart: always



Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mysql:latest
FROM mysql:5.7

# Copy the database initialize script:
# Contents of /docker-entrypoint-initdb.d are run on mysqld startup
@@ -8,4 +8,4 @@ ADD docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
# ENV MYSQL_ROOT_PASSWORD=my-secret-pw # Not defaulted for security reasons!
ENV MYSQL_DATABASE=dockercon2035
ENV MYSQL_USER=gordon
ENV MYSQL_PASSWORD=password
ENV MYSQL_PASSWORD=password
2 changes: 1 addition & 1 deletion developer-tools/java/chapters/ch01-setup.adoc
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@

= Setup Environments

This section describes the hardware and software needed for this workshop, and how to configure them. This workshop is designed for a BYOL (Brying Your Own Laptop) style hands-on-lab.
This section describes the hardware and software needed for this workshop, and how to configure them. This workshop is designed for a BYOL (Bring Your Own Laptop) style hands-on-lab.

== Hardware & Software

2 changes: 1 addition & 1 deletion developer-tools/java/chapters/ch10-monitoring.adoc
Original file line number Diff line number Diff line change
@@ -307,7 +307,7 @@ image::prometheus-metrics5.png[]
+
image::prometheus-metrics6.png[]
+
. Stop the container: `docker container rm -f metrics`
. Stop the container: `docker service rm metrics`

Multiple graphs can be added this way.

8 changes: 4 additions & 4 deletions developer-tools/nodejs-debugging/app/package-lock.json
2 changes: 1 addition & 1 deletion developer-tools/ruby/README.md
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ There are many different versions of Ruby in use. Ruby applications can be based

In contrast, there are also many many versions of Python in use, but the majority of applications use the lastest 2.X or 3.X versions. Similarly, Java applications use the last two major releases of either Java released by Oracle or OpenJDK.

Earlier versions of Ruby are used in production because upgrading presents challenges such as, critical gems are not backward-compatible. Debugging tools like pry, rubocop, byebug... do work on many versions, but not consistently on all Ruby verisons.
Earlier versions of Ruby are used in production because upgrading presents challenges such as, critical gems are not backward-compatible. Debugging tools like pry, rubocop, byebug... do work on many versions, but not consistently on all Ruby versions.

As a result, Ruby developers (and people deploying Ruby apps) rely on tools like [rvm](https://rvm.io/) or [rbenv](https://github.com/rbenv/rbenv) to install a specific version of Ruby. These tools enable developers to switch between different versions of Ruby, and between different sets of gems (when different applications have conflicting requirements).

4 changes: 2 additions & 2 deletions dockercon-us-2017/README.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@

This repo contains the series of hands-on labs presented at DockerCon 2017 in Austin. They are designed to help you gain experience in various Docker features, products, and solutions. Depending on your experience, each lab requires between 30-45 minutes to complete. They range in difficulty from easy to advanced.

At the Hands-on Labs at DockerCon 2017 in Austin, we issued [Microsoft Azure](https://azure.microsoft.com/) credentials and hostnames. Many of these labs assumes you have Azure VMs and Docker Datacenter licenses. You can sign up for Azure resources through the Azure site. Each lab will identify prerequists at the begining of the lab. For Linux base nodes you
At the Hands-on Labs at DockerCon 2017 in Austin, we issued [Microsoft Azure](https://azure.microsoft.com/) credentials and hostnames. Many of these labs assumes you have Azure VMs and Docker Datacenter licenses. You can sign up for Azure resources through the Azure site. Each lab will identify prerequists at the beginning of the lab. For Linux base nodes you

You can get a trial license for Docker Datacenter through [Docker Store](https://store.docker.com/search?offering=enterprise&type=edition).

@@ -140,4 +140,4 @@ This lab is aimed at ops and system admins. It steps through packaging an ASP.NE
## [DockerCon 2017 Austin Workshops](workshop-slides/README.md)

At DockerCon 2017 in Austin, we had [10 workshops](https://2017.dockercon.com/workshops/), each lasting about 3 hours.
At DockerCon 2017 in Austin, we had [10 workshops](https://2017.dockercon.com/workshops/), each lasting about 3 hours.
2 changes: 1 addition & 1 deletion dockercon-us-2017/docker-cloud/README.md
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ Specify the Dockerfile path (in Step 7):
+ Enter **/voting/Dockerfile** for the **Dockerfile Path**

### Check to make sure the repositories were created
If you click the **Repositories** menu on the left you should see both the ```voting``` and ```results``` respositories were created.
If you click the **Repositories** menu on the left you should see both the ```voting``` and ```results``` repositories were created.

Well done! You've created two new repos and configured them to autobuild whenever new changes are pushed to the associated GitHub repos.

4 changes: 2 additions & 2 deletions dockercon-us-2017/docker-enterprise/README.md
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ It will take up to 30 seconds to install.

4. Log in to UCP by going to `https://<node0-public-dns>` in your browswer

Depending on what browser you are using, you will receive a warning about the connection. Proceed through to the UCP URL. The warning is occuring because we UCP uses privately signed certificates by default. In a production installation we would add our own certificates that would be trusted by our browser.
Depending on what browser you are using, you will receive a warning about the connection. Proceed through to the UCP URL. The warning is occurring because we UCP uses privately signed certificates by default. In a production installation we would add our own certificates that would be trusted by our browser.

![](images/private.png)

@@ -203,7 +203,7 @@ A [Docker Stack](https://docs.docker.com/engine/reference/commandline/stack_depl
In this section we will deploy the [Docker Pets](https://github.com/mark-church/docker-paas) application using a compose file. In the following sections we will add features to our compose file and make our application progressively more complex and feature-full. Docker Pets is a simple web app that records votes for different animals and uses a persistent backend to record the votes. It's comprised of two images:

- **`chrch/docker-pets`** is a front-end Python Flask container that serves up random images of housepets, depending on the given configuration
- **`consul`** (which will be used in a later compose file) is a back-end KV store that stores the number of visits that the web services recieve. It's configured to bootstrap itself with 3 replicas so that we have fault tolerant persistence.
- **`consul`** (which will be used in a later compose file) is a back-end KV store that stores the number of visits that the web services receive. It's configured to bootstrap itself with 3 replicas so that we have fault tolerant persistence.

This is the first iteration of our compose file for the Docker Pets application:

Original file line number Diff line number Diff line change
@@ -333,7 +333,7 @@ Creating network pets_backend
Creating service pets_web
```

6. Go to your browser and in the address pane type in `<node0-public-ip>`. You should see that the app has succesfully deployed with the new change.
6. Go to your browser and in the address pane type in `<node0-public-ip>`. You should see that the app has successfully deployed with the new change.

### <a name="Task 3.2"></a>Task 3.2: Rescan the Remediated Application

Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
<package id="Antlr" version="3.4.1.9004" targetFramework="net452" />
<package id="AspNet.ScriptManager.bootstrap" version="3.0.0" targetFramework="net452" />
<package id="AspNet.ScriptManager.jQuery" version="1.10.2" targetFramework="net452" />
<package id="bootstrap" version="3.0.0" targetFramework="net452" />
<package id="bootstrap" version="3.4.1" targetFramework="net452" />
<package id="EntityFramework" version="4.3.1" targetFramework="net452" />
<package id="jQuery" version="1.10.2" targetFramework="net452" />
<package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net452" />
2 changes: 1 addition & 1 deletion security/apparmor/README.md
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ For more information, see the [official AppArmor documentation wiki](http://wiki

In this step you will check the status of AppArmor on your Docker Host and learn how to identify whether or not Docker containers are running with an AppArmor profile.

1. View the status of AppArmor on your Docker Host with the `apparmor_status` command. You may need to preceed the command with `sudo`.
1. View the status of AppArmor on your Docker Host with the `apparmor_status` command. You may need to precede the command with `sudo`.

```
$ apparmor_status
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ The Customizer Library adds sections, settings and controls to the customizer ba

At the moment there is only one custom control (for textarea), but look for additional controls as the library matures.

The Customizer Library includes additional classes and helper functions for creating inline styles and loading Google fonts. These functions and classes were developed by [The Theme Foundry](https://thethemefoundry.com/) for their theme [Make](https://thethemefoundry.com/wordpress-themes/make/) and I've found them quite useful in my own projects. However, I'm considering moving them into seperate modules in order to make the core library as focused as possible. Feedback on this is welcome.
The Customizer Library includes additional classes and helper functions for creating inline styles and loading Google fonts. These functions and classes were developed by [The Theme Foundry](https://thethemefoundry.com/) for their theme [Make](https://thethemefoundry.com/wordpress-themes/make/) and I've found them quite useful in my own projects. However, I'm considering moving them into separate modules in order to make the core library as focused as possible. Feedback on this is welcome.

## Installation

@@ -390,4 +390,4 @@ Development
1.0.0
===

* Public Release
* Public Release
2 changes: 1 addition & 1 deletion security/capabilities/README.md
Original file line number Diff line number Diff line change
@@ -198,7 +198,7 @@ usage: capsh [args ...]
--killit=<n> send signal(n) to child
--forkfor=<n> fork and make child sleep for <n> sec
== re-exec(capsh) with args as for --
-- remaing arguments are for /bin/bash
-- remaining arguments are for /bin/bash
(without -- [capsh] will simply exit(0))
```

8 changes: 4 additions & 4 deletions security/cgroups/README.md
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ You will complete the following steps as part of this lab.
- [Step 1 - cgroups and the Docker CLI](#cli)
- [Step 2 - Max-out two CPUs](#cpu_max)
- [Step 3 - Set CPU affinity](#cpu_affinity)
- [Step 4 - CPU share constraints](#cpu-share)
- [Step 4 - CPU share constraints](#cpu_share)
- [Step 5 - Docker Compose and cgroups](#compose)
- [Step 6 - Preventing a fork bomb](#fork_bomb)

@@ -187,7 +187,7 @@ In this step you will use the `docker run` command with the `--cpu-shares` flag
2. Start the second container with 256 CPU shares.

```
$ sudo docker run -d --name container-2 --cpuset-cpus 0 --cpu-shares 256 cpu-stress
$ sudo docker run -d --name container-2 --cpuset-cpus 0 --cpu-shares 256 cpu-stress
```

3. Verify that both containers are running with the `docker ps` command.
@@ -196,8 +196,8 @@ In this step you will use the `docker run` command with the `--cpu-shares` flag
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
725dc16fac5a cpu-stress "/bin/sh -c 'stress -" 2 minutes ago Up 2 minutes container-2
f82f95757d3f cpu-stress "/bin/sh -c 'stress -" 2 minutes ago Up 2 minutes container-1
725dc16fac5a cpu-stress "/bin/sh -c 'stress -" 2 minutes ago Up 2 minutes container-2
f82f95757d3f cpu-stress "/bin/sh -c 'stress -" 2 minutes ago Up 2 minutes container-1
```

4. View the output of `htop`.
2 changes: 1 addition & 1 deletion security/scanning/README.md
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ Be sure to substitute `nigelpoulton` with your own Docker ID in the steps below.
v1: digest: sha256:99588bc8883c9...5f600a3e9f8d5cd size: 528
```

Congratualtions. In this step you tagged and pushed an image to your newly
Congratulations. In this step you tagged and pushed an image to your newly
created *private repo* on Docker Hub.

# <a name="results"></a>Step 4: View scan results
4 changes: 2 additions & 2 deletions security/trust/README.md
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ In this step you will enable Docker Content Trust, sign images as you push them,

> **Note:** If you are using `sudo` with your Docker commands, you will need to preceded the above command so that it looks like this`sudo export DOCKER_CONTENT_TRUST=1`
It is worth nothing that although Docker Content Trust is now enabled, all Docker commands remain the same. Docker Content Trust will work silently in the background.
It is worth noting that although Docker Content Trust is now enabled, all Docker commands remain the same. Docker Content Trust will work silently in the background.

2. Pull the `riyaz/dockercon:trust` signed image.

@@ -407,7 +407,7 @@ Now we'll explore delegation roles in notary. Delegation roles are a subset of t

This command will allow the collaborator to push any target (from `--all-paths`) to the `targets/releases` role if they can sign with their private key `delegation.key` in order to produce a valid signature that can be verified by `delegation.crt`'s public key material.

Be aware that this commmand only stages the delegation role addition.
Be aware that this command only stages the delegation role addition.

5. Publish the addition of the delegation role

2 changes: 1 addition & 1 deletion windows/readme.md
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@

We have these Windows and .NET tutorials:

* [Getting Started with Windows Containers](windows-containers/) - *updated for Windows Server 2019*
* [Windows 101 - from DockerCon](../dockercon-us-2017/windows-101)
* [Getting Started with Windows Containers](windows-containers/)
* [Beginning ASP.NET Web application](aspnet-web/README.md)
* [SQL Server Database](sql-server/README.md)
* [Run a local Docker Registry](registry/README.md)
17 changes: 2 additions & 15 deletions windows/sql-server/Dockerfile.builder
Original file line number Diff line number Diff line change
@@ -1,15 +1,2 @@
# escape=`
FROM microsoft/windowsservercore
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

RUN Install-PackageProvider -Name chocolatey -RequiredVersion 2.8.5.130 -Force; `
Install-Package -Name microsoft-build-tools -RequiredVersion 15.0.26228.0 -Force; `
Install-Package -Name netfx-4.5.2-devpack -RequiredVersion 4.5.5165101 -Force

RUN Install-Package nuget.commandline -RequiredVersion 3.5.0 -Force; `
& C:\Chocolatey\bin\nuget install Microsoft.Data.Tools.Msbuild -Version 10.0.61026
ENV MSBUILD_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin"
RUN $env:PATH = $env:MSBUILD_PATH + ';' + $env:PATH; `
[Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine)
FROM microsoft/dotnet-framework:4.7.2-sdk-windowsservercore-ltsc2016
RUN nuget install Microsoft.Data.Tools.Msbuild -Version 10.0.61804.210
27 changes: 21 additions & 6 deletions windows/sql-server/Dockerfile.v1
Original file line number Diff line number Diff line change
@@ -4,18 +4,33 @@ FROM dockersamples/assets-db-builder AS builder
WORKDIR C:\src
COPY src\Assets.Database-v1\ .
RUN msbuild Assets.Database.sqlproj `
/p:SQLDBExtensionsRefPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61026\lib\net40" `
/p:SqlServerRedistPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61026\lib\net40"
/p:SQLDBExtensionsRefPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61804.210\lib\net46" `
/p:SqlServerRedistPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61804.210\lib\net46"

# update to latest SqlPackage
FROM microsoft/windowsservercore:ltsc2016 AS sqlpackage
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ENV download_url="https://download.microsoft.com/download/6/E/4/6E406E38-0A01-4DD1-B85E-6CA7CF79C8F7/EN/x64/DacFramework.msi"

RUN Invoke-WebRequest -Uri $env:download_url -OutFile DacFramework.msi ; `
Start-Process msiexec.exe -ArgumentList '/i', 'DacFramework.msi', '/quiet', '/norestart' -NoNewWindow -Wait; `
Remove-Item -Force DacFramework.msi

# db image
FROM microsoft/mssql-server-windows-express
FROM microsoft/mssql-server-windows-express:2016-sp1
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

VOLUME C:\database
ENV sa_password D0cker!a8s
COPY --from=sqlpackage ["C:\\Program Files\\Microsoft SQL Server\\140\\DAC", "C:\\Program Files\\Microsoft SQL Server\\140\\DAC"]

ENV ACCEPT_EULA="Y" `
DATA_PATH="C:\database" `
sa_password="D0cker!a8s"

VOLUME ${DATA_PATH}

WORKDIR C:\init
COPY Initialize-Database.ps1 .
CMD ./Initialize-Database.ps1 -sa_password $env:sa_password -Verbose
ENTRYPOINT ["powershell", "./Initialize-Database.ps1"]

COPY --from=builder C:\src\bin\Debug\Assets.Database.dacpac .
27 changes: 21 additions & 6 deletions windows/sql-server/Dockerfile.v2
Original file line number Diff line number Diff line change
@@ -4,18 +4,33 @@ FROM dockersamples/assets-db-builder AS builder
WORKDIR C:\src
COPY src\Assets.Database-v2\ .
RUN msbuild Assets.Database.sqlproj `
/p:SQLDBExtensionsRefPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61026\lib\net40" `
/p:SqlServerRedistPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61026\lib\net40"
/p:SQLDBExtensionsRefPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61804.210\lib\net46" `
/p:SqlServerRedistPath="C:\Microsoft.Data.Tools.Msbuild.10.0.61804.210\lib\net46"

# update to latest SqlPackage
FROM microsoft/windowsservercore:ltsc2016 AS sqlpackage
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ENV download_url="https://download.microsoft.com/download/6/E/4/6E406E38-0A01-4DD1-B85E-6CA7CF79C8F7/EN/x64/DacFramework.msi"

RUN Invoke-WebRequest -Uri $env:download_url -OutFile DacFramework.msi ; `
Start-Process msiexec.exe -ArgumentList '/i', 'DacFramework.msi', '/quiet', '/norestart' -NoNewWindow -Wait; `
Remove-Item -Force DacFramework.msi

# db image
FROM microsoft/mssql-server-windows-express
FROM microsoft/mssql-server-windows-express:2016-sp1
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

VOLUME C:\database
ENV sa_password D0cker!a8s
COPY --from=sqlpackage ["C:\\Program Files\\Microsoft SQL Server\\140\\DAC", "C:\\Program Files\\Microsoft SQL Server\\140\\DAC"]

ENV ACCEPT_EULA="Y" `
DATA_PATH="C:\database" `
sa_password="D0cker!a8s"

VOLUME ${DATA_PATH}

WORKDIR C:\init
COPY Initialize-Database.ps1 .
CMD ./Initialize-Database.ps1 -sa_password $env:sa_password -Verbose
ENTRYPOINT ["powershell", "./Initialize-Database.ps1"]

COPY --from=builder C:\src\bin\Debug\Assets.Database.dacpac .
91 changes: 55 additions & 36 deletions windows/sql-server/Initialize-Database.ps1
Original file line number Diff line number Diff line change
@@ -1,47 +1,66 @@
# Adapted from Microsoft's SQL Server Express sample:
# https://github.com/Microsoft/sql-server-samples/blob/master/samples/manage/windows-containers/mssql-server-2016-express-windows/start.ps1

param(
[Parameter(Mandatory=$false)]
[string]$sa_password)
[string] $sa_password = $env:sa_password,
[string] $data_path = $env:data_path,
[string] $TargetServerName = '.\SQLEXPRESS',
[string] $TargetDatabaseName = 'AssetsDB',
[string] $TargetUser = 'sa',
[string] $TargetPassword = $env:sa_password
)

# start the service
Write-Verbose 'Starting SQL Server'
start-service MSSQL`$SQLEXPRESS
if ($TargetDatabaseName -eq '.\SQLEXPRESS') {

if ($sa_password -ne "_") {
Write-Verbose 'Changing SA login credentials'
$sqlcmd = "ALTER LOGIN sa with password='$sa_password'; ALTER LOGIN sa ENABLE;"
Invoke-Sqlcmd -Query $sqlcmd -ServerInstance ".\SQLEXPRESS"
}
# start the service
Write-Verbose 'Starting SQL Server'
Start-Service MSSQL`$SQLEXPRESS

if ($sa_password -ne "_") {
Write-Verbose 'Changing SA login credentials'
$sqlcmd = "ALTER LOGIN sa with password='$sa_password'; ALTER LOGIN sa ENABLE;"
Invoke-SqlCmd -Query $sqlcmd -ServerInstance ".\SQLEXPRESS"
}

# attach data files if they exist:
$mdfPath = 'c:\database\AssetsDB_Primary.mdf'
if ((Test-Path $mdfPath) -eq $true) {
$sqlcmd = "CREATE DATABASE AssetsDB ON (FILENAME = N'$mdfPath')"
$ldfPath = 'c:\database\AssetsDB_Primary.ldf'
$mdfPath = "$data_path\AssetsDB_Primary.mdf"
$ldfPath = "$data_path\AssetsDB_Primary.ldf"

# attach data files if they exist:
if ((Test-Path $mdfPath) -eq $true) {
$sqlcmd = "$sqlcmd, (FILENAME = N'$ldfPath')"
$sqlcmd = "IF DB_ID('AssetsDB') IS NULL BEGIN CREATE DATABASE AssetsDB ON (FILENAME = N'$mdfPath')"
if ((Test-Path $ldfPath) -eq $true) {
$sqlcmd = "$sqlcmd, (FILENAME = N'$ldfPath')"
}
$sqlcmd = "$sqlcmd FOR ATTACH; END"
Write-Verbose 'Data files exist - will attach and upgrade database'
Invoke-Sqlcmd -Query $sqlcmd -ServerInstance ".\SQLEXPRESS"
}
else {
Write-Verbose 'No data files - will create new database'
}
$sqlcmd = "$sqlcmd FOR ATTACH;"
Write-Verbose "Invoke-Sqlcmd -Query $($sqlcmd) -ServerInstance '.\SQLEXPRESS'"
Invoke-Sqlcmd -Query $sqlcmd -ServerInstance ".\SQLEXPRESS"
}

# deploy or upgrade the database:
$SqlPackagePath = 'C:\Program Files (x86)\Microsoft SQL Server\130\DAC\bin\SqlPackage.exe'
$SqlPackagePath = 'C:\Program Files\Microsoft SQL Server\140\DAC\bin\SqlPackage.exe'
& $SqlPackagePath `
/sf:Assets.Database.dacpac `
/a:Script /op:create.sql /p:CommentOutSetVarDeclarations=true `
/tsn:.\SQLEXPRESS /tdn:AssetsDB /tu:sa /tp:$sa_password

$SqlCmdVars = "DatabaseName=AssetsDB", "DefaultFilePrefix=AssetsDB", "DefaultDataPath=c:\database\", "DefaultLogPath=c:\database\"
Invoke-Sqlcmd -InputFile create.sql -Variable $SqlCmdVars -Verbose

# relay SQL event logs to Docker
$lastCheck = (Get-Date).AddSeconds(-2)
while ($true) {
Get-EventLog -LogName Application -Source "MSSQL*" -After $lastCheck | Select-Object TimeGenerated, EntryType, Message
$lastCheck = Get-Date
Start-Sleep -Seconds 2
}
/a:Script /op:deploy.sql /p:CommentOutSetVarDeclarations=true `
/TargetServerName:$TargetServerName /TargetDatabaseName:$TargetDatabaseName `
/TargetUser:$TargetUser /TargetPassword:$TargetPassword

if ($TargetServerName -eq '.\SQLEXPRESS') {
$SqlCmdVars = "DatabaseName=$TargetDatabaseName", "DefaultFilePrefix=$TargetDatabaseName", "DefaultDataPath=$data_path\", "DefaultLogPath=$data_path\"
Invoke-Sqlcmd -InputFile deploy.sql -Variable $SqlCmdVars -Verbose

Write-Verbose "Deployed AssetsDB database, data files at: $data_path"

$lastCheck = (Get-Date).AddSeconds(-2)
while ($true) {
Get-EventLog -LogName Application -Source "MSSQL*" -After $lastCheck | Select-Object TimeGenerated, EntryType, Message
$lastCheck = Get-Date
Start-Sleep -Seconds 2
}
}
else {
$SqlCmdVars = "DatabaseName=$TargetDatabaseName", "DefaultFilePrefix=$TargetDatabaseName", "DefaultDataPath=$data_path\", "DefaultLogPath=$data_path\"
Invoke-Sqlcmd -ServerInstance $TargetServerName -Database $TargetDatabaseName -User $TargetUser -Password $TargetPassword -InputFile deploy.sql -Variable $SqlCmdVars -Verbose

Write-Verbose "Deployed AssetsDB database, data files at: $data_path"
}
22 changes: 12 additions & 10 deletions windows/sql-server/part-3.md
Original file line number Diff line number Diff line change
@@ -7,21 +7,23 @@ You now have a Docker image with a SQL schema and deployment script, packaged on
The image can be used in development environments where a fresh database is needed for working on new app features, and you want to easily reset the data to an initial state. In this scenario you don't want to persist data between containers, you want the database container to be disposable:

```Docker
docker container run --detach --name assets-db --publish 1433 dockersamples/assets-db:v1
docker container run --detach --name assets-db --publish 1433:1433 dockersamples/assets-db:v1
```

When the container starts it runs the deployment script, finds that there are no existing database files and creates a new database. You can check that by viewing the logs from the container - you'll see the output from the script:

```
> docker container logs assets-db
...
VERBOSE: Starting SQL Server
VERBOSE: Changing SA login credentials
VERBOSE: No data files - will create new database
Generating publish script for database 'AssetsDB' on server '.\SQLEXPRESS'.
Successfully generated script to file C:\init\deploy.sql.
VERBOSE: Changed database context to 'master'.
VERBOSE: Creating AssetsDB...
VERBOSE: Changed database context to 'AssetsDB'.
VERBOSE: Creating [dbo].[Assets]...
VERBOSE: Creating [dbo].[AssetTypes]...
VERBOSE: Creating [dbo].[Locations]...
VERBOSE: Creating [dbo].[FK_Assets_To_Locations]...
VERBOSE: Creating [dbo].[FK_Assets_To_AssetTypes]...
```

You can connect to the database container using SQL Server Management Studio or any other SQL client. From your Docker machine you need to get the IP address of the container with `docker container inspect`:
@@ -54,7 +56,7 @@ You can see that when you remove the container, and start a new one with the sam
```PowerShell
docker container rm --force assets-db
docker container run --detach --publish 1433 --name assets-db dockersamples/assets-db:v1
docker container run --detach --publish 1433:1433 --name assets-db dockersamples/assets-db:v1
```

Inspect this container with `docker container inspect` and you'll see it has a new IP address - this is a whole new container. Connect your SQL client, repeat the `SELECT * FROM Assets` query and you'll see the table is empty - the old data was lost when you removed the container, and its volume was removed. The new container starts with a new database.
@@ -70,7 +72,7 @@ docker container rm --force assets-db
mkdir C:\mssql
docker container run -d -p 1433 --name assets-db --volume C:\mssql:C:\database dockersamples/assets-db:v1
docker container run -d -p 1433:1433 --name assets-db --volume C:\mssql:C:\database dockersamples/assets-db:v1
```

When the container has started, you can verify that the new database is created and the files are written to the host directory by listing the contents on the host:
@@ -82,16 +84,16 @@ When the container has started, you can verify that the new database is created
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 25/09/2017 16:20 8388608 AssetsDB_Primary.ldf
-a---- 25/09/2017 16:20 8388608 AssetsDB_Primary.mdf
-a---- 10/09/2018 15:13 8388608 AssetsDB_Primary.ldf
-a---- 10/09/2018 15:13 8388608 AssetsDB_Primary.mdf
```

Now you can inspect the container to get its IP address, connect and insert rows into the `Assets` table. The data will be stored outside of the container, in the directory on the host. You can replace the container without changing the schema - say you rebuild it with a new version of the base image to get the latest Windows updates. As long as you use the same volume mapping as the previous container, you'll retain all the data:

```PowerShell
docker container rm -f assets-db
docker container run -d -p 1433 --name assets-db --volume C:\mssql:C:\database dockersamples/assets-db:v1
docker container run -d -p 1433:1433 --name assets-db --volume C:\mssql:C:\database dockersamples/assets-db:v1
```

This is a new container with a new file system, but the database location is mapped to the same host directory as the previous container. The setup script still runs, but it finds no differences in the current database schema and the schema definition in the Dacpac, so there's no diff script to apply.
4 changes: 2 additions & 2 deletions windows/sql-server/part-4.md
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ Now you have two images locally, each packaging a separate version of the databa
```PowerShell
docker container rm -f assets-db
docker container run -d -p 1433 --name assets-db -v C:\mssql:C:\database dockersamples/assets-db:v2
docker container run -d -p 1433:1433 --name assets-db -v C:\mssql:C:\database dockersamples/assets-db:v2
```

When this new container starts, the init script attaches the existing data files and runs `SqlPackage`. Noe the schema is different from the Dacpac, so the tool generates a diff script to apply. Then it runs the script to update the schema - you can see the output in `docker container logs`:
@@ -46,7 +46,7 @@ VERBOSE: Creating [dbo].[FK_Assets_To_Users]...
The container retains the upgrade script which `SqlPackage` generates, and you can read it from the container to see the exact SQL statements that were used in the upgrade:

```PowerShell
docker container exec assets-db powershell cat C:\init\create.sql
docker container exec assets-db powershell cat C:\init\deploy.sql
```

For the v2 upgrade the script is 150+ lines of SQL, containing the DDL to update the schema, and the DML post-deployment scripts. The DDL includes the table changes and the new table, as in this snippet:
59 changes: 23 additions & 36 deletions windows/windows-containers/MultiContainerApp.md
Original file line number Diff line number Diff line change
@@ -2,16 +2,16 @@

This tutorial walks you through building and running the sample Album Viewer application with Windows containers. The [Album Viewer](https://github.com/RickStrahl/AlbumViewerVNext) app is an ASP.NET Core application, maintained by Microsoft MVP [Rick Strahl](https://weblog.west-wind.com). There is a fork at [dockersamples/dotnet-album-viewer](https://github.com/dockersamples/dotnet-album-viewer "link to forked version of Album Viewer") which uses Docker Windows containers.

> Docker isn't just for new apps built with .NET Core. You can run full .NET Framework apps in Docker Windows containers, with production support in [Docker EE](https://www.docker.com/enterprise-edition). Check out the labs for [Modernizing .NET apps with Docker](https://github.com/docker/labs/tree/master/windows/modernize-traditional-apps).
> Docker isn't just for new apps built with .NET Core. You can run full .NET Framework apps in Docker Windows containers, with production support in [Docker Enterprise](https://www.docker.com/enterprise-edition). Check out the labs for [Modernizing .NET apps with Docker](https://github.com/docker/labs/tree/master/windows/modernize-traditional-apps).
## Using Docker Compose on Windows

[Docker Compose](https://docs.docker.com/compose/) is a great way develop distributed applications, where all the components run in their own containers. In this lab you'll use Docker Compose to run SQL Server in a container, as the data store for an ASP.NET Core web application running in another container.

Docker Compose is installed with [Docker for Windows](https://www.docker.com/docker-windows). If you've installed Docker as a Windows Service instead, you can download the compose command line using PowerShell:
Docker Compose is installed with [Docker Desktop on Windows 10](https://www.docker.com/docker-windows). If you've installed the Docker Engine as a Windows Service instead, you can download the compose command line using PowerShell:

```
Invoke-WebRequest https://github.com/docker/compose/releases/download/1.16.0/docker-compose-Windows-x86_64.exe -UseBasicParsing -OutFile $env:ProgramFiles\docker\docker-compose.exe
Invoke-WebRequest https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Windows-x86_64.exe -UseBasicParsing -OutFile $env:ProgramFiles\docker\docker-compose.exe
```

To run the sample application in multiple Docker Windows containers, start by cloning the GithUb [dockersamples/dotnet-album-viewer](https://github.com/dockersamples/dotnet-album-viewer/) repository:
@@ -27,41 +27,32 @@ cd dotnet-album-viewer
docker-compose build
```

You'll see a lot of output here. Docker will pull the .NET Core images if you don't already have them, then it will run `dotnet restore` and `dotnet build` inside a container. You will see the usual NuGet and MSBuild output, even if you don't have the SDK installed.
You'll see a lot of output here. Docker will pull the .NET Core images if you don't already have them, then it will run `dotnet restore` and `dotnet build` inside a container. You will see the usual NuGet and MSBuild output - you don't need to have the .NET Core SDK installed, because it is part of the Docker image.

When the build completes, run the app with:

```
docker-compose up -d
```

Docker starts a database container using Microsoft's [SQL Server Express Windows image](https://store.docker.com/images/mssql-server-windows-express), and when the database is running it starts the application container. The database and application containers are in the same Docker network, so they can reach each other.
Docker starts a database container using [TiDB](https://github.com/pingcap/tidb), which is a modern distributed database system compatible with MySQL. When the database is running it starts the application container. The database and application containers are in the same Docker network, so they can reach each other.

The container for the web application maps to port 80 on the host, so from a different machine you can browse to your host address and see the site:
The container for the web application publishes port 80 on the host, so you can browse to your http://localhost and see the site:

![ASP.NET Core Album Viewer app running in a Docker Windows container](images/dotnet-album-viewer.png)

If you're working on the host, you need to browse to the container's IP address. You can find it with `docker container inspect`:

```
docker container inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" dotnetalbumviewer_app_1
172.21.124.54
```

### Organizing Distributed Solutions with Docker Compose

Take a closer look at the [docker-compose.yml](https://github.com/dockersamples/dotnet-album-viewer/blob/master/docker-compose.yml) file. There are two [services](https://docs.docker.com/compose/compose-file/#service-configuration-reference) defined, which are the different components of the app that will run in Docker containers. The first is the SQL Server database:
Take a closer look at the [docker-compose.yml](https://github.com/dockersamples/dotnet-album-viewer/blob/master/docker-compose.yml) file. There are two [services](https://docs.docker.com/compose/compose-file/#service-configuration-reference) defined, which are the different components of the app that will run in Docker containers. The first is the MySQL-compatible database:

```
db:
image: microsoft/mssql-server-windows-express
environment:
sa_password: "DockerCon!!!"
ACCEPT_EULA: "Y"
image: dockersamples/tidb:nanoserver-1809
ports:
- "3306:4000"
```

This uses Microsoft SQL Server Express, which runs as a Docker Windows container. Express edition has a production licence, so you can use it for live applications. The environment settings configure the database, setting the password for the `sa` user account, and accepting the licence agreement.

The second service is the ASP.NET Core web application, which uses the custom image you built at the start of the lab:

```
@@ -70,42 +61,40 @@ The second service is the ASP.NET Core web application, which uses the custom im
build:
context: .
dockerfile: docker/app/Dockerfile
ports:
- "80:80"
environment:
- "Data:useSqLite=false"
- "Data:SqlServerConnectionString=Server=db;Database=AlbumViewer;User Id=sa;Password=DockerCon!!!;MultipleActiveResultSets=true;App=AlbumViewer"
- "Data:Provider=MySQL"
- "Data:ConnectionString=Server=db;Port=4000;Database=AlbumViewer;User=root;SslMode=None"
depends_on:
- db
ports:
- "80:80"
```

The [build](https://docs.docker.com/compose/compose-file/#build) details capture the path to the Dockerfile. The environment variables are used to configure the app - they override the settings in [appsettings.json](https://github.com/dockersamples/dotnet-album-viewer/blob/master/src/AlbumViewerNetCore/appsettings.json). This configuration uses SQL Server rather than the default SQLite database, and sets the connection string to use the SQL Server container.
The [build](https://docs.docker.com/compose/compose-file/#build) details capture the path to the Dockerfile. The environment variables are used to configure the app - they override the settings in [appsettings.json](https://github.com/dockersamples/dotnet-album-viewer/blob/master/src/AlbumViewerNetCore/appsettings.json). This configuration uses MySQL rather than the default SQLite database, and sets the connection string to use the TiDB database container.

> In the database connection string, the server name is `db` - which is the name of the service for the SQL container. Docker has service discovery built-in, so when the app tries to connect using the server name `db`, Docker will direct it to the database container.
> The database container has a built-in user called `root` with no password, and this is the account used by the web application in the connection string.
The app definition also captures the [dependency](https://docs.docker.com/compose/compose-file/#depends_on) on the database server, and publishes port 80 so any traffic coming into the host gets directed by Docker into the container.


## Packaging ASP.NET Core apps in Docker

How can you compile and run this app without .NET Core installed? Docker compiles and runs the app using containers. The tasks are in the [Dockerfile](https://github.com/dockersamples/dotnet-album-viewer/blob/master/docker/app/Dockerfile), which captures all the app dependencies so the only pre-requisite you need is Docker. The first stage in the Dockerfile publishes the app:
How can you compile and run this app without .NET Core installed? Docker compiles and runs the app using containers. The tasks are in the [Dockerfile](https://github.com/dockersamples/dotnet-album-viewer/blob/master/docker/app/Dockerfile), which captures the app dependencies so the only pre-requisite you need is Docker. The first stage in the Dockerfile publishes the app:

```
FROM microsoft/dotnet:2.0.0-sdk-nanoserver AS builder
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
FROM microsoft/dotnet:2.1-sdk-nanoserver-1809 AS builder
WORKDIR /album-viewer
COPY AlbumViewerNetCore.sln .
COPY src/AlbumViewerNetCore/AlbumViewerNetCore.csproj src/AlbumViewerNetCore/AlbumViewerNetCore.csproj
COPY src/AlbumViewerBusiness/AlbumViewerBusiness.csproj src/AlbumViewerBusiness/AlbumViewerBusiness.csproj
COPY src/Westwind.Utilities/Westwind.Utilities.csproj src/Westwind.Utilities/Westwind.Utilities.csproj
RUN dotnet restore
RUN dotnet restore src/AlbumViewerNetCore/AlbumViewerNetCore.csproj
COPY src src
RUN dotnet publish .\src\AlbumViewerNetCore\AlbumViewerNetCore.csproj
```

This uses Microsoft's [.NET Core Docker image](https://store.docker.com/images/dotnet) as the base in the `FROM` instruction. It uses a specific version of the image, with the .NET Core 2.0.0 SDK installed, running on Microsoft Nano Server. Then the `COPY` instructions copy the project files and solution files into the image, and the `RUN` instruction executes `dotnet restore` to restore packages.
This uses Microsoft's [.NET Core Docker image](https://hub.docker.com/r/microsoft/dotnet) as the base in the `FROM` instruction. It uses a specific version of the image, with the .NET Core 2.1 SDK installed, running on the 1809 release of Microsoft Nano Server. Then the `COPY` instructions copy the project files and solution files into the image, and the `RUN` instruction executes `dotnet restore` to restore packages.

Docker caches parts of the image as it build them, and this Dockerfile separates out the restore part to take advantage of that. Unless the solution or project files change, Docker will re-use the image layer with the dependencies already restored, saving time on the `dotnet restore` operation.

@@ -115,18 +104,16 @@ The final stage in the Dockerfile packages the published application:

```
# app image
FROM microsoft/aspnetcore:2.0.0-nanoserver
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-1809
WORKDIR /album-viewer
COPY --from=builder /album-viewer/src/AlbumViewerNetCore/bin/Debug/netcoreapp2.0/publish/ .
CMD ["dotnet", "AlbumViewerNetCore.dll"]
```

This uses a different base image, which is optimized for running [ASP.NET Core](https://store.docker.com/community/images/microsoft/aspnetcore) apps. It has the .NET Core runtime, but not the SDK, and the ASP.NET core packages are already installed. The `COPY` instruction copies the published .NET Core app from the previous stage in the Dockerfile (called `builder`), and the `CMD` instruction tells Docker how to start the app.

The Dockerfile syntax is simple. You only need to learn a handful of instructions to build production-grade Docker images. Inside the Dockerfile, you can use PowerShell to deploy MSIs, update Windows Registry settings, set file permissions and do anything else you need.
This uses a different variant of the `dotnet` base image, which is optimized for running ASP.NET Core apps. It has the .NET Core runtime, but not the SDK, and the ASP.NET core packages are already installed. The `COPY` instruction copies the published .NET Core app from the previous stage in the Dockerfile (called `builder`), and the `CMD` instruction tells Docker how to start the app.

The Dockerfile syntax is simple. You only need to learn a handful of instructions to build production-grade Docker images. Inside the Dockerfile you can use PowerShell to deploy MSIs, update Windows Registry settings, set file permissions and do anything else you need.

## Next Steps

60 changes: 52 additions & 8 deletions windows/windows-containers/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,58 @@
## Getting Started with Windows Containers
# Getting Started with Windows Containers

In September 2016, Microsoft announced the general availability of Windows Server 2016, and with it, Docker engine running containers natively on Windows. This tutorial describes how to get setup to run Docker Windows Containers on Windows 10 or using a Windows Server 2016 VM.
Docker containers run natively in Windows Server 2016, Windows Server 2019 and Windows 10. These labs are based on the latest releases of Windows and Docker which provide the best experience for containerized Windows applications.

If you are developing locally, you must be running Windows 10 pro or Windows 2016 in a virtual machine to be able to use this tutorial.
The minimum requirements are:

If you're using a cloud VM, you must use Windows 2016 VM.
* Windows 10 Professional or Enterprise, with Windows update 1809 *or*
* Windows Server 2019

## Step 1 - Setup

This tutorial consists of three parts:
You can run Windows containers on Windows 10, Windows Server 2016 and Windows Server 2019:

1. [Setup](Setup.md "Setup"): Making sure your development environment is properly set-up to work with Windows Containers.
2. [Getting Started with Windows Containers](WindowsContainers.md "Getting Started with Windows Containers"): The basics of Windows Containers.
3. [Multi-Container Applications](MultiContainerApp.md "Multi-Container Applications"): Using [Docker Compose](https://docker.github.io/compose/ "Docker Compose") to launch a website based on Microsoft SQL Server.
+ [Install Docker Desktop on Windows 10](https://hub.docker.com/editions/community/docker-ce-desktop-windows "Windows 10 Setup")
+ [Install Docker Enterprise Engine on Windows Server](https://hub.docker.com/editions/enterprise/docker-ee-server-windows "Setup on Windows Server")

> Most public cloud providers also have a VM image with Docker already installed. You can use Microsoft's **Windows Server 2019 Datacenter with Containers** VM image on Azure, and Amazon's **Microsoft Windows Server 2019 Base with Containers** AMI on AWS.
## Verification

Run `docker version` to check the basic details of your deployment. You should see "Windows" listed as the operating system for the Docker client and the Docker Engine:

```
PS>docker version
Client: Docker Engine - Community
Version: 18.09.1
API version: 1.39
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:34:26 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.1
API version: 1.39 (minimum version 1.24)
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:50:10 2019
OS/Arch: windows/amd64
Experimental: true
```

> The `OS/Arch` field tells you the operating system and CPU architecture you're using. Docker is cross-platform, so you can manage Windows Docker servers from a Linux client and vice-versa, using the same `docker` commands.
## Windows Versions

The latest release of Windows to support Docker containers is Windows Server 2019, and Windows 10 with the 1809 update. There are many enhancements from the original Windows containers release in Server 2016.

> [Read about the new container features with Docker on Windows Server 2019](https://blog.docker.com/2019/01/announcing-support-for-windows-server-2019-within-docker-enterprise/)
Windows containers need to match the version of the OS where the container is running with the version of the OS inside the container. Container images flagged as `ltsc2019` or `1809` work with the latest Windows versions.


## Next Steps

Continue to Step 2: [Getting Started with Windows Containers](WindowsContainers.md "Getting Started with Windows Containers")
27 changes: 0 additions & 27 deletions windows/windows-containers/Setup-AWS.md

This file was deleted.

30 changes: 0 additions & 30 deletions windows/windows-containers/Setup-Azure.md

This file was deleted.

55 changes: 0 additions & 55 deletions windows/windows-containers/Setup-Server2016.md

This file was deleted.

18 changes: 0 additions & 18 deletions windows/windows-containers/Setup-Win10.md

This file was deleted.

13 changes: 0 additions & 13 deletions windows/windows-containers/Setup.md

This file was deleted.

49 changes: 13 additions & 36 deletions windows/windows-containers/WindowsContainers.md
Original file line number Diff line number Diff line change
@@ -4,51 +4,28 @@ This chapter will cover the basics of using Windows Containers with Docker.

## Running Windows containers

First, make sure the Docker installation is working correctly by running `docker version`. The output should tell you the basic details about your Docker environment:
First pull a Docker image which you can use to run a Windows container:

```
> docker version
Client:
Version: 17.06.1-ee-1
API version: 1.30
Go version: go1.8.3
Git commit: 4dd6e94
Built: Sat Aug 12 01:34:13 2017
OS/Arch: windows/amd64
Server:
Version: 17.06.1-ee-1
API version: 1.30 (minimum version 1.24)
Go version: go1.8.3
Git commit: 4dd6e94
Built: Sat Aug 12 02:14:08 2017
OS/Arch: windows/amd64
Experimental: true
docker image pull mcr.microsoft.com/windows/nanoserver:1809
```
> The `OS/Arch` field tells you the operating system you're using. Docker is cross-platform, so you can manage Windows Docker servers from a Linux client and vice-versa, using the same `docker` commands.

Next, pull a Docker image which you can use to run a Windows container:

```
docker image pull microsoft/windowsservercore
```

This downloads Microsoft's [Windows Server Core](https://store.docker.com/images/windowsservercore) Docker image onto your environment. That image is a full deployment of Windows Server 2016 Core edition (with no UI), packaged to run as a Docker container. You can use it as the base for your own apps, or you can run containers from it directly.
This downloads Microsoft's [Nano Server](https://hub.docker.com/_/microsoft-windows-nanoserver) Docker image onto your environment. That image is a minimal Windows server operating system, packaged to run as a Docker container. You can use it as the base for your own apps, or you can run containers from it directly.

Try a simple container, passing a command for the container to run:

```
docker container run microsoft/windowsservercore hostname
69c7de26ea48
PS> docker container run mcr.microsoft.com/windows/nanoserver:1809 hostname
a33758b2dbea
```

This runs a new container from the Windows Server Core image, and tells it to run the `hostname` command. The output is the machine name of the container, which is actually a random ID set by Docker. Repeat the command and you'll see a different host name every time.
This runs a new container from the Windows Nano Server image, and tells it to run the `hostname` command. The output is the machine name of the container, which is actually a random ID set by Docker. Repeat the command and you'll see a different host name every time.

## Building and pushing Windows container images

You package your own apps in Docker by building a Docker image. You share the app by pushing the image to a registry - it could be a public registry like [Docker Cloud](https://cloud.docker.com), or a private registry running in your own environment like [Docker Trusted Registry](https://docs.docker.com/datacenter/dtr/2.0/). Anyone with access to your image can pull it and run containers - just like you did with Microsoft's public Windows Server Core image.
You package your own apps in Docker by building a Docker image. You share the app by pushing the image to a registry - it could be a public registry like [Docker Hub](https://hub.docker.com), or a private registry running in your own environment like [Docker Trusted Registry](https://docs.docker.com/ee/dtr/). Anyone with access to your image can pull it and run containers - just like you did with Microsoft's public Windows Nano Server image.

Pushing images to Docker Cloud requires a [free Docker ID](https://cloud.docker.com/ "Click to create a Docker ID"). Storing images on Docker Cloud is a great way to share applications, or to create build pipelines that move apps from development to production with Docker.
Pushing images to Docker Hub requires a [free Docker ID](https://hub.docker.com/ "Click to create a Docker ID"). Storing images on Docker Hub is a great way to share applications, or to create build pipelines that move apps from development to production with Docker.

Register for an account, and then save your Docker ID in a variable in your PowerShell session. We will use it in the rest of the lab:

@@ -63,7 +40,7 @@ Docker images are built with the [docker image build](https://docs.docker.com/en
You can generate a very simple Dockerfile with PowerShell:

```
'FROM microsoft/windowsservercore' | Set-Content Dockerfile
'FROM mcr.microsoft.com/windows/nanoserver:1809' | Set-Content Dockerfile
'CMD echo Hello World!' | Add-Content Dockerfile
```

@@ -76,18 +53,18 @@ docker image build --tag $dockerId/hello-world .
Run a container from the image, and you'll see it just executes the instruction from the `CMD` line:

```
docker container run $dockerId/hello-world
> docker container run $dockerId/hello-world
Hello World!
```

Now you have a Docker image for a simple Hello World app. The image is the portable unit - you can push the image to Docker Cloud, and anyone can pull it and run your app for themselves. First run `docker login` with your credentials, to authenticate with the registry. Then push the image:
Now you have a Docker image for a simple Hello World app. The image is the portable unit - you can push the image to Docker Hub, and anyone can pull it and run your app for themselves. First run `docker login` with your credentials, to authenticate with the registry. Then push the image:

```
docker image push $dockerId/hello-world
```

Images stored on Docker Cloud are available in the web interface and public images can be pulled by other Docker users.
Images stored on Docker Hub are available in the web interface, and public images can be pulled by other Docker users.

### Next Steps

Continue to Step 3: [Multi-Container Applications](MultiContainerApp.md "Multi-Container Applications"), to see how to build and run a web application which uses a SQL Server database - all using Docker Windows containers.
Continue to Step 3: [Multi-Container Applications](MultiContainerApp.md "Multi-Container Applications"), to see how to build and run a web application which uses an ASP.NET Core web application and a SQL Server database - all using Docker Windows containers.