DigitalOcean - Gunicorn and NginX Tutorial
To configure your DigitalOcean server to have SSH and DNS point to its www address, such as coldcmerch.com, you need to follow these general steps:
- Log in to your DNS registrar or hosting provider where you manage the DNS records for coldcmerch.com.
- Create an "A" record or edit the existing one for the "www" subdomain.
- Set the IP address of your DigitalOcean server as the destination for the "www" subdomain.
- Connect to your DigitalOcean server via SSH using its IP address.
- Update the server's host file to associate the hostname with the loopback IP address.
- Open the hosts file with the command:
sudo nano /etc/hosts
- Add an entry at the end of the file like this:
127.0.0.1 coldcmerch.com www.coldcmerch.com
- Save the changes and exit the editor.
- Update the server's hostname:
-
- Execute the command:
sudo hostnamectl set-hostname coldcmerch.com
- Execute the command:
- This will set the server's hostname to "coldcmerch.com".
- Restart the server networking for the changes to take effect:
- Run the command:
sudo systemctl restart systemd-networkd
(Works for Ubuntu 23, will be different for older versions of Ubuntu/Linux)
- Open the SSH configuration file using the command:
sudo nano /etc/ssh/sshd_config
- Locate the line that starts with
#ListenAddress
. - Uncomment it by removing the '#' at the beginning of the line.
- Update the line to listen on the
IP address
of your DigitalOcean server. - Save the changes and exit the editor.
- Restart the SSH service for the changes to take effect:
-
- Execute the command:
sudo /etc/init.d/ssh restart
- Execute the command:
- Once these steps are completed, your DigitalOcean server's SSH and DNS should point to its www address, allowing you to SSH into the server using "coldcmerch.com" or "www.coldcmerch.com" instead of the IP address.
https://stackoverflow.com/questions/39460892/gunicorn-no-module-named-myproject
Note that DNS changes can take some time to propagate, so it may take a while for the changes to take effect globally.
Here's a legend to help you figure out what each field should be in /etc/systemd/system/gunicorn.service
:
-
WorkingDirectory -> Where your django APP is located (the whole app, not the subfolder within the app that shares its name, nor the parent folder holding the Django app which has some arbitrary name like 'django_stuff')
-
my_project.sock -> Goes in the exact same folder as above, which is your django APP folder. Not its subfolders.
-
my_project.wsgi -> From my understanding, there's no need to add any prefixes or parent directories to this, just keep it as
my_project.wsgi
(with your actual project name ofc), but everything around it will need to be properly directed to for this to be recognized.
In the end, you may end up with something LIKE this, but not exactly like this. Use the above tips to get it right:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=coco
Group=www-data
WorkingDirectory=/home/coco/coldcmerch.com/django/coldcmerch
ExecStart=/home/coco/coldcmerch.com/django/env/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/coco/coldcmerch.com/django/coldcmerch/coldcmerch.sock coldcmerch.wsgi:application
[Install]
WantedBy=multi-user.target****
In a production environment, you typically want your Node.js applications (like your Express server) to run in the background, start automatically when the server boots up, and restart automatically if they crash. There are several ways to do this, but one of the most common methods is to use a process manager like PM2.
PM2 is a production process manager for Node.js applications with a built-in load balancer. It keeps your applications alive forever, reloads them without downtime, helps you to manage application logging, and more.
-
First, install PM2 globally on your server with npm:
sudo npm install -g pm2
-
Navigate to the folder containing your Express server and start it with PM2:
cd /path/to/your/express/server pm2 start index.js --name "my-express-app"
Replace
index.js
with the entry point to your Express application, and replace"my-express-app"
with a name of your choosing. -
PM2 will now keep your Express server running in the background. You can check the status of your applications with:
pm2 list
And view their logs with:
pm2 logs
-
To ensure that your Express server (and any other applications managed by PM2) start automatically on boot, you can use the
pm2 startup
command, which will provide instructions based on your system.pm2 startup
Remember, your Express server should be running on its own port (like 5000), and your Nginx configuration should include a reverse proxy to that port for the appropriate routes.
Seems like folder permissions and ownership are INCREDIBLY IMPORTANT to getting nginx and gunicorn to host the website.
SO. Here are the problems I ran into when trying to set up nginx and gunicorn overall:
Seriously, check for stupid typos first. Sometimes you may forget to replace the 'myproject' with your real project name, or you may have created a file /home/coco.conf.conf
when you meant to create /home/coco/conf.conf
.
Refer to the 'chown' section somewhere below regarding changing ownership of folders and files. This mostly applies to DATABASE bugs. But if you're experiencing nginx bugs with what you think is maybe 'ownership, try...:
Make sure that nginx is able to access your .sock file by checking with
namei -nom /home/my_user/my_project/my_project.sock
The above will display the ownership, and more importantly, RIGHTS to all folders leading up to your sock file. Yes, these all count.
The solution to my problem? For some reason, my 'user' folder had 'other' permissions set to 'r--', which means yes read, no write, no execute.
I need it to be 'r-x' all the way up to my .sock file, which means I needed to use this command on my 'coco' user directory/folder:
sudo chmod o=r+x /home/coco
namei -nom /home/coco
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-20-04
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04
https://linux.die.net/man/1/chown
-R, --recursive
# operate on files and directories recursively
chown root /u
#Change the owner of /u to "root".
chown root:staff /u
#Likewise, but also change its group to "staff".
chown -hR root /u
#Change the owner of /u and subfiles to "root".
sudo chown $USER:$USER -R this_subdirectory
#Change the ownership of this_subdirectory
https://www.guru99.com/file-permissions.html
# gunicorn setup file:
/etc/systemd/system/gunicorn.service
# nginx setup for your project:
/etc/nginx/sites-available/myproject
#
#
Editing the nginx config:
sudo nano /etc/nginx/nginx.conf
sudo systemctl status gunicorn
sudo journalctl -u gunicorn
sudo nginx -t
nginx access logs:
sudo less /var/log/nginx/access.log
nginx process logs:
sudo journalctl -u nginx
nginx error logs:
sudo tail -F /var/log/nginx/error.log
sudo ufw status
When you change gunicorn.service file:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
To restart nginx:
sudo systemctl restart nginx
https://snapcraft.io/docs/installing-snapd
https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal
https://stackoverflow.com/questions/66929579/django-nginx-413-request-entity-too-large
sudo nano /etc/nginx/nginx.conf
client_max_body_size 200M;
Restarting Nginx, Gunicorn, and Express. (React needs no restart, it is static and served by Express)
sudo systemctl reload nginx
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
pm2 reload my-express-server