Django Heroku Porting - django

Trying to set up Django configurations for a public url.
So I ran this first.
$ echo "web: python manage.py runserver 0.0.0.0:\$PORT" > Procfile
$ git add Procfile
$ git commit -m "Specify the command to run your project"
In Procfile:
web: python manage.py runserver 0.0.0.0:\$PORT
release: python manage.py migrate
In Settings.py:
PORT = os.getenv("PORT", default="5000")
# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True
DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'
ALLOWED_HOSTS = ["url"]
In env.:
PORT=5000
SECRET_KEY=value
Was using the above commands and got
(portfolio) PS C:\Users\arund\Desktop\Code\Django\portfolio-project> heroku config:get PORT
5000
(portfolio) PS C:\Users\arund\Desktop\Code\Django\portfolio-project> heroku local
[OKAY] Loaded ENV .env File as KEY=VALUE Format
3:08:10 PM web.1 | CommandError: "0.0.0.0:\$PORT" is not a valid port number or address:port pair.
[DONE] Killing all processes with signal SIGINT
3:08:10 PM web.1 Exited with exit code null
I also used $PORT without the backslash and $. How would I proceed from here to make the public url working.
CommandError: "0.0.0.0:PORT" is not a valid port number or address:port pair does the same thing.
web: python manage.py runserver 0.0.0.0:5000 will work though for local

Use gunicorn to serve your web application via Heroku as described here:
https://devcenter.heroku.com/articles/python-gunicorn
Regarding your error, I think you're technically escaping the $ and so its not expanding the variable.
Try removing the \ or, for debugging purposes see if this works by hard coding the port you expect to be in $PORT and see if that works, if it does, I imagine you need to set the $PORT env variable.

Took me about 2 hours to finally figure out what was happening that's why I'm dropping this answer for anyone it might help. If you're using a Windows OS locally (say powershell on vscode), either $PORT or \$PORT will not be parsed as environmental variables. So you might want to test out with something hardcoded like 5000. But since the Heroku OS is Linux based, it is recognized. So in short, locally, you can use
'web: python manage.py runserver 0.0.0.0:5000'
and before pushing to Heroku, change the line to
'web: python manage.py runserver 0.0.0.0:$PORT'
(without the backslash, the backslash escapes on Linux).

Related

How to see full Heroku stacktrace in logs?

When I deploy my Django app to Heroku, in the console (heroku logs --tail -a george-paintings) I see an error:
2021-04-15T15:14:42.109272+00:00 app[web.1]: Error: No application module specified.
2021-04-15T15:14:42.161597+00:00 heroku[web.1]: Process exited with status 1
2021-04-15T15:14:42.290903+00:00 heroku[web.1]: State changed from starting to crashed
But I can't figure out what particular went wrong. My Procfile looks like this
web: gunicorn --pythonpath application.george_paintings.george_paintings.wsgi --log-file - --log-level debug
Where can I find more info about my error?
I suspect there's nothing more to see. A good first step would be to try running heroku local to see if you are having the same problem on your development machine. This will use your Procfile whereas if you are running via python manage.py migrate or similar your Procfile will not be used.
The error gives a good hint, though:
app[web.1]: Error: No application module specified.
Gunicorn expects an application module name as a command-line argument. I suspect you intend application.george_paintings.george_paintings.wsgi to be interpreted as your application module, but it's getting swallowed up as an argument to --pythonpath:
gunicorn --pythonpath application.george_paintings.george_paintings.wsgi #...
You shouldn't need to explicitly provide a PYTHONPATH. Try removing that argument from your Procfile entirely:
gunicorn application.george_paintings.george_paintings.wsgi --log-file - --log-level debug
If this works locally with heroku local, commit the change and redeploy.
If not, take a look at your directory structure. application.george_paintings.george_paintings.wsgi is a bit of a weird module name for a Django project. Usually you'd just need something like george_paintings.wsgi (indicating that Gunicorn should use the Python module it finds at george_paintings/wsgi.py as its entry point).

Connect refused in response to Django runserver

