Last active
August 4, 2020 18:47
-
-
Save cmbaughman/ff8b7c578cc52b3dfbe9c986349f2d67 to your computer and use it in GitHub Desktop.
Revisions
-
cmbaughman revised this gist
Aug 4, 2020 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -276,5 +276,13 @@ sudo certbot --nginx -d example.com -d www.example.com sudo certbot renew --dry-run ``` ## Troubleshooting - Check the Nginx process logs by typing: `sudo journalctl -u nginx` - Check the Nginx access logs by typing: `sudo less /var/log/nginx/access.log` - Check the Nginx error logs by typing: `sudo less /var/log/nginx/error.log` - Check the Gunicorn application logs by typing: `sudo journalctl -u gunicorn` - Check the Gunicorn socket logs by typing: `sudo journalctl -u gunicorn.socket` *References: [https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04)* -
cmbaughman revised this gist
Aug 4, 2020 . 1 changed file with 266 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,8 @@ # Simple Ubuntu Server Setup ---------------------------- ## Create a user *NOTE: You must use public key based authentication.* 1. Create user `adduser testuser` @@ -12,3 +14,267 @@ ```sh rsync --archive --chown=testuser:testuser ~/.ssh /home/testuser ``` ## Setup Python, Nginx, Postgres, Gunicorn and other apps 1. Run `sudo apt update` 2. Run `sudo apt install -y python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl` 3. Log in to Postgres: `sudo -u postgres psql` 4. Create DB: `CREATE DATABASE myproject;` 5. CREATE USER testuser WITH PASSWORD 'password'; 6. Set the following: ```sql ALTER ROLE testuser SET client_encoding TO 'utf8'; ALTER ROLE testuser SET default_transaction_isolation TO 'read committed'; ALTER ROLE testuser SET timezone TO 'UTC'; GRANT ALL PRIVILEGES ON DATABASE myproject TO testuser; ``` 7. Type \q 8. `sudo -H pip3 install --uprgade pip` 9. `sudo -H pip3 install virtualenv` 10. Create project directory: `mkdir ~/myprojects/ && cd ~/myprojects` 11. Run virtualenv: `virtualenv myprojectenv` 12. Run `source /myprojects/myprojectenv/bin/activate` 13. Install more packages: `pip install django gunicorn psycopg2-binary` 14. Setup Django: `django-admin.py startproject myproject ~/myprojects/myproject` ## Configure Django Configuration is stored in the file `~/myprojects/myprojectsettings.py`. Update the section with the relevant info: ``` ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost'] ``` Configure Django to use the `psycopg2` lib from pip we installed above: ``` DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } } ``` Next, move down to the bottom of the file and add a setting indicating where the static files should be placed. This is necessary so that Nginx can handle requests for these items. The following line tells Django to place them in a directory called static in the base project directory: ``` STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/') ``` Now, we can migrate the initial database schema to our PostgreSQL database using the management script: ``` ~/myprojects/manage.py makemigrations ~/myprojects/manage.py migrate ``` Create an admin: ``` ~/myprojectdir/manage.py createsuperuser ``` We can collect all of the static content into the directory location we configured by typing: ``` ~/myprojectdir/manage.py collectstatic ``` You will have to confirm the operation. The static files will then be placed in a directory called static within your project directory. ``` sudo ufw allow 8000 ~/myprojectdir/manage.py runserver 0.0.0.0:8000 ``` Open a browser to servername:8000 and servername:8000/admin The last thing we want to do before leaving our virtual environment is test Gunicorn to make sure that it can serve the application. We can do this by entering our project directory and using gunicorn to load the project’s WSGI module: ``` cd ~/myprojects/myproject gunicorn --bind 0.0.0.0:8000 myproject.wsgi ``` ## Creating systemd Socket and Service Files for Gunicorn 1. Create or update the file `sudo nano /etc/systemd/system/gunicorn.socket` to look like this: ``` [Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target ``` 2. Next, create and open a systemd service file for Gunicorn with sudo privileges in your text editor. The service filename should match the socket filename with the exception of the extension `sudo nano /etc/systemd/system/gunicorn.service`: ``` [Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=testuser Group=www-data WorkingDirectory=/home/testuser/myprojectdir ExecStart=/home/testuser/myprojectdir/myprojectenv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application [Install] WantedBy=multi-user.target ``` 3. Configure systemd ``` sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket ``` 4. Check the status of the process to find out whether it was able to start: ``` sudo systemctl status gunicorn.socket ``` Next, check for the existence of the `gunicorn.sock` file within the `/run` directory: ``` file /run/gunicorn.sock ``` *NOTE: If there are any errors starting gunicorn, run `sudo journalctl -u gunicorn.socket`* *Also, check ``* Currently, if you’ve only started the `gunicorn.socket` unit, the `gunicorn.service` will not be active yet since the socket has not yet received any connections. You can check this by typing: ``` sudo systemctl status gunicorn Output: ● gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: inactive (dead) ``` To test the socket activation mechanism, we can send a connection to the socket through curl by typing: ``` curl --unix-socket /run/gunicorn.sock localhost ``` You should see the HTML output from your application in the terminal. This indicates that Gunicorn was started and was able to serve your Django application. You can verify that the Gunicorn service is running by typing: ``` sudo systemctl status gunicorn ``` If the output from curl or the output of systemctl status indicates that a problem occurred, check the logs for additional details: ``` sudo journalctl -u gunicorn ``` Check your `/etc/systemd/system/gunicorn.service` file for problems. If you make changes to the `/etc/systemd/system/gunicorn.service` file, reload the daemon to reread the service definition and restart the Gunicorn process by typing: ``` sudo systemctl daemon-reload sudo systemctl restart gunicorn ``` Make sure you troubleshoot the above issues before continuing. ## Configure Nginx to Proxy Pass to Gunicorn Start by creating and opening a new server block in Nginx’s sites-available directory: ``` sudo nano /etc/nginx/sites-available/myproject ``` Inside, open up a new server block. We will start by specifying that this block should listen on the normal port 80 and that it should respond to our server’s domain name or IP address: ``` /etc/nginx/sites-available/myproject server { listen 80; server_name server_domain_or_IP; } ``` Next, we will tell Nginx to ignore any problems with finding a favicon. We will also tell it where to find the static assets that we collected in our `~/myprojectdir/static directory`. All of these files have a standard URI prefix of “/static”, so we can create a location block to match those requests: ``` /etc/nginx/sites-available/myproject server { listen 80; server_name server_domain_or_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/sammy/myprojectdir; } } ``` Finally, we’ll create a location / {} block to match all other requests. Inside of this location, we’ll include the standard `proxy_params` file included with the Nginx installation and then we will pass the traffic directly to the Gunicorn socket: ``` /etc/nginx/sites-available/myproject server { listen 80; server_name server_domain_or_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/sammy/myprojectdir; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } } ``` Save and close the file when you are finished. Now, we can enable the file by linking it to the sites-enabled directory: ``` sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled ``` Test your Nginx configuration for syntax errors by typing: ``` sudo nginx -t ``` If no errors are reported, go ahead and restart Nginx by typing: ``` sudo systemctl restart nginx ``` Finally, we need to open up our firewall to normal traffic on port 80. Since we no longer need access to the development server, we can remove the rule to open port 8000 as well: ``` sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full' ``` You should now be able to go to your server’s domain or IP address to view your application. ## Next Steps 1. `sudo add-apt-repository ppa:certbot/certbot` 2. `sudo apt install python-certbot-nginx` 3. Check that the `server_name` attribute is filled in in the Nginx `sites-available` configuration. For example: ``` server_name example.com www.example.com; ``` 4. Test config changes `sudo nginx -t` 5. `sudo systemctl reload nginx` 6. Update ufw: ``` sudo ufw allow 'Nginx Full' sudo ufw delete allow 'Nginx HTTP' sudo certbot --nginx -d example.com -d www.example.com ``` 7. Test renewal functionality: ``` sudo certbot renew --dry-run ``` *References: [https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04)* -
cmbaughman created this gist
Aug 4, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ # Simple Ubuntu Server Setup ---------------------------- *NOTE: You must use public key based authentication.* 1. Create user `adduser testuser` 2. Grant sudo `usermod -aG sudo testuser` 3. ufw enable/disable a. `ufw disable` b. `ufw add OpenSSH` and `ufw enable` and whatever else you want. 4. Run the following command to allow your new user to log in: ```sh rsync --archive --chown=testuser:testuser ~/.ssh /home/testuser ```