cdn-django/install.sh
raw link view readme1 | STORAGE_KEY=$2 |
2 | DNS_NAME=$3 |
3 | CDN_ROOT=$4.azureedge.net |
4 | |
5 | yum install epel-release -y |
6 | |
7 | yum install policycoreutils-python -y |
8 | semanage fcontext -at httpd_sys_rw_content_t "/srv/cdndjango(/.*)?" |
9 | semanage fcontext -at httpd_sys_content_t "/srv/common(/.*)?" |
10 | |
11 | yum install firewalld -y |
12 | systemctl start firewalld |
13 | systemctl enable firewalld |
14 | firewall-cmd --permanent --zone=public --add-interface=eth0 |
15 | firewall-cmd --permanent --add-service=http --add-service=https --zone=public |
16 | firewall-cmd --reload |
17 | |
18 | # Just for testing... |
19 | |
20 | mkdir /srv/common |
21 | cat > /srv/common/robots.txt << EOF |
22 | User-agent: ia_archiver |
23 | Disallow: / |
24 | EOF |
25 | |
26 | # UWSGI |
27 | |
28 | yum install uwsgi uwsgi-plugin-python3 -y |
29 | |
30 | cat > /etc/uwsgi.d/cdndjango.ini << EOF |
31 | [uwsgi] |
32 | project = engine |
33 | base = /srv/cdndjango/site |
34 | virtualenv = /srv/cdndjango |
35 | |
36 | chdir = %(base) |
37 | home = %(virtualenv) |
38 | module = %(project).core.wsgi:application |
39 | |
40 | master = true |
41 | processes = 5 |
42 | |
43 | socket = %(base)/%(project).sock |
44 | chmod-socket = 660 |
45 | uid = uwsgi |
46 | gid = uwsgi |
47 | vacuum = true |
48 | |
49 | plugins = python3 |
50 | EOF |
51 | |
52 | chown -R nobody:uwsgi /etc/uwsgi.d |
53 | chmod -R g+s /etc/uwsgi.d |
54 | |
55 | # App |
56 | |
57 | yum install python34 python-pip -y 2> /dev/null |
58 | pip install --upgrade pip |
59 | pip install --upgrade virtualenv |
60 | cd /srv |
61 | virtualenv -p python3 cdndjango |
62 | chmod -R 2750 /srv/cdndjango |
63 | setfacl -m d:o:--- /srv/cdndjango |
64 | cd /srv/cdndjango |
65 | source bin/activate |
66 | mkdir site |
67 | cd site |
68 | |
69 | mkdir -p engine/core |
70 | mkdir templates |
71 | |
72 | cat > ./requirements.txt << EOF |
73 | Django==1.10.1 |
74 | EOF |
75 | |
76 | pip install -r requirements.txt |
77 | |
78 | cat > ./engine/core/views.py << EOF |
79 | from django.shortcuts import render |
80 | from engine import settings as engine_settings |
81 | |
82 | def process(request): |
83 | render_data = { |
84 | 'title': 'random demo', |
85 | 'cdn': engine_settings.CDN_ROOT.replace('https:', '') |
86 | } |
87 | |
88 | return render(request, ['index.html', 'index.htm'], render_data) |
89 | |
90 | EOF |
91 | |
92 | cat > ./engine/core/__init__.py << EOF |
93 | EOF |
94 | |
95 | cat > ./engine/core/wsgi.py << EOF |
96 | import os |
97 | from django.core.wsgi import get_wsgi_application |
98 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "engine.settings") |
99 | application = get_wsgi_application() |
100 | EOF |
101 | |
102 | cat > ./engine/core/urls.py << EOF |
103 | from django.conf.urls import url |
104 | import sys |
105 | |
106 | from . import views |
107 | |
108 | class CoreUrl: |
109 | def init(self): |
110 | pass |
111 | |
112 | def setup(self): |
113 | self.urlpatterns = [ |
114 | url(r'^$', views.process), |
115 | ] |
116 | |
117 | return self.urlpatterns |
118 | |
119 | urlpatterns = CoreUrl().setup() |
120 | EOF |
121 | |
122 | cat > ./engine/__init__.py << EOF |
123 | EOF |
124 | |
125 | cat > ./engine/settings.py << EOF |
126 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) |
127 | import os, sys |
128 | |
129 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
130 | |
131 | SECRET_KEY = 'whatever8786ubhj8giyhbjhuiybhuhu08h9ui38u084hubj' |
132 | |
133 | DEBUG = True |
134 | |
135 | ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'does.nothing.in.debug.mode'] |
136 | |
137 | INSTALLED_APPS = ( |
138 | 'engine', |
139 | 'engine.core', |
140 | 'django.contrib.auth', |
141 | 'django.contrib.contenttypes', |
142 | 'django.contrib.messages', |
143 | ) |
144 | |
145 | MIDDLEWARE_CLASSES = ( |
146 | 'django.middleware.common.CommonMiddleware', |
147 | ) |
148 | |
149 | ROOT_URLCONF = 'engine.core.urls' |
150 | |
151 | ROOT_PATH = os.path.split(os.path.abspath(__file__))[0] |
152 | |
153 | TEMPLATES = [ |
154 | { |
155 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', |
156 | 'DIRS': [ |
157 | os.path.join(BASE_DIR, 'templates') |
158 | ], |
159 | 'OPTIONS': { |
160 | 'context_processors': [ |
161 | 'django.template.context_processors.debug', |
162 | 'django.template.context_processors.request', |
163 | 'django.contrib.auth.context_processors.auth', |
164 | 'django.contrib.messages.context_processors.messages', |
165 | ], |
166 | 'loaders': [ |
167 | ('django.template.loaders.cached.Loader', [ |
168 | 'django.template.loaders.filesystem.Loader', |
169 | 'django.template.loaders.app_directories.Loader', |
170 | ]), |
171 | ], |
172 | }, |
173 | }, |
174 | ] |
175 | |
176 | PROJECT_DIR = os.path.dirname(__file__) |
177 | |
178 | STATICFILES_DIRS = ( |
179 | os.path.join(PROJECT_DIR, 'static'), |
180 | ) |
181 | |
182 | LANGUAGE_CODE = 'en-us' |
183 | |
184 | TIME_ZONE = 'UTC' |
185 | |
186 | USE_I18N = True |
187 | |
188 | USE_L10N = True |
189 | |
190 | USE_TZ = True |
191 | |
192 | DOMAIN = 'https://does.not.matter' |
193 | |
194 | # the web doesn't have folders; this isn't 1994 |
195 | APPEND_SLASH = False |
196 | |
197 | application_root = '/' |
198 | |
199 | CDN_ROOT = '$CDN_ROOT' |
200 | |
201 | EOF |
202 | |
203 | cat > ./manage.py << EOF |
204 | #!/usr/bin/env python2 |
205 | import os |
206 | import sys |
207 | |
208 | if __name__ == "__main__": |
209 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "engine.settings") |
210 | |
211 | from django.core.management import execute_from_command_line |
212 | |
213 | execute_from_command_line(sys.argv) |
214 | |
215 | EOF |
216 | |
217 | cat > ./runserver.sh << EOF |
218 | python manage.py runserver 127.0.0.1:8081 --settings=engine.settings |
219 | EOF |
220 | chmod +x ./runserver.sh |
221 | |
222 | cat > ./templates/index.html << EOF |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | {{ title }} |
232 | |
233 | |
234 | |
235 | Here is my content. The CDN is up and running when this is blue. |
236 | |
237 | |
238 | |
239 | |
240 | EOF |
241 | |
242 | deactivate |
243 | |
244 | chown -R nobody:uwsgi /srv/cdndjango |
245 | restorecon -R /srv |
246 | |
247 | #Nginx |
248 | |
249 | cat > /etc/yum.repos.d/nginx.repo << EOF |
250 | [nginx] |
251 | name=nginx repo |
252 | baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/ |
253 | gpgcheck=0 |
254 | enabled=1 |
255 | EOF |
256 | |
257 | yum install -y nginx |
258 | |
259 | export PUBLIC_IP=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/') |
260 | |
261 | mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled |
262 | cat > /etc/nginx/conf.d/cdndjango.conf << EOF |
263 | server { |
264 | listen $PUBLIC_IP:80; |
265 | |
266 | location /robots.txt { |
267 | alias /srv/common/robots.txt; |
268 | } |
269 | |
270 | location / { |
271 | include uwsgi_params; |
272 | uwsgi_pass unix:/srv/cdndjango/site/engine.sock; |
273 | |
274 | proxy_redirect off; |
275 | proxy_set_header Host \$host; |
276 | proxy_set_header X-Real-IP \$remote_addr; |
277 | proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; |
278 | proxy_set_header X-Forwarded-Host \$server_name; |
279 | } |
280 | } |
281 | EOF |
282 | |
283 | usermod nginx -aG uwsgi |
284 | |
285 | systemctl start uwsgi |
286 | systemctl enable uwsgi |
287 | |
288 | systemctl start nginx |
289 | systemctl enable nginx |
290 | |
291 | cat > /tmp/site.css <<\EOF |
292 | p > span > span { |
293 | color: #00f; |
294 | } |
295 | EOF |
296 | |
297 | yum install openssl-devel python-devel gcc -y |
298 | cd /srv |
299 | # azure storage still requires legacy python (aka python2) |
300 | virtualenv assetuploader |
301 | cd /srv/assetuploader |
302 | source bin/activate |
303 | pip install azure-storage |
304 | mkdir app |
305 | cd app |
306 | cat > upload.py << EOF |
307 | from azure.common import AzureMissingResourceHttpError |
308 | from azure.storage.blob import BlockBlobService, ContentSettings, PublicAccess |
309 | from azure.storage import CorsRule |
310 | |
311 | blob_service = BlockBlobService(account_name='$STORAGE_NAME', account_key='$STORAGE_KEY') |
312 | |
313 | content_settings = ContentSettings() |
314 | content_settings.content_type = 'text/css' |
315 | |
316 | blob_service.create_container('css', public_access=PublicAccess.Blob) |
317 | with open('/tmp/site.css', 'r') as f: |
318 | blob_service.create_blob_from_bytes('css', 'site.css', f.read(), content_settings=content_settings) |
319 | |
320 | blob_service.set_blob_service_properties(cors=[CorsRule( |
321 | allowed_origins=['$DNS_NAME'], |
322 | allowed_methods=['GET'], |
323 | allowed_headers = ['*'], |
324 | exposed_headers = ['*'], |
325 | max_age_in_seconds = 1800 |
326 | )]) |
327 | EOF |
328 | chmod 0600 upload.py |
329 | |
330 | python upload.py |
331 | deactivate |
332 |