Working my way through a Django tutorial, I have run django-admin startproject mysite. Now I cannot get the next step to work.
$ python manage.py runserver
>>>
$
where the blank line is where Ctrl-C was entered to break the loop. The >>> was the prompt I defined for the virtualenv. In other words, no output.
Most importantly, I get a connection refused error when connecting to http://127.0.0.1:8000. I do not get the the "'Welcome to Django' page, in pleasant, light-blue pastel" as described in the tutorial.
For other commands python manage.py works correctly. For example:
$ python manage.py check
System check identified no issues (0 silenced).
$ python manage.py shell --command 'import sys; print(sys.version)'
3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)]
$/ python manage.py shell --command 'import django; print(django.__version__)'
1.11.2
I am at loss for how explore further. I have tried:
Using multiple browsers
Varying the IP and port, including using LOCALHOST.
Turning off the proxy
Consulting other Stack Overflow, such as here and here
Rebooting my computer
Exploring Chrome's log's. Perhaps someone else can get something valueable out of these: Request Headers & Timing Diagram.
I am at loss for other steps to debug this problem.
If you didn't change something in the settings.py you should enter the service in
localhost:8000
Using the same machine where you are runing the server.
If you want to enter from another computer in the same network you should use
$ python manage.py runserver 0.0.0.0:8000
And change your "allowed hosts" to the ip of your computer or to *

Running Docker-Compose Commands With Fabric

I have a Django site running in Docker containers, which uses docker-compose to manage the various containers (database, nginx, etc.). There are a few Django tasks that I use for site maintenance using the Django manage.py command. They commands take the form of:
manage.py updateflickr --settings=mysite.myproj.prod
Running under docker-compose, they look like:
docker-compose run --rm app manage.py updateflickr --settings=mysite.myproj.prod
My problem is that when I try to run these same commands using Fabric, it appears that the settings file I am specifying is not being used. Django is returning database connection errors, which typically mean that it is not getting the correct database information, or in this case the connection specified in mysite.myprod.prod
My Fabric file looks like:
import os
from fabric.api import *
env.hosts = ['myserver.com']
env.user = "myuser"
env.key_filename = '~/.ssh/do_rsa'
env.shell = '/bin/bash -c'
#task
def updateflickr():
run('docker-compose run --rm app python manage.py updateflickr --settings=mysite.myproj.prod')
I have also expirimented with setting the DJANGO_SETTINGS_MODULE environment variable in my docker-compose.yml but am getting the same results. Finally, the last thing I tried was wrapping the command in a shell script. Same results - if I run on the server, it runs fine. If I run the shell script from Fabric, I get database connection issues.
UPDATE
I am not so sure this is so much a question about Fabric, then a question about how docker-compose runs. If I try the following:
ssh -t me#myserver.com 'docker-compose run --rm app python manage.py updateflickr --settings=mysite.myproj.prod'
I still get the same results. There must be something different about loading up an interactive shell with just sending a command. I have tried using ssh with and without a -t flag, because docker-compose might need a pty active.

how to use upstart?

I have a django app that i am looking to deploy. I would like to use upstart to run the app.
So far I have added the upstart.conf file to /etc/init
and tried to run it using
start upstart
but all i get is
start: Rejected send message, 1 matched rules; type="method_call", sender=":1.90" (uid=1000 pid=5873 comm="start upstart ") interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply="0" destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")
the contents of the .conf file are:
# my upstart django script
# this script will start/stop my django development server
# optional stuff
description "start and stop the django development server"
version "1.0"
author "Calum"
# configuration variables.
# You'll want to change thse as needed
env DJANGO_HOME=/home/django/django-nexus7/nexus7
env DJANGO_PORT=8000
env DJANGO_HOST=0.0.0.0 # bind to all interfaces
# tell upstart we're creating a daemon
# upstart manages PID creation for you.
#expect fork
pre-start script
chdir $DJANGO_HOME
exec /usr/bin/python rm sqlite3.db
exec /usr/bin/python manage.py syncdb
exec /usr/bin/python manage.py loaddata fixtures/data.json
emit django_starting
end script
script
# My startup script, plain old shell scripting here.
chdir $DJANGO_HOME
exec /usr/bin/python manage.py run_gunicorn -c config/gunicorn
#exec /usr/bin/python manage.py runserver $DJANGO_HOST:$DJANGO_PORT &
# create a custom event in case we want to chain later
emit django_running
end script
i have also tried using a much simpler .conf file but have come up with more or less the same error.
Would really appreciate it if someone could give me an idea of what im doing wrong
Upstart jobs can only be started by root, and that error appears if you try to start one as a normal user. Try this:
sudo start upstart

