Cloud native applications are packaged, distributed, and run in containers. Docker is a key container technology. This video shows how a Docker container for a Go microservice can be run locally. It also shows how ENV variables, port mappings, and resource constraints can be specified.
- Hi and welcome back to Cloud Native Go. My name is Leander Reimer and I'm happy to be your host. So this video is all about running containerized Go Microservices Locally. So in this video we are going to take a look at how I can run a Docker image locally. And we want to run the Docker image we've built previously. I'm going to show you how I can specify invariable, environment variables and ports on a command line, we will talk about starting, stopping and restarting running containers, and finally, I'm going to show you how I can add CPU and memory constraints to your container.
So this is quite some stuff, so let's get started. Let's switch your console here. So remember, in the previous video we've filled our Cloud Native Go Microservice image. So you see here... Here, our images we've filled previously. So what we want to do now, well, it's basically, that this image run.
So will we use the docker run command for this? So let's see what's going on in this line. So we used "docker run -it", it's we going to attach the "t" to "i" to it, "-p" basically tells that the port mapping, which contain a port is mapped to the docker host port, so in our case we mapped "8080" container port straight to "8080" port on the host machine, and here, as the last command, we want to specify the image tag we want to run.
So let's see. Now, on first sight, this doesn't do terribly much at the moment, but it looks like our image is already running. So we can check this, so let's go here, and we try to access the REST API of our Go Microservice. And you see here, that we're not accessing "localhost" anymore. We access the IP address of the docker host machine, which in my case is "192.168.99.100:8080/api/books".
Let's see... And hooray! You to see here, we are now accessing the REST API of, well, our Go Microservice running as a container on our docker host. So let's try something else, so here, we'll come to Cloud Native Go, we have the echo, and yes, everything is working as expected. So let's kill that one.
Now imagine we have this environment variable called "port", which we can specify, well, to let our Microservice run on a different port. So let's see how we can do this with docker. So it's to run command again and now we use "-e" to specify an environment variable. So, in this case "9090" if we like. We insert the port mapping again, and the image tag to run.
So, let's see. So, once again it's running. We're going to switch to our REST client, and you see here now that I've changed the port to "9090" now, but I'm still running against the docker host. And you see here "9090", we get a response, whereas if you do that on "8080", the previous port and the default port, well, we do not get a response, because basically we're not listening on this port anymore.
So let's go back to our console again, now, if you use the "docker ps" command, you should usually see the running containers, while currently when not running any containers at all. If you use "docker ps --all", you see the two previous containers we ran, okay? Now obviously, in real life isn't situations, it's not practical to run our docker container blocking on the console.
What we want to do is to run it in the background as a background process, right? So let's do that... We give our container a name this time, makes life a little easier later on, we use "-d" for daemon, we have the port mapping again, and the image tag to run. So, to use "docker ps" now, you see that we have one running container here, okay? With the name Cloud Native Go.
So if we go here again, we see that everything's working as expected again. We can access our REST APIs on port "8080" on our docker host. Great. If it interested in some stats, well, you should "docker stats". Well, see here is the CPU and the memory limit it is using. Well, sometimes is useful for debugging purposes how to find out about the memory usage of your docker image or your docker container.
Okay, well, we can use "docker stop" now to stop our Microservice, as seen here, well you give the name "docker stop cloud-native-go", that'll stop, use "docker ps" and you'll see it's not running anymore, "--0", you see here that the first line, this was our container, and what we now can do it's start the container again.
So here we go, we have our container running again. Now, to forcefully kill a container you use the "kill" command, so here, "docker kill cloud-native-go". You see here, "docker ps", again they're all stopped. If you want to remove a container, you use the "docker rm" command, with the container name. See that works, we have one container less in there, in the list.
Finally, I want to show you how you can specify resource constrains for CPU and memory when launching a container. So again we use the "docker run" command, you specify CPU quota, specify some memory, default the memory swapiness to zero, "-d" for deamon, "-p 8080:8080" for specifying the port mapping again, and we specify the image tag we want to run.
So let's see... Oh, I seem to have a typo here, yes. Double "p" and we're back up. So "docker ps", see, we have all Microservice running again as a container on our local host. So this was it for this video, and in the next video I'm going to show you how we can build and improve Docker Image and how we can use Docker Compose to easily run your container locally, in addition to, well, maybe, a few other services.
Hope to see you then, bye bye.
This course was created and produced by Packt Publishing. We are honored to host this training in our library.
- Implementing Go HTTP Server
- JSON marshalling and unmarshalling of Go structs
- Implementing a simple REST API
- Using Docker workflows and commands
- Building a naïve Docker image
- Running a containerized Go microservice
- Kubernetes architecture and concepts
- Deploying a Go microservice to Kubernetes
- Implementing service descriptors
- Performing rolling updates