Improve production setup
This commit is contained in:
parent
c489f354c5
commit
70f9fb9818
16
.dockerignore
Normal file
16
.dockerignore
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Remove project files, data, tmp files, build files
|
||||||
|
/.env
|
||||||
|
/.idea
|
||||||
|
/data
|
||||||
|
/node_modules
|
||||||
|
/tmp
|
||||||
|
|
||||||
|
/.dockerignore
|
||||||
|
/.gitignore
|
||||||
|
/build-*.sh
|
||||||
|
/Dockerfile
|
||||||
|
/*.iml
|
||||||
|
/package*.json
|
||||||
|
|
||||||
|
# Remove development settings
|
||||||
|
/siteroot/settings/dev.py
|
18
Dockerfile
18
Dockerfile
@ -5,25 +5,17 @@ RUN apt-get update
|
|||||||
RUN apt-get -y install build-essential
|
RUN apt-get -y install build-essential
|
||||||
|
|
||||||
# Install requirements and uwsgi server for running python web apps
|
# Install requirements and uwsgi server for running python web apps
|
||||||
WORKDIR /etc/linkdings
|
WORKDIR /etc/linkding
|
||||||
COPY requirements.prod.txt ./requirements.txt
|
COPY requirements.prod.txt ./requirements.txt
|
||||||
RUN pip install -U pip
|
RUN pip install -U pip
|
||||||
RUN pip install -Ur requirements.txt
|
RUN pip install -Ur requirements.txt
|
||||||
RUN pip install uwsgi
|
|
||||||
|
|
||||||
# Copy application
|
# Copy application
|
||||||
COPY bookmarks ./bookmarks
|
COPY . .
|
||||||
COPY siteroot ./siteroot
|
|
||||||
COPY static ./static
|
|
||||||
COPY manage.py .
|
|
||||||
COPY uwsgi.ini .
|
|
||||||
COPY bootstrap.sh .
|
|
||||||
RUN ["chmod", "+x", "./bootstrap.sh"]
|
|
||||||
|
|
||||||
# Create data folder
|
|
||||||
RUN ["mkdir", "data"]
|
|
||||||
|
|
||||||
|
# Expose uwsgi server at port 9090
|
||||||
EXPOSE 9090
|
EXPOSE 9090
|
||||||
|
|
||||||
# Start uwsgi server
|
# Run bootstrap logic
|
||||||
|
RUN ["chmod", "+x", "./bootstrap.sh"]
|
||||||
CMD ["./bootstrap.sh"]
|
CMD ["./bootstrap.sh"]
|
||||||
|
10
bootstrap.sh
10
bootstrap.sh
@ -1,14 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Bootstrap script that gets executed in new Docker containers
|
# Bootstrap script that gets executed in new Docker containers
|
||||||
|
|
||||||
# Set host name in settings if it was passed as environment variable
|
# Create data folder if it does not exist
|
||||||
if [[ -v HOST_NAME ]]
|
mkdir -p data
|
||||||
then
|
|
||||||
printf "ALLOWED_HOSTS=['%s']" $HOST_NAME > ./siteroot/settings_custom.py
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run database migration
|
# Run database migration
|
||||||
python manage.py migrate
|
python manage.py migrate
|
||||||
|
# Generate secret key file if it does not exist
|
||||||
|
python manage.py generate_secret_key
|
||||||
|
|
||||||
# Start uwsgi server
|
# Start uwsgi server
|
||||||
uwsgi uwsgi.ini
|
uwsgi uwsgi.ini
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
./build-static.sh
|
./build-static.sh
|
||||||
docker build -t sissbruecker/linkding .
|
#docker build -t sissbruecker/linkding .
|
||||||
#docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t sissbruecker/linkding:latest --push .
|
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t sissbruecker/linkding:latest --push .
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<facet type="django" name="Django">
|
<facet type="django" name="Django">
|
||||||
<configuration>
|
<configuration>
|
||||||
<option name="rootFolder" value="$MODULE_DIR$" />
|
<option name="rootFolder" value="$MODULE_DIR$" />
|
||||||
<option name="settingsModule" value="siteroot/settings.py" />
|
<option name="settingsModule" value="siteroot/settings" />
|
||||||
<option name="manageScript" value="manage.py" />
|
<option name="manageScript" value="manage.py" />
|
||||||
<option name="environment" value="<map/>" />
|
<option name="environment" value="<map/>" />
|
||||||
<option name="doNotUseTestRunner" value="false" />
|
<option name="doNotUseTestRunner" value="false" />
|
||||||
@ -25,10 +25,5 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="TemplatesService">
|
<component name="TemplatesService">
|
||||||
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
||||||
<option name="TEMPLATE_FOLDERS">
|
|
||||||
<list>
|
|
||||||
<option value="$MODULE_DIR$/polls/templates" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -4,6 +4,7 @@ chardet==3.0.4
|
|||||||
Django==2.2.2
|
Django==2.2.2
|
||||||
django-appconf==1.0.3
|
django-appconf==1.0.3
|
||||||
django-compressor==2.3
|
django-compressor==2.3
|
||||||
|
django-generate-secret-key==1.0.2
|
||||||
django-picklefield==2.0
|
django-picklefield==2.0
|
||||||
django-sass-processor==0.7.3
|
django-sass-processor==0.7.3
|
||||||
django-widget-tweaks==1.4.5
|
django-widget-tweaks==1.4.5
|
||||||
@ -16,3 +17,4 @@ six==1.12.0
|
|||||||
soupsieve==1.9.2
|
soupsieve==1.9.2
|
||||||
sqlparse==0.3.0
|
sqlparse==0.3.0
|
||||||
urllib3==1.25.3
|
urllib3==1.25.3
|
||||||
|
uWSGI==2.0.18
|
||||||
|
@ -4,6 +4,7 @@ chardet==3.0.4
|
|||||||
Django==2.2.2
|
Django==2.2.2
|
||||||
django-appconf==1.0.3
|
django-appconf==1.0.3
|
||||||
django-compressor==2.3
|
django-compressor==2.3
|
||||||
|
django-generate-secret-key==1.0.2
|
||||||
django-picklefield==2.0
|
django-picklefield==2.0
|
||||||
django-sass-processor==0.7.3
|
django-sass-processor==0.7.3
|
||||||
django-widget-tweaks==1.4.5
|
django-widget-tweaks==1.4.5
|
||||||
|
5
siteroot/settings/__init__.py
Normal file
5
siteroot/settings/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Use dev settings as default, use production if dev settings do not exist
|
||||||
|
try:
|
||||||
|
from .dev import *
|
||||||
|
except:
|
||||||
|
from .prod import *
|
@ -13,7 +13,8 @@ https://docs.djangoproject.com/en/2.2/ref/settings/
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||||
@ -22,9 +23,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
SECRET_KEY = 'kgq$h3@!!vbb6*nzfz(dbze=*)zsroqa8gvc0#1gx$3cd8z99^'
|
SECRET_KEY = 'kgq$h3@!!vbb6*nzfz(dbze=*)zsroqa8gvc0#1gx$3cd8z99^'
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = False
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'sass_processor',
|
'sass_processor',
|
||||||
'widget_tweaks',
|
'widget_tweaks',
|
||||||
|
'django_generate_secret_key',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -123,8 +125,9 @@ STATIC_URL = '/static/'
|
|||||||
# Collect static files in static folder
|
# Collect static files in static folder
|
||||||
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
||||||
|
|
||||||
|
# Turn off SASS compilation by default
|
||||||
|
SASS_PROCESSOR_ENABLED = False
|
||||||
# Location where generated CSS files are saved
|
# Location where generated CSS files are saved
|
||||||
SASS_PROCESSOR_ENABLED = True
|
|
||||||
SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, 'tmp', 'build', 'styles')
|
SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, 'tmp', 'build', 'styles')
|
||||||
|
|
||||||
# Add SASS preprocessor finder to resolve generated CSS
|
# Add SASS preprocessor finder to resolve generated CSS
|
||||||
@ -138,26 +141,3 @@ STATICFILES_FINDERS = [
|
|||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
os.path.join(BASE_DIR, 'bookmarks', 'styles'),
|
os.path.join(BASE_DIR, 'bookmarks', 'styles'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Logging with SQL statements
|
|
||||||
LOGGING = {
|
|
||||||
'version': 1,
|
|
||||||
'filters': {
|
|
||||||
'require_debug_true': {
|
|
||||||
'()': 'django.utils.log.RequireDebugTrue',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'handlers': {
|
|
||||||
'console': {
|
|
||||||
'level': 'DEBUG',
|
|
||||||
'filters': ['require_debug_true'],
|
|
||||||
'class': 'logging.StreamHandler',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'loggers': {
|
|
||||||
'django.db.backends': {
|
|
||||||
'level': 'DEBUG',
|
|
||||||
'handlers': ['console'],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1
siteroot/settings/custom.py
Normal file
1
siteroot/settings/custom.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Placeholder, can be mounted in a Docker container with a custom settings
|
40
siteroot/settings/dev.py
Normal file
40
siteroot/settings/dev.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""
|
||||||
|
Development settings for linkding webapp
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Start from development settings
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
from .base import *
|
||||||
|
|
||||||
|
# Turn on debug mode
|
||||||
|
DEBUG = True
|
||||||
|
# Turn on SASS compilation
|
||||||
|
SASS_PROCESSOR_ENABLED = True
|
||||||
|
|
||||||
|
# Enable debug logging
|
||||||
|
# Logging with SQL statements
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'filters': {
|
||||||
|
'require_debug_true': {
|
||||||
|
'()': 'django.utils.log.RequireDebugTrue',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'console': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'filters': ['require_debug_true'],
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'django.db.backends': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'handlers': ['console'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Import custom settings
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
from .custom import *
|
33
siteroot/settings/prod.py
Normal file
33
siteroot/settings/prod.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
"""
|
||||||
|
Production settings for linkding webapp
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Start from development settings
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
import os
|
||||||
|
|
||||||
|
from .base import *
|
||||||
|
|
||||||
|
# Turn of debug mode
|
||||||
|
DEBUG = False
|
||||||
|
# Turn off SASS compilation
|
||||||
|
SASS_PROCESSOR_ENABLED = False
|
||||||
|
|
||||||
|
# Try read secret key from file
|
||||||
|
try:
|
||||||
|
with open(os.path.join(BASE_DIR, 'secretkey.txt')) as f:
|
||||||
|
SECRET_KEY = f.read().strip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Set ALLOWED_HOSTS
|
||||||
|
# By default look in the HOST_NAME environment variable, if that is not set then allow all hosts
|
||||||
|
host_name = os.environ.get('HOST_NAME')
|
||||||
|
if host_name:
|
||||||
|
ALLOWED_HOSTS = [host_name]
|
||||||
|
else:
|
||||||
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
|
# Import custom settings
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
from .custom import *
|
@ -1 +0,0 @@
|
|||||||
# Placeholder, can be overridden in Docker container with a custom settings like ALLOWED_HOSTS
|
|
@ -1,18 +0,0 @@
|
|||||||
"""
|
|
||||||
Production settings for linkding webapp
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Start from development settings
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
from .settings import *
|
|
||||||
|
|
||||||
# Turn of debug mode
|
|
||||||
DEBUG = False
|
|
||||||
# Turn off SASS compilation
|
|
||||||
SASS_PROCESSOR_ENABLED = False
|
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['*']
|
|
||||||
|
|
||||||
# Import custom settings
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
from .settings_custom import *
|
|
@ -1,12 +1,11 @@
|
|||||||
[uwsgi]
|
[uwsgi]
|
||||||
#socket = 127.0.0.1:3031
|
|
||||||
http = :9090
|
http = :9090
|
||||||
chdir = /etc/linkdings
|
chdir = /etc/linkding
|
||||||
module = siteroot.wsgi:application
|
module = siteroot.wsgi:application
|
||||||
env = DJANGO_SETTINGS_MODULE=siteroot.settings_prod
|
env = DJANGO_SETTINGS_MODULE=siteroot.settings.prod
|
||||||
static-map = /static=static
|
static-map = /static=static
|
||||||
processes = 4
|
processes = 4
|
||||||
threads = 2
|
threads = 2
|
||||||
pidfile = /tmp/project-master.pid
|
pidfile = /tmp/linkding.pid
|
||||||
vacuum=True
|
vacuum=True
|
||||||
stats = 127.0.0.1:9191
|
stats = 127.0.0.1:9191
|
||||||
|
Loading…
Reference in New Issue
Block a user