Are you sure you want to delete this access key?
DigitalOcean calls their Virtual Machines Droplets
We now want to take the next step from the last lesson. The last lesson covered how to serve a static website from a Docker container. This next step is a very real world operational step. We want to launch that same website container on a production level cloud platform - DigitalOcean.
DigitalOcean is like AWS, Azure, and GCP in principle, but it is more simple than all of those. I like to say that it's more elegant - beautiful and powerful - with just what we need. While Digital Ocean is powerful, it's more of a "bring your own tools and approaches" kind of cloud platform. They aren't trying to invent a bunch of new tools that "code it myself" practitioners don't really want or need. And they are beginner friendly.
I am NOT trying to say that the other cloud platforms aren't good in their own ways. I am only trying to stress how Digital Ocean is different and advantageous. Use what you most like and hopefully you can give all of them a fair try.
Find this and all the other lessons of this Docker Mastery journey in my Docker Mastery repo on DagsHub. DagsHub is the Cloud Git Repo system for data scientists and machine learning engineers. And just so you know, you can get a free DagsHub account.
In the previous lesson, we looked at my repo Docker Served Static Website in my DagsHub repo for Docker Mastery. We went over lesson 2.0 of the Beginner Lab for Docker on the Docker docs website. I hope you will look through the earlier lessons for this Docker Mastery Journey if you feel like you are missing something in this lesson.
In this lesson, we will learn how to launch that same container from a DigitalOcean virtual machine called a droplet. This is ONLY a conceptual level lesson to help with this learning step. There's still more ground to cover for:
This lesson is to show how to serve a simple website from a Docker container running in a virtual machine on DigitalOcean.
Some of you, who have never done this, may only need the high level procedure. This would be due to your overall experience with such things. Even if you need every detail, this high level procedure will help you. The high level steps of our procedure will also serve as the approximate or exact titles for each section that covers the procedural steps in detail.
Here are the high level procedural steps that we will follow.
You may come across some other great tutorials that go about things a little bit differently. Those procedures are OK. All the procedures are roughly accomplishing the same things, but they may be using different tools to accomplish the same steps. However, I must confess that I could not find a procedure like the one that I have presented in the previous paragraph. I was striving to do the above steps, or something close to them, in the simplest possible way.
One video that I found was very thorough and VERY close to what I am showing. I will include a link to that YouTube video at the end of this document from the Faraday Academy channel. The main difference was that NGINX was not included in the Docker container. I hope you will subscribe to Gwen, the owner of the Faraday Academy. She's a very thorough teacher.
There's also a SaaS instructor that is an AWS champion and a Docker master that I encourage you to consider adding to your group of teachers for this type of material. His name is Nick Janetakis. He teaches you how to build a SaaS app, and he uses Docker heavily. You can find him on the web AND on Udemy.
Why is my procedure the way that it is? Two things. First, I REALLY like to find the simplest way to do something. Then, after I see how to do that, I am eager to add helpful sophistication. Second, I am now beginning to realize that I am a bit old school. I like the simple low level tools that have been around a long time. And trust me, there are steps that I take, that true computational elders would snicker at. The main thing I want to encourage you to do is to see my procedure conceptually. Then, over time, change this procedure to use step descriptions and tools that you prefer.
Finally, I worked through all the above steps over many days. I made many mistakes along the way. Many of them were basic conceptual mistakes that made me laugh at myself and sometimes cringe in embarrassment. I admit to such things so that if you encounter similar learning hurdles, you won't feel alone. It still amazes me how, when I am trying something completely new, I can forget basic principles that I already knew. However, once I get over the pain of lost time and embarrassment with myself, I am grateful to be more skilled for the future.
Go to DigitalOcean to sign-up for your free account if you do not already have one. I will forgo going through the details on how to sign up for DigitalOcean. A good web search on how to sign-up for DigitalOcean will guide you well, but even the sign-up process itself will guide you. This page in DigitalOcean Docs, Getting Started with DigitalOcean, has a Sign Up section and more.
So that you can manage resources in logical groups, it's good to create projects by name. When you log into Digital Ocean, you are taken to your DigitalOcean control panel. In the upper left, you will see where you can create a new project. The below image is a screen shot of my control panel. Just follow the indicated steps and describe things clearly. When DigitalOcean makes suggestions based on the nature of your project, just be happy to be exposed to them. You needn't feel compelled to explore and use everything right away.
Great. Now we have a project to assign resources to. Note that I will be using my existing project indicated by a partial name in the upper left. It's full name is Simple-Dockerized-WebSite.
There are many ways to use DigitalOcean and many ways to go about each kind of work you can do on DigitalOcean. For each type of task, you will still be using a virtual machine (a droplet) or a cluster of virtual machines. Those clusters of droplets would be managed by Kubernetes. DigitalOcean is now offering some high level simplified work paths. They are definitely worth checking out. I am not discouraging the use of those higher level work paths. However, for myself, I feel that once I start using tools that do many of the background steps for me, I can lose some of my low level skills. Those low level skills are great and can help you be more creative and agilent when necessary. So, I am only saying, be careful to learn and maintain some low level skills even as you adopt high level tools.
That said, creating a virtual machine, on any given cloud platform, is something that we all want to know how to do. Keeping with their Ocean theme, it's not surprising that DigitalOcean would call their virtual machines droplets. Let's create a virtual machine, a droplet, in our DigitalOcean account. You can use the Create button in the upper right OR the Droplets option under Manage in the left menu. Either way, we want to create a droplet. So that we are sure to be looking at the same screen, choose the Droplets option under Manage in the left menu. You will first see a screen like the one below.
Once you click on Droplets_ you will see the next screen.
Now simply click on the Create Droplet button. The screen below will appear at the top of the page. It really does not matter what parameters that you choose for your virtual machine. However, I will encourage you to choose the ones that I have chosen. I've chosen the simplest and least expensive ones, and they are more than adequate for our needs.
Scroll the page down until you see the options shown in the below image. Choose a number that's not grayed under a location nearest to you. Hence, since I live in Southwest Idaho USA, I picked San Francisco 3.
Scroll down to the next section shown in the next image. If you already have an SSH key for your local machine, use that and give the key a name. If you use multiple machines, you'll just want to add an SSH key for each machine that you will use to work with DigitalOcean. IF you have never used SSH keys, I encourage you to take the time right now to learn how to create them and use them. It's easy on Linux and MacOS. It's been a while since I created one for Windows, but I don't remember it being hard. When you search for creating SSH keys, search with creating SSH keys on .
The high level procedure is:
Also, when you add an SSH key for a machine, you can usually give it a descriptive name. It's good to do this so that you can remove old keys for old machines that aren't in use anymore.
Remember, this is a simple website and simple example that we intend to serve. I recommend for this exercise to keep the remaining checkboxes in the below steps of the below image blank.
The final part of the droplet setup screen is shown in the below image. We only need one droplet. I've named mine a super long descriptive name. How you name is totally up to you. Note that you cannot use underscores in the name. You can add a tag name as suggested too. I only have one project in my DigitalOcean control panel so far. If you have multiple projects, choose which project you want this droplet to belong to. Finally, create your droplet.
If you hover your mouse pointer over the IP address of your virtual machine, the blue Copy text will appear to the right of the IP address. Click the Copy, and the IP address is now in your keyboard buffer (clipboard).
Open a command terminal on your machine.
Type ssh root@<ip_address>
.
For my specific case, that would be ssh root@164.92.120.60
.
The below terminal interactions show my first connection to this new droplet through a secure shell connection.
thom@thom-PT5610:~$ ssh root@164.92.120.60
The authenticity of host '164.92.120.60 (164.92.120.60)' can't be established.
ECDSA key fingerprint is SHA256:Z5g/hkOGwDeh9/sKQjI82xPAtzlT883djguipqauvrk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '164.92.120.60' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-107-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Jun 13 22:54:40 UTC 2022
System load: 0.0 Users logged in: 0
Usage of /: 6.3% of 24.06GB IPv4 address for eth0: 164.92.120.60
Memory usage: 20% IPv4 address for eth0: 10.48.0.5
Swap usage: 0% IPv4 address for eth1: 10.124.0.2
Processes: 103
71 updates can be applied immediately.
45 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@ubuntu-droplet-1-simple-static-website-thru-docker:~#
Understand that you are literally now connected to your droplet with a command line interface. It is totally appropriate to get up and dance now ... even if someone is watching ;-) . But wait! There's yet another way to connect via a command line console to your droplet. Refer to the previous image again. The name of the your droplet in blue is a link to a page that provides many extra bits of information and options for your droplet. This page for my droplet is shown below. Note that in the top right area is a blue link called console.
Click that link, and you will see a console startup on your machine. My version of that console on my machine looks like the following.
You can use either method:
The important thing is that now we have command line access to our droplet. Now we can manage that droplet like we would want to manage any of our other linux machines - virtual or real.
I suggest that you run some linux command line commands on your droplet to see that you are in fact interacting with a Linux Ubuntu distribution. We will be using that command line quite a bit in the next session. There are some additional slick things that you can do to improve the look and feel of working with this droplet. We will cover those in future lessons.
For the command line commands in this section, we will not show the output lines of the terminal except for the last command. That command is a great way to verify our install. I want to provide THAT output so that you can detect if anything went wrong with your Docker installation.
Let's run these next two commands on our droplet as good stewards of it.
sudo apt-get update
sudo apt-get upgrade
The next group of commands prepare our droplet for our Docker engine installation. Please see the learning step Docker Concepts and Install to understand the details of the install steps.
sudo apt-get install ca-certificates
sudo apt-get install curl
sudo apt-get install gnupg
sudo apt-get install lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable nightly test" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Finally, we do an update for the new packages installed.
sudo apt-get update
This next line actually installs the Docker programs that we need to run the Docker engine.
sudo apt-get install docker-ce docker-ce-cli containerd.io
The next command line command tries to run the hello-world image to launch it in a container. It is not yet on our droplet, so Docker will then pull that image / container from Docker Hub, and then run it.
sudo docker run hello-world
The output on my Linux box for this command is shown below.
root@ubuntu-droplet-1-simple-static-website-thru-docker:~# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
root@ubuntu-droplet-1-simple-static-website-thru-docker:~#
Docker compose is not yet installed. We do not need it for this step, but we will use it in the future. If you want to install it for the experience of it, the commands are below. Again, please see the learning step Docker Concepts and Install to understand the details of the install steps. I also like this tutorial by "did code" for explanations.
Obtain Docker Compose, install it, and set it up.
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Make sure it is executable.
sudo chmod +x /usr/local/bin/docker-compose
Some people like to create this symbolic link. You can determine if you need or want this.
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
A good way to check your Docker Compose install is to check the version from the command line with the following command.
docker-compose --version
You will see something similar to the following output if all is good.
docker-compose version 1.29.2, build 5becea4c
We do this to transfer files from our local machine and the droplet machine's file system as necessary. FileZilla is a great tool for doing this with secure shell FTP (secure shell file transfer protocol - SFTP). I recommend installing it from your Linux Distro's software management application. You can install FileZilla, or something like it, on Windows and Mac also. I used this guide on Docker Docs, How to Transfer Files to Droplets With FileZilla, to install FileZilla and begin to use it. Remember, when you are telling FileZilla where to find your private ssh key file, you are telling a program installed on your machine that is controlled by your security where to find your private key, so that your machine can connect with machines (such as droplets on DigitalOcean) that have your public ssh key.
After following the steps to install FileZilla, we are ready to transfer our Dockerfile and our HTML file to our droplet. Hey Thom, why not use vi or vim or nano to author those files from your droplet console? Yeah right! I am too lazy for that. Plus, I wanted to a tool in place that I could use to move large files and large numbers of files from my local machine to my droplets.
Per the FileZilla install directions, my setup for my droplet's IP looks like the following.
The first that you connect with SFTP, you will see this warning from FileZilla. FileZilla is just making sure that you want to connect using your ssh to this ip address. And now that we've verified that the ip address is the correct one, we can trust the key and add this ip address to our ssh cache.
Next, let's use some additional power of FileZilla and create a new directory for our Dockerfile and our HTML file.
Nice! Now we can highlight our Dockerfile and Hello_Docker.html file to our new directory on the droplet.
FileZilla shows that the move was successful.
Let's also cd
into /home/website in the droplet console and verify that our new files are there.
SWEET! Now we can build our Docker image and create our Docker container.
Now that we are in the directory where our Dockerfile and our Hello_Docker.html file resides, we can run the following command in our droplet console.
docker build -t website:0.1 .
This command will yield results for you similar to those shown in my console for my droplet.
Oh My! This is getting serious! We are almost there :-) .
Let's check Docker processes and Docker images.
We should expect just this. We've only built our image so far. It is not yet running. So we see the website image and the hello-world image that we ran and that exited earlier after installing Docker, but no processes (containers) are currently running.
Now that we have a built image, we can run the image in Docker container using ...
docker run -p 80:80 -d -P website:0.1
This command will give you output similar to what is shown in my droplet console.
Note that we have a big return id for our container. Well, the container for our website is running and its port 80 is exposed to port 80 of our droplet. We should be able to see our website being served from http://164.92.120.60/. I hope I did not just should on us!
Oh my! It actually worked! Wooo Hoooo! But alas, it's only on the Dark Web.
I think Gwen of the Faraday Academy on YouTube is doing a great job educating and helping people in this space. If you want to see an alternative approach, check out her two videos below.
Deploying a Web App with Docker & Github Actions | Part 1
Deploying a Web App to Digital Ocean with Docker & Nginx | Part 2
I also found the Did Coding channel to be helpful. Their Setting up a Digital Ocean Droplet With Docker video was helpful. And their website has The Same Material But In Website Tutorial Form.
That was WAY MORE FUN than we should be allowed to have! But we had it anyway. You should be dancing - yeah! Next step? Let' grow the abilities of our Dockerized website in the wild. There's still tons of things that we can do better, BUT we've learned the basics, and now we can grow a lot from here.
Press p or to see the previous file or, n or to see the next file
Are you sure you want to delete this access key?
Are you sure you want to delete this access key?
Are you sure you want to delete this access key?
Are you sure you want to delete this access key?