├── .gitignore ├── DESKTOP.md ├── README.md └── images ├── add_a_node.png ├── add_designer_library.png ├── add_java_user_to_organization.png ├── add_java_web_to_team.png ├── add_node.png ├── add_repository_database.png ├── add_repository_java.png ├── add_win_node_1.png ├── add_win_node_2.png ├── add_win_node_3.png ├── add_win_node_4.png ├── app-design-choose.png ├── app-design-custom.png ├── app-design-start.png ├── choose-application-template.png ├── clear_filter.png ├── create-service.png ├── create_java_user.png ├── create_repository.png ├── customize-application-template.png ├── cves.png ├── dashboard.png ├── deploy-links-k8s.png ├── design-new-app.png ├── docker_service_start.png ├── docker_service_stopped.png ├── dtr_fqdn.png ├── dtr_users_created.png ├── inspect_resoource.png ├── java-scanned.png ├── java-web1.png ├── java_organization_new.png ├── join_text.png ├── k8s_lb.jpg ├── k8s_stack.png ├── kube-controllers.png ├── kube-create-stack.png ├── kube-java-lb.png ├── kube-lb.png ├── kube-pods.png ├── kube-running-app.png ├── kube-stack-created.png ├── kube-stack-details.png ├── kube-stacks.png ├── kube_enable.png ├── kube_enable_win.png ├── kube_pods.png ├── kube_run_background.png ├── kube_run_background_win.png ├── kube_run_launch_app_win.png ├── layers.png ├── linux.png ├── linux75.png ├── linux_constraint.png ├── linux_details.png ├── linux_ports.png ├── linux_tweet_app_container.png ├── multi-arch-deploy.png ├── mysql-secret.png ├── name-application-template.png ├── node_listing.png ├── node_mixed.png ├── node_types.png ├── on_push_scan.png ├── organization_screen.png ├── pushed_image.png ├── pwd_screen.png ├── red_warning.png ├── scanning-activate.png ├── secret_add.png ├── secret_add_completed.png ├── secret_add_config.png ├── select_nodes.png ├── service_details.png ├── session-information.png ├── ssl_error.png ├── swarm-services.png ├── team.png ├── team_add_user.png ├── team_with_user.png ├── three_repositories.png ├── tomcat9-components.png ├── tomcat9-scanned.png ├── two_organizations.png ├── two_repositories.png ├── ucp_add_app_file.png ├── ucp_create_stack.png ├── ucp_java_deploy.png ├── ucp_network.png ├── ucp_network_1.png ├── ucp_network_2.png ├── ucp_node_setting.png ├── ucp_nodes.png ├── ucp_secret.png ├── ucp_secret_menu.png ├── ucp_secret_menu_1.png ├── ucp_service_database.png ├── ucp_service_network.png ├── ucp_service_ports.png ├── ucp_service_secret.PNG ├── ucp_shared_stacks.png ├── ucp_stack.png ├── update_status.png ├── user_screen.png ├── vm_roles.png ├── windows.png ├── windows75.png └── windows_ports.png /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | -------------------------------------------------------------------------------- /DESKTOP.md: -------------------------------------------------------------------------------- 1 | # Developing applications with Docker Desktop Enterprise 2 | 3 | Docker Enterprise 3.0 is the first Containers-as-a-Service platform that extends from the developer’s desktop to production. Docker Desktop Enterprise offers developers the ability to create container-based applications quickly and easily, even if they have little prior knowledge of Docker or Kubernetes. Developers on Windows 10 can create both Windows and Linux applications, and developers on macOS can create Linux applications with Docker Desktop Enterprise. Application Templates enable developers to build modern applications using a library of predefined and organization-approved application and service templates, without requiring prior knowledge of Docker commands. By providing re-usable “scaffolding” for developing modern container-based applications, Application Templates accelerate developer onboarding and improve productivity. Docker Enterprise is the first platform to support both Docker Swarm and Kubernetes orchestration which also extends to developer desktops with Docker Desktop Enterprise. Docker Desktop Enterprise includes the ability to ensure matching API versions through the use of Version Packs. 4 | 5 | In this lab, we’ll use Docker Desktop Enterprise to create container-based applications locally. If you’re also running the Docker Enterprise workshop, you will have the opportunity to push these applications to the Docker Enterprise cluster using both Swarm and Kubernetes. 6 | 7 | Suggested workshop order: 8 | * Task 1 - Task XX in this workshop can be run as a standalone workshop using only Docker Desktop Enterprise. 9 | * If running in conjunction with the [Docker Enterprise workshop](README.md) you can switch over and run Task 1 in that workshop to setup your Docker Enterprise environment. 10 | * After completing Task 1 in the Docker Enterprise workshop you can return to this lab and complete Task XX - XX to push and deploy applications to your cluster. 11 | 12 | **System Requirements** 13 | 14 | 15 | You need Docker Desktop Enterprise installed on your laptop or workstation with internet access to complete this lab. An XX-day evaluation license is included with the download of Docker Desktop Enterprise. 16 | * You will also need a code editor of your choice. Instructions here demonstrate the use of [Microsoft Visual Studio Code (vscode)](https://code.visualstudio.com/download), but any code editor should work. 17 | * No knowledge of the code syntax is assumed. 18 | * Some steps demonstrate the use of the [Docker plugin](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) in vscode; many code editors have Docker plugins available that should function similarly. The plugins are not required and the equivalent command will be given to complete the step. 19 | * **The Docker Desktop Enterprise download is approximately 1.8 GB so please download and install before the workshop** 20 | 21 | **Windows OS Requirements** 22 | > 23 | > * Windows 10 Professional or Enterprices 24 | > * Hyper-V features enable. If you want to see how to enable Hyper-V, [check it out over here.](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v). 25 | > * [Download Docker Desktop Enterprise for Windows 10](https://docs.docker.com/ee/desktop/admin/install/windows/) 26 | > * Windows 10 Pro or Enterprise 27 | 28 | 29 | **Mac OS Requirements** 30 | > * [Download Docker Desktop Enterprise for macOS](https://docs.docker.com/ee/desktop/admin/install/mac/) 31 | > * macOS: Docker Desktop requires macOS 10.12 and newer 32 | > * Mac Hardware must be a 2010 or newer model 33 | 34 | 35 | **Difficulty**: Intermediate (assumes basic familiarity with Docker) If you're looking for a basic introduction to Docker, check out [https://training.play-with-docker.com](https://training.play-with-docker.com) 36 | 37 | **Time**: Approximately XX minutes 38 | 39 | > **Introduction**: 40 | > * [What is the Docker Enterprise Platform](#intro1) 41 | > * [Overview of Docker Desktop Enterprise](#intro2) 42 | > * [Overview of Orchestration](#intro3) 43 | > * [Overview of Docker Swarm mode](#intro3.1) 44 | > * [Overview of Kubernetes](#intro3.2) 45 | 46 | > **Tasks**: 47 | > * Using Docker Desktop Enterprise 48 | > * [Task 1: Configure Docker Desktop Enterprise](#task1) 49 | > * [Task 1.1: Launch Docker Desktop Enterprise](#task1.1) 50 | > * [Task 1.2: Admin settings](#task1.2) 51 | > * [Task 1.3: Enable Kubernetes](#task1.3) 52 | > * [Task 1.4: Use Buildkit](#task1.4) 53 | > * [Task 2: Create an Application Template](#task2) 54 | > * [Task 2.1: Choose a Template](#task2.1) 55 | > * [Task 2.2: Customize the Template Settings](#task2.2) 56 | > * [Task 2.3: Scaffold the Application Template](#task2.3) 57 | > * [Task 2.4: Start the Application](#task2.4) 58 | > * [Task 3: Develop an Application with Docker Desktop](#task3) 59 | > * [Task 3.1: Add a Custom Template Repository](#task3.1) 60 | > * [Task 3.2: Choose the New Template](#task3.2) 61 | > * [Task 3.3: Scaffold the Application Template](#task3.3) 62 | > - Show `template` CLI too 63 | > * [Task 3.4: Start the Application](#task3.4) 64 | > * [Task 3.5: Live Code Changes](#task3.5) 65 | > * [Task 3.6: Customize the Application](#task3.6) 66 | > * [Task 3.7: Deploy the Application on Kubernetes](#task3.7) 67 | > * [Task XX: Using Docker Assemble](#taskXX) 68 | 69 | > * Deploying to Docker Enterprise Clusters 70 | > * These tasks should be completed after completing Task 1 in the [Docker Enterprise](README.md) workshop 71 | > * [Task 4: Connecting to Docker Enterprise UCP and DTR](#task4) 72 | > * [Task 4.1: Client Bundles](#task4.1) 73 | > * [Task 4.2: Docker Context](#task4.2) 74 | > * [Task 5: Push to DTR](#task5) 75 | > * [Task 5.1: Push Images to DTR](#task5.1) 76 | > * [Task 5.2: Bundle the Application](#task5.2) 77 | > * [Task 5.3: Push Docker App to DTR](#task5.3) 78 | > * [Task 6: Deploy App to UCP](#task6) 79 | > * [Task 6.1: Deploy to Swarm](#task6.1) 80 | > * [Task 6.2: Deploy to Kubernetes](#task6.2) 81 | 82 | 83 | ## Document conventions 84 | 85 | - When you encounter a phrase in between `<` and `>` you are meant to substitute in a different value. 86 | 87 | For instance if you see `` you would actually type something like `myemail@host.com` 88 | 89 | ## Introduction 90 | **JIM TO UPDATE** -- Docker Enterprise provides an integrated, tested and certified platform for apps running on enterprise Linux or Windows operating systems and Cloud providers. Docker Enterprise is tightly integrated to the the underlying infrastructure to provide a native, easy to install experience and an optimized Docker environment. Docker Certified Infrastructure, Containers and Plugins are exclusively available for Docker Enterprise with cooperative support from Docker and the Certified Technology Partner. 91 | 92 | ### Overview of Docker Desktop Enterprise 93 | **JIM TO PROVIDE** 94 | 95 | ### Overview of Orchestration in Docker Desktop 96 | #### Overview of Docker Swarm mode 97 | A Swarm is a group of machines that are running Docker and joined into a cluster. After that has happened, you continue to run the Docker commands you’re used to, but now they are executed on a cluster by a Swarm manager. The machines in a Swarm can be physical or virtual. After joining a Swarm, they are referred to as nodes. 98 | 99 | Swarm mode uses managers and workers to run your applications. Managers run the Swarm cluster, making sure nodes can communicate with each other, allocate applications to different nodes, and handle a variety of other tasks in the cluster. Workers are there to provide extra capacity to your applications. 100 | 101 | With Docker Desktop Enterprise, you have a single Docker node. Because it is a single node, Swarm mode is not enabled by default, however, Swarm mode can be enabled if required to test commands or features which are only available in Swarm mode. These commands or features include `docker stack deploy` or the `docker service` commands. 102 | 103 | In a multi-node clustered environment, Swarm mode uses managers and workers to run your applications. Managers run the swarm cluster, making sure nodes can communicate with each other, allocating applications to different nodes, and handling a variety of other tasks in the cluster. Workers are there to provide the capacity for your applications. If you are completing the [Docker Enterprise workshop](README.md) along with these exercises you will have a remote cluster with one manager and three workers and later tasks will have you push images and deploy applications from your Docker Desktop Enterprise to the remote cluster. 104 | 105 | #### Overview of Kubernetes 106 | 107 | Kubernetes is part of Docker Enterprise 3.0 in both Docker Desktop Enterprise and Docker Enterprise referred to as Docker Kubernetes Service or DKS. Kubernetes deployments tend to be more complex than Docker Swarm, and there are many additional component types within Kubernetes. The Universal Control Plane (UCP) in Docker Enterprise clusters simplifies much of the complexities using Kubernetes. The Docker platform includes a [fully-comformant Kubernetes Distribution](https://www.cncf.io/certification/software-conformance). We'll concentrate on Pods and Load Balancers in this workshop, but there's plenty more supported by UCP 2.XX. 108 | 109 | ## Task 1: Configure Docker Desktop Enterprise 110 | Docker Desktop Enterprise installation comes pre-configured with administration tools. The admin settings enable administrators to configure Docker Desktop for developer teams and we'll explore some of the administration settings in this section. 111 | 112 | ### Task 1.1: Launch Docker Desktop Enterprise 113 | The first time you launch Docker Desktop Enterpirse it will prompt you for a license file. You can install the license file directly through the prompt or manually based on your Operating System 114 | 115 | **Mac** 116 | 117 | Install the Docker Desktop Enterprise (DDE) license file at the following location: 118 | 119 | `/Library/Group Containers/group.com.docker/docker_subscription.lic` 120 | 121 | **Windows** 122 | 123 | Install the Docker Desktop Enterprise (DDE) license file at the following location for Windows users: 124 | 125 | `%ProgramData%\DockerDesktop\docker_subscription.lic` 126 | 127 | 128 | ### Task 1.2: Admin Settings 129 | 130 | System administrators can configure Docker Desktop Enterprise (DDE) settings, specify and lock configuration parameters to create a standardized development environment based on the developers operating systems. 131 | 132 | * Show admin-settings.json (lockable settings) 133 | * Windows location: `\%ProgramData%\DockerDesktop\admin-settings.json` which defaults to `C:\ProgramData\DockerDesktop\admin-settings.json`. 134 | **NOTE:** You need Administrator privelages to edit this file 135 | * Mac location: `/Library/Application\ Support/Docker/DockerDesktop` 136 | 137 | The `admin-settings.json` allows the configuration of DDE settings. Each configuration can be configured with a default value and whether this value is locked for users or not. The configurations include: 138 | 139 | * `proxy` allow users to change the proxy settings 140 | * `filesharingDirectories` Which directories are shared with Docker Desktop 141 | * `CPU` number of CPU cores 142 | * `memoryMib` amount of memory allocated to Docker Desktop 143 | * `dataFolder` Where Docker stores date 144 | * `diskSizeMib` amount of disk space allocated to Docker Desktop of for images, volumes, etc 145 | * `swamMib` amount of swamp memory for Docker Desktop 146 | * `kubernetes` enable Kubernetes 147 | * `showSystemContainers` Shows containers running in the background 148 | 149 | 1. Navigate to the `admin-settings.json` location based on your Operating System. See above for the location for Mac or Windows. 150 | 2. Using your favorite editor, open the `admin-settings.json` file and review the available configurations. 151 | 152 | The `dockerdesktop-admin` tool allows System Administators to manage DDE applications version packs from the command line. 153 | 154 | **Mac** 155 | * Show dockerdesktop-admin tool 156 | * Mac location: `/Applications/Docker.app/Contents/Resources/bin` 157 | * `sudo ./dockerdesktop-admin --help` 158 | * `sudo ./dockerdesktop-admin app uninstall` to remove DDE and VPs (do not run!) 159 | * Install a Version Pack with dockerdesktop-admin tool 160 | * `sudo ./dockerdesktop-admin version-pack install ` 161 | * Note that Desktop needs to be stopped to add a Version Pack 162 | 163 | **Windows** 164 | * Show dockerdesktop-admin tool 165 | * Windows location: `[`*`ApplicationPath`*`]\dockerdesktop-admin.exe` 166 | * Install a Version Pack with dockerdesktop-admin tool 167 | * `dockerdesktop-admin.exe -InstallVersionPack=['path-to-archive']` 168 | * Version-pack uninstall with dockerdesktop-admin tool 169 | * `dockerdesktop-admin.exe -UninstallVersionPack=[version-pack-name|'path-to-archive']` 170 | * **NOTE:** You must stop Docker Desktop before installing a version pack. 171 | 172 | ### Task 1.3: Enable Kubernetes 173 | 174 | Enabling Kubernetes in Docker Desktop only requires a single click. 175 | 176 | > NOTE: Offline mode is supported when enabling Kubernetes in Docker Desktop Enterprise. 177 | 178 | 1. Open Docker Desktop Enterprise -> Settings 179 | 2. Switch to the Kubernetes Tab 180 | 3. Check the `Enable Kubernetes` box 181 | 4. Click Apply. This will take a couple minutes depending on the performance of your computer 182 | 183 | **Mac** 184 | 185 | ![](./images/kube_enable.png) 186 | 187 | **Windows** 188 | 189 | ![](./images/kube_enable_win.png) 190 | 191 | 5. Run the Kubernetes Cluster creation in the background and will be ready once the Kubernetes status turns green 192 | 193 | **Mac** 194 | 195 | ![](./images/kube_run_background.png) 196 | 197 | **Windows** 198 | 199 | ![](./images/kube_run_background_win.png) 200 | 201 | Congratulations! Docker Desktop Enterprise is now ready to deploy applications to use either Swarm or Kubernetes. 202 | 203 | ### Task 1.4: Use Buildkit 204 | 205 | **Jim** can you provide more background what you need here? 206 | 207 | By default, Docker Desktop uses Build.XX. Buildkit is not required for any exercises in this workshop but we will go ahead and enable it so you can see it in action in case you want to explore advanced build actions on your own. 208 | 209 | 1. Right Click `Docker Desktop Enterprise` -> `Settings` 210 | 2. Open the `Deamon` Tab 211 | 3. Switch to the `Advanced Tab` This is the Docker Daemon configuration file `daemon.json` 212 | 4. Delete the existing configuration 213 | 5. Copy and paste the `daemon.json` configuration below 214 | 215 | **Jim** Windows app doesn't have Daemon > advanced tab. Do we need to split this out as a seperate Windows section [marcel]? 216 | 217 | ```json 218 | { 219 | "debug" : true, 220 | "experimental" : false, 221 | "features": { "buildkit": true } 222 | } 223 | ``` 224 | 5. Click the `Apply & Restart` button 225 | 226 | Docker Desktop Enterprise is now running with Buildkit enabled. 227 | 228 | ## Task 2: Create an Application Template 229 | 230 | In this section, we will explore the capabilities of the DDE Application Designer. The Application Designer comes with a librbary of pre-configured application templates. The Apllication Designer is a visual designer enabling developers to create Docker based applications. 231 | 232 | ### Task 2.1: Choose a Template 233 | 234 | Next, we will explore the Application Designer and learn how to design a new application. When we create a new application we are provided the choice to use a template which contains preconfigured applications or define a custom applications. 235 | 236 | 1. Reight Click on `Docker Desktop` -> `Design new application` 237 | 238 | ![](./images/app-design-choose.png) 239 | 240 | 2. Select `Choose Template` 241 | 242 | 3. Choose the `Flask/ NGINX / MYSQL application` 243 | 244 | ![](./images/choose-application-template.png) 245 | 246 | ### Task 2.2: Customize Template Settings 247 | 248 | Customize the default settings of the `Flask/ NGINX / MYSQL application` template 249 | 250 | 1. Remove port `8080` from Flask and leave blank as we don't want the backend to communicate directly to the internet. 251 | 252 | 2. Change the port of the NGINX Proxy from port `80` --> `8081` so now the NGINX proxy is handeling routing of traffic to the backend service. 253 | 254 | ![](./images/customize-application-template.png) 255 | 256 | ### Task 2.3: Scaffold the Application Template 257 | 258 | The scaffoloding of the template copies all the necessary Dockerfiles, docker-compose, and application specific files locally to DDE. Once all the files have been copied locally, DDE then builds the images and prepares them for use. 259 | 260 | 1. Name the Application 261 | 262 | 2. Change the `location` of Scaffolded project, if required. 263 | 264 | 3. Click `Scaffold` 265 | 266 | 4. Open `Show Logs` to view the log output from `docker-compose` starting the application stack in the foreground allowing us to view all the logs for each contianer in the stack. 267 | 268 | ![](./images/name-application-template.png) 269 | 270 | ### Task 2.4: Start the Application 271 | 272 | Once the `Scaffold` has complete we have the option to `Run Application` 273 | 274 | 1. Click `Run Application` 275 | 276 | ![](./images/kube_run_launch_app_win.png) 277 | 278 | The log output displays `docker-compose` starting the application stack in the foreground allowing us to view all the logs for each contianer. 279 | 280 | ## Task 3: Develop an Application with Docker Desktop 281 | 282 | In this section we will add a custom template repository allowing us to import our own custom application templates. Our demo application is a Link Extractor application containing a PHP Frontend and an API written in Python. Next, we will make some live coding changes to the running application, customize the application by upgrading the Docker images, and finally deploy our application to Kubernetes. 283 | 284 | ### Task 3.1: Add a Custom Template Repository 285 | 286 | It is also possible to add a custom template repository to DDE. The `library.yaml` file defines the plugins and application dependencies required for the new template. 287 | 288 | The Docker Desktop Enterprise Application Designer is configured with a standard library of Application templates. We will add an additional custom library for this hands on lab. The library configuration is defined in the `preferences.yaml` file. Here we define where the Desktop Designer will fetch the `library.yaml` files from. 289 | 290 | Using your favorite text editor edit `preferences.yaml`. The library configuration can be found at: 291 | 292 | **Mac/Linux** 293 | 294 | /Users//.docker/application-template/preferences.yaml 295 | 296 | **Windows** 297 | 298 | C:\Users\\.docker\application-template\preferences.yaml 299 | 300 | 301 | Add a new repository, which is shown below the `library` repository as the `custom-services` repository with a URL pointing to the DDE Lab GitHub Repo. The file should look like this when you're done: 302 | 303 | 304 | apiVersion: v1alpha1 305 | disableFeedback: true 306 | kind: Preferences 307 | repositories: 308 | - name: library 309 | url: https://docker-application-template.s3.amazonaws.com/production/v0.1.5/library.yaml 310 | - name: custom-services 311 | url: https://raw.githubusercontent.com/JimCodified/dde-handsonlab/master/labsetup/appdesignertemplates/library.yaml 312 | 313 | ### Task 3.2: Choose new Library Template 314 | 315 | Next, the `custom-services` template will now be avaialble when we open `Application Designer` and `Choose a template` 316 | 317 | 1. Right Click on `Docker Desktop` -> `Design new application` 318 | 319 | 2. Select `Choose Template` 320 | 321 | 3. Choose the `Flask/ Apache application` 322 | 323 | ![](./images/app_designer_library.png) 324 | 325 | 326 | ### Task 3.3: Scaffold the Application Template 327 | 328 | The scaffoloding of the template copies all the necessary Dockerfiles, docker-compose, and application specific files locally to DDE. Once all the files have been copied locally, DDE then builds the images and prepares them for use. 329 | 330 | 1. Name the Application `links-app` 331 | 332 | 2. Change the `location` of Scaffolded project, if desired. 333 | 334 | 3. Click `Scaffold` 335 | 336 | 4. Open `Show Logs` to view the log output from `docker-compose` starting the application stack in the foreground allowing us to view all the logs for each contianer in the stack. 337 | 338 | ### Task 3.4: Start the Application 339 | 340 | Once the `Scaffold` has complete we have the option to `Run Application` 341 | 342 | 1. Click `Run Application` 343 | 344 | ![](./images/kube_run_launch_app_win.png) 345 | 346 | Inside the `links-app` project we can see the live log output from our application stack. We also have the possability to `Stop` or `Restart` our application stack. 347 | 348 | 2. Open the `links-app` in a browser tab [http://localhost](http://localhost) 349 | 3. Test the `links-app` by providing a full URL `https://www.docker.com` 350 | 4. Click `Extract Links` button 351 | 5. Let's test the API as well. Open a new Browser tab. Copy and paste `http://localhost:5000/` which returns the usage of the API 352 | 6. Provide a query to the API. Copy and paste `http://localhost:5000/api/https://docker.com` which displayes the same results from the the UI but in `JSON` format. 353 | 354 | ### Task 3.5: Live Code Changes 355 | 356 | Now, we will make changes to our running Links application. The `Application Designer` comes with the included feature to launch `Visual Studio Code` (VS Code) directly in the project directory or Open Windows Explorer or Finder on Mac and edit the files directly with another editor. In this example, we will use `Visual Studio Code` 357 | 358 | 1. Click the `Open in Visual Studio Code` which now opens the `links-app` in VS Code. 359 | 2. Navigate and open `www/index.php` 360 | 3. Change the HTML Color on line #61 & #62 from `#082E41` to `#007bff` and save the `index.php` 361 | 362 | ```css 363 | div.header { 364 | background: #007bff; 365 | margin: 0; 366 | } 367 | div.footer { 368 | background: #007bff; 369 | margin: 0; 370 | padding: 5px; 371 | } 372 | ``` 373 | 4. Return to your Browser Tab running [http://localhost](http://localhost) and refresh the page. You should now see the `links-app` has been rebranded with Docker colors. 374 | 375 | ### Task 3.6: Customize the Application 376 | 377 | We can also customize the Application Stack. In this task, we will upgrade the `links-app` images to the newest version. 378 | 379 | 1. Click the `Open in Visual Studio Code` which now opens the `links-app` in VS Code. 380 | 2. Open the `docker-compose.yml` file in the root of the `links-app` directory 381 | 3. Update Docker images for both `api` and `www` services which should match the below 382 | 383 | ```yaml 384 | version: "3.6" 385 | services: 386 | api: 387 | build: api 388 | image: ollypom/ee-templates-api:step4-v1 389 | ports: 390 | - 5000:5000 391 | www: 392 | environment: 393 | - API_ENDPOINT=http://api:5000/api/ 394 | image: ollypom/ee-templates-web:step4-v1 395 | ports: 396 | - 80:80 397 | volumes: 398 | - ./www/web:/var/www/html 399 | ``` 400 | 401 | 4. Save the `docker-compose.yml` file 402 | 5. Inside `Application Designer` click `Restart` which will rebuild the `links-app` using the updated images. 403 | 6. Open your browser tab [http://localhost](http://localhost) and refresh and verify the `links-app` is still running 404 | 405 | **Cleanup** 406 | Let's cleanup our enviornemnt in preperation for the next task. 407 | 408 | 1. Inside `Application Designer` click `Stop` which stop our `links-app` application using `docker-compose` 409 | 410 | ### Task 3.7: Deploy the Application on Kubernetes 411 | 412 | Our application runs inside `Application Designer` using `docker-compose`. In this section, we will re-use the same `docker-compose` file, Python & PHP files, and the same project directory to start our `links-app` using Kubernetes which we enabled earlier in [task 1.3](#task1.3). Without making any further changes we will now deploy the `links-app` with DDE Kubernetes. 413 | 414 | First, we need to prepare our enviornments. 415 | 416 | 1. Within `Application Designer` click `Open in Visual Studio Code` which will open the `links-app` project in VS Code. 417 | 2. Next, open a terminal inside VS Code. From the VS Code menu `Terminal` -> `New Terminal` 418 | 3. Set the default Orchestrator to Kubernetes 419 | 420 | **Mac** 421 | 422 | ```bash 423 | export DOCKER_STACK_ORCHESTRATOR=kubernetes 424 | ``` 425 | 426 | **Windows** 427 | 428 | ```bat 429 | set DOCKER_STACK_ORCHESTRATOR=kubernetes 430 | ``` 431 | 432 | Next, we will deploy the `links-app` to Kubernetes running inside our DDE environment. 433 | 434 | 1. Deploy the `links-app` to Kubernetes 435 | 436 | ```docker 437 | docker stack deploy -c docker-compose.yaml links-app 438 | ``` 439 | 440 | ![](./images/deploy-links-k8s.png) 441 | 442 | 2. Verify the deployment was successful and in the terminal run: `kubectl get services` 443 | 444 | ```bash 445 | kubectl get services 446 | 447 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 448 | api ClusterIP None 55555/TCP 3m31s 449 | api-published LoadBalancer 10.102.157.172 localhost 5000:32662/TCP 3m31s 450 | kubernetes ClusterIP 10.96.0.1 443/TCP 18d 451 | www ClusterIP None 55555/TCP 3m31s 452 | www-published LoadBalancer 10.102.165.196 localhost 80:32291/TCP 3m31s 453 | ``` 454 | 455 | 3. Notice that `www-published` is mapped to `localhost:80` and `api-published` is mapped to `localhost:5000` just as we saw previously in `Application Designer` 456 | 4. Open a new Browser Tab for `www-published` [http://localhost](http://localhost) 457 | 5. Open another Browser Tab for `api-published` for [http://localhost:5000/api/https://docker.com](http://localhost:5000/api/https://docker.com) 458 | 459 | 460 | ## Recap 461 | 462 | Congruatulations! In this section you have successfully added a custom repository, built and deployed the `links-app` application with `Application Designer`, performed live code changes to make the `links-app` Docker blue, and finally we deployed the same application in Kubernetes. 463 | 464 | 465 | ## Task 4: Connecting to Docker Enterprise UCP and DTR 466 | ### Task 4.1: Client Bundles 467 | ### Task 4.2: Docker Context 468 | 469 | ## Task 5: Push to DTR 470 | ### Task 5.1: Push Images to DTR 471 | ### Task 5.2: Bundle the Application 472 | ### Task 5.3: Push Docker App to DTR 473 | 474 | ## Task 6: Deploy to UCP 475 | ### Task 5.1: Deploy to Swarm 476 | ### Task 5.2: Deploy to Kubernetes 477 | 478 | ## Conclusion 479 | 480 | In this lab we've looked how Docker Enterprise can help you manage both Linux and Windows workloads whether they be traditional apps you've modernized or newer cloud-native apps, leveraging Swarm or Kubernetes for orchestration. 481 | 482 | You can find more information on Docker Enterprise at [http://www.docker.com](http://www.docker.com/enterprise-edition) as well as continue exploring using our hosted trial at [https://dockertrial.com](https://dockertrial.com) 483 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deploying Multi-OS applications with Docker Enterprise 2 | 3 | Docker Enterprise 3.0 is the first Containers-as-a-Service platform to offer production-level support for the integrated management and security of both Linux and Windows Server Containers. It is also the first platform to support both Docker Swarm and Kubernetes orchestration. 4 | 5 | In this lab we'll use a Docker Enterprise 3.0 cluster. You will have an environment that is either Linux only, or comprised of Windows and Linux nodes. We'll deploy both a Java web application on Linux and a multi-service application that includes both Windows and Linux components using Docker Swarm. Then, we'll take a look at securing and scaling the application. Finally, we will then deploy the app using Kubernetes. 6 | 7 | > **Difficulty**: **Intermediate** (assumes basic familiarity with Docker and Command Line) If you're looking for a basic introduction to Docker, check out [https://training.play-with-docker.com](https://training.play-with-docker.com) 8 | 9 | > **Workshop Time**: Approximately 75 minutes 10 | 11 | > **Introduction**: 12 | > * [What is the Docker Platform](#intro1) 13 | > * [Overview of Orchestration](#intro2) 14 | > * [Basics of Docker Swarm mode](#intro2.1) 15 | > * [Basics of Kubernetes](#intro2.2) 16 | 17 | > **Tasks**: 18 | 19 | > * [Task 1: Configure the Docker Enterprise Cluster](#task1) 20 | > * [Task 1.1: Accessing PWD](#task1.1) 21 | > * [Task 1.2: Install a Windows worker node](#task1.2) 22 | > * [Task 1.3: Create Three Repositories](#task1.3) 23 | > 24 | **Note:** If you are also running the optional [Docker Desktop Enterprise exercises](DESKTOP.md), you can complete Tasks 4 and later after you have completed Task 1 above. 25 | > * Tasks 2-4 below are optional since you will push an app to DTR and UCP from the desktop. 26 | > * **Task 5 below should still be completed.** 27 | 28 | > * [Task 2: Deploy a Java Web App](#task2) 29 | > * [Task 2.1: Clone the Demo Repo](#task2.1) 30 | > * [Task 2.2: Build and Push the Linux Web App Image](#task2.2) 31 | > * [Task 2.3: Deploy the Web App using UCP](#task2.3) 32 | > * [Task 3: Deploy the next version with a Windows node](#task3) 33 | > * [Task 3.1: Clone the repository](#task3.1) 34 | > * [Task 3.2: Build and Push Your Java Images to Docker Trusted Registry](#task3.2) 35 | > * [Task 3.3: Deploy the Java web app with Universal Control Plane](#task3.3) 36 | > * [Task 3.4: Deploy the Windows .NET App](#task3.4) 37 | > * [Task 4: Deploy to Kubernetes](#task4) 38 | > * [Task 4.1: Build .NET Core app instead of .NET](#task4.1) 39 | > * [Task 4.2: Examine the Docker Compose File](#task4.2) 40 | > * [Task 4.3: Deploy to Kubernetes using the Docker Compose file](#task4.3) 41 | > * [Task 4.4: Verify the app](#task4.4) 42 | > * [Task 5: Image Scanning](#task5) 43 | 44 | ## Understanding the Play With Docker Interface 45 | 46 | ![](./images/pwd_screen.png) 47 | 48 | This workshop is only available to people attending a scheduled Docker workshop. This could be arranged through: 49 | * [Docker Meetups](https://events.docker.com/chapters/) 50 | * Conference sessions including this workshop 51 | * Special arrangements between your company and Docker. 52 | 53 | The workshop organizer will provide you with the URL to a workshop environment that includes [Docker Enterprise Edition](https://www.docker.com/enterprise-edition). The environment will be based on [Play with Docker](https://labs.play-with-docker.com/). 54 | 55 | If none of these apply to you, contact your local [Docker Meetup Chapter](https://events.docker.com/chapters/) and inquire if there are any scheduled workshops. In the interim, you might be interested in the online labs available through the [Play with Docker Classroom](training.play-with-docker.com) portal. 56 | 57 | There are three main components to the Play With Docker (PWD) interface: 58 | 59 | ### 1. Console Access 60 | Play with Docker provides access to the 4 Docker Enterprise hosts in your Cluster. These machines are: 61 | 62 | * A Linux-based Docker Enterprise 19.XX Manager node 63 | * Three Linux-based Docker Enterprise 19.XX Worker nodes 64 | * A Windows Server 2019-based Docker Enterprise XX.XX Worker Node 65 | 66 | > In some cases, your workshop organizer will have requested a Linux only environment. In this case, feel free skip the Windows sections of the workshop. 67 | 68 | By selecting the nodes in the left panel of the user interface, the console will connect to that node. 69 | 70 | ### 2. Access to your Universal Control Plane (UCP) and Docker Trusted Registry (DTR) servers 71 | 72 | Additionally, the PWD screen provides you with a one-click access to the Universal Control Plane (UCP) 73 | web-based management interface as well as the Docker Trusted Registry (DTR) web-based management interface. Clicking on either the `UCP` or `DTR` button will bring up the respective server web interface in a new tab. 74 | 75 | ### 3. Session Information 76 | 77 | Throughout the lab you will be asked to provide either hostnames or login credentials that are unique to your environment. The user credentials for both `UCP`and `DTR` can be found at the bottom of the PWD screen in the `Session Information` table. 78 | 79 | ## Document conventions 80 | 81 | - When you encounter a phrase in between `<` and `>` you are meant to substitute in a different value. 82 | 83 | For instance if you see `` you would actually type something like `ip172-18-0-7-b70lttfic4qg008cvm90.direct.ee-workshop.play-with-docker.com` 84 | 85 | 86 | - Wherever n you see the Linux logo, all the following instructions should be completed in your Linux console 87 | 88 | ![](./images/linux75.png) 89 | 90 | - Wherever you see the Windows logo, all the subsequent instructions should be completed in your Windows console. These sections can be skipped if you are working with a Linux environment only. 91 | 92 | ![](./images/windows75.png) 93 | 94 | ## Introduction 95 | Docker Enterprise provides an integrated, tested and certified platform for apps running on enterprise Linux or Windows operating systems and cloud providers. Docker Enterprise is tightly integrated to the the underlying infrastructure to provide a native, easy to install experience and an optimized Docker environment. Docker Certified Infrastructure, Containers and Plugins are exclusively available for Docker Enterprise with cooperative support from Docker and the Certified Technology Partners. 96 | 97 | #### Overview of Orchestration 98 | While it is easy to run an application in isolation on a single machine, orchestration allows you to coordinate multiple machines to manage an application, with features like replication, encryption, load-balancing, service discovery and more. If you've read anything about Docker, you have probably heard of Kubernetes and Docker Swarm mode. Docker Enterprise allows you to use either Docker Swarm mode or Kubernetes for orchestration. 99 | 100 | Both Docker Swarm mode and Kubernetes are declarative: you declare your cluster's desired state, and applications you want to run and where, networks, and resources they can use. Docker Enterprise simplifies this by taking common concepts and moving them to the a shared resource. 101 | 102 | #### Overview of Docker Swarm mode 103 | A Swarm is a group of machines that are running Docker and joined into a cluster. After that has happened, you continue to run the Docker commands you’re used to, but now they are executed on a cluster by a Swarm manager. The machines in a Swarm can be physical or virtual. After joining a Swarm, they are referred to as nodes. 104 | 105 | Swarm mode uses managers and workers to run your applications. Managers run the Swarm cluster, making sure nodes can communicate with each other, allocate applications to different nodes, and handle a variety of other tasks in the cluster. Workers are there to provide extra capacity to your applications. In this workshop, you have one manager and three workers. 106 | 107 | #### Overview of Kubernetes 108 | 109 | Kubernetes is available in Docker Enterprise 3.0 and included in this workshop. Kubernetes deployments tend to be more complex than Docker Swarm, and there are many component types. UCP simplifies a lot of that, relying on Docker Swarm to handle shared resources. We'll concentrate on Pods and Load Balancers in this workshop, but there's plenty more supported by UCP 3.XX. 110 | 111 | ## Task 1: Configure the Docker Enterprise Cluster 112 | 113 | The Play with Docker (PWD) environment is almost completely set up, but before we can begin the labs, we need to do two more steps. First we'll add a Windows node to the cluster. We've left the node unjoined so you can see how easy it is to do. Then we'll create two repositories in Docker Trusted Registry. 114 | (The Linux worker nodes are already added to the cluster) 115 | 116 | ### Task 1.1: Accessing PWD 117 | 118 | 1. Navigate to the provided URL using your favorite browser. 119 | 120 | 2. Fill out the form, and click `submit`. You will then be redirected to the PWD environment. 121 | 122 | It may take a few minutes to provision out your PWD environment. After this step completes, you'll be ready to move on to task 1.2: Install a Windows worker node 123 | 124 | ### Task 1.2: Join a Windows worker node 125 | 126 | Next we are going to add a Windows Server 2016 to the cluster using Docker Swarm. 127 | 128 | 1. From the main PWD screen click the `UCP` button on the left side of the screen 129 | 130 | > **Note**: This Docker Enterprise install uses the default self-signed certs. Because of this, your browser may display a security warning similar to the message below. This message might appear different depending on your web browser. It is safe to 'acknowledge' and proceed. 131 | > 132 | > In a production environment you would use certs from a trusted certificate authority and would not see this screen. 133 | > 134 | > ![](./images/ssl_error.png) 135 | 136 | 2. When prompted enter your username and password, use the credentials that are located below the console window on the main PWD screen. The UCP web interface will open in your web browser. 137 | 138 | > **Note**: Once the main UCP screen loads you'll notice there is a red warning bar displayed at the top of the UCP screen, this is an artifact of running in a lab environment. A UCP server configured for a production environment would not display this warning 139 | > 140 | > ![](./images/red_warning.png) 141 | 142 | 143 | 3. From the main dashboard screen, click `Add a Node` on the bottom left of the screen 144 | 145 | ![](./images/add_a_node.png) 146 | 147 | 4. Select node type "Windows". 148 | 149 | ![](./images/add_win_node_1.png) 150 | 151 | Under the Step 2 section check the box `I have followed the instructions and I'm ready to join my windows node.` Next, copy the text from the `docker swarm join` command from the dark box shown on the `Add Node` screen. Don't select a custom listen or advertise address. 152 | 153 | ![](./images/add_win_node_2.png) 154 | 155 | > **Note** There is an icon in the upper right corner of the dark box that you can click to copy the text to your clipboard. 156 | 157 | > ![](./images/join_text.png) 158 | 159 | 160 | > **Note**: You may notice that there is a UI component to select `Linux` or `Windows`on the `Add Node` screen. In a production environment where you are starting from scratch, there are [a few prerequisite steps](https://docs.docker.com/install/windows/docker-ee/) that need to be completed prior to adding Windows node. However, we've already done these steps in the PWD environment. For this lab, just leave the selection on `Linux` and move on to step 2 161 | 162 | ![](./images/windows75.png) 163 | 164 | 5. Return to the PWD interface and click the name of your Windows node. This will connect the web-based console to your Windows Server 2016 Docker Enterprise host. 165 | 166 | ![](./images/add_win_node_3.png) 167 | 168 | 6. Paste the text from Step 4 at the command prompt in the Windows console. (depending on your browser, this can be tricky: try the "paste" command from the edit menu instead of right clicking or using keyboard shortcuts) 169 | 170 | ![](./images/add_win_node_4.png) 171 | 172 | You should see the message `This node joined a Swarm as a worker.` indicating you've successfully joined the node to the cluster. 173 | 174 | **Note** If the command failed, verify that the command was correctly entered into the Windows console. 175 | 176 | 7. Switch back to the UCP server in your web browser and click the `x` in the upper right corner to close the `Add Node` window 177 | 178 | 8. You will be taken back to the UCP Dashboard. In the left menu bar, click Shared Resources and then select Nodes. 179 | 180 | ![](/images/select_nodes.png) 181 | 182 | The `Nodes` screen will opeb and you can see 4 `worker` nodes and 1 `manager` listed on your screen. 183 | 184 | > Initially the new worker node will be shown with status `down`. After a minute or two, refresh your web browser to ensure that your Windows worker node has come up as `Healthy UCP worker` 185 | 186 | ![](./images/node_listing.png) 187 | 188 | Congratulations on adding a Windows node to your UCP cluster. Your are now ready to use the worker in either a Swarm or Kubernetes. Next, we'll create a few repositories in Docker Trusted registry. 189 | 190 | ### Task 1.3: Create Three DTR Repositories 191 | 192 | Docker Trusted Registry (DTR) is a special service designed to store and manage your Docker images. In this lab we're going to create three different Docker images, and push them to DTR. Before we can do that, we need to setup repositories in which those images will reside. 193 | 194 | However, before we create the repositories, we do want to restrict access to them. Since we have two distinct app components, a Java web app (with a database), and a .NET API, we want to restrict access to them to the team that develops them, as well as the administrators. To do that, we need to create two users and then two organizations. 195 | 196 | 1. In the PWD web interface, click the `DTR` button on the left side of the screen. 197 | 198 | > **Note**: As with UCP before, DTR is also using self-signed certs. It's safe to click through any browser warning you might encounter. 199 | 200 | 2. From the main DTR page, click users and then the New User button. 201 | 202 | ![](./images/user_screen.png) 203 | 204 | 3. Create a new user, `java_user` and give it a password you'll remember. I used `user1234`. Be sure to save the user. 205 | 206 | ![](/images/create_java_user.png) 207 | 208 | Then do the same for a `dotnet_user`. You should see a similar users as below. 209 | 210 | ![](./images/dtr_users_created.png) 211 | 212 | 4. In the left Menu, select Organizations 213 | 214 | ![](./images/organization_screen.png) 215 | 216 | 5. Press the `New organization` button, name it `java`, and click save. 217 | 218 | ![](./images/java_organization_new.png) 219 | 220 | Then do the same with dotnet and you'll have two organizations. 221 | 222 | ![](./images/two_organizations.png) 223 | 224 | 6. Now you get to add a repository! Click on the java organization, select Repositories and then `New repository` 225 | 226 | ![](./images/add_repository_java.png) 227 | 228 | 7. Name the repository `java_web`. Provide a Description and click `Save`. 229 | 230 | > Note the repository is listed as "Public" but that means it is publicly viewable by users of DTR. It is not available to the general public. 231 | 232 | ![](./images/create_repository.png) 233 | 234 | 8. Now it's time to create a team so you can restrict access to who administers the images. Select the Members Menu Tab and Press `Add user` button. Start typing in java in the Search by Username box.. Select the `java_user` when it comes up. Select `Save`. 235 | 236 | ![](./images/add_java_user_to_organization.png) 237 | 238 | 9. Next select the `java` organization and press the Teams Green `+` button to create a `web` team. 239 | 240 | ![](./images/team.png) 241 | 242 | 10. Select the `web` Team and click the `Add user` button. Add the `java_user` user to the `web` team and click save. 243 | 244 | ![](./images/team_add_user.png) 245 | 246 | ![](./images/team_with_user.png) 247 | 248 | 11. Next select the `web` team and select the `Repositories` tab and click `New repository`. Select `Add Existing repository` and click in the `Repository Name` field and choose the `java_web` repository. You'll see the `java` account is already selected. Then select `Read/Write` permissions so the `web` team has permissions to push images to this repository. Finally click `Save`. 249 | 250 | ![](./images/add_java_web_to_team.png) 251 | 252 | 12. Now add a `New` repository also owned by the web team and call it `database`. This can be done directly from the web team's `Repositories` tab by clicking the `New repository` button, select Add `New` repository and name the repository `database`. Be sure to grant `Read/Write` permissions for this repository which will be part of the `web` team as well. 253 | 254 | ![](./images/add_repository_database.png) 255 | 256 | 13. Repeat 4-11 above to create the same structure in the `dotnet` organization. First, create the `api` Team, add the `dotnet_user` as member to to the `api` Team and create the repository `dotnet_api`. Grant `read/write` permissions for the `dotnet_api` repository to the `api` team. 257 | 258 | 14. From the main DTR page, click Repositories, you will now see all three repositories listed. 259 | 260 | ![](./images/three_repositories.png) 261 | 262 | 15. (optional) If you want to check out security scanning in Task 5, you should turn on scanning now so DTR downloads the database of security vulnerabilities. In the left-hand panel, select `System` and then the `Security` tab. Select `ENABLE SCANNING` method for installation and updates is `Online` and click `Enable Online Syncing` 263 | 264 | ![](./images/scanning-activate.png) 265 | 266 | Congratulations, you have created three new repositories in two new organizations, each with one team and a user each. 267 | 268 | ## Task 2: Deploy a Java Web App with Universal Control Plane 269 | 270 | Now that we've completely configured our cluster, let's deploy a web app. The Signup application is a basic Java CRUD (Create, Read, Update, Delete) application that uses Spring and Hibernate to transact queries against MySQL. It runs in Tomcat. 271 | 272 | ### Task 2.1: Clone the Demo Repo 273 | 274 | ![](./images/linux75.png) 275 | 276 | 1. From PWD click on the `worker1` link on the left to connect your web console to the UCP Linux worker node. Click the terminal window and hit the enter or space key to activate the terminal window. 277 | 278 | 2. Before we do anything, let's configure an environment variable for the DTR URL/DTR hostname. You may remember that the session information from the Play with Docker landing page (Below the terminal window). Select and copy the URL for the DTR hostname. 279 | 280 | ![](./images/session-information.png) 281 | 282 | 3. Set an environment variable `DTR_HOST` using the DTR host name defined on your Play with Docker landing page: 283 | 284 | ```bash 285 | export DTR_HOST= 286 | echo $DTR_HOST 287 | ``` 288 | 289 | 4. Now use git to clone the workshop repository. 290 | 291 | ```bash 292 | git clone https://github.com/dockersamples/hybrid-app.git 293 | ``` 294 | 295 | You should see something like this as the output: 296 | 297 | ```bash 298 | Cloning into 'hybrid-app'... 299 | remote: Counting objects: 389, done. 300 | remote: Compressing objects: 100% (17/17), done. 301 | remote: Total 389 (delta 4), reused 16 (delta 1), pack-reused 363 302 | Receiving objects: 100% (389/389), 13.74 MiB | 3.16 MiB/s, done. 303 | Resolving deltas: 100% (124/124), done. 304 | Checking connectivity... done. 305 | ``` 306 | 307 | You now have the necessary demo code on your worker host. 308 | 309 | ### Task 2.2: Build and Push the Linux Web App Images 310 | 311 | ![](./images/linux75.png) 312 | 313 | 1. Change into the `java-app` directory. 314 | 315 | ```bash 316 | cd ./hybrid-app/java-app/ 317 | ``` 318 | 319 | 2. Use `docker build` to build your Docker image. 320 | 321 | ```bash 322 | docker build -t $DTR_HOST/java/java_web . 323 | ``` 324 | > Note the final "." in the above command. The "." is the build context, specifically the current directory. One of the most common mistakes even experienced users make is leaving off the build context. 325 | 326 | The `-t` tags the image with a tag or name. In our case, the name indicates which DTR server and under which organization's repository the image will reside. 327 | 328 | > **Note**: Feel free to examine the Dockerfile in this directory if you'd like to see how the image is being built. 329 | 330 | There will be quite a bit of output. The Dockerfile describes a two-stage build. In the first stage, a Maven base image is used to build the Java app. But to run the app you don't need Maven or any of the JDK stuff that comes with it. So the second stage takes the output of the first stage and puts it in a much smaller Tomcat image. 331 | 332 | 3. Log into your DTR server from the command line. 333 | 334 | First use the `dotnet_user` and password `user1234` which isn't part of the java organization 335 | 336 | ```bash 337 | docker login $DTR_HOST 338 | 339 | Username: 340 | Password: 341 | Login Succeeded 342 | ``` 343 | 344 | Use `docker push` to upload your image up to Docker Trusted Registry. 345 | 346 | ```bash 347 | docker push $DTR_HOST/java/java_web 348 | ``` 349 | 350 | ```bash 351 | docker push $DTR_HOST/java/java_web 352 | 353 | The push refers to a repository [./java/java_web] 354 | 8cb6044fd4d7: Preparing 355 | 07344436fe27: Preparing 356 | ... 357 | e1df5dc88d2c: Waiting 358 | denied: requested access to the resource is denied 359 | ``` 360 | 361 | As you can see, the access control that you established in the [Task 1.3](#task1.3) prevented you from pushing to this repository. 362 | 363 | 4. Now try logging in using `java_user`and password `user1234` then use `docker push` to upload your image up to Docker Trusted Registry. 364 | 365 | ```bash 366 | docker push $DTR_HOST/java/java_web 367 | ``` 368 | 369 | The output should be similar to the following: 370 | 371 | ```bash 372 | The push refers to a repository [/java/java_web] 373 | feecabd76a78: Pushed 374 | 3c749ee6d1f5: Pushed 375 | af5bd3938f60: Pushed 376 | 29f11c413898: Pushed 377 | eb78099fbf7f: Pushed 378 | latest: digest: sha256:9a376fd268d24007dd35bedc709b688f373f4e07af8b44dba5f1f009a7d70067 size: 1363 379 | ``` 380 | 381 | Success! Because you are using a user name that belongs to the right team in the right organization, you can push your image to DTR. 382 | 383 | 5. In your web browser head back to DTR and click `View Details` next to your `java_web` repository to see the details of the repository. 384 | 385 | > **Note**: If you've closed the tab with your DTR server, just click the `DTR` button from the PWD page. 386 | 387 | 6. Click on `Tags` from the horizontal menu. Notice that your newly pushed image is now on your DTR. 388 | 389 | ![](./images/pushed_image.png) 390 | 391 | 7. Next, build the MySQL database image. Change into the database directory. 392 | 393 | ```bash 394 | cd ../database 395 | ``` 396 | 397 | 8. Use `docker build` to build your Docker image. 398 | 399 | ```bash 400 | docker build -t $DTR_HOST/java/database . 401 | ``` 402 | > Note the final "." in the above command. The "." is the build context, specifically the current directory. One of the most common mistakes even experienced users make is leaving off the build context. 403 | 404 | 9. Use `docker push` to upload your image up to Docker Trusted Registry. 405 | ```bash 406 | docker push $DTR_HOST/java/database 407 | ``` 408 | 409 | 10. In your web browser head back to your DTR server, select your `java/database` repository and click `Tags` from the horizontal menu. Notice that your newly pushed image is now in your DTR. 410 | 411 | 412 | ### Task 2.3: Deploy the Web App using UCP 413 | ![](./images/linux75.png) 414 | 415 | The next step is to run the app in Swarm. **Remember**, the application has two components, the web front-end and the database. In order to connect to the database, the application needs a password. If you were just running this in development you could easily pass the password around as a text file or an environment variable. But keys and passwords should **never** be be shared in a production environment. Instead, we're going to create an encrypted secret which will allow us to strictly control access. 416 | 417 | 1. Go back to the first Play with Docker tab. Click on the UCP button. You'll receive the same `https` warning that you have before. Acknowledge the warnings and log in. You'll see the Universal Control Panel dashboard. 418 | 419 | ![](./images/pwd_screen.png) 420 | 421 | 2. There's a lot of information on this page about managing the cluster. You can take a moment to explore around and get familiar with the layout. 422 | 423 | Next, click on `Swarm` and select `Secrets`. 424 | 425 | ![](./images/ucp_secret_menu_1.png) 426 | 427 | 3. Click the `Create` button to access the `Create Secret` screen. Type `mysql_password` in `Name` and `Dockercon!!!` in `Content`, then click `Create` in the lower right corner. For production environments, more complex passwords should be used. You'll notice the content box allows you to create structured content that will be encrypted with the secret. 428 | 429 | ![](./images/secret_add_config.png) 430 | 431 | 4. Next we're going to create two networks. First click on `Networks` under the `Swarm` section on the left panel, and select `Create` in the upper right corner of the page. You'll be presented with a `Create Network` form. Name this network `back-tier`. Leave everything else the default and click `Create` in the lower right. 432 | 433 | ![](./images/ucp_network_1.png) 434 | ![](./images/ucp_network_2.png) 435 | 436 | 5. Repeat step 4 but with a new network called `front-tier`. 437 | 438 | 6. Now we're going to use the fast way to create your application using `Stacks`. In the left panel, click `Shared Resources`-> `Stacks` and then `Create Stack` in the upper right corner. 439 | 440 | ![](./images/ucp_shared_stacks.png) 441 | 442 | 7. Name your stack `java_web` and select `Swarm Services` for your `Orchestrator Mode`. Leave `Application File Mode` as default, then click `Next`. 443 | 444 | ![](./images/ucp_add_app_file.png) 445 | 446 | Below is a sample `.yml` file that you can use to populate your file. 447 | 448 | > **Note** : Before pasting the content into your `compose.yml` edit box, you'll need to modify a couple of items. Each of the images is defined as `/java/`, which you'll need to change to the `` found on the Play with the Docker landing page for your session. 449 | 450 | > It will look something like this: 451 | `ip172-18-0-21-baeqqie02b4g00c9skk0.direct.ee-beta2.play-with-docker.com` 452 | 453 | > This can be done right from the `Add Application File` edit box on the `UCP Create Application` form. 454 | 455 | ```yaml 456 | version: "3.3" 457 | 458 | services: 459 | 460 | database: 461 | image: /java/database 462 | # set default mysql root password, change as needed 463 | environment: 464 | MYSQL_ROOT_PASSWORD: mysql_password 465 | # Expose port 3306 to host. 466 | ports: 467 | - "3306:3306" 468 | networks: 469 | - back-tier 470 | 471 | webserver: 472 | image: /java/java_web 473 | ports: 474 | - "8080:8080" 475 | networks: 476 | - front-tier 477 | - back-tier 478 | 479 | networks: 480 | back-tier: 481 | external: true 482 | front-tier: 483 | external: true 484 | 485 | secrets: 486 | mysql_password: 487 | external: true 488 | ``` 489 | 490 | Then click `Create` in the lower right corner of the window. 491 | 492 | ![](./images/ucp_java_deploy.png) 493 | 494 | Once deployed, click `Done`. 495 | 496 | > You might see a websocket error, but the stack is still being created. You can safely ignore this error. 497 | 498 | 8. Congratulations! You've deployed your first app! Now it's time to go and test the functionality. Open a new tab or browser window and enter the `UCP Hostname` and append `:8080/java-web` to the end of the URL. 499 | 500 | `E.g. http://ip172-18-0-21-baeqqie02b4g00c9skk0.direct.ee-beta2.play-with-docker.com:8080/java-web` 501 | 502 | ![](./images/java-web1.png) 503 | 504 | 9. Delete your `java_web` application stack. 505 | 506 | ## Task 3: Deploy the next version with a Windows node 507 | 508 | Now that the app has been moved and updated, we'll be adding an user sign-in API. To illustrate Docker Enterprise's cross-platform capabilities, we'll be performing this deployment using a Windows container. 509 | 510 | > If your workshop organizer requested a Windows only environment, you can skip ahead to Task 4. 511 | 512 | ### Task 3.1: Clone the repository 513 | 514 | ![](./images/windows75.png) 515 | 516 | 1. Because this is a Windows container, it has to be deployed on a Microsoft Windows host. Switch back to the main Play with Docker page and select the name of the Windows worker. 517 | 518 | First verify that Docker is `running` - it runs as a background Windows Service. This can be done by the following command: 519 | 520 | ```powershell 521 | Get-Service docker 522 | ``` 523 | ![](./images/docker_service_stopped.png) 524 | 525 | If the service is not running, it can be started with the following command: 526 | 527 | ```powershell 528 | Start-Service docker 529 | ``` 530 | ![](./images/docker_service_start.png) 531 | 532 | Next, clone the repository again onto this host: 533 | 534 | ```powershell 535 | PS C:\> git clone https://github.com/dockersamples/hybrid-app.git 536 | ``` 537 | 538 | 2. Set an environment variable for the DTR host name. Similar to what you did for the Java app, this will simplify a few steps. Copy the DTR host name again and create the environment variable. For instance, if your DTR host FQDN is `"ip172-18-0-17-bajlvkom5emg00eaner0.direct.ee-beta2.play-with-docker.com"` you would type: 539 | 540 | ![](./images/dtr_fqdn.png) 541 | 542 | ```powershell 543 | PS C:\> $env:DTR_HOST="ip172-18-0-17-bajlvkom5emg00eaner0.direct.ee-beta2.play-with-docker.com" 544 | ``` 545 | 546 | 547 | > **Note** ensure the DTR hostname includes quotes otherwise the command will fail `""` 548 | 549 | 550 | 551 | ### Task 3.2: Build and Push Windows Images to Docker Trusted Registry 552 | ![](./images/windows75.png) 553 | 554 | 1. Change your path to `c:\hybrid-app\netfx-api`. 555 | 556 | ```powershell 557 | PS C:\> cd c:\hybrid-app\netfx-api\ 558 | ``` 559 | 560 | 2. Use `docker build` to build your Windows image. 561 | 562 | ```powershell 563 | PS C:\hybrid-app\netfx-api> docker build -t $env:DTR_HOST/dotnet/dotnet_api . 564 | ``` 565 | 566 | > **Note** the final "." in the above command. The `"."` is the build context, specific to the current directory. One of the most common mistakes even experienced users make is leaving off the build context. 567 | 568 | > **Note**: Feel free to examine the Dockerfile in this directory if you'd like to see how the image is being built. 569 | 570 | Your output should be similar to what is shown below 571 | 572 | ```powershell 573 | PS C:\hybrid-app\netfx-api> docker build -t $env:DTR_HOST/dotnet/dotnet_api . 574 | 575 | Sending build context to Docker daemon 415.7kB 576 | Step 1/8 : FROM microsoft/iis:windowsservercore-10.0.14393.1715 577 | ---> 590c0c2590e4 578 | 579 | 580 | 581 | Removing intermediate container ab4dfee81c7e 582 | Successfully built d74eead7f408 583 | Successfully tagged /dotnet/dotnet_api:latest 584 | ``` 585 | 586 | > **Note**: It will take a few minutes for your image to build. 587 | 588 | 4. Log into the Docker Trusted Registry 589 | 590 | ```powershell 591 | PS C:\hybrid-app\netfx-api> docker login $env:DTR_HOST 592 | Username: dotnet_user 593 | Password: user1234 594 | Login Succeeded 595 | ``` 596 | 597 | 5. Push your new image up to Docker Trusted Registry(DTR). 598 | 599 | ```powershell 600 | PS C:\hybrid-app\netfx-api> docker push $env:DTR_HOST/dotnet/dotnet_api 601 | The push refers to a repository [/dotnet/dotnet_api] 602 | 5d08bc106d91: Pushed 603 | 74b0331584ac: Pushed 604 | e95704c2f7ac: Pushed 605 | 669bd07a2ae7: Pushed 606 | d9e5b60d8a47: Pushed 607 | 8981bfcdaa9c: Pushed 608 | 25bdce4d7407: Pushed 609 | df83d4285da0: Pushed 610 | 853ea7cd76fb: Pushed 611 | 55cc5c7b4783: Skipped foreign layer 612 | f358be10862c: Skipped foreign layer 613 | latest: digest: sha256:e28b556b138e3d407d75122611710d5f53f3df2d2ad4a134dcf7782eb381fa3f size: 2825 614 | ``` 615 | 616 | 6. Verify your newly pushed image within the DTR web interface. 617 | 618 | ### Task 3.3: Deploy the Java web app 619 | ![](./images/linux75.png) 620 | 621 | 1. Firstly, we need to update our Java web app to take advantage of the .NET API. Switch back to `worker1` and change directories to the `java-app-v2` directory. Repeat steps 1,2, and 4 from [Task 2.2](#task2.2) but add a tag `:2` to your build and pushes: 622 | 623 | ```bash 624 | $ docker login 625 | username: java_user 626 | password: user1234 627 | 628 | $ docker build -t $DTR_HOST/java/java_web:2 . 629 | $ docker push $DTR_HOST/java/java_web:2 630 | ``` 631 | > **Note** the final "." in the above `docker build` command. The "." is the build context, specifically the current directory. One of the most common mistakes even experienced users make is leaving off the build context. 632 | 633 | This will push a different version of the app, version 2, to the same `java_web` repository. 634 | 635 | 2. Next repeat the steps 6-8 from [Task 2.3](#task2.3), but use this `Compose` file instead: 636 | 637 | > **Note** : Before pasting the content into your `compose.yml` edit box, you'll need to modify a couple of items. Each of the images is defined as `/java/`, which you'll need to change to the `` found on the Play with the Docker landing page for your session. 638 | 639 | > It will look something like this: 640 | `ip172-18-0-21-baeqqie02b4g00c9skk0.direct.ee-beta2.play-with-docker.com` 641 | 642 | > This can be done right from the `Add Application File` edit box on the `UCP Create Application` form. 643 | 644 | ```yaml 645 | version: "3.3" 646 | 647 | services: 648 | 649 | database: 650 | image: /java/database 651 | # set default mysql root password, change as needed 652 | environment: 653 | MYSQL_ROOT_PASSWORD: mysql_password 654 | # Expose port 3306 to host. 655 | ports: 656 | - "3306:3306" 657 | networks: 658 | - back-tier 659 | 660 | webserver: 661 | image: /java/java_web:2 662 | ports: 663 | - "8080:8080" 664 | networks: 665 | - front-tier 666 | - back-tier 667 | environment: 668 | BASEURI: http://dotnet-api/api/users 669 | 670 | dotnet-api: 671 | image: /dotnet/dotnet_api 672 | ports: 673 | - "57989:80" 674 | networks: 675 | - front-tier 676 | - back-tier 677 | 678 | networks: 679 | back-tier: 680 | external: true 681 | front-tier: 682 | external: true 683 | 684 | secrets: 685 | mysql_password: 686 | external: true 687 | ``` 688 | **Congratulations, you deployed a multi-acrhictecture application on Docker Swarm** 689 | 690 | 3. Navigate to `Shared Resources -> Stacks -> java_web` then click the `services` tab. 691 | 692 | ![](./images/multi-arch-deploy.png) 693 | 694 | 4. After a couple mintues you should see all the services green and deplyoed. 695 | 696 | 5. Once tested, delete the stack. 697 | 698 | ## Task 4: Deploy to Kubernetes 699 | 700 | Now that we have built, deployed and scaled a multi OS application to Docker Enterprise using Swarm mode for orchestration, let's look at how to use Docker Enterprise with Kubernetes. 701 | 702 | Docker Enterprise lets you choose the orchestrator used to deploy and manage your application between Swarm and Kubernetes. In the previous tasks we've used Swarm for our orchestration. In this section we will deploy the application to Kubernetes and see how Docker Enterprise exposes Kubernetes concepts. 703 | 704 | Before moving forward we need to make sure that our cluster worker nodes can schedule Kubernetes workloads. Navigate to the nodes section: 705 | 706 | * `UCP > Shared Resources > Nodes` 707 | 708 | ![](./images/ucp_nodes.png) 709 | 710 | You'll notice that the scheduler type of `worker2` and `worker3` is set to Swarm. 711 | 712 | ![](./images/node_types.png) 713 | 714 | Click on the `worker2` node and change it's orchestration type to `mixed` using the gear icon on the top right corner and click `Save`. 715 | 716 | Repeat the same step for `worker3`. 717 | 718 | ![](./images/ucp_node_setting.png) 719 | 720 | ![](./images/node_mixed.png) 721 | 722 | 723 | Now your cluster is configured to run both Kuberentes and Swarm workloads 724 | 725 | 726 | ### Task 4.1: Build .NET Core app instead of .NET 727 | ![](./images/linux75.png) 728 | 729 | For now Kubernetes does not support Windows workloads in production, so we will start by porting the .NET part of our application to a Linux container using .NET Core. 730 | 731 | 1. From the Play with Docker landing page, click on `worker1` and CD into the `hybrid-app/dotnet-api` directory. 732 | 733 | ```bash 734 | cd ~/hybrid-app/dotnet-api/ 735 | ``` 736 | 737 | 2. Use `docker build` to build your Linux image. 738 | 739 | ```bash 740 | docker build -t $DTR_HOST/dotnet/dotnet_api:core . 741 | ``` 742 | > Note the final "." in the above command. The "." is the build context, specifically the current directory. One of the most common mistakes even experienced users make is leaving off the build context. 743 | 744 | > **Note**: Feel free to examine the Dockerfile in this directory if you'd like to see how the image is being built. Also, we used the `:core` tag so that the repository has two versions, the original with a Windows base image, and this one with a Linux .NET Core base image. 745 | 746 | Your output should be similar to what is shown below 747 | 748 | ```bash 749 | Sending build context to Docker daemon 29.7kB 750 | Step 1/10 : FROM microsoft/aspnetcore-build:2.0.3-2.1.2 AS builder 751 | 2.0.3-2.1.2: Pulling from microsoft/aspnetcore-build 752 | 723254a2c089: Pull complete 753 | 754 | 755 | 756 | Removing intermediate container 508751aacb5c 757 | Step 7/10 : FROM microsoft/aspnetcore:2.0.3-stretch 758 | 2.0.3-stretch: Pulling from microsoft/aspnetcore 759 | 760 | Successfully built fcbc49ef89bf 761 | Successfully tagged ip172-18-0-8-baju0rgm5emg0096odmg.direct.ee-beta2.play-with-docker.com/dotnet/dotnet_api:latest 762 | ``` 763 | 764 | > **Note**: It will take a few minutes for your image to build. 765 | 766 | 4. Log into Docker Trusted Registry 767 | 768 | ```bash 769 | $ docker login $DTR_HOST 770 | Username: dotnet_user 771 | Password: user1234 772 | Login Succeeded 773 | ``` 774 | 775 | 5. Push your new image up to Docker Trusted Registry. 776 | 777 | ```bash 778 | $ docker push $DTR_HOST/dotnet/dotnet_api:core 779 | The push refers to a repository [/dotnet/dotnet_api] 780 | 5d08bc106d91: Pushed 781 | 74b0331584ac: Pushed 782 | e95704c2f7ac: Pushed 783 | 669bd07a2ae7: Pushed 784 | d9e5b60d8a47: Pushed 785 | 8981bfcdaa9c: Pushed 786 | 25bdce4d7407: Pushed 787 | df83d4285da0: Pushed 788 | 853ea7cd76fb: Pushed 789 | 55cc5c7b4783: Skipped foreign layer 790 | f358be10862c: Skipped foreign layer 791 | latest: digest: sha256:e28b556b138e3d407d75122611710d5f53f3df2d2ad4a134dcf7782eb381fa3f size: 2825 792 | ``` 793 | 794 | 6. You may check your repositories in the DTR web interface to see the newly pushed image. 795 | 796 | ### Task 4.2: Examine the Docker Compose File 797 | ![](./images/linux75.png) 798 | 799 | Docker Enterprise lets you deploy Kubernetes applications natively using the Kubernetes deployment descriptors. This can be done by providing the yaml files in the UI, or using the `kubectl` CLI tool. 800 | 801 | However, many developers choose `docker-compose` to build and test their applications. Having to create Kubernetes deployment descriptors as well as maintaining them in sync with the Docker Compose file, is a tedious and error prone process. 802 | 803 | In order to simply developent and operations tasks, Docker Enterprise lets you deploy an application defined with a Docker Compose file as a Kubernetes workload. Internally Docker Enterprise uses the official Kubernetes extension mechanism by defining a [Custom Resource Definition](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/) (CRD) defining a stack object. When you post a Docker Compose stack definition to Kubernetes in Docker Enterprise, the CRD controller takes the stack definition and translates it to Kubernetes native resources like pods, controllers and services. 804 | 805 | We'll use a Docker Compose file to instantiate our application. This is the same file you used in a prior task, with a few changes. 806 | * We will switch the .NET Docker Windows image with the .NET Core Docker Linux image we just built. 807 | * Create a new secret `mysql-secret` with `DockerCon!!!` as the password. 808 | 809 | Follow the instructions above but use `-` instead of `_` as Kubernetes doesn't allow underscores. 810 | 811 | Let's look at the Docker Compose file in `app/docker-stack.yml`. 812 | 813 | 814 | ```yaml 815 | version: '3.3' 816 | 817 | services: 818 | database: 819 | deploy: 820 | placement: 821 | constraints: 822 | - node.platform.os == linux 823 | image: /java/database 824 | environment: 825 | MYSQL_ROOT_PASSWORD: mysql-password 826 | networks: 827 | back-tier: 828 | ports: 829 | - published: 32768 830 | target: 32768 831 | 832 | dotnet-api: 833 | deploy: 834 | placement: 835 | constraints: 836 | - node.platform.os == linux 837 | image: /dotnet/dotnet_api:core 838 | networks: 839 | back-tier: 840 | ports: 841 | - published: 32769 842 | target: 80 843 | 844 | java-web: 845 | deploy: 846 | placement: 847 | constraints: 848 | - node.platform.os == linux 849 | image: /java/java_web:2 850 | environment: 851 | BASEURI: http://dotnet-api/api/users 852 | networks: 853 | back-tier: 854 | front-tier: 855 | ports: 856 | - published: 32770 857 | target: 8080 858 | 859 | networks: 860 | back-tier: 861 | external: true 862 | front-tier: 863 | external: true 864 | 865 | secrets: 866 | mysql-password: 867 | external: true 868 | ``` 869 | 870 | 871 | ### Task 4.3: Deploy to Kubernetes using the Docker Compose file 872 | 873 | ![](./images/linux75.png) 874 | 875 | 1. Create a new secret `UCP -> Swarm -> Secrets` Create a secret`mysql-secret` with `DockerCon!!!` as the password 876 | 877 | ![](./images/mysql-secret.png) 878 | 879 | 2. Login to UCP, and select `Shared resources > Stacks`. 880 | 881 | ![](./images/kube-stacks.png) 882 | 883 | 3. Click **`Create Stack`**. Fill name: **`hybrid-app`**, mode: **`Kubernetes Workloads`**, namespace: **`Default`**. 884 | 885 | ![](./images/k8s_stack.png) 886 | 887 | 4. Copy the below `app/docker-stack.yml` into the `Add Application File` window and click `Create` 888 | > **NOTE: **Change the images for the dotnet-api and java-app services for the ones we just built. And remember to change `` to the long DTR hostname listed on the landing page for your Play with Docker instance. 889 | 890 | ```yaml 891 | version: '3.3' 892 | 893 | services: 894 | database: 895 | deploy: 896 | placement: 897 | constraints: 898 | - node.platform.os == linux 899 | image: /java/database 900 | environment: 901 | MYSQL_ROOT_PASSWORD: mysql-password 902 | networks: 903 | back-tier: 904 | ports: 905 | - published: 32768 906 | target: 32768 907 | 908 | dotnet-api: 909 | deploy: 910 | placement: 911 | constraints: 912 | - node.platform.os == linux 913 | image: /dotnet/dotnet_api:core 914 | networks: 915 | back-tier: 916 | ports: 917 | - published: 32769 918 | target: 80 919 | 920 | java-web: 921 | deploy: 922 | placement: 923 | constraints: 924 | - node.platform.os == linux 925 | image: /java/java_web:2 926 | environment: 927 | BASEURI: http://dotnet-api/api/users 928 | networks: 929 | back-tier: 930 | front-tier: 931 | ports: 932 | - published: 32770 933 | target: 8080 934 | 935 | networks: 936 | back-tier: 937 | external: true 938 | front-tier: 939 | external: true 940 | 941 | secrets: 942 | mysql-password: 943 | external: true 944 | ``` 945 | 946 | 5. To see the stack being created, navigate to `Kubernetes > Pods`. You should see the stack being created. 947 | 948 | ![](./images/kube_pods.png) 949 | 950 | ![](./images/kube-stack-created.png) 951 | 952 | 6. Click on the `hybrid-app` stack to see the details. 953 | 954 | ![](./images/ucp_stack.png) 955 | 956 | ![](./images/kube-stack-details.png) 957 | 958 | ### Task 4.4: Verify the app 959 | ![](./images/linux75.png) 960 | 961 | 1. Navigate to `Kubernetes > Pod` to verify the pods are being deployed. 962 | 963 | ![](./images/kube-pods.png) 964 | 965 | 2. Navigate to `Kubernetes > Controllers` to verify the deployments and ReplicaSets. 966 | 967 | ![](./images/kube-controllers.png) 968 | 969 | 3. Navigate to `Kubernetes > Load Balancers` to verify the Kubernetes services that have been created. 970 | 971 | ![](./images/k8s_lb.jpg) 972 | 973 | 4. Click on `java-web-published` to the the details of the public load balancer created for the Java application. 974 | 975 | ![](./images/kube-java-lb.png) 976 | 977 | 5. The `Node Port` 32770 is exposed. Note that this is different than previous implementations due to Kubernetes NodePort range limitations. Open a new browser tab, paste in the `UCP Hostname` from the Play with Docker landing page and add `:32770/java-web/` at the end of the url. You should be led to the running application. 978 | 979 | ![](./images/kube-running-app.png) 980 | 981 | ## Task 5: Image Scanning 982 | 983 | Security is crucial for all organizations and covers a wide range of topics. Far too many to cover them in-depth in this workshop. We'll be examining just one of the features that Docker Enterprise provides to assist you in building a secure software supply chain: `Image Scanning` which checks for vulnerabilities in your images. 984 | 985 | 1. If you turned on security in Task 1.3 step 14 you can skip this step. Otherwise, proceed to enable scanning now to allow DTR to download the latest security and vulnerabilities database. On the left-hand panel, select `System` and then the `Security` tab. Select `ENABLE SCANNING` and click `Enable Online Syncing` to start the download of database of security vulnerabilities. 986 | 987 | 988 | ![](./images/scanning-activate.png) 989 | 990 | 991 | > **Note**: This will take awhile so you may want to take a break by reading up on [Docker Security](https://www.docker.com/docker-security). 992 | 993 | 2. Once the security database has downloaded, you can scan individual images. Select a repository, such as `java/java_web`, and then select the `Tags` tab. If it hasn't already scanned, select `Start scan`. If it hasn't scanned already, this can take 5-10 minutes or so. 994 | 995 | ![](./images/java-scanned.png) 996 | 997 | > Note all the vulnerabilities found! This is due to deliberately using an old version of the `tomcat` base image. 998 | 999 | Most operating systems and many libraries contain some vulnerabilities. The details of these vulnerabilities and when they come into play are important. You can select `View details` to get additional information. Vulnerabilities within your image layers can be identified here. 1000 | 1001 | ![](./images/layers.png) 1002 | 1003 | By selecting `Components`, you can see what the vulnerabilities are and what components introduced the vulnerabilities. You can also select the vulnerabilities and examine them in the [Common Vulnerabilities and Exploits database](https://cve.mitre.org/). 1004 | 1005 | ![](./images/cves.png) 1006 | 1007 | 3. Another way reduce your vulnerabilities is to identify the vulnerability origin. For example, you can see that in `java_web:latest`, 1 Critical and 9 Major issues were introduced with the Spring Framework. Time to upgrade that framework! Of course, upgrading the app is out of scope for this workshop, but you can see how this would give you the needed information to mitigate vulnerabilities. 1008 | 1009 | 4. You can also choose newer base images. For example, you can revisit to the Dockerfile in the `~/hybrid-app/java-app` directory, and change the second base image to `9.0.13-jre11-slim`. Slim images in official images are generally based on lighter-weight operating systems like `Alpine Linux` or `Debian`, which have reduced attack vector. Then check the scanning again (this may again take 5-10 minutes). You might still see some vulnerabilities, however, there should be fewer. 1010 | 1011 | 5. To enable scanning of images automatically, select a repository. Navigate to the `Settings` tab and select `On Push` in the `Image Scanning` section. This will initiate a scan every time a new image is pushed to this repository. 1012 | 1013 | ![](./images/on_push_scan.png) 1014 | 1015 | 1016 | 6. DTR also allows you to [Sign Images](https://docs.docker.com/datacenter/dtr/2.4/guides/user/manage-images/sign-images/) and [Create promotion policies](https://docs.docker.com/datacenter/dtr/2.4/guides/user/create-promotion-policies/) which prevent users from using images in production that don't meet your criteria, including blocking images with critical and/or major vulnerabilities. 1017 | 1018 | ## Common Issues 1019 | 1020 | * Confirm that you are setting the environmental variable DTR_HOST to the DTR hostname. The DTR hostname can be found in the PWD session information at the bottom of the PWD page. 1021 | 1022 | ## Conclusion 1023 | 1024 | In this lab we've looked how Docker Enterprise can help you manage both Linux and Windows workloads whether they be traditional apps you've modernized or newer cloud-native apps, leveraging Swarm or Kubernetes for orchestration. 1025 | 1026 | You can find more information on Docker Enterprise at [http://www.docker.com](http://www.docker.com/enterprise-edition) as well as continue exploring using our hosted trial at [https://dockertrial.com](https://dockertrial.com) 1027 | -------------------------------------------------------------------------------- /images/add_a_node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_a_node.png -------------------------------------------------------------------------------- /images/add_designer_library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_designer_library.png -------------------------------------------------------------------------------- /images/add_java_user_to_organization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_java_user_to_organization.png -------------------------------------------------------------------------------- /images/add_java_web_to_team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_java_web_to_team.png -------------------------------------------------------------------------------- /images/add_node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_node.png -------------------------------------------------------------------------------- /images/add_repository_database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_repository_database.png -------------------------------------------------------------------------------- /images/add_repository_java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_repository_java.png -------------------------------------------------------------------------------- /images/add_win_node_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_win_node_1.png -------------------------------------------------------------------------------- /images/add_win_node_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_win_node_2.png -------------------------------------------------------------------------------- /images/add_win_node_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_win_node_3.png -------------------------------------------------------------------------------- /images/add_win_node_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/add_win_node_4.png -------------------------------------------------------------------------------- /images/app-design-choose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/app-design-choose.png -------------------------------------------------------------------------------- /images/app-design-custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/app-design-custom.png -------------------------------------------------------------------------------- /images/app-design-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/app-design-start.png -------------------------------------------------------------------------------- /images/choose-application-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/choose-application-template.png -------------------------------------------------------------------------------- /images/clear_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/clear_filter.png -------------------------------------------------------------------------------- /images/create-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/create-service.png -------------------------------------------------------------------------------- /images/create_java_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/create_java_user.png -------------------------------------------------------------------------------- /images/create_repository.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/create_repository.png -------------------------------------------------------------------------------- /images/customize-application-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/customize-application-template.png -------------------------------------------------------------------------------- /images/cves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/cves.png -------------------------------------------------------------------------------- /images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/dashboard.png -------------------------------------------------------------------------------- /images/deploy-links-k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/deploy-links-k8s.png -------------------------------------------------------------------------------- /images/design-new-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/design-new-app.png -------------------------------------------------------------------------------- /images/docker_service_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/docker_service_start.png -------------------------------------------------------------------------------- /images/docker_service_stopped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/docker_service_stopped.png -------------------------------------------------------------------------------- /images/dtr_fqdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/dtr_fqdn.png -------------------------------------------------------------------------------- /images/dtr_users_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/dtr_users_created.png -------------------------------------------------------------------------------- /images/inspect_resoource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/inspect_resoource.png -------------------------------------------------------------------------------- /images/java-scanned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/java-scanned.png -------------------------------------------------------------------------------- /images/java-web1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/java-web1.png -------------------------------------------------------------------------------- /images/java_organization_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/java_organization_new.png -------------------------------------------------------------------------------- /images/join_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/join_text.png -------------------------------------------------------------------------------- /images/k8s_lb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/k8s_lb.jpg -------------------------------------------------------------------------------- /images/k8s_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/k8s_stack.png -------------------------------------------------------------------------------- /images/kube-controllers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-controllers.png -------------------------------------------------------------------------------- /images/kube-create-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-create-stack.png -------------------------------------------------------------------------------- /images/kube-java-lb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-java-lb.png -------------------------------------------------------------------------------- /images/kube-lb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-lb.png -------------------------------------------------------------------------------- /images/kube-pods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-pods.png -------------------------------------------------------------------------------- /images/kube-running-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-running-app.png -------------------------------------------------------------------------------- /images/kube-stack-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-stack-created.png -------------------------------------------------------------------------------- /images/kube-stack-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-stack-details.png -------------------------------------------------------------------------------- /images/kube-stacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube-stacks.png -------------------------------------------------------------------------------- /images/kube_enable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_enable.png -------------------------------------------------------------------------------- /images/kube_enable_win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_enable_win.png -------------------------------------------------------------------------------- /images/kube_pods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_pods.png -------------------------------------------------------------------------------- /images/kube_run_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_run_background.png -------------------------------------------------------------------------------- /images/kube_run_background_win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_run_background_win.png -------------------------------------------------------------------------------- /images/kube_run_launch_app_win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/kube_run_launch_app_win.png -------------------------------------------------------------------------------- /images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/layers.png -------------------------------------------------------------------------------- /images/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux.png -------------------------------------------------------------------------------- /images/linux75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux75.png -------------------------------------------------------------------------------- /images/linux_constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux_constraint.png -------------------------------------------------------------------------------- /images/linux_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux_details.png -------------------------------------------------------------------------------- /images/linux_ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux_ports.png -------------------------------------------------------------------------------- /images/linux_tweet_app_container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/linux_tweet_app_container.png -------------------------------------------------------------------------------- /images/multi-arch-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/multi-arch-deploy.png -------------------------------------------------------------------------------- /images/mysql-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/mysql-secret.png -------------------------------------------------------------------------------- /images/name-application-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/name-application-template.png -------------------------------------------------------------------------------- /images/node_listing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/node_listing.png -------------------------------------------------------------------------------- /images/node_mixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/node_mixed.png -------------------------------------------------------------------------------- /images/node_types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/node_types.png -------------------------------------------------------------------------------- /images/on_push_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/on_push_scan.png -------------------------------------------------------------------------------- /images/organization_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/organization_screen.png -------------------------------------------------------------------------------- /images/pushed_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/pushed_image.png -------------------------------------------------------------------------------- /images/pwd_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/pwd_screen.png -------------------------------------------------------------------------------- /images/red_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/red_warning.png -------------------------------------------------------------------------------- /images/scanning-activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/scanning-activate.png -------------------------------------------------------------------------------- /images/secret_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/secret_add.png -------------------------------------------------------------------------------- /images/secret_add_completed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/secret_add_completed.png -------------------------------------------------------------------------------- /images/secret_add_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/secret_add_config.png -------------------------------------------------------------------------------- /images/select_nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/select_nodes.png -------------------------------------------------------------------------------- /images/service_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/service_details.png -------------------------------------------------------------------------------- /images/session-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/session-information.png -------------------------------------------------------------------------------- /images/ssl_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ssl_error.png -------------------------------------------------------------------------------- /images/swarm-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/swarm-services.png -------------------------------------------------------------------------------- /images/team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/team.png -------------------------------------------------------------------------------- /images/team_add_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/team_add_user.png -------------------------------------------------------------------------------- /images/team_with_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/team_with_user.png -------------------------------------------------------------------------------- /images/three_repositories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/three_repositories.png -------------------------------------------------------------------------------- /images/tomcat9-components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/tomcat9-components.png -------------------------------------------------------------------------------- /images/tomcat9-scanned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/tomcat9-scanned.png -------------------------------------------------------------------------------- /images/two_organizations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/two_organizations.png -------------------------------------------------------------------------------- /images/two_repositories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/two_repositories.png -------------------------------------------------------------------------------- /images/ucp_add_app_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_add_app_file.png -------------------------------------------------------------------------------- /images/ucp_create_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_create_stack.png -------------------------------------------------------------------------------- /images/ucp_java_deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_java_deploy.png -------------------------------------------------------------------------------- /images/ucp_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_network.png -------------------------------------------------------------------------------- /images/ucp_network_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_network_1.png -------------------------------------------------------------------------------- /images/ucp_network_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_network_2.png -------------------------------------------------------------------------------- /images/ucp_node_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_node_setting.png -------------------------------------------------------------------------------- /images/ucp_nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_nodes.png -------------------------------------------------------------------------------- /images/ucp_secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_secret.png -------------------------------------------------------------------------------- /images/ucp_secret_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_secret_menu.png -------------------------------------------------------------------------------- /images/ucp_secret_menu_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_secret_menu_1.png -------------------------------------------------------------------------------- /images/ucp_service_database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_service_database.png -------------------------------------------------------------------------------- /images/ucp_service_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_service_network.png -------------------------------------------------------------------------------- /images/ucp_service_ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_service_ports.png -------------------------------------------------------------------------------- /images/ucp_service_secret.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_service_secret.PNG -------------------------------------------------------------------------------- /images/ucp_shared_stacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_shared_stacks.png -------------------------------------------------------------------------------- /images/ucp_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/ucp_stack.png -------------------------------------------------------------------------------- /images/update_status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/update_status.png -------------------------------------------------------------------------------- /images/user_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/user_screen.png -------------------------------------------------------------------------------- /images/vm_roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/vm_roles.png -------------------------------------------------------------------------------- /images/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/windows.png -------------------------------------------------------------------------------- /images/windows75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/windows75.png -------------------------------------------------------------------------------- /images/windows_ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/docker-archive/ee-workshop/8a571bf5f9f3f38aa84a1cdead1e4c8e5f068c60/images/windows_ports.png --------------------------------------------------------------------------------