Once you learn how to get a container up and running in Docker, you can then move on to running and managing multiple containers in the same docker engine for your environment. Much like anything else, practicing setting up containers, interacting with them, and tearing them down once done will get you comfortable with the process and workflow for managing containers. In this tutorial, we’ll practice by setting up 3 individual containers. One will be MySQL, another Nginx, and the last Apache.
MySQL Container
First up, we can spin up a MySQL container in Docker.
docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql Unable to find image 'mysql:latest' locally latest: Pulling from library/mysql d121f8d1c412: Pull complete f3cebc0b4691: Pull complete 1862755a0b37: Pull complete 489b44f3dbb4: Pull complete 690874f836db: Pull complete baa8be383ffb: Pull complete 55356608b4ac: Pull complete dd35ceccb6eb: Pull complete 162d8291095c: Pull complete 5e500ef7181b: Pull complete af7528e958b6: Pull complete Digest: sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808 1309c4b670f02dfffe5ef3ae0c405867fdad81b61bb3a60f08018273d035830b
Apache Container
Now that MySQL is up and running, let’s get the Apache webserver started.
docker container run -d -p 8080:80 --name webserver httpd Unable to find image 'httpd:latest' locally latest: Pulling from library/httpd d121f8d1c412: Already exists 9cd35c2006cf: Pull complete b6b9dec6e0f8: Pull complete fc3f9b55fcc2: Pull complete 802357647f64: Pull complete Digest: sha256:5ce7c20e45b407607f30b8f8ba435671c2ff80440d12645527be670eb8ce1961 Status: Downloaded newer image for httpd:latest d2659ccf4b39ad461b0352af1b096f5835726c8042f32916febd948e0c819482
Nginx Container
The last container we will launch is an Nginx Container.
docker container run -d -p 80:80 --name proxy nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx d121f8d1c412: Already exists ebd81fc8c071: Pull complete 655316c160af: Pull complete d15953c0e0f8: Pull complete 2ee525c5c3cc: Pull complete Digest: sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0 Status: Downloaded newer image for nginx:latest 5f65da618b6aae8e9cd223f7bba046c2efaf9573753fd9c40cdabca12593adfe
List Containers
Ok, all of those prior steps went well. Let’s view the running containers with the docker container ls command.
docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5f65da618b6a nginx "/docker-entrypoint.…" 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp proxy d2659ccf4b39 httpd "httpd-foreground" 27 seconds ago Up 26 seconds 0.0.0.0:8080->80/tcp webserver 1309c4b670f0 mysql "docker-entrypoint.s…" 40 seconds ago Up 37 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp db
Test Port 80
We can test port 80 which our Nginx container is running on using both curl at the command line and also in a web browser. Looking Good!
curl http://localhost StatusCode : 200 StatusDescription : OK Content : <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> <... RawContent : HTTP/1.1 200 OK Connection: keep-alive Accept-Ranges: bytes Content-Length: 612 Content-Type: text/html Date: Wed, 30 Sep 2020 20:58:08 GMT ETag: "5f32b03b-264" Last-Modified: Tue, 11 Aug 2020 ... Forms : {} Headers : {[Connection, keep-alive], [Accept-Ranges, bytes], [Content-Length, 612], [Content-Type, text/html]...} Images : {} InputFields : {} Links : {@{innerHTML=nginx.org; innerText=nginx.org; outerHTML=<A href="http://nginx.org/">nginx.org</A>; outerText=nginx.org; tagName=A; href=http://nginx.org/}, @{innerHTML=nginx.com; innerText=nginx.com; outerHTML=<A href="http://nginx.com/">nginx.com</A>; outerText=nginx.com; tagName=A; href=http://nginx.com/}} ParsedHtml : System.__ComObject RawContentLength : 612
Test Port 8080
Testing port 8080 for the Apache server follows the same process whether with curl or the browser. Apache responds with a simple “It Works!”
curl http://localhost:8080 StatusCode : 200 StatusDescription : OK Content : <html><body><h1>It works!</h1></body></html> RawContent : HTTP/1.1 200 OK Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Accept-Ranges: bytes Content-Length: 45 Content-Type: text/html Date: Wed, 30 Sep 2020 21:03:11 GMT ETag: "2d-432a5e4a73a80... Forms : {} Headers : {[Keep-Alive, timeout=5, max=100], [Connection, Keep-Alive], [Accept-Ranges, bytes], [Content-Length, 45]...} Images : {} InputFields : {} Links : {} ParsedHtml : System.__ComObject RawContentLength : 45
Stop All The Containers
We want to clean up our Docker environment, so let’s stop all the running containers by name.
docker container stop db webserver proxy db webserver proxy
Confirm Containers Are Exited
The status shows as exited so we know the containers are not running.
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5f65da618b6a nginx "/docker-entrypoint.…" 11 minutes ago Exited (0) 59 seconds ago proxy d2659ccf4b39 httpd "httpd-foreground" 12 minutes ago Exited (0) 58 seconds ago webserver 1309c4b670f0 mysql "docker-entrypoint.s…" 12 minutes ago Exited (0) 58 seconds ago db
Remove The Containers
No need to keep these containers around if we are done with the exercise, so let’s go ahead and remove them.
docker container rm db webserver proxy db webserver proxy
Containers Are Gone
Confirming the continaers both running and not running are gone.
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Remove Images
While we’re cleaning things up, we can also remove the images we used to power the containers.
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest 417af7dc28bc 2 weeks ago 138MB nginx latest 7e4d58f0e5f3 2 weeks ago 133MB mysql latest e1d7dc9731da 2 weeks ago 544MB docker image rm httpd nginx mysql Deleted: sha256:ba0c2ff8d3620c0910832424efef02787214013b1c5b1d9dc9d87d638e2ceb71 Deleted: sha256:db9c97c9ad968b91c4499e5cca7435a155bfef6f5fb9c6cd5543481e47ff4f71 Deleted: sha256:8cdd4c6014e71c2f6ff38dadcaec2003b955230d38831e85db5a44fa38320e6b
Images Are Gone
Lastly, we check for any images in our Docker environment and sure enough, there are none. We have a nice clean environment to work with once again.
docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE
Learn More
- Containers And Docker Compose (code.visualstudio.com)
- Multiple Containers Docker Compose (digitalocean.com)
- Multi Service_Container (docs.docker.com)
- Dockerizing Multiple Services Inside A Single Container (medium.com)
- Creating A Multi Container Application With Docker (dev.to)
- Mysql Docker Containers Understanding Basics (severalnines.com)
- How To Run Mysql Using Docker (towardsdatascience.com)
- How To Deploy And Use A Mysql Docker Container (techrepublic.com)
- Install Apache Web Server In A Docker Container (tecmint.com)
- How To Setup A Simple Apache Web Server In A Docker Container (examples.javacodegeeks.com)
Summary
We can see launching more than one container is not all that hard. In the examples above we were able to get several containers up and running, test out their services, and then stop and remove them from Docker. Some takeaways include: