Recently, I read a blog post about customizing APIs from Gemini Models, but when I tried following the instructions, everything got stuck at localhost:5000. Basically, my apps were only visible on my computer. So, I went on a quest to figure out how to make it accessible to everyone. That's when I learned about deploying Flask apps on a Digital Ocean droplet. This guide is like a map to help you do the same, so your projects don't get stuck at localhost:5000 either. Let's share your awesome creations with the world! ✨ It's time to unleash them onto the global stage by mastering the art of deploying Flask applications on a Digital Ocean droplet or any Ubuntu Server.
Step by step guide to deploying Flask app in digital ocean droplet using gunicorn and nginx.
Things we are going to cover
- Creating digital ocean droplet
- Preparing environment
- Actual deployment guide
Go to digital ocean and create an account if you don't have one. here is the link
✨ Digital Ocean 🎉 ~ This is a referral link, you will get $200 credit for 60 days. so no more excuses to why your projects are not deployed.
After creating an account, click on the create button and select droplets. You will be presented with a list of options. Select the Ubuntu 20.04 LTS. Choose the plan of your preference. You can choose any data center region you want. I usually choose the one closest to me.
Choose the authentication method. SSH keys are the best but for this guide, we are going to use a password. You can always add SSH keys later.
if you are a windows user get yourself a virtual box and install Ubuntu. or use WSL 😂.
Now that we have our droplet up and running, let's prepare our environment. connect to your droplet using ssh.
ssh root@your_droplet_ipProvide your password and you are in.
sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptoolsthe command sudo apt update refreshes the list of available software packages on your system, ensuring that it has the latest information from the repositories. Following that, sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools installs essential tools and dependencies for Python development. This includes the Python 3 package manager (python3-pip), development headers for Python (python3-dev), fundamental build tools (build-essential), as well as libraries for SSL and FFI (libssl-dev and libffi-dev), and the Python package distribution tools (python3-setuptools).
sudo apt install python3-venvCreate a directory for your project and navigate to it.
mkdir apps
cd appsCreate a virtual environment
python3 -m venv venvActivate the virtual environment
source venv/bin/activatelet's call our project flask_app
git clone your_project_url.git
cd flask_apppip install -r flask_app/requirements.txtnow that we have your project up and running, let's run it and see if everything is working as expected. first lets allow the port we are going to use.
sudo ufw allow 5000
run the app
python app.pyif everything is working as expected, you should be able to access your app using your droplet ip and port 5000.
something like this http://your_droplet_ip:5000
Create a file called wsgi.py in your project root directory.
or just copy app.py to wsgi.py
cp app.py wsgi.pySafe check if gunicorn is installed
gunicorn --versionif not installed install it using pip
pip install gunicorntry running your app using gunicorn
gunicorn --bind 0.0.0.0:5000 wsgi:appCheck your app using your droplet ip and port 5000. something like this http://your_droplet_ip:5000
if everything is working as expected, let's move to the next step.
Create a systemd service file for gunicorn, this will allow gunicorn to automatically start on boot. first deactivate your virtual environment
deactivateThen create a file called flask_app.service in /etc/systemd/system/ directory.
sudo nano /etc/systemd/system/flask_app.serviceAdd the following configuration to the file
[Unit]
Description=Gunicorn instance to serve flask_app
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/root/apps/flask_app
Environment="PATH=/root/apps/venv/bin"
ExecStart=/root/apps/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:5000 -m 777 wsgi:app
[Install]
WantedBy=multi-user.targetAfter creating the file, start the gunicorn service and enable it to start on boot.
sudo systemctl start flask_app
sudo systemctl enable flask_appCheck the status of the service to make sure it's running without any issues.
sudo systemctl status flask_appInstall Nginx
sudo apt install nginxCreate a new server block configuration file in Nginx's sites-available directory.
sudo nano /etc/nginx/sites-available/flask_appAdd the following configuration to the file. Replace your_domain_or_ip with your actual domain name or IP address.
server {
listen 80;
server_name 143.198.232.28;
location / {
proxy_pass https://143.198.232.28:5000;
}
}Create a symbolic link to the file in the sites-enabled directory.
sudo ln -s /etc/nginx/sites-available/flask-app /etc/nginx/sites-enabledTest your Nginx configuration for syntax errors.
sudo nginx -tyou should see something like this
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulIf the test is successful, restart Nginx.
sudo systemctl restart nginxRemember we allowed port 5000 earlier, now we can remove it.
sudo ufw delete allow 5000Now you should be able to access your app using your domain name or IP address without the port number. something like this http://your_droplet_ip
Install certbot
sudo apt install certbot python3-certbot-nginxObtain a free SSL certificate for your domain using certbot if you have a domain.
sudo certbot --nginx -d your_domain_or_ipCertbot will ask you to provide an email address for lost key recovery and notices, and to agree to the terms of service. After doing so, certbot will communicate with the Let's Encrypt server, then run a challenge to verify that you control the domain you're requesting a certificate for.
When that's finished, certbot will ask how you'd like to configure your HTTPS settings.
or you can use openssl to generate a self-signed certificate.
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/flask_app.key -out /etc/ssl/certs/flask_app.crtCreate a new server block configuration file in Nginx's sites-available directory.
sudo nano /etc/nginx/sites-available/flask_appAdd the following configuration to the file. Replace your_domain_or_ip with your actual domain name or IP address.
server {
listen 80;
server_name
location / {
proxy_pass https://your_domain_or_ip;
}
}
server {
listen 443 ssl;
server_name your_domain_or_ip;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
location / {
proxy_pass https://your_domain_or_ip;
}
}This configuration tells Nginx to listen on both port 80 (HTTP) and port 443 (HTTPS). It uses the self-signed certificate and private key that you created.
After updating the Nginx configuration, remember to test the configuration and reload or restart Nginx:
sudo nginx -t
sudo systemctl reload nginxThe nginx -t command checks the configuration for syntax errors. The systemctl reload nginx command reloads the Nginx configuration without interrupting currently connected clients.
Please note that because the certificate is self-signed, browsers will show a warning to users that the site is not secure. Users will need to manually accept the risk and proceed to the site.
Hopefully with this guide, you were able to deploy your flask app in a digital ocean droplet. Your projects are way too precious to be running on localhost. Deploy them and share them with the world. If you have any questions or suggestions, feel free to reach out help is everywhere. ✨

