Skip to content

Instantly share code, notes, and snippets.

@BroHui
Last active November 1, 2023 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BroHui/a5c62653de0a844eac32299f414b52af to your computer and use it in GitHub Desktop.
Save BroHui/a5c62653de0a844eac32299f414b52af to your computer and use it in GitHub Desktop.
Django4.2LTS with Python3.11
FROM python:3.11-slim-bookworm as base
WORKDIR /wheels
COPY ./requirements.txt .
RUN sed -i s@/deb.debian.org/@/mirrors.163.com/@g /etc/apt/sources.list.d/debian.sources \
&& apt-get clean
RUN apt-get update && \
apt-get install -y \
default-libmysqlclient-dev \
libmariadb3 \
gcc libjpeg-dev libpng-dev
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ \
&& pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn
RUN pip install -U pip \
&& pip install --no-cache-dir wheel \
&& pip wheel --no-cache-dir --wheel-dir=/wheels -r requirements.txt
FROM python:3.11-slim-bookworm
ENV PYTHONUNBUFFERED 1
COPY --from=base /wheels /wheels
COPY --from=base /usr/lib/x86_64-linux-gnu/libmariadb.so.3 /usr/lib/x86_64-linux-gnu/
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ \
&& pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn
RUN pip install -U pip \
&& pip install -f /wheels -r /wheels/requirements.txt \
&& rm -rf /wheels \
&& rm -rf /root/.cache/pip/*
WORKDIR /var/www/
ADD entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["gunicorn", "yourapp.wsgi:application", "-b 0.0.0.0:8000"]
#!/bin/bash
# Install the project's requirements.txt, cached in .wheel in project directory.
# 指定requirements.txt文件的路径
requirements_file="/app/requirements.txt"
# .wheels目录
wheel_dir="/app/.wheels"
# 指定存储先前MD5值的文件路径
md5_file="/app/.wheels/requirements.md5"
function pip_install() {
echo "[*] Wheels not downloaded, downloading..."
pip wheel --no-cache-dir --wheel-dir=$wheel_dir -r $requirements_file
}
if [ -f "$requirements_file" ]; then
# 计算requirements.txt文件的当前MD5值
current_md5=$(md5sum "$requirements_file" | awk '{print $1}')
if [ ! -d "$wheel_dir" ]; then
pip_install
echo "$current_md5" > "$md5_file"
else
# 检查存储先前MD5值的文件是否存在
if [ -f "$md5_file" ]; then
# 读取先前的MD5值
previous_md5=$(cat "$md5_file")
# 比较当前MD5值和先前的MD5值
if [ "$current_md5" != "$previous_md5" ]; then
pip_install
echo "$current_md5" > "$md5_file"
else
echo "[*] Wheels already downloaded, skipping..."
fi
else
# 如果存储先前MD5值的文件不存在,将当前MD5值写入文件
echo "$current_md5" > "$md5_file"
pip_install
fi
fi
echo "[*] Installing..."
pip install --no-index --find-links=/app/.wheels -r /app/requirements.txt
echo "[*] Python packages installed."
echo "[*] Current Django version: $(python -c "import django; print(django.get_version())")"
fi
exec "$@"
Django >4.2,<4.3
uwsgi >2.0,<2.1
whitenoise == 6.6.0
...
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
"whitenoise.middleware.WhiteNoiseMiddleware",
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
STORAGES = {
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
'default': {
'BACKEND': 'django.core.files.storage.FileSystemStorage',
'LOCATION': os.path.join(BASE_DIR, "media"),
}
}
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT= os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
...
# hack for non-debug media files.
from django.http import HttpResponse, HttpResponseNotFound
from django.conf import settings
import os
def serve_media(request, path):
media_root = settings.MEDIA_ROOT
file_path = os.path.join(media_root, path)
if os.path.exists(file_path):
with open(file_path, 'rb') as file:
response = HttpResponse(file.read(), content_type='application/force-download')
response['Content-Disposition'] = f'attachment; filename="{os.path.basename(file_path)}"'
return response
else:
return HttpResponseNotFound('File not found')
urlpatterns = [
...
path('media/<path:path>', serve_media, name='serve_media')
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment