Use Docker, upgrade deps

This commit is contained in:
Jonathan Cremin 2018-08-07 16:55:22 +01:00
parent 16f8eb0470
commit 90f2fe1ced
18 changed files with 231 additions and 79 deletions

4
.gitignore vendored
View file

@ -1,3 +1,3 @@
venv .envrc
*.pyc *.pyc
staticfiles staticfiles

21
Dockerfile Normal file
View file

@ -0,0 +1,21 @@
FROM python:3.7.0-alpine3.8
WORKDIR /app
EXPOSE 8000
ENV DEBUG false
ENV SECRET_KEY unsafe
RUN pip install pipenv && \
apk add postgresql-dev gcc python3-dev musl-dev
ADD Pipfile* ./
RUN pipenv install
ADD . .
RUN pipenv run ./manage.py collectstatic --noinput
CMD ["pipenv", "run", "gunicorn", "-b", "0.0.0.0:8000", "app.wsgi", "--log-file", "-"]

16
Pipfile Normal file
View file

@ -0,0 +1,16 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
dj-database-url = "~=0.5.0"
gunicorn = "~=19.9.0"
"psycopg2-binary" = "~=2.7.5"
Django = "~=2.1.0"
whitenoise = "~=3.3.1"
[dev-packages]
[requires]
python_version = "3.7"

110
Pipfile.lock generated Normal file
View file

