├── 0-Concepts.md ├── 1-Basics.md ├── 2-Images.md ├── 3-Tags-and-Push.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── images ├── 1-vms.png ├── 10-push-tag.png ├── 2-containers.png ├── 3-concerns.png ├── 4-docker.png ├── 5-docker2.png ├── 6-create-repo.png ├── 7-create-repo.png ├── 8-docker-build.png └── 9-pull-run.png ├── index.html └── wassup.conf /0-Concepts.md: -------------------------------------------------------------------------------- 1 | ## Basic Concepts 2 | 3 | Docker is in use now by a lot of companies when deploying applications to the cloud. However, to explain why Docker is important, we may need to go back a couple of years to revisit how we used to deploy applications. 4 | 5 | In the past, we used to deploy applications against operating systems installed on hardware that we bought. Much like how you'd install software on your Windows operating system, which is installed on your laptop. 6 | 7 | Over time, we started having [Hypervisors](https://en.wikipedia.org/wiki/Hypervisor) - software that would allow you to emulate hardware, and install *another* operating system on top of it. Conceptually, it all stacks up like this: 8 | 9 | ![Virtualization](/images/1-vms.png) 10 | 11 | You would install the Hypervisor, and then "*fake*" hardware that you can install an operating system in. 12 | 13 | During the last couple of years, people have started using Docker. Compared to Virtual Machines, it all stacks up like this: 14 | 15 | ![Containerization](/images/2-containers.png) 16 | 17 | The operating system ( or to be more correct, the [kernel](https://en.wikipedia.org/wiki/Kernel_(operating_system)) ) began to be reused, and all you had to do was pack up *just what you need* - the libraries, or anything "uncommon" that doesn't exist in the kernel by default. 18 | 19 | Dockerizing applications gave us a couple of things: 20 | 21 | - **Portability**. A Dockerized application will now run the *exact same way* regardless of what the host operating system is, as long as it's a compatible Docker Host. 22 | 23 | - **Isolation**. With everything that you need encapsulated inside the image/container, this means that you no longer have to worry about dependencies being missing on your destination host. 24 | 25 | ![Concerns](/images/3-concerns.png) 26 | 27 | ### Docker basics 28 | 29 | The Docker ecosystem has three primary parts to it - the **Client**, the **Host**, and the **Registry**. 30 | 31 | ![Ecosystem](/images/4-docker.png) 32 | 33 | The **Client** is the primary way of interacting with the Docker host. In very much the same way that client applications talk to an API, the Docker command line interacts with the Docker server. 34 | 35 | The **Docker Host** is the service that runs the API and the daemon that manages your images and containers. Note that we have this annotated as `DOCKER_HOST`, because while this is usually installed in the same system as the **Client**, your Docker Host can be in another machine. 36 | 37 | The **Registry** is where your images are stored. We'll talk about all of these in more detail later, but for now, all you need to know is they roughly wire up like this: 38 | 39 | ![Ecosystem](/images/5-docker2.png) 40 | 41 | Don't worry about absorbing this all - we'll slowly unpack how everything wires together. 42 | 43 | 44 | ### Containers and Images 45 | 46 | A Docker image is a file, composed of multiple layers, used to execute code. When this code is in execution and is able to read/write is when we consider it a **container**. In short, an **image** is an inert **container**, and a **container** is an image that is running. 47 | -------------------------------------------------------------------------------- /1-Basics.md: -------------------------------------------------------------------------------- 1 | ## Docker Basics 2 | 3 | In this section, we'll be talking about what it means to do a `docker run` and a `docker pull`: 4 | 5 | ![Docker run-pull](/images/9-pull-run.png) 6 | 7 | 8 | ## Running Docker 9 | 10 | Before we start with anything, let's run the following command in the command line interface (CLI): 11 | 12 | ``` 13 | docker run hello-world 14 | ``` 15 | 16 | This runs a pre-existing image called `hello-world` on your Docker host, which runs and outputs some cute text. 17 | 18 | #### Pulling images 19 | 20 | Running a `docker pull` means that your Docker Host downloads an image from the registry (but does not run it). So try running the following command: 21 | 22 | ``` 23 | docker pull busybox 24 | ``` 25 | 26 | This will pull the `busybox` image from the default Docker registry: https://hub.docker.com/explore/. You can also try pulling other images from the registry if you want! 27 | 28 | Now that you have the `busybox` image, you can try running it: 29 | 30 | ``` 31 | docker run busybox 32 | ``` 33 | 34 | Notice that nothing happened. *This is on purpose* - we didn't specify a command, so all Docker did was to load up `busybox`, ran an empty command, then exited. So what does it look like when we want to run a command? Try: 35 | 36 | ``` 37 | docker run busybox echo "Hallo Avocado\!" 38 | ``` 39 | 40 | This will load up the `busybox` image, then run a command which outputs `Hallo Avocado!`. Look at you, you command-line *slayer*. 41 | 42 | 43 | #### Seeing your Docker Images 44 | 45 | Oh homes, now you have two images downloaded. You can check the Docker images you have by running `images`: 46 | 47 | ``` 48 | docker images 49 | ``` 50 | 51 | This should list something similar to: 52 | 53 | ``` 54 | REPOSITORY TAG IMAGE ID CREATED SIZE 55 | hello-world latest fce289e99eb9 2 weeks ago 1.84kB 56 | busybox latest 3a093384ac30 2 weeks ago 1.2MB 57 | ``` 58 | 59 | #### Let's run something in Docker 60 | 61 | Okay. Now let's try running a website - say, an Nginx application that just serves the default page. For this, all we have to do is run: 62 | 63 | ``` 64 | docker run nginx:latest 65 | ``` 66 | 67 | Notice that we didn't have to do a `docker pull`. What essentially happens is shown in the output of the command: 68 | 69 | ``` 70 | $ docker run nginx 71 | Unable to find image 'nginx:latest' locally 72 | latest: Pulling from library/nginx 73 | 177e7ef0df69: Pull complete 74 | ea57c53235df: Pull complete 75 | bbdb1fbd4a86: Pull complete 76 | Digest: sha256:b543f6d0983fbc25b9874e22f4fe257a567111da96fd1d8f1b44315f1236398c 77 | Status: Downloaded newer image for nginx:latest 78 | ``` 79 | 80 | As per the above, Docker tries to see if the image you're trying to run exists locally - then pulls from somewhere else if it does not exist. The *somewhere else* is the Docker Hub we saw earlier - it just grabs the matching version off that. 81 | 82 | But there's no website, right? How do we access it? It turns out that we need to *publish ports* for Docker to be able to serve out anything. 83 | 84 | But wait, it seems to be stuck? Not really. Docker is just running on attached mode, so we also need to run Docker in a *detached mode* it looks like. Just type *Ctrl-C* to cancel the running container, and rerun it with as the following: 85 | 86 | ``` 87 | docker run -d -P --name banana-smith-container nginx 88 | ``` 89 | 90 | `-d` runs Docker in *detached mode*, and `-P` publishes all exposed ports so we can access it. `banana-smith` is what we're naming the container - feel free to change it to any name you want. We can then find out how to access the site by running: 91 | 92 | ``` 93 | docker port banana-smith-container 94 | ``` 95 | 96 | Which will give us something like: 97 | 98 | ``` 99 | 80/tcp -> 0.0.0.0:32768 100 | ``` 101 | 102 | This basically means that the service is accessible from port `32768` of your machine. You should be able to open up your browser and go to: 103 | 104 | ``` 105 | http://localhost:32768 106 | ``` 107 | 108 | Neat, right? Finally, stop the container by running: 109 | 110 | ``` 111 | docker stop banana-smith-container 112 | ``` 113 | 114 | 115 | #### Docker Run Shell Within Nginx 116 | 117 | Note that the Docker image you're running also contains other things. It has a small slice of the operating system, and this slice is actually available to you. You can access the command line inside the `nginx` container we were running earlier by running: 118 | 119 | ``` 120 | docker run -it nginx:latest /bin/bash 121 | ``` 122 | 123 | The `-it` flag attaches you to an interactive "console" within the container. `/bin/bash` is a shell that exists within the container. To see where the page that you saw before was, try running the following while inside the console: 124 | 125 | ``` 126 | cat /usr/share/nginx/html/index.html 127 | ``` 128 | 129 | To exit the container use *Ctrl-D* 130 | 131 | And there you go! You can pull down and run containers. 132 | 133 | 134 | #### Exercise 135 | 136 | Now, what you're going to find is that there are lots of Docker containers out in the wild. Now that you know how to pull down and run images, I've got a challenge for you: why not see if you can find and run the `wordpress` image from https://hub.docker.com/_/wordpress ? 137 | -------------------------------------------------------------------------------- /2-Images.md: -------------------------------------------------------------------------------- 1 | ## Making your own Docker images 2 | 3 | As neat as it is to quickly run preexisting images, we probably want to explore how we can create our own images. In this section, we'll be taking a look at `Dockerfile`. 4 | 5 | A `Dockerfile` is the traditional naming of a file which contains instructions on how to build an image. 6 | 7 | ![Dockerfile](/images/8-docker-build.png) 8 | 9 | #### Docker Images 10 | 11 | Before we start making Docker images, it's best if we familiarize ourselves with how images are stored in your Docker host (effectively, your laptop). Run the following command to get a list: 12 | 13 | ``` 14 | docker images 15 | ``` 16 | 17 | This will produce a list of images on your laptop that look like this: 18 | 19 | ``` 20 | REPOSITORY TAG IMAGE ID CREATED SIZE 21 | hello-world latest fce289e99eb9 3 weeks ago 1.84kB 22 | busybox latest 3a093384ac30 3 weeks ago 1.2MB 23 | nginx latest 7042885a156a 4 weeks ago 109MB 24 | ``` 25 | 26 | This effectively lists the images you have, the tags they are associated with, and the image ID. Note that you can also use image IDs as a reference when running Docker commands. Like so: 27 | 28 | ``` 29 | docker run -it 7042885a156a /bin/bash 30 | ``` 31 | 32 | #### Dockerfiles 33 | 34 | Okay! Now let's make us some images. In the `docker-101` directory, you'll find a file called `Dockerfile`. Inside this file, you'll see: 35 | 36 | ``` 37 | FROM nginx:mainline-alpine 38 | ``` 39 | 40 | This basically means that we're starting from the `nginx:mainline-alpine` image at the starting layer. This layer contains similar things to the `nginx` container you were running earlier. 41 | 42 | To build the image, we can then run the following from inside the `docker-101` directory: 43 | 44 | ``` 45 | docker build -t banana-smith-image . 46 | ``` 47 | 48 | This takes our `Dockerfile` file, reads the instructions, and creates the basic image on your Docker host called `banana-smith-image`. Again, change the name if you want. You can verify that the image is built by listing the images you now have: 49 | 50 | ``` 51 | docker images 52 | ``` 53 | 54 | You should see the image you just created. Finally, run the image by running: 55 | 56 | ``` 57 | docker run -d -P --name banana-smith-container banana-smith-image 58 | ``` 59 | 60 | To see that it's actually running, check the port by: 61 | 62 | ``` 63 | docker port banana-smith-container 64 | ``` 65 | If you get an error, something like : 66 | 67 | ``` 68 | docker: Error response from daemon: Conflict. The container name "/banana-smith-container" is already in use by container "dd22b733a855cafc3a9235efbe892828ca82a9ee02cd30b9c7120ba891825414". You have to remove (or rename) that container to be able to reuse that name. 69 | See 'docker run --help'. 70 | ``` 71 | this might be because you already had a banana-smith-container and a banana-smith-image. You can remove the container by running 72 | 73 | ``` 74 | docker rm banana-smith-container 75 | ``` 76 | 77 | ⚠️ Did you get the following error? ⚠️ 78 | 79 | ``` 80 | Error response from daemon: You cannot remove a running container b854db1f962007c030a3609683903644511337cde67da69d45d5702240a8cb9a. Stop the container before attempting removal or force remove 81 | ``` 82 | We need to stop the container first by running 83 | 84 | ``` 85 | docker stop banana-smith-container 86 | ``` 87 | Let's try that again: 88 | 89 | ``` 90 | docker rm banana-smith-container 91 | ``` 92 | 93 | and remove the image by running 94 | 95 | ``` 96 | docker image rm banana-smith-image 97 | ``` 98 | Then try building the image again. 99 | 100 | Then open up your browser, and access the same page - e.g., `http://localhost:32768`. Once done, cleanup the running container by running: 101 | 102 | ``` 103 | docker stop banana-smith-container 104 | ``` 105 | 106 | #### Dockerfile instructions breakdown 107 | 108 | Now, in the `docker-101` directory, you'll find a file called `index.html`. Unfortunately, I have no eye for design - so feel free to modify the page to make it look as good as possible. 109 | 110 | For the next section, we're going to be modifying our Dockerfile so that 1.) We replace the configuration, and 2.) We insert our `index.html` file. We'll do this by changing the `Dockerfile` so it looks like this: 111 | 112 | ``` 113 | FROM nginx:mainline-alpine 114 | RUN rm /etc/nginx/conf.d/* 115 | ADD wassup.conf /etc/nginx/conf.d/ 116 | ADD index.html /usr/share/nginx/html/ 117 | ``` 118 | 119 | The `RUN` directive runs the command specified (in this case, `rm /etc/nginx/conf.d/*` - which cleans out the configuration directory for Nginx). The `ADD` directive adds the files from your current directory into the image's directories. What we're doing here is we're basically: 120 | 121 | 1.) Referencing the `nginx:mainline-alpine` image to start with 122 | 123 | 2.) Removing existing configuration files 124 | 125 | 3.) Adding a new configuration file (`wassup.conf`) 126 | 127 | 4.) And adding a new index.html file. 128 | 129 | To build the image, run the same command as before: 130 | 131 | ``` 132 | docker build -t banana-smith-image . 133 | ``` 134 | 135 | Now, if you list out your images with `docker images`, you'll see something like: 136 | 137 | ``` 138 | REPOSITORY TAG IMAGE ID 139 | banana-smith-image latest 98be87baf87e 140 | hello-world latest fce289e99eb9 141 | busybox latest 3a093384ac30 142 | nginx latest 7042885a156a 143 | ``` 144 | 145 | What you might have noticed is that the IMAGE ID is now different. Run it the way you've run any other image: 146 | 147 | ``` 148 | docker run -d -P --name banana-smith-container banana-smith-image 149 | ``` 150 | 151 | Then check the port it's running under: 152 | 153 | ``` 154 | docker port banana-smith-container 155 | ``` 156 | 157 | Then open up your browser, and access the same page - e.g., `http://localhost:32768`. What you should see is your new, fresh image! 158 | 159 | 160 | #### Exercise 161 | 162 | Why not try adding CSS to the index.html page? 163 | -------------------------------------------------------------------------------- /3-Tags-and-Push.md: -------------------------------------------------------------------------------- 1 | ## Tags and registries 2 | 3 | Images are good and fine, but eventually you'll need a way to share them with people or systems so that they can be executed or deployed. Docker uses mechanisms like `docker tag` and `docker push` to make this happen. 4 | 5 | ![Push-tag](/images/10-push-tag.png) 6 | 7 | #### The basics of tags 8 | 9 | First off, you can see the tags that you currently have by running `docker images`. The output should look like this: 10 | 11 | ``` 12 | REPOSITORY TAG IMAGE ID CREATED SIZE 13 | banana-smith-image latest 98be87baf87e 28 seconds ago 17.8MB 14 | hello-world latest fce289e99eb9 3 weeks ago 1.84kB 15 | busybox latest 3a093384ac30 3 weeks ago 1.2MB 16 | nginx latest 7042885a156a 4 weeks ago 109MB 17 | ``` 18 | 19 | The `latest` tag gets appended to the latest build of a particular image name. However, you can add more tags to that image ID by running: 20 | 21 | ``` 22 | docker tag 98be87baf87e banana-smith-image:tag-2 23 | ``` 24 | 25 | Where you can replace `98be87baf87e` with the IMAGE ID of your image. Now, if you run `docker images`, you should see: 26 | 27 | ``` 28 | REPOSITORY TAG IMAGE ID CREATED SIZE 29 | banana-smith-image tag-2 98be87baf87e 28 seconds ago 17.8MB 30 | banana-smith-image latest 98be87baf87e 28 seconds ago 17.8MB 31 | hello-world latest fce289e99eb9 3 weeks ago 1.84kB 32 | busybox latest 3a093384ac30 3 weeks ago 1.2MB 33 | nginx latest 7042885a156a 4 weeks ago 109MB 34 | ``` 35 | 36 | Note that you can also use repositories and tags as a source image. For example: 37 | 38 | ``` 39 | docker tag banana-smith-image:latest banana-smith-image:tag-3 40 | ``` 41 | 42 | Now, when you run `docker images`, you should get: 43 | 44 | ``` 45 | REPOSITORY TAG IMAGE ID CREATED SIZE 46 | banana-smith-image tag-3 98be87baf87e 28 seconds ago 17.8MB 47 | banana-smith-image tag-2 98be87baf87e 28 seconds ago 17.8MB 48 | banana-smith-image latest 98be87baf87e 28 seconds ago 17.8MB 49 | hello-world latest fce289e99eb9 3 weeks ago 1.84kB 50 | busybox latest 3a093384ac30 3 weeks ago 1.2MB 51 | nginx latest 7042885a156a 4 weeks ago 109MB 52 | ``` 53 | 54 | Now your image has three tags. Note that you can use tags as a way of referencing where to upload your images, but we'll tackle that later. 55 | 56 | #### Docker repositories 57 | 58 | Docker repositories allow you to share your images with the community. To get started, we'll create a repository by [going to Docker Hub](https://hub.docker.com/) and selecting **Create A Repository**: 59 | 60 | ![Create-Repo](/images/6-create-repo.png) 61 | 62 | Name it however you want. In the below example, we're calling it `/my-first-repo`: 63 | 64 | ![Private Repo](/images/7-create-repo.png) 65 | 66 | We're setting it to **Private**. You can change the repository privileges anytime! 67 | 68 | Now, remember the images we had earlier? We're going to add a tag - except the tag will be your Docker Hub username, and the repository you have created: 69 | 70 | ``` 71 | docker tag banana-smith-image:latest banana-smith/my-first-repo 72 | ``` 73 | 74 | Where `banana-smith` is your Docker Hub username. Finally, we'll login to Docker Hub with the following command: 75 | 76 | ``` 77 | docker login 78 | ``` 79 | 80 | Use your Docker Hub credentials to login. Once you're logged in, you can push your image to Docker Hub: 81 | 82 | ``` 83 | docker push banana-smith/my-first-repo 84 | ``` 85 | 86 | Now, we can check if we've uploaded our image to Docker hub. With your browser, go to your Docker Hub repository and check under ***Tags***. Do you see your image? 87 | 88 | To verify that your image can be pulled down, you can try running: 89 | 90 | ``` 91 | docker pull banana-smith/my-first-repo 92 | ``` 93 | 94 | #### Exercise 95 | 96 | Now that you know how to login and push images, try creating a ***Public*** repository and pushing an image to it. Ask the person next to you to pull the image down and run it. 97 | 98 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | - [Contributing](#contributing) 2 | * [Pull Request Process](#pull-request-process) 3 | * [Module Guidelines](#module-guidelines) 4 | + [Good questions to ask](#good-questions-to-ask) 5 | - [1.) Who is it for?](#1--who-is-it-for-) 6 | - [2.) What are my learning outcomes?](#2--what-are-my-learning-outcomes-) 7 | - [3.) What does feedback look like?](#3--what-does-feedback-look-like-) 8 | + [Module Format](#module-format) 9 | - [1.) Talk and Theory (15-30 minutes)](#1--talk-and-theory--15-30-minutes-) 10 | - [2.) Self-driven practical (60-90 minutes)](#2--self-driven-practical--60-90-minutes-) 11 | - [3.) Knowledge check](#3--knowledge-check) 12 | + [Overall structure](#overall-structure) 13 | - [Option A.) The "Kata"](#option-a--the--kata-) 14 | - [Option B.) The "Castle"](#option-b--the--castle-) 15 | * [Code of Conduct](#code-of-conduct) 16 | + [Our Pledge](#our-pledge) 17 | + [Our Standards](#our-standards) 18 | + [Our Responsibilities](#our-responsibilities) 19 | + [Scope](#scope) 20 | + [Attribution](#attribution) 21 | 22 | 23 | # Contributing 24 | 25 | When contributing to this repository, please first discuss the change you wish to make via issue, 26 | email, or any other method with the owners of this repository before making a change. 27 | 28 | Please note we have a code of conduct, please follow it in all your interactions with the project. 29 | 30 | ## Pull Request Process 31 | 32 | 1. Update the CHANGES.md with details of changes to the modules - this includes corrections, 33 | syllabus updates for new features, or practical information. 34 | 2. You may merge the Pull Request in once you have the sign-off of another developer, or if you 35 | do not have permission to do that, you may request the reviewer to merge it for you. 36 | 37 | ## Module Guidelines 38 | 39 | ### Good questions to ask 40 | 41 | Before making a DevOps Represent module, consider asking the following questions: 42 | 43 | ![Lean Canvas](/images/CONTRIBUTING/module-lean-canvas.png) 44 | 45 | #### 1.) Who is it for? 46 | 47 | It's important to identify who your target audience is, and what their knowledge baselines would be. 48 | Put into practical terms: are you planning to cater for absolute beginners? Or do you aim to teach 49 | people with existing backgrounds in tech? 50 | 51 | Even then, it's important to identify the level of experience you're working with. This is critical as 52 | you define the level of depth you want to dive in - e.g., do you assume that the attendees have experience 53 | with the command line, or do you also need to cover CLI basics? 54 | 55 | #### 2.) What are my learning outcomes? 56 | 57 | It is also good to be able to articulate what you want the attendees to be able to do: the workshop aims to 58 | empower people, and it's useful to declare where you'd want them to be by the end of the day. 59 | 60 | To put it into questions: do you want the attendees to be able to *remember* what you covered, or do you 61 | want them to be able to *create a solution*? Would they be able to *evaluate* between different solutions? 62 | 63 | Consider using [Bloom's Taxonomy of Learning](https://en.wikipedia.org/wiki/Bloom%27s_taxonomy) 64 | as a guide. 65 | 66 | ![Bloom's Taxonomy](/images/CONTRIBUTING/blooms-taxonomy.png) 67 | 68 | #### 3.) What does feedback look like? 69 | 70 | **Knowledge checks** are a powerful tool - they let you verify if the attendees understand your content, 71 | while at the same time encouraging knowledge retention. This is why teachers usually structure lessons 72 | so that there are quizzes at the end of it. 73 | 74 | Feedback can take many shapes: a quiz, a poll, or a question at the end of your practicals. Maybe make it 75 | fun even - have some small prizes for attendees who ask good questions. 76 | 77 | ### Module Format 78 | 79 | #### 1.) Talk and Theory (15-30 minutes) 80 | 81 | It's good to have a fun, informative talk before diving into the practicals. Consider covering the following areas: 82 | 83 | - The history and context of the particular technology 84 | - How it works 85 | - How and when to use it 86 | - How it's valuable to the business 87 | 88 | Keep it short, but remember to pace down. It's better to take your time than rush too fast and risk leaving people 89 | behind - remember: not everyone is willing to ask you to repeat concepts and facts. 90 | 91 | 92 | #### 2.) Self-driven practical (60-90 minutes) 93 | 94 | Consider running a practical exercise that the attendees can follow. A few things to keep in mind: 95 | 96 | - Make sure that everyone knows beforehand what they need to go through it. Do they need `awscli` installed? Do they need their own AWS account? 97 | - Make sure that the environments the attendees are deploying/building to are enclosed and free of dependencies. 98 | - Make sure that coaches have gone through the material beforehand. 99 | 100 | If you're feeling up for it, *moonshots* are also a good idea - optional exercises for those who blitz through the material. 101 | 102 | #### 3.) Knowledge check 103 | 104 | Consider saving a portion of time for reflection and self-evaluation. Ask the attendees questions (whether in text or face-to-face): 105 | 106 | - What did you learn? 107 | - How would you apply this to something you want to do? 108 | 109 | ### Overall structure 110 | 111 | It's worth thinking about the day as a whole. There's multiple ways that you can structure an all-day DevOps Represent workshop. 112 | 113 | #### Option A.) The "Kata" 114 | 115 | ![The Kata](/images/CONTRIBUTING/the-kata.png) 116 | 117 | The "Kata" is essentially a way of structuring your content so that all your modules produce roughly the same output. 118 | Imagine an EC2, ECS, and Lambda modules all producing a standard webapp. 119 | 120 | This approach works if you want to enable attendees by giving them the ability to distinguish between different 121 | ways to approach a problem. *When do I use an EC2 versus a Lambda?* would be the kind of questions that they will 122 | be able to answer. 123 | 124 | #### Option B.) The "Castle" 125 | 126 | ![The Castle](/images/CONTRIBUTING/the-castle.png) 127 | 128 | The "Castle" is a way of structuring your content so that your modules contribute to *one big thing*. Imagine an 129 | EC2, RDS, and ELB module all contributing towards building a reasonably complex ecosystem. 130 | 131 | This approach works if you want to enable attendees by giving them the experience of wiring up several systems 132 | and making them understand how to make everything work together. AWS thrives on providing "lego blocks" that 133 | you can stitch together, and this is a good way to highlight that. 134 | 135 | 136 | ## Code of Conduct 137 | 138 | ### Our Pledge 139 | 140 | In the interest of fostering an open and welcoming environment, we as 141 | contributors and maintainers pledge to making participation in our project and 142 | our community a harassment-free experience for everyone, regardless of age, body 143 | size, disability, ethnicity, gender identity and expression, level of experience, 144 | nationality, personal appearance, race, religion, or sexual identity and 145 | orientation. 146 | 147 | ### Our Standards 148 | 149 | Examples of behavior that contributes to creating a positive environment 150 | include: 151 | 152 | * Using welcoming and inclusive language 153 | * Being respectful of differing viewpoints and experiences 154 | * Gracefully accepting constructive criticism 155 | * Focusing on what is best for the community 156 | * Showing empathy towards other community members 157 | 158 | Examples of unacceptable behavior by participants include: 159 | 160 | * The use of sexualized language or imagery and unwelcome sexual attention or 161 | advances 162 | * Trolling, insulting/derogatory comments, and personal or political attacks 163 | * Public or private harassment 164 | * Publishing others' private information, such as a physical or electronic 165 | address, without explicit permission 166 | * Other conduct which could reasonably be considered inappropriate in a 167 | professional setting 168 | 169 | ### Our Responsibilities 170 | 171 | Project maintainers are responsible for clarifying the standards of acceptable 172 | behavior and are expected to take appropriate and fair corrective action in 173 | response to any instances of unacceptable behavior. 174 | 175 | Project maintainers have the right and responsibility to remove, edit, or 176 | reject comments, commits, code, wiki edits, issues, and other contributions 177 | that are not aligned to this Code of Conduct, or to ban temporarily or 178 | permanently any contributor for other behaviors that they deem inappropriate, 179 | threatening, offensive, or harmful. 180 | 181 | ### Scope 182 | 183 | This Code of Conduct applies both within project spaces and in public spaces 184 | when an individual is representing the project or its community. Examples of 185 | representing a project or community include using an official project e-mail 186 | address, posting via an official social media account, or acting as an appointed 187 | representative at an online or offline event. Representation of a project may be 188 | further defined and clarified by project maintainers. 189 | 190 | ### Attribution 191 | 192 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 193 | available at [http://contributor-covenant.org/version/1/4][version] 194 | 195 | [homepage]: http://contributor-covenant.org 196 | [version]: http://contributor-covenant.org/version/1/4/ 197 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:mainline-alpine 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DevOps Represent Docker 101 2 | 3 | ## What This Is 4 | 5 | This is a workshop which introduces basic Docker concepts - how to use it, why it's important, and where to get more information afterwards. This workshop is designed to be self-running, and contains practical and conceptual information inside the repository. 6 | 7 | This workshop aims to for the comprehension and application of Docker knowledge. 8 | 9 | ## Prerequisites 10 | 11 | Before beginning this workshop, you must: 12 | 13 | - Install Docker ( [Instructions for Windows](https://docs.docker.com/v17.09/docker-for-windows/install/) / [Instructions for Macs](https://docs.docker.com/docker-for-mac/install/) ) 14 | 15 | - Signup for an account in [Docker Hub](https://hub.docker.com/) 16 | 17 | - After signing up for an account, make sure you can login by running the following in your command line: 18 | 19 | ``` 20 | docker login 21 | ``` 22 | 23 | 24 | ## The Workshop 25 | 26 | This workshop has three components: 27 | 28 | - [Part 0: Concepts.](https://github.com/DevOps-Represent/docker-101/blob/master/0-Concepts.md) In this part, we'll review *what Docker is* and why it is important. 29 | 30 | - [Part 1: Docker Basics.](https://github.com/DevOps-Represent/docker-101/blob/master/1-Basics.md) In this part of the workshop, we'll go through basic commands to run containers and pull images. 31 | 32 | - [Part 2: Creating Docker Images.](https://github.com/DevOps-Represent/docker-101/blob/master/2-Images.md) We'll break down how to create your own Docker images. 33 | 34 | - [Part 3: Docker Tagging.](https://github.com/DevOps-Represent/docker-101/blob/master/3-Tags-and-Push.md) We'll take a look at what Docker tags are, and how to publish your images. 35 | 36 | ## What happens next? 37 | 38 | Once you're done with this workshop, you can also go through our [Kubernetes Workshop here.](https://github.com/DevOps-Represent/kubernetes-101/) 39 | -------------------------------------------------------------------------------- /images/1-vms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/1-vms.png -------------------------------------------------------------------------------- /images/10-push-tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/10-push-tag.png -------------------------------------------------------------------------------- /images/2-containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/2-containers.png -------------------------------------------------------------------------------- /images/3-concerns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/3-concerns.png -------------------------------------------------------------------------------- /images/4-docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/4-docker.png -------------------------------------------------------------------------------- /images/5-docker2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/5-docker2.png -------------------------------------------------------------------------------- /images/6-create-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/6-create-repo.png -------------------------------------------------------------------------------- /images/7-create-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/7-create-repo.png -------------------------------------------------------------------------------- /images/8-docker-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/8-docker-build.png -------------------------------------------------------------------------------- /images/9-pull-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevOps-Represent/docker-101/43bab6b0e41891274ffe38eef365bbfe0042818f/images/9-pull-run.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | Hello there! 2 | -------------------------------------------------------------------------------- /wassup.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | 4 | root /usr/share/nginx/html; 5 | try_files /index.html =404; 6 | 7 | expires -1; 8 | 9 | sub_filter_once off; 10 | sub_filter 'server_hostname' '$hostname'; 11 | sub_filter 'server_address' '$server_addr:$server_port'; 12 | sub_filter 'server_url' '$request_uri'; 13 | sub_filter 'server_date' '$time_local'; 14 | sub_filter 'request_id' '$request_id'; 15 | } 16 | --------------------------------------------------------------------------------