 Ještě na toho dělává. Što mám? O, je ozvážená, bude to o kilom svou. Můžete jsou jít na komeropetu? Můžete? Ještě na toto dělává. Ještě na toto dělává. A když? Dělává. A když? A když? Dělává. Dělává. Dělává. Dělává. S třeba, dělává. Dělává. Třeba to být mítro. Hej. I hovět, že jsi být mítro. Píklad, brnokým. A, to je dobroká. Takže, můžeme mítro. Takže, můžeme mítro. OK. OK, tak hlavně, díky, přepravitr the workshop. V hrění se dýle. Jsme dějiš, že jste třeba třeba... ...h Malá příjemně poprůvodně 말ovitřil na Antigo. Až sevící jsou Petr Šifer a Tomáš Toměček. Váš vám dělá větma. Prodějte, že jste uživáte tu passiore i takて. a to je tady. Válkou. Proč jsme nějaké vědělosti v městě. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. Děkuju. je exams, on the next slide, like, what's your experience so we can adjust the, I mean, adjust the workshop to your skills or experience. Then Peter will give some introduction to Ansible, so if you don't know Ansible, it's like great, like, with basics, like play books and variables and that kind of stuff. až se děláme, co bych mohl podítiť kontánovit, které se to přišel, až se podítímá spod čahy. Až tu to bude svoje těknáčy přemými až ze všichni nebylo děláte, tak mi to však jdeme, co už jsou vstupenávala. A infekci, které zndríte, můžete přišel a přišel to zvuknit. To je měst. Takže, než se to závodují. Když se konečná dělávala dokerou? O, vám. Jak se kastují? Když se kastují dělávala dokerou? Takže, to je měst. Takže, máte already some cluster with Docker installed, and do have some applications running production. OK, so, well, one person. Nice. And how about our sible? So who is using an sible, actually? OK. And do actually use it in production, like do manager cluster, so on. OK. And how about some orchestration? Do you use Kubernetes? OK. And yeah, that's it. So I guess that we have some pictures, like, who are you? OK, so if you'd like to do the examples we'll be doing, we have prepared several examples. And you need the images to run them. So if you'd like to keep with us, I suggest to pull the images from the internet right now. And hopefully, they will be on your laptops in, like, 20 minutes or something like that. So here is the list of images. And also, what software will be using, it's, like, obviously, an sible, Docker. And you also need, I mean, it's possible that your distribution doesn't, like, fill in dependency with Python Docker Pi, which is a sible. So this is our request, if you'd like to do the stuff which we'll be doing. But if you don't, like, just keep it. Also, we have all the examples and slides available on internet. So it's on our GitHub repo. And I can show you the name of the repo. So this is the repo. Is the background called Fedora? No, it's actually Fedora. It's Fedora package manager. So just, like, use your package manager. So I'm not sure if you can see it. But here are the slides. Here is the repo with all the examples. And the slides are there. So, yeah, we'll show this definitely, like, in the end. Or if you just want to know the name, just tell me. And I'll show it again. Yeah, I guess we can start with the introduction to Ansible. So, uh-huh, yeah, that's a good point. So originally, we didn't want to do intro to containers. So is here anyone who need, like, introduction to Docker or containers or container images? I mean, please pick up because we'll be, like, we'll expect that you know what it is and how to use it and start the features and that kind of stuff. So is anyone who needs, like, intro to containers? Yeah, OK. I mean, OK, it's fine. So I'll give you, like, 10 minutes intro to containers, like, really basic stuff. Yeah, first I will talk about it, and then I'll show you some examples. That's OK. So containers, like, that's, like, topic of our industry for, like, two or three years. And everyone is talking about it. And, I mean, I can imagine that, like, someone can be, like, confused, like, what's so great about containers. So containers are basically just Linux processes. Like, that's it. It's nothing special. Well, they are kind of special, actually. So they are Linux processes, but they are isolated from the rest of the system and from various aspects of the system. So you can have, like, a container which has its own file system. And it's running, like, isolated from other processes, or from the network, or from all the file systems, like, mounts. And that's it. And what's really interesting about it is that you can take the file system and, like, store it on the internet and just, like, distribute it on the service. And then you have the whole container inside our infrastructure. And it's, like, all its managed, like, automated. So you don't have to, like, deploy it manually or stuff like that. Like, it's all automated. And it's running isolated from rest of the services. So you can be sure that there are no conflicts. So you can easily run, like, one service, like, it's replicated in 10 containers within one server. Like, that's super easy. And without containers, I think that should be pretty hard to run, like, I know if I wanted to run, like, 10 times, 10 PostgreSQL services on my laptop, to be, like, pretty hard to do, because, like, they will be, they will all conflict and that kind of stuff, so how do I figure it out? So with containers, this is actually pretty easy. And it's also easy to manage them. So this is the reason why we are running this course, actually, like, can show you, like, how you can easily run all your, like, all your infrastructure with Ansible. And it's pretty easy. So the important part with containers is the content, actually, of the file system. Like, you can have, like, you can have their, like, various distributions and it's really up to you, like, what's the distribution you trust and what's the software you trust and how the software you get there. And that's actually a bit topic right now, like. So how to actually, like, provide this. So it's, like, basic intro and I can show you, like, how to work with containers and Docker, like, in five or ten minutes. So, OK, so I'll show my terminal. So I hope it's visible. OK, so the command you use when you use Docker is called Docker. It's not so. So there are actually, like, two entities, like, the two important, like, containers and container images. And they are different, actually. So container image is, like, let's say it's a tarbol or an archive with some metadata, which can be, like, somewhere on the internet and you can just, like, download it and that's it. So it's, like, archive. And container, actually, is, like, something similar, but it's already, like, on your system. It's, like, instantiated from the container image and you can just run it. So that's the main difference. So within Docker, like, you can see, like, what images you have. You just do Docker images and here's a list of my thousand images, which I had to pull for this workshop. And the other is, like, well, I could write, like, Docker containers and this was actually added in Docker 1.13, like, they changed the way the CLI is structured, but the former command for that is called PS, like, list me all containers. So it's, like, list or running. So I'm just running two or one right now and if I do dash A, you can see all the containers, which means that I have only one process running, which is the running container and these are stopped. So they are just sitting on the file system and nothing is running and I can just start it with one command very easily. So that's it. So there are also, like, other abstractions within Docker, like volumes and networks and we'll be actually, like, working with that today so I can talk about it. So the way you manage data in containers, like, you have container, you have the file system somewhere and if you store some data, you can easily lose it because the way it should be meant to work with containers is just their fmr. They can disappear, like, any time and it shouldn't break your infrastructure. You should actually have, like, multiple replicas running and some load balancer on top of it and these replicated containers could be, like, disappeared any time and should be, like, okay. So the way you manage data is that you have it, like, somewhere outside the container. So you have it in either a volume or some network-shared storage or something like that and you actually mount the, like, the external volume inside the container. So this is the way you should manage, like, data. So you can do this, like, various ways. So Docker on its own has its concept of volumes. So you can do Docker volume. I think, yeah, so I have some volumes. So these are just my directories somewhere on my system and I'm having some data in there and I know that I won't lose this data. So there's volumes and how about networking? So by default, Docker creates its own virtual network and you can manage your own, like, subnet. But that's just, like, for one node. If you want to have it, like, to spend the network the whole your data center, that's way complicated and we actually won't be talking about that. So that's actually a topic for, like, a whole workshop. So on one node you have, like, virtual network and, again, the command for that is called Docker Network. Yeah, that's the help. So let's see how many networks. So I have some networks there and each of these networks is its own subnet and I can actually attach containers to this network and they'll see each other but they won't see the other containers from other networks. So we'll be actually doing that, like, some of our examples are, like, projects or, like, deployments where they are composed of multiple containers and they will be on one network so they will easily see each other but they won't conflict with other containers. And what's also kind of interesting about these networks is that Docker implemented its own DNS server and if you are running on, I mean, if you create your custom network you have this DNS available within the network and so this is the way that containers can discover each other easily. So if you name your container web so then within this network it's available on DNS on this name. So it's pretty cool, actually. But, again, this is just for, like, one node if you wanted to have overall cluster that's way complicated. So was that, like, OK introduction to containers or do you have any questions? OK, so I guess that's OK. So Peter won't be the answerable? OK. Punget. So now about Ansible. As you might see, Tomászman was using Docker he was using the command line and for every container he created he had to write some command. And in production you probably really don't want to do that because, for example, you have multiple servers and for another case you want to have your infrastructure to be deployed in a clear and automatic manner. Meaning there's less human errors and, like, two admins can repeat the same steps again. So Ansible can do that for you. In this workshop we will be talking mostly about Ansible but Docker has another tool. It's called Docker Compose. Probably you've heard about it. Probably you used it. Another question. Who used the Docker Compose from here? OK, so not that much, all right. So Docker Compose can be used only to manage containers. So you create a configuration file written in YAML and you specify there what containers do you want to have running on your host, what volumes, what networks and, for example, you can also build images from source. Ansible can do the same but with Ansible you can manage your whole host and infrastructure. So, for example, with a single Ansible Playbook you are able to install Docker, configure networking, configure storage and create a couple of containers. So that's like a main advantage of Ansible against Docker Compose. And now let's talk directly about Ansible. I'll go through a couple of key features of Ansible or how to use it. The core thingy or feature or the core stone of Ansible is a task. Everything is a task. Tasks are written in YAML format and usually in YAML files. And one single task represents single action. For example, in this case we want to install HTTPD or Apache package on host. Usually you want to name your task. So when you run the script you see what tasks are running and if there is a problem you can easily identify the problem. And the second part of the task is invocation of module. Ansible has plenty of modules. Its numbers are in hundreds, like 800 maybe more. Some modules are core, some are additional and there is also a possibility to write your own module if you need it. So documentation is available online in Ansible docs from the... This is just... I chose a couple of most used core modules which are used to install packages on Linux distribution. UM is for Fedora CentOS apt for Debian Ubuntu and there is also a metamodule package which works on any distribution. PIP is for Python. File module is used to create and manipulate files. So if you need to create file, if you need to change properties of a file like owner and permissions, you can use that module. Template module is used when you have a template of a file, like some configuration file and you want to fill in with custom variables, you need to use template module. We will be talking about this one. Service module is for managing services on the host. It doesn't matter if it's systemd or not. You can start service, stop service, restart service and stuff like that. Command and shell modules are used for invoking command or raw commands directly on the host. If you need to run a simple command, like, I don't know, for example, if you want it to run Docker pull, we should use command because it's invoking directly the binary specified in the command. But for example, if you need pipes or redirection, you need to use shell command, which takes your argument and run it in the shell. Basically, I guess that's it. Enemously is, for example, module for a network manager, for example. OK, so we have simple task. One task do one thing. And when you want to orchestrate or configure something, you should organize your task in a playbook. Now, playbook is usually a file containing a list of tasks with some additional metadata. For example, again, every playbook should have a file, should have a name, so you know what you're dealing with, and it's always included in the output of Ansible Run. Now, for every playbook you specify hosts where the playbook is executed. It can be, by default, it's a local host, but it needs to be defined anyway, so you can execute your task on your local host or any remote machine. Ansible is usually using SSH for connection, and we talk about, on the next slide, how to configure it and how to tell Ansible how to connect to other hosts. You can group hosts to groups, and, for example, in this example, we are using hosts for host group web servers, which cannot contain any number of servers. Again, on the next slide, we'll see how it looks. Then Ansible can work pretty well with variables. You can specify directly in the playbook or any, there is actually a lot of places where you can specify variables. We will talk about it later again, but in this case, let's say that for this specific playbook we have two variables, and we want to specify them here. Now, yep. Are variables lower to the playbook or are they local to the task they are for? Yeah, can be both. In this case, they are local for the playbook, so every task has access to those two variables, but you can also specify variables for task or you can specify variables for hosts or for group of hosts, and then every task has access to all variables for the group or host. Yep. So, if you have any questions, any time just ask, one of us will definitely be able to answer. So, there is also one example of one special task called Handler. In this playbook, we are installing Apache, configure it, configure the service, and in case the configuration file is changed, we automatically restart the Apache. So, first task is just you. As we talked about it, we say, please install HTTPD package on the host. Second task creates a configuration file from template source of the configuration file is usually on the host where the Ansible command is running. So, usually you organize your playbooks in a way that all the configuration file is on the same place with the playbook, but you can choose differently if you need it, right? So, the template file takes the source of the configuration file from your, for example, localhost copies over the destination machines and create the destination configuration file by replacing variables. In this case, we are assuming that HTTP port and max client variables are used in the template configuration file. We use notify to mark that we want to use Handler. Just name of the notify and name of the Handler needs to match and basically that's how it will find the correct Handler. And last task is about the Apache service where you want to ensure that Apache is running and enabled at boot. That's it. Questions? Yep. Yes. This is the configuration file is YAML and in YAML this is how we write arrays. So, you can have multiple lines and every line starting with another item in the array. The other part is referring to the name of the Handler. Yes. Yep. Name of the Handler is YAML. Do you make any of that? I guess yes. But there is a new feature in Ansible, I think 2.0 where you can also specify for Handler something like listen and then you can use the listen name in notify. So, one Handler can be called by multiple names. It's a little bit more powerful than shown here. Like a subscribe from... Yes, subscribe and notify. Yep, exactly. I also have questions for you. So, does anyone have issues with pulling the images? Because I can save them on USB and you can load them within your local Docker engine and you don't need to pull them. So, is anyone... It's a bit slower, it's normal, yes. Yeah, okay, so I'll do it and I'll pass you USB so you can get it from there. Can you fill in your platform? All right, so this is the play. Thank you. Any questions to the playbook and players? Yep, all right. Yep. How do you behave with some of the data plus the sound play? The playbook will stop and error. You can... Do you try to type of this task again? Yes, you can configure that and you can also configure that for every task there is set of attributes. We will be talking about it, but for example, one attribute is ignore errors. So, you can, if you set that attribute to true, even if the task fails, the play will continue or there is two other attributes, there is like until and retry and you can create some conditional which will be checked for true and until the condition is not true, the task will be repeated over and over. So, for example, if you need to wait for a web server or database or something like that, we have examples and we will be showing them. Just to clarify, so by default, let's say there were five web servers and no more tasks will be tried against the failed host or the other four hosts will continue if they continue to proceed. Now, at the end of it, we'll get a dump for you that would be the failed host so that you could re-apply the same playbook called the doled host. Any more questions? Nope. So, now the inventory and here we see how we specify the hosts. We want to apply the playbook to. Inventory is a file, it can be static or dynamic. We'll be talking about dynamic later. This is an example of static inventory. So, first part of the, or one part of the inventory is used to specify how to connect to the hosts. In this case, we just take some host and name it with full, it's like an alias and we specify that host of these hosts or URL, how to connect it is food.example.com. We say that Ansible port is meant by SSH port is listening on 555 and Ansible user is sent those or something, right? So, you can specify the connection parameters for any number of hosts and aliases and whatever. And the second part of the inventory is specifying groups of hosts. In this case, we specify the group web servers and we put a full host in it and something called www 01 until 15.example.com. So, you can save some typing but by expressing this kind of stuff. Other type of inventory called dynamic is used, for example, for cloud providers. It can be used for doctor. It's usually a script, which returns JSON. JSON output, it can be written in any language, doesn't matter. And it queries the provider and outputs all available hosts there with some groups. So, if you know GCE or AWS, you know that you can tag your hosts there. So, for every web server, you add a tag, for example, web server and with dynamic inventory, you can query the GCE to return all hosts in a group web server. And we have some example and we'll show that. Now, Ansible knows a couple of control structures which can be used in your playbooks. Here, we have conditions and loops. As you know that if you want to install a Apache in Debian and Red Hat distribution at the same time, you will have a problem with package manager and package name. So, in this case, we have two tasks, which do the same thing, but the first task is run only Red Hat family of distributions and the second one is run on Debian. So, the when and with items are the parameter or attributes. I was talking before about which can be used for any tasks. There is multiple of them, multiple of them. And when is just really simple conditional. If the conditional evaluates to true, the task is run, if not, the task is skipped. That's about it. Ansible always family variable. Ansible contains something called like facts, which are evaluated for every host. The playbook is running for. So, the facts are gathered before the playbook is run and you can use these variables about the host in your playbooks and tasks. The facts contains a number of variables about hardware, about network configuration, about the operating systems and whatnot. You can also define your custom tasks if you need for your applications. So, Ansible as family variable is automatically determined. Then we can see, yep. How do you catch your facts? If you want to see the effects of the host, you can use a setup module, which we'll show them to. Or you can print a vars variable. I think vars contains. So, there's no factor or something like it to show your? I think there is also no factor. So, implicit in every play in a whole setup which gathers facts. So, for every host in the play, we'll gather disk information, network information, seeding information, memory information, very similar default set of things that you might find in something like Factor. You can disable that behavior with gather facts, false, which would be necessary in some cases. But, as over each play, it will gather a default set of facts and you can create plugins that define additional fact gathering tasks to run with the ever-synced applications. All right, so. And from command line, if you want to show them, you can use invoke the setup module directly. Which will print all the variables from facts to the command to terminal. Any more questions? Yep. Is it possible to know this decision in the table? Yeah. There is something called roles. We won't be talking about them because it's too difficult to discuss, but you can organize your configuration. Let's say, in a roles. Roles is something like, can be set of tasks. For example, a role to configure, a patch role to configure, MariaDB, and so on. And this role contains set of tasks. Role can contain files, can contain templates and variables. And in playbook, in the end, you just include roles and specify some couple of specific variables if you need to. It's documented on the Ansible website. It's kind of a big topic, but. To galaxy, galaxy.ample.com. There's over 9000 roles that have been contributed by the program. So if you start writing playbooks and you want to see how someone else has done something, like installed Apache or NGNX or whatever, galaxy is a good place to take a look. You can download those roles and use them with your own playbooks and infrastructure. Yep. All right, so. And about the loops. Here's the most, probably most commonly used loop is with items. With item contains array of, in this case, package names. And in the task, we have a variable called item. This is how you invoke variable. Item will be replaced by one of, one of the lines from here. And the task will be executed like every, for every item in the list will be, the task will be executed, right? So usually this is better than writing multiple tasks below as this should be efficient and much faster. Redefines. Yes. Item is defined by with items loop. It can be changed or redefined if you need to. How we define the ansible voice harmony? Why do we check how to see that ansible voice harmony read platform? Yeah, the ansible voice family is automatically evaluated by ansible. It's part of set of facts which ansible is gathering about every host of the playbook is run on. Also, there's one thing. If you want to use variable in task you need to use this double, double bracket. But in a when, you don't. So in when you need to specify that this is a string, so you need to quote it and this is a variable. So you don't need to do anything about it. But here, this is assumed that that's a string by default. And if you need to variable, you need to explicitly set variable. All right. I guess that's it. Any questions to this? More, any more questions? All right. So, something more about variables. Here we can see two examples or multiple examples of variables. Epic Listenport is a simple integer variable. It's just a number. Epic Sheet Warehouse is an array of maps or array of associated arrays, how you call it. The dash represents or represents starting of a new item in an array. And there is a simple key and value stuff for the map. In this variable, we specify like two server or two virtual hosts with attribute server name. One is GoExample.com another one is RustExample.com and we also specify document root. Then, we are using template module, template enzible module to create Apache configuration file. So, the template is stored in a t-folder slash httpd.j2 template file on my host, where I'm running enzible. It will be copied to the destination host and it will be placed in a file marked in an apache underscore conf variable. But if this variable is not specified, the default will be used. So, enzible is using Jinja2 for variables and templates. And basically, you can use all features of Jinja2 in enzible. This pipe is called filter. There's plenty of them. You can find the documentations on the enzible site. Besides default filter, there is filters like Min, Max, join for joining lists and many more. So, is this clear? Okay, so now let's check how the httpd to the j2 templates look like. Again, it's the Jinja2 template. The first line is just a comment. Now, we are using here mainly this apache v host variable. So, first loop is for every item in apache v host. It will create the virtual host directory for apache. There are apache list and IP variable. Again, if not defined default asterix will be used and apache list and port. And the server name is defined by vhost.servername. So, it will take the item for a single item in this array of the first key or the server name key. There can be also used conditional. So, if this variable is defined, this block will be present. If not, this block will be skipped. That's it. Questions? If you use the Jinja is used mostly or it's originated from Python or it's used by Python frameworks, it was used to render HTML web pages but it's really powerful and can be used for any templating whatsoever. So, it's a pretty neat feature of Ansible. Okay. Now, that's probably the theoretical introduction to Ansible. Now, we will start working directly with containers. Do you have any questions to what have been told so far? All right. So, for now on, we will be talking mostly about these four Docker modules. They are part of the Ansible. So, if you install Ansible, you have available them. The container module is used for managing containers. So, you can create, start, stop and modify containers with it. DockerNetwork is used to manage DockerNetworking. DockerImage manages DockerImages and DockerService is used for compatibility with DockerCompose. So, if you have already created a decompose file or some projects on GitHub has specified the DockerCompose file for the application, you don't need to recreate the configuration for Ansible, but you can use DockerService module, which just accepts parameter to do DockerCompose file and it will consume that and create the container specified by DockerCompose. Documentations there. And now, we should probably start working in the console. All right, so, we will be working with us. We will be showing the examples directly in the command line and we will be showing the examples live. Is anybody here who will be doing the same? Okay, great. Do you have the images downloaded? Not yet? So... So, I'm still trying, in five or ten minutes it should be there just like super slow to copy all the content from hard disk to the flash drive. All right, so, I'll start with a couple of simple containers. Basically, here, we can just see how the structure of the playbook with DockerContainer module looks like. This is a playbook. So, there is a name, there is a host. We will be doing everything on the local host, but you can easily use any remote host just by configure it in the inventory file and change the host attribute of the playbook. And there is, in this playbook there is single task which will create first simple container gox. If you know it, it's alternative to GitHub or it's kind of self-hosted GitHub written in Go language. The first parameter of the DockerContainer module is name, which will be name of the container, which will be created. Image just takes the image name and tag of the Docker image you want to download and use. State, almost every task or almost every module in Ansible has a state parameter which defines if the item created by the task should be present or absent. In this DockerContainer has two mores. It's stopped and started. So, state absent will ensure the DockerContainer is not present on the host. If it is, it will be removed. If not, the task will do nothing. Stopped ensures that the container is present on the host and it's not running. And present means that the container is present on the host and on the host and it doesn't matter if it's running or stopped. And started means that the container is on the host and it's running. Published ports and volumes plenty of attributes for the DockerContainer Ansible modules are similar to the Docker command itself. So, in this case, it's published ports similar to the P option of Docker run. And you can specify here just the port on the host and the port in the container which will be connected together. You can also use slash UDP, whatever, like you would do in the Docker run command. Volumes act the same as the V option. In this case, or here in YAML, you don't need to specify multiple, like volumes, double command volumes, again. But in single volumes you specify multiple volumes separated by dash. It's representing array. That's basically it. So now let's try to create some let's try to create this container. This is the repo from the GitHub where we have slides. There are also all examples prepared in front. So you can check them later or if you need to check something and it doesn't work for you so you can see there. So I created a new directory workshop and here I create a simple playbook, let's say. YAML files are the three free dashes in front represents something like a new document in YAML. I think it's good to have it in every file defining this is a new document but I don't think it's required, don't need to do that. So I do I name my playbook, something like my Gox I say host is localhost this is required even if it's localhost by default if you don't create a new if you don't create any inventory file only localhost will be always available. So we don't for localhost you don't need to create you don't need to specify you don't need to specify inventory file just use localhost. And probably has some additionals to easy with the task of writing the YAMLs. So you are using a plugin for Vim? So this is Vim with tons of plugins. YAML is very hard to type from scratch. Yeah, you definitely want to use some some coloring for that but it's definitely much easier than XML or JSON. So think about that if you sure. For example this is this is Tomas notebook and he's using this supercharged Vim. I'm using Atom editor and it's if it's not there by default you can just install plugin it. I think when at least mine on better on 25 already has auto highlighting syntax highlighting on 3 YAML files. One single space under in the wrong place and the YAML Yeah, yeah. I'm using in Atom I'm using the white space highlighting so I see so I would see a dot here and I see like and there is also the lines so I know that it's correctly aligned now every task or every module can be written in two ways as we saw before for example for YUM I can do I can do this it's good for for short for short tasks to just put it on one line but sometimes you might need some modules need a lot of attributes so you need to so it's better to put it on multiple lines and when putting on multiple lines it's the syntax is a little bit different in this case like this now this is a string I don't need to quote it it's automatically a string but if I want to use a variable instead of this for example I want so I would somewhere have defined apache package a variable it would contain HTTPD or whatever so in this case this wouldn't work because you can't start start value of the attribute with this curly braces you need to quote it right so this is a problem of YAML you need to do this otherwise it will write an error for you but it will in the error it will be written that you should quote the variable name so it's not a big problem you can use something like prefix for the variable so it will be my dash content of apache package variable and in this case again you don't need to quote it it's magic so now to do the carry container module name let's oh let's do it this way if you want to specify variables for a play you just add additional additional attribute for the play so attribute variance is a map so it doesn't take array of values but you can just you can just start start without the dash right so so i already have the images on the flash drive so does anyone need them also another attribute in Ansible or in YAML variables and variable names cannot contain dashes only underscores so this is a valid variable name this is not there might be problem if you use the dash so you always have to use underscore in the variable name so we create the carry module with attribute name but name is specified by this variable present we change to start it and also the variables in Ansible are pretty there can be overridden and so on in this case i'm writing my this is my playbook and i want by default that container created by this playbook will be named by we will have named my gox but when i'm running the playbook i can override the variable name on the command line if i wouldn't use the variable here i couldn't change the name from command line when running the playbook but when i use the variable i can alternative if i would like to have the variable but i don't want to specify it here i can use the default filter it would look like this ok in this case i don't need these two lines but i guess this is better because you can see when opening the playbook you can directly see what variables are used in the playbook and you can easily change them from command line if needed to so name started let's specify image image is 0 0 9 3 and from the documentation of the docker image on docker hub by inspecting docker file you can see that this image is using two parts so i'll use for host i'm going to use 1002 and for web interface it's port number 3000 alright in this case i'm using again quoting because even if it's string or it's expecting string or numbers there is a problem with semicolon because semicolon is important to yaml and if you have a string which contains semicolon you need to quote it that's it and for volumes there is single volume of data so let's say i want to associate the volume name with content name i'll use it as volume so basically this is a really simple playbook now i'm let's say i want to test the playbook out so i have a playbook playbook can be run with ansible playbook command i have an email there ansible playbook command and it just accepts the one required parameter is just path to the playbook so this is how i run the playbook and that's it i have running container i have more running containers but the second one i didn't create uh no so we have the gox container running and v somehow and if i open localhost on port 3000 i see installation of the gox so you can if you want to try play with it you just change the database type to create the container and you can configure them play with gox so now we have a simple playbook let's let's update it a little bit for example now i can create a container but i have no way how to stop it without modifying the playbook so to help with that i'll update i'll update the playbook and i make a state parameter a variable so i want to use prepared but i use something like c state alright and again by default i say that c state is started now what this what this can make me or why this will help me so now when when running the playbook i can redefine the c state variable and i say that c state won't be started but absent and now the variable will be modified will be overridden overridden by value from command line and the container will be removed alright does it work for you sure again if you need to look how it's done check the examples folder in our repository there the playbooks are a little bit more complete but you get the idea ok, i'll show some i'll add some additional or some useful attributes to the container now when i run the playbook every time the car module will check if the container is present and it started and it will do nothing but i want a behavior every time i run the playbook the ansible will check if there is a newer version of image available and it will download it for me so to do that there is another attribute called pool and if i change it to true ansible will automatically check for the for the newer version of image if new version is available it will be downloaded and the container will be recreated the old container will be deleted and you will create it so you should definitely check that the volumes that all the persistent data you have in the container are mounted to the car volume or to some path on the host now there i have some ok so there is also there is also useful attribute called restart policy it's the same as in the docker run command if this you configure docker demon to to ensure that this container is always running it's good for basically any web service or database or any service which should be run because it can happen that there will be some kind of error in your application it will crash or it will leak memory and it will eat all memory and docker will kill it if restart policy is set to always once the container crashes docker will start it again there is great documentation in ansible on ansible sites pages it's called docs.com and basically go to module index the modules are divided in categories docker is in the cloud category you open cloud modules you go you look for docker see it's oh here it is and we are using docker container module you can open it and here you can see all the options if it's required default values description also thing is that for every module there is also example sections so you can see how the attributes are used because sometimes it's not clear or you are not sure how to format the more complex data for example networks networks might be a little bit confusing but here you can see that you specify name and attributes for network now the good thing is that now we can we can start and we can also remove the container but but the volume created by this container won't be removed when the container is stopped it's because the volume contains probably important data and by default it's on the host so because we are using Ansible we can do various stuff with conditions and tasks so let's add one last feature to this playbook let's say let's define new variable and by default it will be false so now or maybe put it here so we don't need to define so we don't need to specify two variables to remove container we can update the default value of C state variable so it can react to the state of Vibe variable so instead of started we fill the C state variable with some value and we say that the value will be absent if Vibe equals to true else it's started so we can use this tertiary condition or how it's called shorthand if and we specify the value if value absent if some condition is true otherwise the value is started so by default if I don't specify any value for C state or Vibe variable the C state will contain started value started if I specify Vibe true the C state variable will contain absent now it would be enough to this if Vibe because Jamo knows the boolings but when I specify the variable on command line and I use the E option the true or false command or the string will be evaluated as string so I can't somehow pass the booling from the command line so I need to do this ok to be consistent I might use to use the false as a string by default it depends on how you are using the variable so and now the docker container yep Vibe was for the volume of Vibe for now it will just remove the container but I'm going to add another task which will remove the volume as well yes the image will stay the docker container module works only with containers and with images only if the image is missing it will be pulled and if I specify pull true and there is a newer version of image it will be updated but otherwise it works only with containers if I want to manage images I have to use the docker image module which can remove the docker image or solve it so now I have prepared Vibe variable and I add additional task I don't know its name I also it's too smart for me docker ansible contains the 3 or 4 ansible modules we are going to use but none of them is for managing volumes so if I want to remove volume I have to like I have to use command module so basically I want to delete docker volume I just use or the command which I would use from terminal so let's docker volume I guess REMA and basically I'm going to use this here and as the the variable is not starting attribute or value I don't have to code it and I specify the condition when this command is run and it's when Vibe equals to true and that's it so to test the module to test the playbook sure sure so I have a question so is there a filter to convert the true to boolean I think yes it should be if this would be boolean I can also use just if Vibe or if not Vibe but I can't specify the command line because it's broken but definitely it's easier to use string because you know a string yeah it's definitely more robust because or you can use just 0 and 1 for example but again there are numbers and there are strings for example in this case I think the scene name must be string because if it would be number it might not you that it can concatenate number and string or stuff like that it's from python so it's similar to python so let's check the playbook I removed this variable I'll try to make it the first vining is that there's missing inventory file so when the locus is available and here we can see that the setup task is gathering the facts about the host there is task gox container it was changed and the container was created and delete the care volumes were skipped because because the conditional in when was related to false now if I run it with variable true I can see that the docker container was probably it was removed and also the docker volume was removed as well nothing is running and there is also no docker volume so basically we will be using this approach for the rest of the examples also this approach is used in the examples directory of our github repo so now you know how it works and you can easily use them and also remove the examples from your from your host we won't manage the container the care images because basically we don't want to remove them as you might want to try to run the example again stuff like that you could use the the same approach as with volumes but you don't have to use the command module but you can use the docker image image module configure name and the states to absent and the image would be removed so it would be good to take a short break so let's say we will be back at 12 so it's 12 minutes we can take a drink or whatever at 12 we will continue so here we define this image because i like it very very soft just i like it yes you can also use the like but if we define as the like that we will download the like that we do version which is in this around in the second one when we get the like in this example in example i have the version in example 0 and as far as image is like that 0 download the version 0 higher it starts with the lower higher so if you download for the first time it depends on the pull so if its pull is false and the tag is everlaver on my house it will be use the image on my house and yeah so because latest the text like the text in docerimetry points to a specific image and one image can have multiple text so it can work so if on your house you have 0.8 and you use this playbook without pull and it sees that it needs to take 0.9 it will download it so it matches the exact time so it's not available it will be pull if it's available it won't be pulled and if you specify pull it will check basically for my they have a good text but plenty of images have only latest thank you very much to to no to to to to to to to to to to to to to to a do do to to to no t incubate to to Tohle ty jsou solitori, čo? Hej, hej, hej. Já nevím, já se nedělal. No tam po coji to právě nefungalo, když jsou větká vysvědět, takže jážem pokazem. Ale tak tom, když jsem tu zkušel, tak to jsem mohl, tak se už nedělal, když jsou v rozním verzi, a mi to bylo rozný, tak to bylo. A jste větká, co jste? Hej, pět, jste ráko, kdo ještě závědět, skoro jsme dvaja. Požel jsem, že je to pár vrátka, kde jsem větká. A kdo ještě závědět, či tu bylo? Hej, to bylo koholik, kdo ještě závědět, kdo ještě závědět, čo ještě závědět, jak se vidět, kdo je závědán, co je, co je, co je, co je, co je, co je, co je, co je? No, hej, no, si bylo, no, ne, ne, ne. Jak se větká, tak se se větká. Skuarně, že by jsem velápil, tak jsem nejvíš pokud. Jak se podaji, tak si včučí někedy, když je to pár dětně, no, pár dětně. No, pár dětně. To by bylo, ale to bylo dobro. Tím nám pár hodince, to pár dávětšep zase mám se tu urná stará stupení, že to bylo v této rádná svům rody, jak se to jim roci pílo, ale mám ten stupení, A čina tak skoro? A čina tak skoro? Vy pí. Nechcmešte nějedalo. Na takovéhce nemáte čas. Na takové cíjakovéto nemáte čas. Klub sus, který si nemáš doložit. Díky, můžu na svoho pláty. Čodorát, můžeme tím tásku? Dásme? My požíváme ansibus práci, co jdeme neželení asi 2-3.000 rostovů. A potravoel by som vidět. A ako můžeme si urobiť také alputné lepšita vůlkustí. Može kterým spoustím playbook, tak to prvujeme dědatou mohou s těchto hol. V spektueli to by jen z hodstv, ale to prvujem vidět akom stavé. A co myslíš jako ten stáv? To je to, že succeed, fail. No, tak to ti píše by the phone. A kdy dáš ten... Tak, ale na konci je taká táto. A tu je, že tu jsou všetké hosty, a je OK, če nejdeš to, han říct, že byl fail. Ano, to jo, ale když máme píkat, byla táskou za sebou. A ty by si chcel, aha, ty by si chcel jako řečo, pre každý ten tásk? Labo to to je státáv pre celý playbook. Já potrebujem pre celý playbook, tak by mi to, aby sem nemá vypísnit na 10.000 riasov. A při takom tom nostvě už odporučáme Ansible Tower. Tamto všetko, takže to je... Věžš, čo to? Takže tam vidíš tě stávy, vidíš tam, možeš tam filterovat hosty a pracovat s tým inventárom. Skedulovat tásky a tak. Pritom, hej, už když tam máš fakt, že 2.000, tak s tým Command Line-om, že on nevěfiltrvat ten tak. Myslím, že tam si věž, že zobraziť, chybne, nebo tak. Takže tady? Pritakom nostvě už bysom chcel do toho. A hlavně tam je ta výhoda, že to máš centralizované, hej. Když použíš, jakože ten největší prínus. Když pracuješ s tým to Command Line-om, tak tě playbuky máš na tom svojom hosty, hej. Alebo tam, kde to spůštáš. Takže bude, máš v práci jeden server, kde jsou playbuky i boudt těl, a všetci adminí to od těl, půštejů. Ale stále máš problém, že kdo kedy pustil centář, tak musíš to nějak auditovat, keď se, že je výtory důžívatelou. A keď máš ten tower, tak to máš všetko centralizované, máš tam audit, máš tam všetky logii, ježdu se prihlásov, kdo kedy spustil té zábuky tima, že neká automaticky, tak máš také, jako je to pravět sprát ten enterprise a hostou už, jakož si ti dovolávčí. Dobrý, děkují. Všetně, dnes mám. Ať mi, jak to vám, alebychom, bychom, bychom, abychom j недláka byiente, podradev se ti jednak vндřer, Máte si vám to tam, jak to bude skupené, můžete to skupené. Máte. Máte tam, že máte. Já si mám. Aha, to děje, ale tak si mám to. Mále bych mohli být větší. To být karmory, ne? Jojo. Samo vezněné. Zájtravu penšiv snadží si, když jsi hodná na pínku Máte. Neprču myslí, že jsi hodná na pínku Máte. Máte, že jsi hodná na pínku Máte. Máte. Máte. Máte. Máte. Zájtravu penšiv snadží si, když jsi hodná na pínku Máte. Máte. Máte, že jsi hodná na pínku Máte. Máte, že jsi hodná na pínku Máte. Máte, že jsi hodná na pínku Máte. A na mě to bylo hodná na pínku Máte. Jojte. Moje hodně. Tak to je to, co máme povídnout. Zájtravu penšiv snadží si, když jsi měli mu tomu. A when you open Github, you see a structure of the roles. The roles in AIS recite have a predefined structure, which is like best to use. U výzvobný spport je děláto dásk výzvob, které používá obáhu main.ymu, které je výzvobný a přesně děláte jak proměžujete ril. Here we can see what is going on. He has separated his role into multiple playbooks. We separated by a thing system family. Když je redhead, to je... Proste? Zům... Zům in? Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... Zům... takže je to příjde srátný. Generalně, když se zvukujete, když se či je největné a největné třeba se vyštěli s těch výjvům dělávom. Jo brzez je můžete vytvořit výjvům výjvům vyskodí, co jsou vyskodit až vyskodit, jaká jestli jste používávala vylíků, odvěději, které je nejlepší. Féproč světe výjde, ale když máte vyskodit, když jste používávala, když jste vyskodit, když jste vyskodit, když jste vyskodit. Vyskodí si to vyskodit, když jste vyskodit. Já nevím, jak se to děláme. Tak. Vypadáme. Vypadáme, nevím, jak se to děláme. There is an example showing how to create multiple containers with one module or one task. If you have a role, you can include a single role multiple times with different variables. If you had a role for creating a Gox container and you would have a name for the container specified as variable, you can include the role multiple times with different names. Basically, if the name had to be unique for a host, because if it's not, the multiple tasks with the same name and the same module would work with the same resource. You can create one task, which will create a container with state present or started. Another task will be with state absent. If you run the playbook, the container will be created and then removed. This is different from Puppet or Chef, because they are, I don't know how it's called, they are pool models, right? No, no, I mean, in Puppet you describe the final state and you can have one resource with two different states in the end. But Ansible is linear, so it's executing tasks one and another. In one task you can create resource and in another task you can delete the resource and the playbook will execute successfully. It depends on the module, no, the name of the task, like this, this can be the same, it doesn't matter, it really like prints to the output when the task is executed. But the name in the module should be unique or it doesn't have to be, but it will always work with the same container. For example, you can have a playbook with two tasks, for example, for some configuration container. In one task you create a new container, in second task you change some configuration in the containers, for example, in a volume. In a third task you can remove the same container and the volume will stay, for example. And in this three tasks you use docker container module and all the time the name will be the same, for example. So if for two tasks with the same module is the name the same, the tasks will work with the same resource. That's what I wanted to say. But that's not an error, it's perfectly fine if you need to. OK, I'll show one more example and then Tomáš will show you how to build images. The reason why I wanted to show you about roles is that I have another example and I'm just including files. I'm not using roles, but if you need to you can use roles. All right, so let's create a new file. It will be, I don't know, the application is called MailPile, it's an email client you can use. Basically, name of the task is the container. And here I'm going to, at first, I'll just write a task to a file. So it's not a playbook, it doesn't have the host attribute. This is just a task, which will be included in a later in the playbook. So name is clear, the module is the container name here. So if I want to include this task multiple times, I definitely need to have name as a variable. Images, oh my god. I'll use the latest type because probably there are no others. State, again, I'll use a parameter. OK, so another thing. As you know, probably you are using the, if you want your container to be accessible to your host or outer network, you want to use, you have to use the port for writing. But for multiple, if you want to create multiple containers from the same image, you need to use different ports, so the service is available, right? So again, for publish port, we also need to use variable for ports, so we can change, so we can change for multiple containers various ports, right? There is also a volume. Again, volumes is another thing, which needs to be unique, right? So we use the variable from container name to different various volumes. The Z, do you know what the Z means? All right. Yeah, signage policy. If you are running as a Linux in a sourcing mode and you want specified Z, the volume won't be labeled in a way that the container can access it, so it will fail. But in the later, I think this was before, and in the latest, Selenux policy is updated, and you don't need to specify the Z. But in case you are running Selenux in a sourcing mode, what you should, for now you should specify it. All right, basically that's it. So we created a new, it's not a playbook, it's a file with a single task, which will create container according to our variables. And now we will create a new playbook, and there will be name, for example, hosts, localhost, and here. So, again, tasks attribute of a playbook is, again, a simple list. So, yeah, basically that's what I want to say. I can put in a file like separate tasks, and then include them. It's basically, it's a directive, it's called include, and it contains parts to a file, which is, hopefully, oh, výkřešek, vymel palium, all right. So, now, okay, so this will include the file, but we don't have a variable specified, and if you don't specify them on the command line, it will be, it will, the play will fail. So let's add a couple of variables to the play, and let's say that we specify a variable content, and it will be an array of maps, and, for example, I specify name, one will be John, I don't know, port will be, and another one will be 4B. So, also, I'll need to specify variable since they started, and when I include the file, it will be executed once, but I want to create multiple containers from that file, so we will use the loop with items, and for the array we use our containers variable. Now, if we want to specify additional variables for a task, we can do it, again, similarly to how we are specifying tasks for playbooks, so we just add additional attributes to a task. So, we have a task, a task has attributes, and also module has attributes. In this case, I'll show you, so, it's not visible, it's easier, but I'll do this. So, the task starts at this level, and the name attribute of task is this, the module of task is here, and this is also the attribute of the tasks. The signal error is for the task, and the doker container is module, and all these attributes are for the module, so task and module can have separate attributes. So, here, we added attribute to the task, and we add another custom variable to the task. So, in this case, it will be CNAME as specified in the mailpile.yaml file, and it will be, let's say, I want all my containers named mailpile dash item name. So, the items loop will create, for every invocation, will create item variable, and if it's name, if it's map, I can have all the attributes available inside. So, for the first invocation of the loop, the name will be John, for the second, the name will be Pete. Also, I need to specify port, so I use the C port variable in the mailpile.yaml, so I'll configure that, and it will be 10.port. So, now, I separated the playbook into two files. One is creating the containers, or it's really a file of tasks, and in the playbook I included that file of tasks, multiple times, and that's it. This is just a string, it's not a variable. This is just a string. Variable starts here. The item name is referring to the names in John? Any more questions? Yeah, sure, no problem. Also, these variables from here, as they are playbook variables, will be also available in the tasks inside of the mailpile.yaml, so I don't need to specify here the C state variable, it will be taken from here. And again, if I specify it on the command line, it will be propagated to the task inside. So, let's try. Here we can see. I don't know how this works. That task create containers was included mailpile.yaml twice, and here we can see output from each inclusion. Right? So, yes, we see two containers, and the name is mailpile.p, mailpile John, and the ports are also different, as well as Docker volumes. OK, so, OK. Mode mount, data from the Docker host into the Docker doc container. Volume and bounce mount. So, the difference is that, like volume in context of Docker, like if you do Docker volume, so, Docker has its own storage where all the containers and images are stored, so it's like varly Docker, and there is a special directory called volumes, and if you do Docker volume create, so it will create a new directory in there, and then it uses it as the volume. So, Docker volumes are like using Docker, like structure, and bind mounts, you can actually just bind mount like whatever directory in your system inside the container. So, that's the difference, and this is how you actually specify it in the, not here, so what was it called? Yeah, so, this is where you specify it, like right now it will be expanded into like by something-data, so that's like name of the volume, so when the Docker figure is out that okay, this is a name of a volume, doesn't, there is no such volume, so I will create it, and I will mount it inside the container under this like path, but if you start it with slash, or I think that even with dot, but I think that it has to start with slash, then it means that it's just bind mount and you can put like whatever there. Yes, exactly. Yes, you can safely do it, but you can do it easily, but there is no like a race condition check, so you can overwrite the data from container, one container and it will be changed into another, right, so you need to, or if you are editing the same file from two containers, you need to know what you are doing. Also you can mount the volumes and bind mount with read only flag, if it's a configuration, so you'll be sure that it's just the configuration and it won't be changed from the container. Yes. And last question, which subject we should search in the documentation to have some kind of shared storage between containers? Ah, because you said there isn't a race condition. You need to use file system, which supports that, basically NFS or Blaster, save as file system, which can be used in this case. So, yeah, you can definitely search for like volume plugins, so Docker has actually like plugin system for like many stuff and one of them is volumes. We are using plugin, which is called local, which is just like create the directory on local file system and mount it inside, like nothing special. And there are other plugins, so as Peter said, some plugins are like store the volume in Blaster, store the volume in Fluendi or something like that, so you can use something like that. And to your question, just read only. So if it's just configuration, you don't expect to be changed, so it can be read only and you are fine. And if you want to see actually what's inside the volume, you can do something like this. So you just do docker run, dash t i, which means like I want a shell there, so like allocate the terminal. You just specify the name of the volume and just path when you want to mount it so I can do CD, ASD and I can see like there is something, so let's see what it is and there are some files, so I can see what they are even I can change them because it's read write right now. So this is like good way to see what's inside the volumes. I mean the other way is to actually like go to varlib docker fumes. Aha. But it's like you can even access it. You need to be root to access varlib docker and it's like internal structure. If you change something there, you can basically break it and you have to like corrupt it, so definitely like mounting the volume inside the container, it's like preferred solution to see what's inside there. Also it's in a really a similar way if it's docker volume like critical difference. If the folder in the image you are going to use as a volume, contain some files and you use docker volumes, docker demon will copy the files from image to the docker volume. But if you use bind mount from some path from host, docker demon won't copy those files. So we need to this is like docker volumes or as difference besides that the docker volumes are always in varlib docker volumes. Sure. I thought that we would have volume here that I would show you, but I don't have it. Dobrý. OK. Did you show the various files for a second? Yeah, sure. I'll show you the other one. Yeah, so right now I will show you how to manage images. It's actually quite simple. And then I'll show you other like pretty complex example which will be like composed of multiple containers which are linked together. It's like one of them is like web. The other one is database and there's also like engines to proxy or the connections. So did you manage to make it work? No. OK, so let's start, so I'll close this one and yeah, so what we'll be doing is that we'll be deploying Ghost which is blogging platform written in Node.js just like whatever let's do this and I mean the image is available under like Ghost but I didn't realize that so I created an image on my own so I mean it's really up to you. I mean if you trust the content which is on Docker Hub feel free to use it but if you are paranoid like me just you can package it yourself it's not that hard and we can go through like very briefly. So it's based on Fedora because that's what I know. Then let's start with OK, so Ghost is in Node.js so we need like Node.js and NPM and that kind of stuff in the image so we installed it from the standard repositories and this flag means that don't install documentation because like we don't want to have like tons of useless data inside the container and to waste our storage I mean for development it's really OK to like install anything inside if it helps you with development or for production like install as few as possible or get as few as possible data inside the container so we are installing NPM Git which is like obvious unzip because it's distributed as zips and get text I'll get to that that's kind of interesting and yeah we will clean all the metadata from the package manager our application will be in slash app which I mean if you prefer something else it can be like slash opt or up or something like that so the way the software is being distributed is like you download a zip file you unzip it and that's your software which is kind of weird to me I tried to install it first from NPM but the thing is that in order to run it you need the package.json file and I was not able to figure out where it is so I had to download the zip file and unzip it and that's it so Peter even improved this docker file to make it like really great that he removes the archive from the container which means I mean if you don't do this it will stay in the image forever because it will be in that layer and you can't remove it in the subsequent layers but if you do it in the same layer it means that it will be removed in one linger in the final image so and that's also why this is written on a single line basically so that all the operations are within the one layer and there's just the like application like explode it inside the inside the directory and finally we have some custom configuration we'll get to that and it's running on this port and we are using custom script to start it and we'll get to that later I mean I can show it yes it's this one well since I opened it so I'll tell you what this is so the so this command comes from the get text package and what it does that it's unlike the templating with enunciable so you have a template configuration file then you have some variables and you want to fill them inside the configuration file so you have your customized configuration that's all that is but unfortunately if we wanted to do this with encible we would have to have encible inside the container so it means Python and encible and all these dependencies I mean it's definitely doable go for it if you want it use less I mean it feels like a lot of these pegs so if this solution is ok just use this simple package to fill in the configuration it's like ok no no there are two ways this is the simpler one from the get text package and it just replaces the variables in batch format the same variable or dollar, curly brace but there is also on pypy there is nvl tpl utility which is which is used the same way as nsubst but it works with Jinja so you can have really powerful templating features in your container if you need to and I don't think it's available in federal repository you need to use pypy to install it ok so that's the templating and finally to start the application you do this with npm start production it's like that's it and the exec is here for so if you do it without exec it means that the process tree within the container that you will have batch which is like executing the shell script and then you will have the application server under it so it means that if you want to control the container batch will eat all the signals and they won't be passed to actually to the npm command so that's and usually that's not what you want so exec means that the npm process will substitute the batch process so you will have only a single process within the container and if you are interested about this kind of stuff containerization I have a talk on Sunday so feel free to take a look ok so that's it let's build the thing so I already have it written in examples so we have 40 minutes and I will run the I will show the example and I will run it and then we will work on the on the playbook which runs all the things so the building is not very interesting so so it's called build yeah that's it so we will actually be building two images we will also build engines and the reason for that is that we will be using the engines Docker image from Docker Hub but we have our own custom configuration like so that engines know where the ghost application is running so we need to get the configuration inside the container and so what we do we just have the config and have a simple Docker file which adds our config inside the container image we just overlay the default configuration that's it and about the ghost image so this is how you build it in Ansible use Docker image module then it has like various arguments and let's go through what we'll have here so so path means that like where the Docker file is stored but actually it's like where all the context for the build is stored so it's in special directory this is how we want to name our image when it's built how we want to tag it there's also like attribute like if we want to so is it base image so if you want to pull the base image which is again like attribute of Docker build so if the image is already present this will save your time but if you want to make sure it's you want latest you can just say to set it to true and force means that if the image is already present this is like everything is skipped but force means that we want to build it all the time like don't so ignore the fact that the image is already present just build it and this is great for development actually like if you are working on the image if you are working on the Docker file build it every time so you can do this with force yeah and that's it so it's like really simple and the so we also had the vibe variable which acts like as you thought if you set it to true the images will be removed and if it's on false which is by default the images like will be built or rebuilt so let's try to run it so i open it at a terminal below and so and it's in ghost and build so so it was really fast right like i just built my images in like a second so the reason is that i mean i've already done it before and this is just taking all the steps from cache so that's the reason i mean i could build images and we could wait here like 20 minutes to build them but i guess that's not what we want so one thing i want to speak about is that it's not possible to get like the whole build log from Ansible i was even checking code and it's just like it's not printing to standard output which is like really annoying so sometimes i was even running like darker commands to build the image to see what's the error i mean i can show you so we can open the docker file and let's okay so let's add something which will fail so just run false so and this should fail the build so if i'll build it so you can see that it's like not the whole log and what it said that the message is that just returned code is just written the code one which is like nonzero code which is error and we have no idea what happened i mean we can do that but it doesn't help because it does so yeah what i was doing is just like using docker to build images so yeah i mean i'm definitely sure that Ansible team is aware of this and they will change it in future but so we just need to wait for it to land to the Ansible module okay so that's so the image is built and let's start with with the deploying of the application so i can briefly like show you the playbook like what we will be doing right now we have like 30 minutes so we probably won't do all the things and then we can start so so the playbook is called i guess it was run so it's actually pretty long so it has like many tasks as you can see it's like really long i was actually working for the whole day so let's go through no i mean let's start with writing from scratch and adding like different features i mean i think that's like more interesting than just go through talking about like okay this is that and so i mean if that's okay for you i will do it my way but in the end i can like skim through the whole playbook and tell you what i was doing and stuff like that so let's start the new file then and let's name it i don't know runGhost.tml and what i will copy from that is at least the Docker container task for running the application because you already saw that so at times i just removed the database stuff and that kind of those of the yeah just this okay so like this tasks okay so this is our new yeah and i copy the wrong i copy the wrong tasks sorry about that yes this is the okay we don't need this and we can do network later okay so this is our start so we have the image built and we can start like using it or run it run the container from the image so let's name it like ghost web so it's the name of the image so let's name it ghost web so we have the image we just built and we want the state to be present yeah start it right okay create start policy yeah that's what we'll do later so we just run the container from the image we want to ensure that it started uh recreate means that if it's already started like do it again so this is very handy if you like tune the parameters you definitely want to recreate it and again the restart policy it's like if it fails as we can or we'll usually recreate the container if you change the parameters but in this case it's more as it's more is used because when we are building the image on our host we can't pull it from anywhere so Ansible won't check or Ansible doesn't know how to check if it's newer so if we create it will automatically recreate the container with newer our latest our built image container it could be better handle that I guess on the Ansible side but it will be updated later ok so I will run it ok so playbook run hmm where is it so I guess that it's in the so I guess it will be in the dash yeah here it is but it won't work because let me just build it ok then so let's see so it's running and now I have to figure out which port is actually running because I don't remember 2,3,6,8 ok so since we didn't expose the ports we need to connect to the container's IP address and to the correct port so let's figure it out and each port if you want to reach your application through localhost you need to you need to publish the port so you need to be a parameter or published port but if you like if you like determine the IP address of the container you don't need to publish the port you can reach the application on the IP address of the container and the port with the application is listening to it so which applications are different IP from the same port? yes yes yes so I will just open the again on the other screen so I don't have to switch switch files every time so based on the Docker inspect we figured that the IP address is this one so it's this one and the port is 2,3,6,8 and doesn't work obviously tak uh promero 8 plus well well it connects to htp by default right ok sorry promero 8 plus promero 8 plus so Peter is right that that we didn't set up the database but I mean originally I wanted to do it like když se vytvořilo na database a tady vytvořilo na database, ale vždyčně. Takže jsme musíme vytvořilo na imidě, protože v imidě máme kastoukonfiguráci, které se vytvořilo na database, takže jsme vidíme v logi, které se vytvořilo na database, takže se vytvořilo na logi a v svoj efekt, takže chci se vidíte, že se vynužíte kastoukonfiguráci a řekno, že se vytvořilo na database. Takže vyžíváme to. Takže jsme mít těžké cynávské kastoukonfiguráci a teď vyžíží, takže jsme vytvořilo na database. Takže se vytvořilo vytvořilo na database. Takže jsme vytvořilo na database. Takže máme to závodnit a vždyš jen takhle závodnit. Až našli se závodnit do dátabéství. Můžeme dělat to zvukovat, protože měto aplikace závodnit, že dátabéství je už vytvořit a představit závodnit. Až než jsme závodnit, protože jsme závodnit stok MarioDB z dockerhubu. Znamením je MariaContainer. Půl je zvukovat, takže jsme chci být všichni, že jsme vždyčené. Vždyčně chci být vždyčené. Vždyčně, že jsme vždyčené. Volumes, takže jsme vždyčené. když se v rově a v torkni na význalí. To je vždyč jen také význali. MariatDb container je konfigurat k tomu význali podmění význali, takže jsme případli podmění význali a tady bylo dělávím podmění podmění konfigurace k tomu byli které byli kůž nevětěni význali dáté za mě, které byli děláví taky taky nevětění nevětěni. A to, co máme, je všechno návětné věře. A tu jsou. A závětné věře je na databaseu. Máme tím věře na databaseu ghost. Takže tím věře měl návětné věře. A vývětné věře je na věře. Takže máme mít tohoto základnout s tým významením, takže to základnout tím významením na database. Takže jak máme to? Takže nebude mít pro významené variable v tomto plébu, které si významené na tým významením, tím významené na svojí jeho základný významený na významené. Takže, se to děláme. Já se to opravdu kopiří. To je všechno. To je v této. DbDatabaseName. DbUser. DbPassword. Zděláme to. To je dbDatabaseName. DbUser. DbPassword. DbOser. DbDatabaseName na této větěváme, ale je ho v takétoappedě zázvané. Vyskávajme závědět díky, a to drugé větěváme, se to náskávastí. Ketý větěváme závědět hodně. Když jsme vyskávali tímplý konfig, a vyskávali nějaké vývěděváváváváví na vývědě. Závodujíme, jak se to vám sečí. A-a-a, takže je to. Takže je to v dne. Vyjímáme to vývěděváváváváví a hodně hodně. A-a-a, vývěděváváváváváváví na vývědě, takže jsme vyskávali. Takže, co je to o tom? Vyjímáte? Jé, vyskávali. Vyjímáte. Já znam, že to nevěděvává. A-a-a, takže můžu věděvat, že to nevěděvává. A-a-a, že můžu věděvává? Jé, to je dobrý moh díl, ale to situace nevěděvává. Vyskávane zaktivou vétejsku, že se to nevěděvává je nevěděvává. To bylo, protože jsme nevěděvávávali nevěděvávává vývěděváví, takže se to vyskávali a byl to v pourraitným nechým defiulům. Takže defiulům je nevěděvává, ale to je jen dobrý moh. Okaco. A zaziv Ra-bhательná, že to vyskávává v 10 sekundí, kitil maria db. Takže jsme záznout na MariaDB kontainer a dnes zároveň jsme zároveň mnou přiděžit, i je to tady nezávodat, ale to nezávodat příště. Takže to nevěděje, možná. Teď než víme, což to nevěděje. Nyní to nejde, takže co chtěl jsem vytvávat, jak je to, co tady součit tvoje kontainer a že jsou nejde kastomnetů, a o tom nevětmé návětmé kontynes. Peter tyto nesměr nejde rád, že se potom musíme ještě našli zvukovat návětmé kontynes. Když se to děláte, když se kontyne nevětmé návětmé návětmé díky a když se to závětí kontynes. Je to nechce, když bych se to dělal. Když se to děláte, když se to děláte, It means that the container will be only on our network, which is the ghost network. Ok, so let's do it again, and hopefully this time it will fail. On the fact that it can't connect. Ok, so the next thing we'll be doing is start the MariaDB container and wait for it to become available and then start the other container. A to je tím, jaké se vysvědělo, kde je to první. Ať se se vysvěděl, že necháme ještě nezapravit. Přeď bychom kondaineru vytvětat. Je se vysvěděl, že musete kondaineru vývětat, co je nepozirávali. Ale s kondainerou máte vůvod, které je vysvědět, a kondaineru necháme větat, ale u větatu je nezapravity kondaineru. Takže se závodujíte. Takže to je většiná. Ale nevím to. Takže... Ok, takže... O, když nedáváte, co se závodují? Je byl je. Je bylo to konfigurace. Takže, takže, takže, nevím, co se závodují port, nevím, co se závodují. Takže, nevím, co se závodují port, nevím, co se závodují. Takže, nevím, co se závodí. To je list a to bylo 2... 3, 6, 8. Je to ještě závodil. A když jsme vyráváme to, takže... Takže můžeme závodit zvukovat a nevíme to závodit kontainer itself. Takže, se závodit krom, můžeme závodit závodit závodit. ale můžeme vytvědětat, takže pléboot je třeba, a to se vědějí, wow. To je tak, že je nejlepší. Děláme, že děláme, že děláme príklad, ale můžeme, že když jděláme děláme děláme děláme děláme. To chilké vytvořiliivala z racíli, že všechno zrůžíme. Moje dělady jsou řekli smění, nebyli, že byla větká, že se dělali. Můžete mít kýdvěgo důvod. Jak se postavím chtělá tato bázu? To tato bázu je můžete kpressivný. Jedině právě je nejleplé k razově. Tam je mnou vidět, kdež jsi chtěl je nejleplý. to procesy. Just because you need to get the IP address of the container you want to wait to get initialized. The thing is this would be easy if you could do this in a container so you are on the network and you can use the network discovery, but since this is running on our laptop we don't have access to that, so we need to figure out the IP address. So its this task. Get the IP address of the Mariat YB které se vzávodují. My jsme vzávodují zvukování a vzávodují se vzávodují závodují závodují. Takže jsme vzávodují vzávodují závodují závodují. A jsme vzávodují závodují závodují. Takže vzávodují. Já jsem vzávodil toho, a Peter cítil jen vždy, takže můžu vzávodí svojí solučeného. A s ním byl se v tomhle skupnit závodí do dílu. A jsme vzávodili toho dílu, můžu vzávodil toho dílu. Prostžíli jsme vzávodili, tohle o tom, zvukování tohle svojí solučeného. A jsme vzávodili, tohle o tom, zvukování toho dílu. A zvukování toho dílu. A mám být návodil. A mám být návodil. A mám být návodil. A mám být návodil. A mám být návodil. Vzal jsem dělal 30 a tam je nějaký věc za výštěnou konekci. Až máme nějaké věci, které je tím, které je MariaDB zavodovat. A máme toho těchtoho, které jsme tím, že MariaDB zavodovat a můžeme mít v roce. které je to uvědět, které se vám udělal. Mělte se. Já vám je tu. Takže tady však se potřeba většinit url. Takže mějte se, kde na zvědětě url je většinit vylit hdp, kde vám zvědět a status code je 200. A nám zpět, že jsme vyspět, že jsme zpět, že jsme zpět, že jsme zpět, že jsme paru na výzvodí závodí závodí, a jsme vyspět, že se to spotrží, že než třeba přijde, Můžu 10 minut, takže přijím do Peteru, takže můžu... Prostě chcete vědět, když jste. Takže... Prostě... Jsme děláte děláte děláte děláte děláte. OK, a vždyť se jen závědějí, když se jen závědějí. Protože, jak se dělává docker-compose? Když máte nějaké docker-compose fále existené, to je to závědějí. Je to nějaké prokzivé, které závědějí a je to klikáčené v rovi koutainého, je to zpět doker kompoz, jít z internetu, a jsi cítil by se takovou nezvědětá. A když cítilaží, když cítilaží, když se v tom plébooku vůstřel, se když je vzbět v dokeru service modul. Projektoční zpět pojíče do dokeru, které je to dokeru plébooku, Bychom kde je nevěřil do̅kářek OK, bychom do̅kářek kompozíje kde je nevěřil do̅kářek kompozíje Až vexážit, nebo vexážit, než vexážit Ať nevěří, že je to A závěřil když je předný, když se rozdělává tím, když ho kompozí lidi blívá Takard je s tím, když dá je zvěřit které je to, když se vás přijde, co se vám vyšloží, co to je. Je to všechno superhendější do migraji, do hodiny. Vůbec nejlepším, co mám závodit. Je to nejlepším, co mám závodit, co mám závodit. Je to nejlepším, co mám závodit. a co je tady, co jsme nás nevěděli. A když je vždyčný netvorek, kontrajné je zvukovat na netvorek s ním, takže je to vždyčný, tady je MongoDB, tady je vždyčný, takže je to vždyčný, ale můžete přijít v kontrajné a můžete dělávalo na kastom netorku, takže db zvědějí množa db-container a množa. A tady je to, když se množa vyskává množa, musíte vytvořit množa db, takže musíte vytvořit množa db a množa musíte dělat množa i množa vyskává množa. A tady je to množa db, které množa db, když množa db množa db stále vyskává množa db a množa db množa db a vzládíš množa db A zběžně je vzávědět tady, když to je vzávědět, když se vzávědět jen závědět, když nevím tyto nezávědět. Když jsem vzlávat výstření, to je takový úplný. Vypravdu výstření musí být výstření, takže výstření je velice výstřenit. Až to je velice výstření, ale to je vypravit v velice výstření, As Enzible has MongoDB users module and it can connect directly to the Docker container. In this case I'm using, I'm echoing some string directly to the Docker exec. Right, but with dynamic inventory, I talked to you about, I can query Docker for all currently running containers. So in Enzible, when I run the playbook, the dynamic inventory will query Docker and I will have information about all running containers. And I can run tasks inside of the container with Enzible. But for this to work, the container has to have Python installed and some dependencies for Enzible. So default MongoDB doesn't have that. But if you are using your own container image, you can make that work. And basically that's the last thing I wanted to mention. So yeah, that's it. Do you have any questions? This is available in the GitHub repo. Example is rocket chat. Example slash rocket chat, yeah, here. All right, that's it. Thank you very much. Yeah, thank you. Do we have all of them? I don't think there are all of them. So I'm not sure if you know how many. Yeah, I think we have all of them. Does this need anything special to set it up or just plug in the VGA? Yeah, you just plug in. So the control is in here. And you can pick like plug in VGA, plug in HDMI. OK. OK, are you bringing your laptop? Yes, yes. OK. OK, do you have VGA? No, I don't need it. I'm not present there, so I'm just a session chair. You are a session chair? OK. Sorry, I thought you were presenting something. OK. So I don't think the guy is here. Probably not. Let's see. There should be the phone number and the formal thing. OK. OK, so basically we just plug in whatever we need, cable for network or HDMI or whatever, and the control is there. Nothing special, I would say. What I don't know is the microphone. Is it recording or something like that?