Olav A Olav A - 5 months ago 40
Python Question

Custom flask application running fine on localhost but returning 500 response to external visitors

Latest update: The problem had indeed to do with permission and user groups, today I learned why we do not simply use root for everything. Thanks to Jakub P. for reminding me to look into the apache error logs and thanks to domoarrigato for providing helpful insight and solutions.

What's up StackOverflow.

I followed the How To Deploy a Flask Application on an Ubuntu VPS tutorial provided by DigitalOcean, and got my application to successfully print out
Hello, I love Digital Ocean!
when being reached externally by making a
request to my public server IP.

All good right? Not really.

After that, I edit the tutorial script and write a custom flask application, I test the script in my personal development environment and it runs without issue, I also test it on the DigitalOcean server by having it deploy on localhost and making another

All works as expected until I try to access it from my public DigitalOcean IP, now suddenly I am presented with a
500 Internal Server Error

What is causing this issue, and what is the correct way to debug in this case?

What have I tried?

  • Setting
    app.debug = True
    gives the same
    500 Internal Server Error
    without a debug report.

  • Running the application on the localhost of my desktop pc and DigitalOcean server gives no error, the script executes as expected.

  • The tutorial code runs and executed fine, and making a
    request to the Digital Ocean public IP returns the expected response.

  • I can switch between the tutorial application and my own application and clearly see that I am only getting the error wit my custom application. However the custom application still presents no issues running on localhost.

My code

from flask import Flask, request, redirect
from netaddr import IPNetwork
import os
import time

app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))

# Custom directories
MODULES = os.path.join(APP_ROOT, 'modules')
LOG = os.path.join(APP_ROOT, 'log')

def check_blacklist(ip_adress):
ipv4 = [item.strip() for item in open(MODULES + '//ipv4.txt').readlines()]
ipv6 = [item.strip() for item in open(MODULES + '//ipv6.txt').readlines()]

for item in ipv4 + ipv6:
if ip_adress in IPNetwork(item):
return True


return False

def hello():
ip_adress = request.environ['REMOTE_ADDR']
log_file = open(LOG + '//captains_log.txt', 'a')

with log_file as f:

if check_blacklist(ip_adress):
f.write('[ {}: {} ][ FaceBook ] - {} .\n'
.format(time.strftime("%d/%m/%Y"), time.strftime("%H:%M:%S"), request.environ))
return 'Facebook'

f.write('[ {}: {} ][ Normal User ] - {} .\n'
.format(time.strftime("%d/%m/%Y"), time.strftime("%H:%M:%S"), request.environ))
return 'Normal Users'

if __name__ == '__main__':
app.debug = True

The tutorial code:

from flask import Flask
app = Flask(__name__)
def hello():
return "Hello, I love Digital Ocean!"
if __name__ == "__main__":


Seems like the following line could be a problem:

log_file    = open(LOG + '//captains_log.txt', 'a')

if the path its looking for is: '/var/www/flaskapp/flaskapp/log//captains_log.txt'

that would make sense that an exception is thrown there. Possible that the file is in a different place, on the server, or a / needs to be removed - make sure the open command will find the correct file.

If captains_log.txt is outside the flask app directory, you can copy it in and chown it. if the txt file needs to be outside the directory then you'll have to add the user to the appropriate group, or open up permissions on the actual directory.

chown command should be:

sudo chown www:www /var/www/flaskapp/flaskapp/log/captains_log.txt

and it might be smart to run:

sudo chown -r www:www /var/www