Build docker image closes #28
This commit is contained in:
+12
-14
@@ -1,7 +1,8 @@
|
||||
FROM python:3.12-alpine3.23
|
||||
|
||||
# Add postgress dependencies
|
||||
# Add dependencies
|
||||
#RUN apk add --no-cache postgresql-libs postgresql-client
|
||||
RUN apk add --no-cache tini
|
||||
|
||||
# Install pipenv
|
||||
RUN pip install pipenv
|
||||
@@ -10,31 +11,28 @@ RUN pip install pipenv
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
DOCKER=true
|
||||
|
||||
#Create app dir and install requirements.
|
||||
RUN mkdir /opt/rsvp
|
||||
RUN mkdir /opt/rsvp/static
|
||||
#Create app dir
|
||||
RUN mkdir -p /opt/rsvp
|
||||
RUN mkdir -p /opt/rsvp/static
|
||||
WORKDIR /opt/rsvp
|
||||
|
||||
# Copy Pipfile and Pipfile.lock
|
||||
COPY Pipfile Pipfile.lock ./
|
||||
|
||||
# Install dependencies
|
||||
# Install python dependencies
|
||||
RUN pipenv install --deploy --system
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
RUN python manage.py collectstatic --no-input
|
||||
RUN python -m blacknoise.compress /opt/rsvp/static/
|
||||
|
||||
#This port will be used by nginx.
|
||||
EXPOSE 8000 8000
|
||||
|
||||
RUN mkdir /data
|
||||
RUN mkdir /data/media
|
||||
RUN mkdir -p /data
|
||||
|
||||
# The volume containing dynamic data
|
||||
VOLUME /data
|
||||
|
||||
#This port will be used by daphne
|
||||
EXPOSE 8000
|
||||
|
||||
# Run the application
|
||||
CMD ["daphne", "rsvpproject.asgi:application"]
|
||||
RUN chmod +x start.sh
|
||||
ENTRYPOINT ["/sbin/tini", "--", "/opt/rsvp/start.sh"]
|
||||
@@ -10,6 +10,7 @@ django = "*"
|
||||
django-markdown = "*"
|
||||
pillow = "*"
|
||||
blacknoise = "*"
|
||||
twisted = {extras = ["http2", "tls"], version = "*"}
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
Generated
+33
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "7e3d07ddaedc66aca9c1608f0fbe329c346a3a763ed0a7af8983ae7fa5f76b20"
|
||||
"sha256": "07e2a33b6016199f2401424d35bc436e5355db12dd734f543d2633b4dd31a22d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -337,6 +337,29 @@
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"h2": {
|
||||
"hashes": [
|
||||
"sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1",
|
||||
"sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"hpack": {
|
||||
"hashes": [
|
||||
"sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496",
|
||||
"sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"hyperframe": {
|
||||
"hashes": [
|
||||
"sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5",
|
||||
"sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==6.1.0"
|
||||
},
|
||||
"hyperlink": {
|
||||
"hashes": [
|
||||
"sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
|
||||
@@ -541,6 +564,13 @@
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==12.1.1"
|
||||
},
|
||||
"priority": {
|
||||
"hashes": [
|
||||
"sha256:6bc1961a6d7fcacbfc337769f1a382c8e746566aaa365e78047abe9f66b2ffbe",
|
||||
"sha256:be4fcb94b5e37cdeb40af5533afe6dd603bd665fe9c8b3052610fc1001d5d1eb"
|
||||
],
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"py-ubjson": {
|
||||
"hashes": [
|
||||
"sha256:b9bfb8695a1c7e3632e800fb83c943bf67ed45ddd87cd0344851610c69a5a482"
|
||||
@@ -603,6 +633,7 @@
|
||||
},
|
||||
"twisted": {
|
||||
"extras": [
|
||||
"http2",
|
||||
"tls"
|
||||
],
|
||||
"hashes": [
|
||||
@@ -640,7 +671,7 @@
|
||||
"sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466",
|
||||
"sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"
|
||||
],
|
||||
"markers": "python_version < '3.13'",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==4.15.0"
|
||||
},
|
||||
"ujson": {
|
||||
|
||||
@@ -33,6 +33,14 @@ Requirements (installed from Pipfile):
|
||||
- Daphne
|
||||
- BlackNoise
|
||||
|
||||
## Publish docker image
|
||||
|
||||
Build
|
||||
`docker build -t gitea.furb.it/kennyboy55/friend-event-rsvp:dev .`
|
||||
|
||||
How to tag:
|
||||
`docker push gitea.furb.it/kennyboy55/friend-event-rsvp:dev`
|
||||
|
||||
## Run
|
||||
|
||||
Run the server during development: `DEBUG=1 python manage.py runserver`
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
app:
|
||||
image: gitea.furb.it/kennyboy55/friend-event-rsvp:dev
|
||||
container_name: friend-event-rsvp
|
||||
ports:
|
||||
- "8000:8000"
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./data:/data
|
||||
@@ -0,0 +1,15 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# This template contains only required options.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
|
||||
SECRET_KEY=
|
||||
|
||||
# your default timezone See https://timezonedb.com/time-zones for a list of timezones
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# allowed hosts (see documentation), must be set to your hostname(s)
|
||||
ALLOWED_HOSTS=events.mydomain.com
|
||||
|
||||
# enable debug log
|
||||
#DEBUG=1
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 6.0 on 2025-12-20 13:32
|
||||
# Generated by Django 6.0.3 on 2026-03-27 12:24
|
||||
|
||||
import datetime
|
||||
import django.db.models.deletion
|
||||
@@ -38,6 +38,7 @@ class Migration(migrations.Migration):
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('location', models.CharField(max_length=255)),
|
||||
('start_time', models.DateTimeField()),
|
||||
('end_time', models.DateTimeField(blank=True, null=True)),
|
||||
('guest_limit', models.PositiveIntegerField(blank=True, null=True)),
|
||||
@@ -66,7 +67,7 @@ class Migration(migrations.Migration):
|
||||
('slug', models.SlugField(max_length=255)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('image', models.ImageField(blank=True, null=True, upload_to=events.models.event_image_path)),
|
||||
('allow_rsvp_without_invite', models.BooleanField(default=True)),
|
||||
('allow_rsvp_without_invite', models.BooleanField(default=False)),
|
||||
('allow_comments', models.BooleanField(default=True)),
|
||||
('default_email_updates_optin', models.BooleanField(default=True)),
|
||||
('guest_limit', models.PositiveIntegerField(blank=True, null=True)),
|
||||
@@ -78,21 +79,6 @@ class Migration(migrations.Migration):
|
||||
'ordering': ['-id'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Comment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('text', models.TextField()),
|
||||
('notify_subscribers', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='activitygroup',
|
||||
name='event',
|
||||
@@ -103,46 +89,6 @@ class Migration(migrations.Migration):
|
||||
name='event',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='events.event'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuestListTemplate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GuestListItem',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('email', models.EmailField(blank=True, max_length=254)),
|
||||
('is_main_invitee', models.BooleanField(default=True)),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='events.guestlisttemplate')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Invite',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('code', models.CharField(db_index=True, max_length=64, unique=True)),
|
||||
('recipient_name', models.CharField(blank=True, max_length=255)),
|
||||
('recipient_email', models.EmailField(blank=True, max_length=254)),
|
||||
('personalized_message', models.TextField(blank=True)),
|
||||
('allow_bring_guests', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invites', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Guest',
|
||||
fields=[
|
||||
@@ -154,7 +100,21 @@ class Migration(migrations.Migration):
|
||||
('is_main_invitee', models.BooleanField(default=False)),
|
||||
('created_by_host', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='guests', to='events.event')),
|
||||
('invite', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='guests', to='events.invite')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Comment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('text', models.TextField()),
|
||||
('notify_subscribers', models.BooleanField(default=False)),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.event')),
|
||||
('guest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='events.guest')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
@@ -187,25 +147,6 @@ class Migration(migrations.Migration):
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='events.question')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RSVP',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('edit_token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
||||
('responder_email', models.EmailField(blank=True, max_length=254)),
|
||||
('send_email_updates', models.BooleanField(default=True)),
|
||||
('status', models.CharField(choices=[('yes', 'Yes'), ('no', 'No'), ('maybe', 'Maybe'), ('pending', 'Pending')], default='pending', max_length=10)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
('activities', models.ManyToManyField(related_name='rsvps', through='events.ActivitySelection', to='events.activity')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rsvps', to='events.event')),
|
||||
('invite', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rsvps', to='events.invite')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Response',
|
||||
fields=[
|
||||
@@ -214,15 +155,60 @@ class Migration(migrations.Migration):
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('value_text', models.TextField(blank=True)),
|
||||
('activity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.activity')),
|
||||
('choice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.questionchoice')),
|
||||
('guest', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.guest')),
|
||||
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.question')),
|
||||
('rsvp', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.rsvp')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ResponseChoice',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='response_choices', to='events.questionchoice')),
|
||||
('response', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='response_choices', to='events.response')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('response', 'choice')},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='response',
|
||||
name='choices',
|
||||
field=models.ManyToManyField(blank=True, related_name='responses', through='events.ResponseChoice', to='events.questionchoice'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RSVP',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('invite', models.SlugField(max_length=255, unique=True)),
|
||||
('edit_token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
||||
('responder_name', models.CharField(blank=True, max_length=255)),
|
||||
('responder_email', models.EmailField(max_length=254)),
|
||||
('send_email_updates', models.BooleanField(default=True)),
|
||||
('personalized_message', models.TextField(blank=True)),
|
||||
('allow_bring_guests', models.BooleanField(default=False)),
|
||||
('page', models.CharField(choices=[('email', 'Email'), ('guests', 'Guests'), ('activities', 'Activities'), ('questions', 'Questions'), ('notes', 'Notes'), ('completed', 'Completed')], default='email', max_length=16)),
|
||||
('furthest_page', models.CharField(choices=[('email', 'Email'), ('guests', 'Guests'), ('activities', 'Activities'), ('questions', 'Questions'), ('notes', 'Notes'), ('completed', 'Completed')], default='email', max_length=16)),
|
||||
('status', models.CharField(choices=[('unopened', 'Not Opened'), ('not_started', 'Not Started'), ('incomplete', 'Incomplete'), ('not_coming', 'Not coming'), ('joining', 'Yes, joining')], default='unopened', max_length=16)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
('activities', models.ManyToManyField(related_name='rsvps', through='events.ActivitySelection', to='events.activity')),
|
||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rsvps', to='events.event')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='response',
|
||||
name='rsvp',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='events.rsvp'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='guest',
|
||||
name='rsvp',
|
||||
|
||||
+14
-5
@@ -8,7 +8,7 @@ https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import logging
|
||||
|
||||
from channels.auth import AuthMiddlewareStack
|
||||
from channels.routing import ProtocolTypeRouter, URLRouter
|
||||
@@ -17,14 +17,23 @@ from channels.security.websocket import AllowedHostsOriginValidator
|
||||
from blacknoise import BlackNoise
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rsvpproject.settings')
|
||||
|
||||
STATIC_DIR = Path(__file__).parent.parent / "static"
|
||||
MEDIA_DIR = Path(__file__).parent.parent / "media"
|
||||
from django.conf import settings
|
||||
|
||||
if settings.DEBUG:
|
||||
logger.warning("DEBUG enabled")
|
||||
|
||||
if settings.DOCKER:
|
||||
logger.warning("DOCKER enabled")
|
||||
|
||||
logger.info(f"ALLOWED_HOSTS={settings.ALLOWED_HOSTS}")
|
||||
|
||||
django_asgi_app = BlackNoise(get_asgi_application())
|
||||
django_asgi_app.add(STATIC_DIR, "/static")
|
||||
django_asgi_app.add(MEDIA_DIR, "/media")
|
||||
django_asgi_app.add(settings.STATIC_ROOT, "/static")
|
||||
django_asgi_app.add(settings.MEDIA_ROOT, "/media")
|
||||
|
||||
from events.routing import websocket_urlpatterns
|
||||
|
||||
|
||||
+27
-11
@@ -13,8 +13,24 @@ https://docs.djangoproject.com/en/6.0/ref/settings/
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def extract_bool(env_key, default):
|
||||
return bool(int(os.getenv(env_key, default)))
|
||||
bool_map = {"true": True, "false": False}
|
||||
|
||||
def extract_bool(env_key, default:bool):
|
||||
|
||||
retval = default
|
||||
env_val = os.getenv(env_key)
|
||||
|
||||
if env_val:
|
||||
# Try as int
|
||||
try:
|
||||
bool_as_num = int(env_val)
|
||||
retval = bool(bool_as_num)
|
||||
# Try as string
|
||||
except ValueError:
|
||||
# Convert string to boolean using the dictionary
|
||||
retval = bool_map.get(env_val.lower(), default)
|
||||
|
||||
return retval
|
||||
|
||||
|
||||
def extract_comma_list(env_key, default=None):
|
||||
@@ -26,14 +42,6 @@ def extract_comma_list(env_key, default=None):
|
||||
else:
|
||||
return []
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
DOCKER_DIR = BASE_DIR
|
||||
|
||||
if extract_bool('DOCKER', False):
|
||||
# We are running in docker
|
||||
DOCKER_DIR = Path('/data')
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/
|
||||
|
||||
@@ -42,11 +50,19 @@ SECRET_KEY = os.getenv('SECRET_KEY', 'INSECURE_STANDARD_KEY_SET_IN_ENV')
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = extract_bool('DEBUG', False)
|
||||
DOCKER = extract_bool('DOCKER', False)
|
||||
|
||||
ALLOWED_HOSTS = extract_comma_list('ALLOWED_HOSTS', ['127.0.0.1'])
|
||||
ALLOWED_HOSTS = extract_comma_list('ALLOWED_HOSTS', '127.0.0.1')
|
||||
CSRF_TRUSTED_ORIGINS = extract_comma_list('CSRF_TRUSTED_ORIGINS')
|
||||
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
DOCKER_DIR = BASE_DIR
|
||||
|
||||
if DOCKER:
|
||||
# We are running in docker
|
||||
DOCKER_DIR = Path('/data')
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
echo "Migrating database"
|
||||
|
||||
python manage.py migrate
|
||||
|
||||
echo "Collecting and optimizing static files, this may take a while..."
|
||||
|
||||
python manage.py collectstatic --noinput --clear
|
||||
python -m blacknoise.compress static/
|
||||
|
||||
echo "Creating all necessary directories..."
|
||||
|
||||
mkdir -p /data/media
|
||||
|
||||
echo "Done"
|
||||
|
||||
daphne -b 0.0.0.0 -p 8000 rsvpproject.asgi:application
|
||||
Reference in New Issue
Block a user