A DeepDive To Where Virtual Computers Exist
DigitalOcean’s primary role is to provide virtual machines, which are essentially computers in the cloud. Each of these machines comes with a dedicated public IP address. This means that when we deploy anything on our virtual machine, DigitalOcean ensures it has a globally reachable IP and specific ports that services listen on.
This article would cover some basic concepts of DigitalOcean and some common error occurrences that you might witness whilst making your first virtual machine acessible to the internet
Droplets
The core concept in DigitalOcean is something called a Droplet. A Droplet is simply your virtual machine.
When a Droplet is created, an operating system needs to be installed on it. These virtual machines run on the Linux kernel, and the most commonly used OS is Ubuntu.
This Ubuntu setup does not include a graphical interface. There is no desktop environment. Everything is done through the terminal, and we interact with the server entirely via the command line.
This is how we navigate, configure services, deploy applications, and manage the system.
Core Idea
- DigitalOcean is a platform where we can get access to virtual machines.
- These machines run Linux kernels on them, and while creating a virtual machine we can choose which operating system we want. The most popular choice is Ubuntu.
- These virtual machines are called Droplets. Each Droplet is assigned a public IP address by DigitalOcean.
- In most cases, if nothing is hosted on the Droplet yet, that public IP is not accessible via the web.
- The configuration of the Droplet decides what can be done with its public IP. Sometimes the public IP is only available for SSH access. The fact that we can SSH into a remote server itself proves that the Droplet has a public IP.
- After connecting through SSH, we need to authenticate. This is usually done using a password or SSH key. Only after successful authentication do we get access to our virtual machine.
Now for you to follow the next parts, let me tell you what you need. We are trying to run a flask application on our linux server. So the idea is to upload a python code onto our virtual machine and make it available to the world
Part 1: Initial Checks and Installing Python Package Manager
I expect you to have ssh into your root server ( Some lingo that a lot many tv channels use to sound CS complex ) To simply break it down for you, what we would do is, open our shell, write this commands
ssh root@<Your public ip> after this youll be prompted to add enter your password, this you would have created during droplet instantiation
Now lets perform some system checks.
ss -tulpn
- ss = Socket Statistics (shows network connections)
- -t = TCP connections
- -u = UDP connections
- -l = Listening ports (ports waiting for connections)
- -p = Show process using the port
- -n = Show numerical addresses (don’t convert to names)
Why? You were checking what ports were already in use on your server.
Now since i said we would be running a flask application, i would need the flask module since i am using python to make a web application.
pip3 install flask
- pip3 = Python’s package installer (the “3” means Python 3 version)
- This command failed because pip3 wasn’t installed yet.
Also keep in mind, given we have entered our VM for the first time, dont expect it to be loaded up with any modules except the ones your VM needs prompted by its kernel. So how do we add the flask module/ package?
apt install python3-pip
- apt = Advanced Package Tool (Ubuntu’s software installer)
- Installs pip3 so you can install Python packages
Now we are at a stage where pip3 is in our VM! We can now use pip3 to install packages in our VM.
Part 2: The “Externally Managed Environment” Error
Do you think after adding the pip3 as a package into our VM, my pip3 install flask command would succeed now?
The answer is NO. Here is why:
Modern Ubuntu versions (like 25.04) prevent you from installing Python packages globally using pip directly. This is to avoid breaking system tools that rely on specific Python package versions.
Think of it like this: Your Ubuntu system uses Python for many of its own tools. If you randomly install packages globally, you might accidentally update a package that Ubuntu needs at a specific version, breaking your system
Part 3: Setting Up a Virtual Environment (The Right Way)
So how do we do it? Yes you guessed it right. By setting up a virtual enviroment that isolates what goes on in its env from the global context which in our case, would absoluetly solve our problem
apt install -y python3-venv python3-full
- python3-venv = Tool to create isolated Python environments (downloads python venv module )
- python3-full = Complete Python installation with all modules
- -y = Automatically say “yes” to installation prompts
This gives creates a python virtual env. This wont alter ubuntu’s default python packages, thereby not throwing in an error
mkdir flask-test
- mkdir = Make Directory
- Creates a folder to keep your Flask project organized
cd flask-test
- cd = Change Directory
- Moves you into the flask-test folder
python3 -m venv venv
Let me break this down carefully:
- python3 = Run Python 3
- -m = Run a module as a script
- venv (first one) = The name of Python’s virtual environment module ( We just installed it )
- venv (second one) = The name you’re giving to your virtual environment folder ( We can name it anything we want )
What this does: Creates an isolated Python environment in a folder called “venv”. This environment has its own copy of Python and pip, separate from the system.
Get Sanshray’s stories in your inbox
Join Medium for free to get updates from this writer.
Why virtual environments?
- Keeps your project’s packages separate from system packages
- You can have different Flask versions for different projects
- You won’t break system tools
- Easy to delete and recreate if something goes wrong
source venv/bin/activate
- source = Run a script in your current shell
- venv/bin/activate = The activation script
What happens: Your command prompt changes to show (venv), meaning you’re now working inside the virtual environment. Any packages you install now go into this isolated environment, not system-wide.
pip install flask
Notice it’s just pip now, not pip3, because inside the virtual environment, pip automatically uses Python 3. This installs Flask and all its dependencies into your virtual environment only.
It runs now and that too with no errors!
Part 4: Creating and Running Your Flask App
nano app.py
- nano = A simple text editor in the terminal ( Just like vs code but for applications not using GUI )
- app.py = The file you created containing your Flask code
You probably wrote something like:
from flask import Flask
app = Flask(__name__)@app.route(‘/’)
def hello():
return “Hello World!”if __name__ == ‘__main__’:
app.run(host=’0.0.0.0', port=5000)
Simply save, and exist the terminal. You still must be in your .venv folder. Now its almost done
python app.py
Runs your Flask application. The output shows:
- 127.0.0.1:5000 = localhost (accessible only from the server itself)
- 139.59.40.155:5000 = Your public IP (should be accessible from anywhere)
- 0.0.0.0 = Listen on all network interfaces (makes it publicly accessible)
Now if you followed correctly, follwed the steps, here are some issues you can face.
Part 5: Firewall Configuration (Why You Couldn’t Access It)
The Problem
Its likey that when you now go to you <public-ip>:5000, You should expect to see your flask app.
Even though Flask was running on port 5000, you couldn’t access it from your browser because the firewall was blocking that port.
Now to debug this, open another window in powershell. Ssh into your root server again and try these commands.
ufw status
- ufw = Uncomplicated Firewall (Ubuntu’s firewall tool)
- Shows which ports are allowed through the firewall
What we expect to see:
- 22/tcp = SSH (how you connect to your server remotely)
- 3100/tcp and 3500/tcp = Other services you’d configured earlier
- No 5000/tcp = That’s why it wasn’t working! ( In my case port 5000 wasn’t configured to anything)
ufw allow 5000/tcp
- allow = Permit traffic through the firewall
- 5000 = The port number
- tcp = Transmission Control Protocol (the type of connection Flask uses)
What this does: Opens port 5000 in the firewall so web traffic can reach your Flask app.
Key Concepts Summary
Virtual Machine (Droplet)
A computer running in Digital Ocean’s data center that you can control remotely. You connected via SSH (Secure Shell) on port 22.
Port
A numbered gateway for network connections. Your computer has 65,535 ports. Port 5000 is where your Flask app listens for web requests.
Firewall (ufw)
A security barrier that blocks unwanted network traffic. You must explicitly allow ports for services to be accessible from the internet.
Virtual Environment (venv)
An isolated Python workspace where you can install packages without affecting the rest of your system.
Flask
A lightweight web framework for Python that lets you build web applications.
Why This Approach Is Important
- Security: Running as root (as you did) is convenient but risky in production. The virtual environment at least isolates your packages.
- Reproducibility: Anyone can recreate your environment by installing from a requirements.txt file.
- Safety: System packages won’t break if you experiment with different Python libraries.
What Happens Now
When someone visits http://<your_public_ip>:5000 in their browser:
- Request reaches Digital Ocean’s network
- Firewall (ufw) checks if port 5000 is allowed ✓
- Request reaches your Flask app running on port 5000
- Flask processes the request and sends back a response
- Your browser displays the result
You’ve successfully deployed a web application!








