I have a basic django rest application in my digital ocean server (Ubuntu 16.04) with a local virtual environment.
The basic wsgi.py is:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "workout_rest.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)
I have followed step by step this tutorial:
https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
When I test Gunicorn's ability to serve the project with this command:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
All works well.
So I've tried to setup Gunicorn to use systemd service file.
My /etc/systemd/system/gunicorn.service file is:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ben
Group=www-data
WorkingDirectory=/home/ben/myproject
ExecStart=/home/ben/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/ben/myproject/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
My Nginx configuration is:
server {
listen 8000;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ben/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ben/myproject/myproject.sock;
}
}
I've changed listen port from 80 to 8000 because 80 give me a err_connection_refused error.
After starting the server with this command:
sudo systemctl restart nginx
When I try to run my website, I get an 502 Bad Gateway error.
I've tried these commands (found on the tutorial comments):
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
sudo systemctl restart nginx
but nothing changes.
When I take a look at the Nginix logs with this command:
sudo tail -f /var/log/nginx/error.log
I can read that sock file doesn't exists:
2016/10/07 09:00:18 [crit] 24974#24974: *1 connect() to unix:/home/ben/myproject/myproject.sock failed (2: No such file or directory) while connecting to upstream, client: 86.197.20.27, server: 139.59.150.116, request: "GET / HTTP/1.1", upstream: "http://unix:/home/ben/myproject/myproject.sock:/", host: "server_ip_adress:8000"
Why this sock file isn't created? How can I configure django/gunicorn to create this file?
I have added gunicorn in my INSTALLED_APP in my Django project but it doesn't change anything.
EDIT:
When I test the nginx config file with nginx -t I get an error: open() "/run/nginx.pid" failed (13: Permission denied).
But if I run the command with sudo: sudo nginx -t, the test is successful. Does that mean that I have to allow 'ben' user to run Ngnix?
About gunicorn logfile, I cannot find a way to read them. Where are they stored?
When I check whether gunicorn is running by using ps aux | grep gunicorn:
ben 26543 0.0 0.2 14512 1016 pts/0 S+ 14:52 0:00 grep --color=auto gunicorn
Here is hat happens when you run the systemctl enable and start commands for gunicorn:
sudo systemctl enable gunicorn
Synchronizing state of gunicorn.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable gunicorn
sudo systemctl start gunicorn
I get no output with this command
sudo systemctl is-active gunicorn
active
sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
Active: active (exited) since Thu 2016-10-06 15:40:29 UTC; 23h ago
Oct 06 15:40:29 DevUsine systemd[1]: Started gunicorn.service.
Oct 06 18:52:56 DevUsine systemd[1]: Started gunicorn.service.
Oct 06 20:55:05 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 20:55:17 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:07:36 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:16:42 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:21:38 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:25:28 DevUsine systemd[1]: Started gunicorn daemon.
Oct 07 08:58:43 DevUsine systemd[1]: Started gunicorn daemon.
Oct 07 15:01:22 DevUsine systemd[1]: Started gunicorn daemon.
I had to change the permissions of my sock folder:
sudo chown ben:www-data /home/ben/myproject/
Another thing is that I have changed the sock location after reading in many post that it's not a good pratice to keep the sock file in the django project.
My new location is:
/home/ben/run/
Don't forget to change permissions:
sudo chown ben:www-data /home/ben/run/
To be sure that gunicorn is refreshed, run these commands:
pkill gunicorn
sudo systemctl daemon-reload
sudo systemctl start gunicorn
That will kill the gunicorn processes and start new ones.
You can run this command to make the process start at server boot:
sudo systemctl enable gunicorn
All works well now.
While the accepted answer works, there is one (imo major) issue with it, which is that the gunicorn web server is (probably) running as root, which is not recommended. The reason you end up needing to chown the socket is because it is owned by root:root, because that is the user/group your init job assumes by default. There are multiple ways to get your job to assume another role. As of this time (with gunicorn 19.9.0), in my opinion, the simplest solution to this is to use the --user and --group flags provided as part of the gunicorn command. This means your server can start with the user/group you specify. In your case:
exec gunicorn --user ben --group www-data --bind unix:/home/ben/myproject/myproject.sock -m 007 wsgi
will start gunicorn under ben:www-data user and create a socket owned by ben:www-data with the permissions 770, or read/write/execute privilege for the user ben and group www-data on the socket, which is exactly what you ned in this case.
I have given path to the sock file outside my project. I needed to just create the directory so that the gunicorn can create the file inside that directory as I had had mentioned that path in the .services file. Basically, I made sure that I had all directories existing according to the path in the .services file. No need to change permissions or ownership
Try run
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl status gunicorn.service
The last line helped me to re-create .scok file
Related
I want to upload my bot to the server. I am using Google Cloud. My bot.service file looks like this:
[Unit]
Description=Telegram bot 'ConverterBot'
After=syslog.target
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/home/misha_markov1015#converterbot/ConverterBot
ExecStart=/usr/bin/python3 /home/misha_markov1015#converterbot/ConverterBot/main.py
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
When I enter the following commands:
sudo systemctl daemon-reload
sudo systemctl enable bot
sudo systemctl start bot
sudo systemctl status bot
I get the following error:
Nov 01 19:08:53 converterbot systemd[1]: Started Telegram bot 'ConverterBot'.
Nov 01 19:08:53 converterbot systemd[8978]: bot.service: Changing to the requested working directory failed: No such file or directory
Nov 01 19:08:53 converterbot systemd[8978]: bot.service: Failed at step CHDIR spawning /usr/bin/python3: No such file or directory
Nov 01 19:08:53 converterbot systemd[1]: bot.service: Main process exited, code=exited, status=200/CHDIR
Nov 01 19:08:53 converterbot systemd[1]: bot.service: Failed with result 'exit-code'.
If you start the bot with the /home/python3/ConverterBot/main.py command, then everything works correctly. I checked several times: the path to this file exists, but why does the error say that this file does not exist?
If suddenly someone encounters such a problem, then the solution was as follows: /home/misha_markov1015#converterbot/ConverterBot this path really does not exist. Instead, you had to write: /home/misha_markov1015/ConverterBot.
I am newbie to Django recently I created a Django app and I uploaded to the server. I assigned a domain name to it. each time I run the server I need to type xyz.com:8000 to see my website. Is there any way to resolve this issue? Also, I have doubt. Do I need to type python manage.py runserver 0:8000 to launch the website or it's just run automatically like PHP.
You should set up a web server!
The web server is required for any site to work. Currently the most popular are Apache and NGINX. It is the web server that responds to user requests. We need to ensure the interaction of the web server and the python application. Most popular solutions:
uwsgi
gunicorn
Consider an example with Nginx and Gunicorn:
Let's start by installing the Gunicorn module in a virtual environment:
pip install gunicorn
Configure the gunicorn service settings for our project:
sudo nano /etc/systemd/system/gunicorn.service
/etc/systemd/system/gunicorn.service:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=my_user
Group=www-data
WorkingDirectory=/home/project_dir/project
ExecStart=/home/project_dir/project/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/project_dir/project/project.sock project.wsgi
[Install]
WantedBy=multi-user.target
We enable and run the gunicorn service, check its status:
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
If all is well, install the nginx web server:
sudo apt install nginx
Configure the project site parameters:
sudo nano /etc/nginx/sites-available/project
/etc/nginx/sites-available/project:
server {
listen 80;
server_name <server IP or domain name>;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/project_dir/project;
}
location /media/ {
root /home/project_dir/project;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/project_dir/project/project.sock;
}
}
We use Nginx as a proxy for the gunicorn Python server:
proxy_pass http://unix:/home/project_dir/project/project.sock;
Create a link in the allowed sites folder “/etc/nginx/sites-enabled”:
sudo ln -s /etc/nginx/sites-available/project/etc/nginx/sites-enabled
We restart the Nginx service and add permissions to the firewall:
sudo systemctl restart nginx
sudo ufw allow 'Nginx Full'
Done! You can check the operation of our site by typing the IP address of the server in the browser.
P.S. Sorry for my english! If you see an error in the text or code, please edit me.
I have a simple python program that does the following
identitydock.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello Docker!\n'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
My Dockerfile is as follows
Dockerfile
FROM python:3.4
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8
WORKDIR /app
COPY app /app
COPY cmd.sh /
EXPOSE 9090 9191
USER uwsgi
CMD ["/cmd.sh"]
my cmd.sh is as follows:
#!/bin/bash
set -e
if [ "$ENV" = 'DEV' ]; then
echo "Running Development Server"
exec python "identidock.py"
else
echo "Running Production Server"
exec uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py \
--callable app --stats 0.0.0.0:9191
fi
A simple web page that should return 'hello docker' for some reason does not work when I run using docker.
The commands I gave to run the application:
docker build -t identidock .
docker run -d -p 5000:5000 identidock
When I do curl localhost:5000 I get the following message
curl: (7) Failed to connect to localhost port 5000: Connection refused
May I know if there is an issue with my docker configuration?
I am using the following docker version on MacOSX
Docker version 17.03.1-ce, build c6d412e
Reference source
https://github.com/using-docker/using_docker_in_dev
Edit -1
On docker ps -a , the container status shows 'UP'
on docker logs CONTAINER_ID, i get the following logs
Running Production Server
*** Starting uWSGI 2.0.8 (64bit) on [Thu Jul 6 02:04:04 2017] ***
compiled with version: 4.9.2 on 06 July 2017 02:03:16
os: Linux-4.4.74-boot2docker #1 SMP Mon Jun 26 18:01:14 UTC 2017
nodename: 323e6ff35d0d
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /app
detected binary path: /usr/local/bin/uwsgi
your processes number limit is 1048576
your memory page size is 4096 bytes
detected max file descriptor number: 1048576
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on 0.0.0.0:9090 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:45710 (port auto-assigned) fd 3
Python version: 3.4.6 (default, Jun 21 2017, 18:32:49) [GCC 4.9.2]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x1bd9640
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 145536 bytes (142 KB) for 1 cores
*** Operational MODE: single process ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1bd9640 pid: 1 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1)
spawned uWSGI worker 1 (pid: 6, cores: 1)
*** Stats server enabled on 0.0.0.0:9191 fd: 13 ***
spawned uWSGI http 1 (pid: 7)
You're connecting port 5000 on the host to port 5000 on the container. But you don't have anything running on port 5000, you have something running on 9090 and 9091. so try docker run -d -p 5000:9090 identidock or docker run -d -p 5000:9091 identidock
I guess you are reading the book Developing and Deploying Software with Containers. I met similar problem and only to find that I didn't follow the steps completely.
According the codes and commands you gives, the author is tying to replace the original Flask WebServer (bind port 5000 in container with port 5000 in host machine) with uWSGI (bind port 9090 in container with 9090 in host machine). But docker run -d -p 5000:5000 identidock indicates that you insist on binding port 5000 in container with port 5000 in host machine, so you can't access uWSGI that is running in the container.
The command EXPOSE 9090 9191 used in dockerfile only assigns ports for the container, so you need to allocate ports for the host machine.
By the way, the author recommend to use -P to make host machine allocate available ports randomly, so you don't need to assign ports like -p 9090:9090 -p 9191:9191 manually.
I'm trying to get a Flask + SocketIO app running as a service on Ubuntu 16.04, inside a virtual environment. My server is restarted every day at 3 am (outside of my control), so I need it to automatically launch on startup.
Running the script by itself works fine:
$ python main.py
(29539) wsgi starting up on http://127.0.0.1:8081
I can tell that it's working because it's serving pages (through an nginx server set up by following this Stack Overflow answer, though I don't think that's relevant.)
Here's my /etc/systemd/system/opendc.service:
[Unit]
Description=OpenDC flask + socketio service
[Service]
Environment=PYTHON_HOME=/var/www/opendc.ewi.tudelft.nl/web-server/venv
Environment=PATH=$VIRTUAL_ENV/bin:$PATH
ExecStart=/var/www/opendc.ewi.tudelft.nl/web-server main.py
Restart=always
[Install]
WantedBy=multi-user.target
So when I try to get that going using:
$ sudo systemctl daemon-reload
$ sudo systemctl restart opendc
It doesn't serve pages anymore. The status shows:
$ sudo systemctl status opendc
* opendc.service - OpenDC flask + socketio service
Loaded: loaded (/etc/systemd/system/opendc.service; enabled; vendor preset: enabled)
Active: inactive (dead) (Result: exit-code) since Fri 2016-08-19 10:48:31 CEST; 15min ago
Process: 29533 ExecStart=/var/www/opendc.ewi.tudelft.nl/web-server main.py (code=exited, status=203/EXEC)
Main PID: 29533 (code=exited, status=203/EXEC)
Aug 19 10:48:31 opendc.ewi.tudelft.nl systemd[1]: opendc.service: Service hold-off time over, scheduling restart.
Aug 19 10:48:31 opendc.ewi.tudelft.nl systemd[1]: Stopped OpenDC flask + socketio service.
Aug 19 10:48:31 opendc.ewi.tudelft.nl systemd[1]: opendc.service: Start request repeated too quickly.
Aug 19 10:48:31 opendc.ewi.tudelft.nl systemd[1]: Failed to start OpenDC flask + socketio service.
I've looked up (code=exited, status=203/EXEC) and done some troubleshooting with what I found:
I checked that main.py is executable:
$ ls -l main.py
-rwxr-xr-x 1 leon leon 2007 Aug 19 10:46 main.py
And that main.py has this first line to point to Python in the virtual environment:
#!/var/www/opendc.ewi.tudelft.nl/web-server/venv/bin/python
So what's the problem here?
Tried and tested way of making a python file run in a Virtual Environment as a service.
[Unit][Unit]
Description=Your own description
After=network.target
[Service]
Type=simple
Restart=always
WorkingDirectory=/home/path/to/WorkingDirectory/
VIRTUAL_ENV=/home/path/to/WorkingDirectory/venv
Environment=PATH=$VIRTUAL_ENV/bin:$PATH
ExecStart=/home/path/to/WorkingDirectory/venv/bin/python app.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
I am putting this one here so I can always come back to it
I believe that you mistype PYTHON_HOME and than PATH=$VIRTUAL_ENV/bin:$PATH
you should use PATH=$PYTHON_HOME/bin:$PATH
I have done endless searching and attempts at fixing this issue, but this refuses to work.
Im using Python 3.3/Gunicorn/Nginx, when I try to run my site I get:
[error] 904#0: *1 connect() to unix:/home/user/project/project.sock failed (111: Connection refused) while connecting to upstream, client: , server: mysite.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://unix:/home/user/project/project.sock:/favicon.ico", host: "mysite.com", referrer: "mysite.com/"
I was following this article completely, after several attempts of reattempting it all I am still receiving this error.
Here is what my configs look like:
upstart script in /etc/init
description "Gunicorn application server running myproject"
start on runlevel [2345]
stop on runlevel [!2345]
respawn #respawn this on reboot
setuid user #set as unix user 'jd' to run as
setgid www-data #user used by nginx
env PATH=/home/user/project/projectenv/bin
chdir /home/user/project
exec gunicorn --workers 3 --bind unix:project.sock -m 007 wsgi
the permissions on this file:
chmod 644
user user 373 Dec 13 09:21 homepage.conf
**nginx
config**
server {
listen 80;
server_name mysite.com;
error_log /home/user/project/nginx_error.log info;
root /home/user/project/projectenv;
location / {
include proxy_params;
proxy_pass http://unix:/home/user/project/project.sock;
}
}
if i run nginx -t in the directory of the nginx config, it shows:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
permissions of /home/user/project/project.sock;
srwxrwx--- 1 user www-data
my wsgi.py file (as outlined in the article) contains:
from homepage import application
if __name__ == "__main__":
application.run()
The interesting thing is, if I try out this command:
gunicorn --bind 0.0.0.0:8000 wsgi
outlined here
Gunicorn starts up fine, and I can view my page perfectly.
The real question is, what is the issue causing this to not run from an ubuntu startup script in /etc/init? ... because the script is running fin
Does anyone see anything?
Thank you.