Getting Django in a VirtualEnv to run through Upstart

I've been trying to trudge through the docs and examples to get my Django running through upstart so I can have it running all the time but am unable to so.
Here's my upstart configuration file located at /etc/init/myapp.conf:
start on startup
#expect daemon
#respawn
console output
script
chdir /app/env/bin
exec source activate
exec /app/env/bin/python /app/src/manage.py runserver 0.0.0.0:8000 > /dev/null 2>&1 &
end script
When I type sudo service myapp start, the console says that it has started but it doesn't seem to be running.
Is it possible to see some debugging output to see what's going wrong?
I need to run my Django application as another user — i.e. djangouser. How can I do so?
(I've been commenting out some lines to test where the service is going wrong). This is not for production use but my internal development use only.
Thanks.
Edit #1:
I have wrapped both my commands into a simple script at /app/run.sh
#!/bin/bash
cd /app/env/bin
source activate
cd /app/src
python manage.py runserver 0.0.0.0:8000 > /dev/null 2>&1 &
..and I've modified my /etc/init/myapp.conf to
start on startup
expect daemon
exec su - djangouser -c "bash /app/run.sh"
When executing sudo service myapp start — the application starts but the PID is wrong and I can't seem to kill it with sudo service myapp stop
Any ideas?
Change:
exec source activate
By just:
source activate
This will load the virtual environment. You should probably drop the other "exec". If that doesn't work, please post your upstart logs.
A couple of remarks:
logging the output to somewhere else than /dev/null might be useful :)
runserver is not ment to be stable, I see it crashing sometimes and in that case i guess you'll need to force upstart to reload, or put the runserver call in a while loop
you will not be able to use an interactive debugger like ipdb with this setup
How about using nginx and uwsgi with your virtualenv. this will give you a production like environment but will also start your django app at start up. if you are using ubuntu 10 you should take a look at uwsgi-python, otherwise just install the latest uwsgi. i usually start my virtualenv in uwsgi like so : sudo nano /etc/uwsgi-python/apps-available/app.xml
<uwsgi>
<socket>127.0.0.1:8889</socket>
<pythonpath>/home/user/code/</pythonpath>
<virtualenv>/home/user/code</virtualenv>
<pythonpath>/home/user/code/app</pythonpath>
<app mountpoint="/">
<script>uwsgiApp</script>
</app>
</uwsgi>
also setup yournginx files at /etc/nginx/apps-available/default (the file is a bit straight forward). this will help you have your django app at all times,
su is problematic becouse it forks the process. You can use sudo -u djangouser instead or simply add
setuid djangouser
in your conf file.
This should work on Ubuntu 14.04 and possibly other versions as well:
root#vagrant-ubuntu-trusty-64:/etc/init# service my_app start
my_app start/running, process 7799
root#vagrant-ubuntu-trusty-64:/etc/init# cat /var/log/upstart/my_app.log
Performing system checks...
System check identified no issues (0 silenced).
You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.
June 30, 2015 - 06:54:18
Django version 1.8.2, using settings 'my_test.settings'
Starting development server at http://0.0.0.0:8080/
Quit the server with CONTROL-C.
root#vagrant-ubuntu-trusty-64:/etc/init# service my_app status
my_app start/running, process 7799
root#vagrant-ubuntu-trusty-64:/etc/init# service my_app stop
my_app stop/waiting
root#vagrant-ubuntu-trusty-64:/etc/init# service my_app status
my_app stop/waiting
Here is the config to make it work:
root#vagrant-ubuntu-trusty-64:/etc/init# cat my_app.conf
description "my_app upstart script"
start on runlevel [23]
respawn
script
su vagrant -c "source /home/vagrant/dj_app/bin/activate; /home/vagrant/dj_app/bin/python /home/vagrant/my_test/manage.py runserver 0.0.0.0:8080"
end script