Skip to content

Commit 8d7026e

Browse files
authored
Merge pull request #168 from dush-t/master
[Autohost] - Script for 'one-click' production deployment for django.
2 parents e194739 + 8dcea82 commit 8d7026e

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Autohost
2+
Shell scripts for quick production deployment of web apps.
3+
4+
## For Django -
5+
6+
Before everything, make sure you have a requirements.txt file inside your project's root which contains all your dependencies.
7+
(Installing dependencies after hosting is kinda messy.)
8+
9+
1. Clone this repository to your local machine/server.
10+
2. Navigate to django-autohost directory and give host.sh executable permissions by `sudo chmod +x ./host.sh`
11+
3. Run `sudo ./host.sh <ProjectName> /path/to/project/root/directory "ip_address" "port"`
12+
13+
Your project root is the folder which contains the manage.py file. The path to project root should be absolute.
14+
For example, if I had a project named MyProject at
15+
/django/MyProject and wanted to host it locally on port 8080, I would use -
16+
17+
`sudo ./host.sh MyProject /django/MyProject "localhost" "8080"` (Notice the quotation marks over IP address and port)
18+
19+
This would store hosting-related info in a directory with path /autohost/MyProject_hostingdata (yes, it is necessary to use the same name as your django project name).
20+
After running that command, you will be able to view your website at localhost:8080. Don't forget the sudo, this script requires root permissions to place config files in the right directories.
21+
22+
#### Note: If you want to host at localhost, make sure you write "localhost" there and not "127.0.0.1". Nginx will have issues if you write 127.0.0.1.
23+
24+
#### Note -
25+
This script will use nginx and gunicorn (with 4 process workers) to host your web app. The script is ONLY for hosting, and not for managing your project.
26+
This means once hosted, you will still need to manage your app. Things like making migrations and collectstatic still need to be
27+
done manually (the script will collect static for you once, at the time of running).
28+
29+
#### How to "un-host" -
30+
To remove your webapp from your server, do the following -
31+
1. Navigate to django-autohost directory and give remove.sh executable permissions by `sudo chmod +x ./remove.sh`
32+
2. Execute `./remove.sh <ProjectName>`, where <ProjectName> is the name of the project that you used earlier when hosting it.
33+
3. You're done.
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/bin/bash
2+
3+
export PROJECT_NAME=$1
4+
export PROJECT_DIR=$2
5+
export HOST_IP=$3
6+
export HOST_PORT=$4
7+
8+
echo "Running autohost on ${PROJECT_NAME}..."
9+
10+
#------
11+
HOSTING_DIR="/autohost/${PROJECT_NAME}_hostingdata"
12+
echo "Saving hosting data in ${HOSTING_DIR}"
13+
14+
sudo rm -rf $HOSTING_DIR
15+
sudo mkdir -p $HOSTING_DIR
16+
sudo mkdir "${HOSTING_DIR}/logs"
17+
sudo touch "$HOSTING_DIR/logs/gunicorn-supervisor.log"
18+
sudo touch "$HOSTING_DIR/logs/nginx-access.log"
19+
sudo touch "$HOSTING_DIR/logs/nginx-error.log"
20+
21+
#------
22+
echo "Setting up Gunicorn..."
23+
GUNICORN_SCRIPT="${HOSTING_DIR}/gunicorn-start.sh"
24+
25+
sudo touch $GUNICORN_SCRIPT
26+
27+
cat >> $GUNICORN_SCRIPT <<\EOF
28+
#!/bin/bash
29+
EOF
30+
31+
cat >> $GUNICORN_SCRIPT <<EOF
32+
NAME="${PROJECT_NAME}"
33+
SOCKFILE="${HOSTING_DIR}/run/gunicorn.sock"
34+
DJANGODIR=${PROJECT_DIR}
35+
USER=root
36+
GROUP=webapps
37+
NUM_WORKERS=4
38+
DJANGO_SETTINGS_MODULE=${PROJECT_NAME}.settings
39+
DJANGO_WSGI_MODULE=${PROJECT_NAME}.wsgi
40+
EOF
41+
42+
cat >> $GUNICORN_SCRIPT <<\EOF
43+
echo "Starting ${NAME} as root"
44+
EOF
45+
46+
cat >> $GUNICORN_SCRIPT <<EOF
47+
source "${HOSTING_DIR}/venv/bin/activate"
48+
EOF
49+
50+
cat >> $GUNICORN_SCRIPT <<\EOF
51+
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
52+
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
53+
EOF
54+
55+
cat >> $GUNICORN_SCRIPT <<EOF
56+
mkdir "${HOSTING_DIR}/run"
57+
58+
EOF
59+
60+
cat >> $GUNICORN_SCRIPT <<\EOF
61+
exec gunicorn ${DJANGO_WSGI_MODULE}:application \
62+
--name $NAME \
63+
--workers $NUM_WORKERS \
64+
--user=$USER \
65+
--bind unix:$SOCKFILE
66+
EOF
67+
68+
sudo chmod u+x $GUNICORN_SCRIPT
69+
70+
71+
#------
72+
python3 -m venv "${HOSTING_DIR}/venv"
73+
source "${HOSTING_DIR}/venv/bin/activate"
74+
75+
pip install -r "${PROJECT_DIR}/requirements.txt"
76+
pip install gunicorn
77+
pip install setproctitle
78+
79+
python "${PROJECT_DIR}/manage.py" collectstatic
80+
81+
deactivate
82+
83+
#-----
84+
echo "Installing dependencies"
85+
sudo apt-get install nginx
86+
sudo apt-get install supervisor
87+
88+
echo " "
89+
echo "Setting up supervisor"
90+
echo "${PROJECT_NAME}.conf"
91+
92+
sudo rm -rf "/etc/supervisor/conf.d/${PROJECT_NAME}.conf"
93+
sudo cat >> "/etc/supervisor/conf.d/${PROJECT_NAME}.conf" <<EOF
94+
[program:${PROJECT_NAME}]
95+
command=${GUNICORN_SCRIPT}
96+
user = root
97+
stdout_logfile = "${HOSTING_DIR}/logs/gunicorn-supervisor.log"
98+
redirect_stderror = true
99+
EOF
100+
101+
sudo supervisorctl reread
102+
sudo supervisorctl update
103+
104+
echo " "
105+
echo "Setting up nginx"
106+
echo "Saving nginx configuration at /etc/nginx/sites-available/${PROJECT_NAME}"
107+
sudo rm -rf /etc/nginx/sites-available/${PROJECT_NAME}
108+
sudo rm -rf /etc/nginx/sites-enabled/${PROJECT_NAME}
109+
touch /etc/nginx/sites-available/${PROJECT_NAME}
110+
111+
sudo cat >> /etc/nginx/sites-available/${PROJECT_NAME} <<EOF
112+
upstream ${PROJECT_NAME}_app_server {
113+
server unix:${HOSTING_DIR}/run/gunicorn.sock fail_timeout=0;
114+
}
115+
116+
117+
server {
118+
listen ${HOST_PORT};
119+
server_name ${HOST_IP};
120+
121+
client_max_body_size 4G;
122+
123+
access_log ${HOSTING_DIR}/logs/nginx-access.log;
124+
error_log ${HOSTING_DIR}/logs/nginx-error.log;
125+
126+
location /static/ {
127+
alias $PROJECT_DIR/static/;
128+
}
129+
130+
location /media/ {
131+
alias $PROJECT_DIR/media;
132+
}
133+
EOF
134+
cat >> /etc/nginx/sites-available/$PROJECT_NAME <<\EOF
135+
location / {
136+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
137+
proxy_set_header Host $http_host;
138+
proxy_redirect off;
139+
if (!-f $request_filename) {
140+
EOF
141+
142+
cat >> /etc/nginx/sites-available/$PROJECT_NAME <<EOF
143+
proxy_pass http://${PROJECT_NAME}_app_server;
144+
break;
145+
}
146+
}
147+
# Error pages
148+
error_page 500 502 503 504 /500.html;
149+
location = /500.html {
150+
root ${PROJECT_DIR}/static/;
151+
}
152+
}
153+
EOF
154+
155+
sudo ln -s /etc/nginx/sites-available/${PROJECT_NAME} /etc/nginx/sites-enabled/
156+
157+
sudo nginx -s reload
158+
sudo nginx -s reopen
159+
sudo supervisorctl status $PROJECT_NAME
160+
161+
162+
echo "Your project is up and running at ${HOST_IP}:${HOST_PORT}"
163+
164+
165+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export PROJECT_NAME=$1
2+
3+
echo "Unhosting your website..."
4+
5+
echo "Removing hosting files..."
6+
sudo rm -rf "/autohost/${PROJECT_NAME}_hostingdata"
7+
echo "Removing nginx configurations..."
8+
sudo rm -rf "/etc/nginx/sites-enabled/${PROJECT_NAME}"
9+
sudo rm -rf "/etc/nginx/sites-available/${PROJECT_NAME}"
10+
echo "Removing supervisor program..."
11+
sudo rm -rf "/etc/supervisor/conf.d/${PROJECT_NAME}.conf"
12+
13+
echo "Done"

0 commit comments

Comments
 (0)