@ -0,0 +1,110 @@
{
"_meta": {
"hash": {
"sha256": "b754949db0271be476fd84d57d71948fd557821ca5593dc44a41b388600c65de"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"dj-database-url": {
"hashes": [
"sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163",
"sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"
],
"index": "pypi",
"version": "==0.5.0"
},
"dj-static": {
"hashes": [
"sha256:032ec1c532617922e6e3e956d504a6fb1acce4fc1c7c94612d0fda21828ce8ef"
],
"index": "pypi",
"version": "==0.0.6"
},
"django": {
"hashes": [
"sha256:0120b3b60760fb0617848b58aaa9702c0bf963320ed472f0879c5c55ab75b64a",
"sha256:b6f3b864944276b4fd1d099952112696558f78b77b39188ac92b6c5e80152c30"
],
"index": "pypi",
"version": "==1.11.0"
},
"gunicorn": {
"hashes": [
"sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471",
"sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"
],
"index": "pypi",
"version": "==19.9.0"
},
"psycopg2-binary": {
"hashes": [
"sha256:04afb59bbbd2eab3148e6816beddc74348078b8c02a1113ea7f7822f5be4afe3",
"sha256:098b18f4d8857a8f9b206d1dc54db56c2255d5d26458917e7bcad61ebfe4338f",
"sha256:0bf855d4a7083e20ead961fda4923887094eaeace0ab2d76eb4aa300f4bbf5bd",
"sha256:197dda3ffd02057820be83fe4d84529ea70bf39a9a4daee1d20ffc74eb3d042e",
"sha256:278ef63afb4b3d842b4609f2c05ffbfb76795cf6a184deeb8707cd5ed3c981a5",
"sha256:3cbf8c4fc8f22f0817220891cf405831559f4d4c12c4f73913730a2ea6c47a47",
"sha256:4305aed922c4d9d6163ab3a41d80b5a1cfab54917467da8168552c42cad84d32",
"sha256:47ee296f704fb8b2a616dec691cdcfd5fa0f11943955e88faa98cbd1dc3b3e3d",
"sha256:4a0e38cb30457e70580903367161173d4a7d1381eb2f2cfe4e69b7806623f484",
"sha256:4d6c294c6638a71cafb82a37f182f24321f1163b08b5d5ca076e11fe838a3086",
"sha256:4f3233c366500730f839f92833194fd8f9a5c4529c8cd8040aa162c3740de8e5",
"sha256:5221f5a3f4ca2ddf0d58e8b8a32ca50948be9a43351fda797eb4e72d7a7aa34d",
"sha256:5c6ca0b507540a11eaf9e77dee4f07c131c2ec80ca0cffa146671bf690bc1c02",
"sha256:789bd89d71d704db2b3d5e67d6d518b158985d791d3b2dec5ab85457cfc9677b",
"sha256:7b94d29239efeaa6a967f3b5971bd0518d2a24edd1511edbf4a2c8b815220d07",
"sha256:89bc65ef3301c74cf32db25334421ea6adbe8f65601ea45dcaaf095abed910bb",
"sha256:89d6d3a549f405c20c9ae4dc94d7ed2de2fa77427a470674490a622070732e62",
"sha256:97521704ac7127d7d8ba22877da3c7bf4a40366587d238ec679ff38e33177498",
"sha256:a395b62d5f44ff6f633231abe568e2203b8fabf9797cd6386aa92497df912d9a",
"sha256:a6d32c37f714c3f34158f3fa659f3a8f2658d5f53c4297d45579b9677cc4d852",
"sha256:a89ee5c26f72f2d0d74b991ce49e42ddeb4ac0dc2d8c06a0f2770a1ab48f4fe0",
"sha256:b4c8b0ef3608e59317bfc501df84a61e48b5445d45f24d0391a24802de5f2d84",
"sha256:b5fcf07140219a1f71e18486b8dc28e2e1b76a441c19374805c617aa6d9a9d55",
"sha256:b86f527f00956ecebad6ab3bb30e3a75fedf1160a8716978dd8ce7adddedd86f",
"sha256:be4c4aa22ba22f70de36c98b06480e2f1697972d49eb20d525f400d204a6d272",
"sha256:c2ac7aa1a144d4e0e613ac7286dae85671e99fe7a1353954d4905629c36b811c",
"sha256:de26ef4787b5e778e8223913a3e50368b44e7480f83c76df1f51d23bd21cea16",
"sha256:e70ebcfc5372dc7b699c0110454fc4263967f30c55454397e5769eb72c0eb0ce",
"sha256:eadbd32b6bc48b67b0457fccc94c86f7ccc8178ab839f684eb285bb592dc143e",
"sha256:ecbc6dfff6db06b8b72ae8a2f25ff20fbdcb83cb543811a08f7cb555042aa729"
],
"index": "pypi",
"version": "==2.7.5"
},
"pytz": {
"hashes": [
"sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
"sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
],
"version": "==2018.5"
},
"static3": {
"hashes": [
"sha256:674641c64bc75507af2eb20bef7e7e3593dca993dec6674be108fa15b42f47c8"
],
"index": "pypi",
"version": "==0.7.0"
},
"whitenoise": {
"hashes": [
"sha256:15f43b2e701821b95c9016cf469d29e2a546cb1c7dead584ba82c36f843995cf",
"sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd"
],
"index": "pypi",
"version": "==3.3.1"
}
},
"develop": {}
}

View file

@ -1 +0,0 @@
web: gunicorn project.wsgi --log-file -

View file

@ -1 +0,0 @@
from django.contrib import admin

View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='Link',
fields=[
('id', models.CharField(primary_key=True, max_length=12, serialize=False)),
('url', models.URLField(max_length=2048)),
('created_at', models.DateTimeField(auto_now_add=True)),
('clicks', models.IntegerField(default=0)),
('ip', models.GenericIPAddressField(null=True)),
],
),
]

View file

