{"id":1900,"date":"2025-04-10T08:00:00","date_gmt":"2025-04-10T05:00:00","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/running-containers-with-docker-on-upcloud-a-complete-guide\/"},"modified":"2025-04-10T08:00:00","modified_gmt":"2025-04-10T05:00:00","slug":"running-containers-with-docker-on-upcloud-a-complete-guide","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/running-containers-with-docker-on-upcloud-a-complete-guide\/","title":{"rendered":"Running Containers with Docker on UpCloud: A Complete Guide"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Containerization technology has revolutionized the way we build, distribute, and run software. It provides a lot of advantages including less resource overhead, portability, and startup speed. The evolution of containerization also paved the way for the microservices architecture to be widely adopted. Since a typical microservices application can be composed of tens or hundreds of separate components, it\u2019s more efficient to use containers for deploying these microservices at scale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the world of containers, Docker is considered one of the most adopted tools for building and running containerized applications. Docker is the container engine that enables the creation and running of the container environment, while abstracting the low-level technologies of the Linux kernel that provide the functionality of the containers. This abstraction creates an easy-to-use interface for developers to work with containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Docker requires an underlying infrastructure of servers, networking, and storage to satisfy the requirements for running the containers. By leveraging a scalable and performant Cloud environment like UpCloud, we can provide the required infrastructure for running Docker and its containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we\u2019re going to cover the steps for installing and configuring Docker on a Cloud server using UpCloud. We\u2019ll then go through the process of building and running a containerized application with Docker. Throughout this guide, you\u2019ll be able to practice the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Installing Docker on a Linux server<\/li>\n\n\n\n<li>Create a Dockerfile for an application<\/li>\n\n\n\n<li>Build a container image from Dockerfile<\/li>\n\n\n\n<li>Run a container from the image using Docker<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To follow along with this guide, you\u2019ll need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Create an <\/strong><a href=\"https:\/\/signup.upcloud.com\/\"><strong>UpCloud account<\/strong><\/a><strong>:<\/strong> This gives you access to different UpCloud services using the GUI control panel, <a href=\"https:\/\/upcloud.com\/global\/resources\/tools\/upcloud-command-line-interface\">command-line interface<\/a>, or the <a href=\"https:\/\/upcloud.com\/global\/resources\/tools\/category\/api-clients\">API<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/deploy-server\"><strong>Deploy a Cloud server on UpCloud<\/strong><\/a><strong>:<\/strong> This is going to be our target server where we\u2019ll install Docker and run our containers.<\/li>\n\n\n\n<li><strong>Create a <\/strong><a href=\"https:\/\/docs.docker.com\/accounts\/create-account\/\" target=\"_blank\" rel=\"noopener\"><strong>Docker Hub account<\/strong><\/a><strong>:<\/strong> Docker Hub is a centralized location for publishing and distributing container images. We\u2019ll use it in this guide to work with our image.<\/li>\n\n\n\n<li><strong>Familiarity with using the CLI:<\/strong> We\u2019ll be using some basic commands throughout this guide to install our tools, navigate project directories, and work with SSH.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Installing Docker<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s begin by installing Docker on our Cloud server. For this guide, we\u2019ll be using an Ubuntu server, but you can find the steps for other operating systems on <a href=\"https:\/\/docs.docker.com\/engine\/install\/\" target=\"_blank\" rel=\"noopener\">Docker\u2019s official documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Connect to your UpCloud server using SSH. You\u2019ll first need to <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/use-ssh-keys-authentication\/\">generate an SSH key and use it for your server<\/a>. Then you can use the command <code>ssh -i &lt;key-file> root@&lt;server-IP>.<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, install Docker using the following steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Remove any unofficial packages that might conflict with the installation packages.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Update apt package repository index.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">apt-get update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Add Docker&#8217;s official GPG key.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">apt-get install ca-certificates curl\ninstall -m 0755 -d \/etc\/apt\/keyrings\ncurl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg -o \/etc\/apt\/keyrings\/docker.asc\nchmod a+r \/etc\/apt\/keyrings\/docker.asc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Add the Docker repository to Apt sources.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">echo \\\n   \"deb [arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.asc] https:\/\/download.docker.com\/linux\/ubuntu \\\n   $(. \/etc\/os-release &amp;&amp; echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\") stable\" | \\\n   sudo tee \/etc\/apt\/sources.list.d\/docker.list > \/dev\/null<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">5. Update the repository index again.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">apt-get update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">6. Install Docker.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">7. Verify the Docker installation and version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">docker --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the installation was successful, the output will print the Docker version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Docker version 28.0.4, build b8034c0<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparing the Local Environment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we\u2019ve Docker installed and running on our server, the next step will be to clone the project repository from GitHub to our local environment so we can work on it. Let\u2019s first verify that Git is installed correctly on our machine with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">git --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the output shows the version of Git, this means that it\u2019s already installed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">git version 2.43.0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next we\u2019ll need to clone the repository with the following command:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">git clone https:\/\/github.com\/Amr-tmorot\/sample-python-app.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will create a local copy of the repository on our environment:\u00a0<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-containers-with-Docker-on-UpCloud-1-1024x485.png\" alt=\"-\" class=\"wp-image-49595\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As we can see in the above image, the project files are now pulled to our local machine. For this guide, we\u2019re mostly concerned with the <code>src <\/code>directory and the <code>requirements.txt <\/code>file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>src <\/code>directory contains the source code for our application, which is a simple Python Flask application that prints a <code>\u201cHello World\u201d<\/code> message, and runs on port <code>5001<\/code> by default. The <code>requirements.txt <\/code>file contains a list of the dependencies (packages\/libraries) that we need for our application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create and Inspect the Dockerfile<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Dockerfile is a text file which contains instructions and commands that Docker uses to create and build a container image. To containerize our application, create a Dockerfile with the following steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Create a new file with the name <code>Dockerfile <\/code>in the root of the project directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">touch Dockerfile<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Open the file with a text editor and paste the following content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">FROM python:3.8.0-alpine3.10\n\nUSER root\n\nWORKDIR \/app\nCOPY src\/ \/app\/src\/\nCOPY .\/requirements.txt \/app\n\nRUN pip3 install --upgrade pip\nRUN pip3 install --no-cache-dir -r \/app\/requirements.txt\n\nUSER 1001\n\nENTRYPOINT [\"python3\", \"\/app\/src\/app.py\"]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These instructions in the Dockerfile follow the <a href=\"https:\/\/docs.docker.com\/reference\/dockerfile\/\" target=\"_blank\" rel=\"noopener\">specification reference<\/a> for the syntax.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s understand our Dockerfile contents:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-2.png\" alt=\"-\" class=\"wp-image-49597\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the above image, we can see our Dockerfile starts with a <code>FROM <\/code>instruction, this specifies the base image that we\u2019ll use. A base image is a starting layer from which we\u2019ll build our container image, it typically contains a minimal operating system and other tools that we\u2019ll need for our container. Here we use the <code>python:3.8.0-alpine3.10 <\/code>base image which will contain Python for running our application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>USER<\/code> instruction specifies which user you want to execute the commands with during the image build process. Here we specify the <code>root <\/code>user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>WORKDIR<\/code> instruction specifies the working directory inside the image that we need to use for the following instructions. Here we specify the <code>\/app <\/code>as our working directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>COPY <\/code> instruction copies files from our local environment filesystem to the image filesystem. Here we copy our <code>src <\/code>folder and the <code>requirements.txt <\/code>file inside the image\u2019s <code>\/app <\/code>directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>RUN<\/code> instruction executes a specific command during the build process. Here we first upgrade the <code>pip<\/code> package manager, and then we use it to install the dependencies in our <code>requirements.txt <\/code>file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, the <code>ENTRYPOINT<\/code> instruction specifies the process or the command that will run when a container is started from this image. Here we want to start our Python application from its source file <code>app.py.<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Building the Container Image<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we understand our Dockerfile, it\u2019s time to build a container image from it. Building an image is the process of executing the instructions inside the Dockerfile to create actual binary data that includes our application, dependencies, and any other files that we copied to the image.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The image build process creates the image on the local filesystem, which is not an efficient option if we want to publish and share the image. Therefore, we need a centralized location where we can store our image and access it from multiple places. This location is the image registry, which in our case is Docker Hub.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So before starting the build process, go to your Docker Hub account and <a href=\"https:\/\/docs.docker.com\/docker-hub\/repos\/create\/\" target=\"_blank\" rel=\"noopener\">create a repository<\/a> to store the image.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ve created my repository with the name <code>python-hello-world:<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-3-1024x499.jpg\" alt=\"-\" class=\"wp-image-49599\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now to build the image from the Dockerfile we can use the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">docker build -t &lt;username>\/&lt;repository> .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the <code>&lt;username><\/code> above with your Docker Hub username, and the <code>&lt;repository> <\/code>with the repository name that you just created on Docker Hub.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-4-1024x666.png\" alt=\"-\" class=\"wp-image-49600\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the above image, we can see the logs of our build process showing the execution of our Dockerfile instructions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once the build is complete, we can push our image to the Docker Hub repository. Since we already tagged our image with the repository name, we can use the same tag to push the image with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">docker push &lt;username>\/&lt;repository><\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-5-1024x442.png\" alt=\"-\" class=\"wp-image-49601\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If you receive an access denied error like the above, this means you need to authenticate to your Docker Hub account from the command line. We can do this with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">docker login -u &lt;username><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again replace the <code>&lt;username><\/code> with your Docker Hub user.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-6-1024x415.png\" alt=\"-\" class=\"wp-image-49602\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can then try to push the image again and should be successful.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-7-1024x371.png\" alt=\"-\" class=\"wp-image-49603\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now that our image is pushed to the registry, we can use it from anywhere that has access to this registry.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running a Container From the Image<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since we already have our image in the registry and we configured our local environment to access it, starting a container from this image is a matter of running the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">docker run -p 5001:5001 &lt;username>\/&lt;repository><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the above command, we\u2019re telling Docker to start a new container and expose port 5001 (the port that the application listens on) from inside the container to port 5001 on our local host machine. As you did previously, replace the <code>&lt;username>\/&lt;repository> <\/code>with your Docker Hub user and the image repository name.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-8-1024x282.png\" alt=\"-\" class=\"wp-image-49604\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The container is now running and the application is listening for requests. Now leave this terminal open and open a new one to send a simple request using the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">curl localhost:5001\ncurl localhost:5001\/ping<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/Running-Containers-with-Docker-on-UpCloud-9-1024x406.png\" alt=\"-\" class=\"wp-image-49605\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As we can see, the endpoints are responding correctly to our requests which means that our application is running as expected.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Containerization has offered great advantages when building and running software. It allows for better resource utilization, more portability between environments, and faster startup times. Docker is one of the most adopted tools in the container technology landscape. It offers a way to build and run containers with simple commands while abstracting the low-level complexity. In this article, we covered a step-by-step walkthrough for installing Docker and running a containerized application using UpCloud cloud servers. We started by creating a Dockerfile that specifies what the image should contain. Then we built and pushed the image to the Docker Hub registry. Finally, we tested our image by running a container from the image on our cloud server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ready to build and deploy your containerized application in the Cloud? <a href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud<\/a> now and create a scalable and performant infrastructure for your container environments.<\/p>\n","protected":false},"author":85,"featured_media":49610,"comment_status":"open","ping_status":"closed","template":"","community-category":[241],"class_list":["post-1900","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/1900","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/85"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=1900"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/1900\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=1900"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=1900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}