@ -11,11 +11,11 @@ import dj_database_url
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ['DEBUG'] == 'True' DEBUG = os.environ['DEBUG'] or False
TEMPLATE_DEBUG = os.environ['DEBUG'] == 'True' TEMPLATE_DEBUG = os.environ['DEBUG'] or False
SECRET_KEY = os.environ['SECRET_KEY'] SECRET_KEY = os.environ['SECRET_KEY']
@ -27,25 +27,35 @@ INSTALLED_APPS = (
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.auth',
'app', 'app',
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE = [
'sslify.middleware.SSLifyMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
) 'whitenoise.middleware.WhiteNoiseMiddleware',
]
TEMPLATE_DIRS = ( TEMPLATES = [
os.path.join(BASE_DIR, 'app/templates'), {
) 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'app/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
ROOT_URLCONF = 'project.urls' ROOT_URLCONF = 'app.urls'
WSGI_APPLICATION = 'project.wsgi.application' WSGI_APPLICATION = 'app.wsgi.application'
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Database # Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases # https://docs.djangoproject.com/en/1.7/ref/settings/#databases
@ -70,7 +80,7 @@ USE_TZ = False
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/ # https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_ROOT = 'staticfiles' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATICFILES_DIRS = ( STATICFILES_DIRS = (

View file

@ -26,9 +26,9 @@
{% endif %} {% endif %}
<div id="info"> <div id="info">
<p>Makes links shorter, like this: <a href="https://min.ie/WVFdWJMa" target="_blank">https://min.ie/WVFdWJMa</a></p> <p>Makes links shorter, like this: <a href="https://min.ie/WVFdWJMa" target="_blank">https://min.ie/WVFdWJMa</a></p>
<p>Drag this bookmarklet <a onclick="return false" class="bookmark" href="javascript:void(window.location='http://min.ie/'+window.location)">min.ie</a> to your bookmark bar for quick shrinking. Then just click the bookmark on a page you want a short url for.</p> <p>Drag this bookmarklet <a onclick="return false" class="bookmark" href="javascript:void(window.location='https://min.ie/'+window.location)">min.ie</a> to your bookmark bar for quick shrinking. Then just click the bookmark on a page you want a short url for.</p>
</div> </div>
<footer><a href="https://twitter.com/kudoz">Tweet</a> or <a href="https://github.com/kudos/min.ie">Fork</a>. &copy; <a href="http://crem.in">Jonathan Cremin</a></footer> <footer><a href="https://twitter.com/kudoz">Tweet</a> or <a href="https://github.com/kudos/min.ie">Fork</a>. &copy; <a href="https://crem.in">Jonathan Cremin</a></footer>
</div> </div>
<script> <script>

7
app/urls.py Normal file
View file

@ -0,0 +1,7 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'(.*)', views.catchall, name='short'),
]

View file

@ -1,4 +1,4 @@
from urlparse import urlparse from urllib.parse import urlparse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.db.models import F from django.db.models import F

View file

@ -8,9 +8,8 @@ https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
""" """
import os import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application()) application = get_wsgi_application()

21
docker-compose.yml Normal file
View file

@ -0,0 +1,21 @@
version: "2"
services:
app:
build: ./
environment:
DJANGO_SETTINGS_MODULE: app.settings
DATABASE_URL: postgres://minie:minie@database:5432/minie
DEBUG: "true"
SECRET_KEY: unsafe
volumes:
- ./:/app
ports:
- "8000:8000"
database:
image: "postgres:10-alpine"
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: "minie"
POSTGRES_USER: "minie"
POSTGRES_DB: "minie"

View file

@ -3,7 +3,7 @@ import os
import sys import sys
if __name__ == "__main__": if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line

View file

@ -1,38 +0,0 @@
upstream {{ .APP }} {
{{ range .DOKKU_APP_LISTENERS | split " " }}
server {{ . }};
{{ end }}
}
server {
listen [::]:{{ .NGINX_PORT }};
listen {{ .NGINX_PORT }};
server_name {{ .NOSSL_SERVER_NAME }};
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;
return 301 https://$host:{{ .NGINX_SSL_PORT }}$request_uri;
}
server {
listen [::]:{{ .NGINX_SSL_PORT }} ssl spdy;
listen {{ .NGINX_SSL_PORT }} ssl spdy;
server_name {{ .NOSSL_SERVER_NAME }};
access_log /var/log/nginx/{{ .APP }}-access.log;
error_log /var/log/nginx/{{ .APP }}-error.log;
ssl_certificate {{ .APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ .APP_SSL_PATH }}/server.key;
location / {
proxy_pass http://{{ .APP }};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-Start $msec;
}
include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf;
}

View file

View file

@ -1,7 +0,0 @@
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^$', 'app.views.home', name='home'),
url(r'(.*)', 'app.views.catchall', name='short'),
)

View file

@ -1,8 +0,0 @@
dj-database-url==0.3.0
dj-static==0.0.6
Django==1.7.3
django-sslify==0.2.5
django-toolbelt==0.0.1
gunicorn==19.1.1
psycopg2==2.5.4
static3==0.5.1