Skip to content

Commit bdc0db3

Browse files
authored
Merge branch 'main' into dependabot/pip/pillow-10.2.0
2 parents 7a3a515 + d94b133 commit bdc0db3

26 files changed

+480
-216
lines changed

Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
1616
set -x \
1717
&& apt-get update \
1818
&& apt-get install --no-install-recommends -y \
19-
pandoc \
2019
texlive-latex-base \
2120
texlive-latex-recommended \
2221
texlive-fonts-recommended \
@@ -35,6 +34,8 @@ WORKDIR /code
3534

3635
COPY dev-requirements.txt /code/
3736
COPY base-requirements.txt /code/
37+
COPY prod-requirements.txt /code/
38+
COPY requirements.txt /code/
3839

3940
RUN pip --no-cache-dir --disable-pip-version-check install --upgrade pip setuptools wheel
4041

Dockerfile.cabotage

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
FROM python:3.9-bullseye
2+
COPY --from=ewdurbin/nginx-static:1.25.x /usr/bin/nginx /usr/bin/nginx
3+
ENV PYTHONUNBUFFERED=1
4+
ENV PYTHONDONTWRITEBYTECODE=1
5+
6+
# By default, Docker has special steps to avoid keeping APT caches in the layers, which
7+
# is good, but in our case, we're going to mount a special cache volume (kept between
8+
# builds), so we WANT the cache to persist.
9+
RUN set -eux; \
10+
rm -f /etc/apt/apt.conf.d/docker-clean; \
11+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache;
12+
13+
# Install System level build requirements, this is done before
14+
# everything else because these are rarely ever going to change.
15+
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
16+
--mount=type=cache,target=/var/lib/apt,sharing=locked \
17+
set -x \
18+
&& apt-get update \
19+
&& apt-get install --no-install-recommends -y \
20+
texlive-latex-base \
21+
texlive-latex-recommended \
22+
texlive-fonts-recommended \
23+
texlive-plain-generic \
24+
lmodern
25+
26+
RUN case $(uname -m) in \
27+
"x86_64") ARCH=amd64 ;; \
28+
"aarch64") ARCH=arm64 ;; \
29+
esac \
30+
&& wget --quiet https://github.com/jgm/pandoc/releases/download/2.17.1.1/pandoc-2.17.1.1-1-${ARCH}.deb \
31+
&& dpkg -i pandoc-2.17.1.1-1-${ARCH}.deb
32+
33+
RUN mkdir /code
34+
WORKDIR /code
35+
36+
COPY dev-requirements.txt /code/
37+
COPY base-requirements.txt /code/
38+
COPY prod-requirements.txt /code/
39+
COPY requirements.txt /code/
40+
41+
RUN pip --no-cache-dir --disable-pip-version-check install --upgrade pip setuptools wheel
42+
43+
RUN --mount=type=cache,target=/root/.cache/pip \
44+
set -x \
45+
&& pip --disable-pip-version-check \
46+
install \
47+
-r requirements.txt -r prod-requirements.txt
48+
COPY . /code/
49+
RUN DJANGO_SETTINGS_MODULE=pydotorg.settings.static python manage.py collectstatic --noinput

Procfile

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
release: python manage.py migrate --noinput
22
web: bin/start-nginx gunicorn -c gunicorn.conf pydotorg.wsgi
3+
worker: celery -A pydotorg worker -l INFO
4+
worker-beat: celery -A pydotorg beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler

base-requirements.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ psycopg2-binary==2.8.6
1313
python3-openid==3.2.0
1414
python-decouple==3.4
1515
# lxml used by BeautifulSoup.
16-
lxml==4.6.3
16+
lxml==4.9.2
1717
cssselect==1.1.0
1818
feedparser==6.0.8
1919
beautifulsoup4==4.11.2
2020
icalendar==4.0.7
2121
chardet==4.0.0
22+
celery[redis]==5.3.6
23+
django-celery-beat==2.5.0
2224
# TODO: We may drop 'django-imagekit' completely.
2325
django-imagekit==4.0.2
2426
django-haystack==3.2.1

bin/start-nginx

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
3+
psmgr=/tmp/nginx-buildpack-wait
4+
rm -f $psmgr
5+
mkfifo $psmgr
6+
7+
n=1
8+
while getopts :f option ${@:1:2}
9+
do
10+
case "${option}"
11+
in
12+
f) FORCE=$OPTIND; n=$((n+1));;
13+
esac
14+
done
15+
16+
# Initialize log directory.
17+
mkdir -p /tmp/logs/nginx
18+
touch /tmp/logs/nginx/access.log /tmp/logs/nginx/error.log
19+
echo 'buildpack=nginx at=logs-initialized'
20+
21+
# Start log redirection.
22+
(
23+
# Redirect nginx logs to stdout.
24+
tail -qF -n 0 /tmp/logs/nginx/*.log
25+
echo 'logs' >$psmgr
26+
) &
27+
28+
# Start App Server
29+
(
30+
# Take the command passed to this bin and start it.
31+
# E.g. bin/start-nginx bundle exec unicorn -c config/unicorn.rb
32+
COMMAND=${@:$n}
33+
echo "buildpack=nginx at=start-app cmd=$COMMAND"
34+
$COMMAND
35+
echo 'app' >$psmgr
36+
) &
37+
38+
if [[ -z "$FORCE" ]]
39+
then
40+
FILE="/tmp/app-initialized"
41+
42+
# We block on app-initialized so that when nginx binds to $PORT
43+
# are app is ready for traffic.
44+
while [[ ! -f "$FILE" ]]
45+
do
46+
echo 'buildpack=nginx at=app-initialization'
47+
sleep 1
48+
done
49+
echo 'buildpack=nginx at=app-initialized'
50+
fi
51+
52+
# Start nginx
53+
(
54+
# We expect nginx to run in foreground.
55+
# We also expect a socket to be at /tmp/nginx.socket.
56+
echo 'buildpack=nginx at=nginx-start'
57+
cd /tmp
58+
/usr/bin/nginx -p . -c /code/config/nginx.conf
59+
echo 'nginx' >$psmgr
60+
) &
61+
62+
# This read will block the process waiting on a msg to be put into the fifo.
63+
# If any of the processes defined above should exit,
64+
# a msg will be put into the fifo causing the read operation
65+
# to un-block. The process putting the msg into the fifo
66+
# will use it's process name as a msg so that we can print the offending
67+
# process to stdout.
68+
read exit_process <$psmgr
69+
echo "buildpack=nginx at=exit process=$exit_process"
70+
exit 1

blogs/tests/test_views.py

-9
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,3 @@ def test_blog_home(self):
2727

2828
latest = BlogEntry.objects.latest()
2929
self.assertEqual(resp.context['latest_entry'], latest)
30-
31-
def test_blog_redirects(self):
32-
"""
33-
Test that when '/blog/' is hit, it redirects '/blogs/'
34-
"""
35-
response = self.client.get('/blog/')
36-
self.assertRedirects(response,
37-
'/blogs/',
38-
status_code=301)

config/mime.types

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
types {
2+
text/html html htm shtml;
3+
text/css css;
4+
text/xml xml;
5+
image/gif gif;
6+
image/jpeg jpeg jpg;
7+
application/javascript js;
8+
application/atom+xml atom;
9+
application/rss+xml rss;
10+
11+
text/mathml mml;
12+
text/plain txt;
13+
text/vnd.sun.j2me.app-descriptor jad;
14+
text/vnd.wap.wml wml;
15+
text/x-component htc;
16+
17+
image/avif avif;
18+
image/png png;
19+
image/svg+xml svg svgz;
20+
image/tiff tif tiff;
21+
image/vnd.wap.wbmp wbmp;
22+
image/webp webp;
23+
image/x-icon ico;
24+
image/x-jng jng;
25+
image/x-ms-bmp bmp;
26+
27+
font/woff woff;
28+
font/woff2 woff2;
29+
30+
application/java-archive jar war ear;
31+
application/json json;
32+
application/mac-binhex40 hqx;
33+
application/msword doc;
34+
application/pdf pdf;
35+
application/postscript ps eps ai;
36+
application/rtf rtf;
37+
application/vnd.apple.mpegurl m3u8;
38+
application/vnd.google-earth.kml+xml kml;
39+
application/vnd.google-earth.kmz kmz;
40+
application/vnd.ms-excel xls;
41+
application/vnd.ms-fontobject eot;
42+
application/vnd.ms-powerpoint ppt;
43+
application/vnd.oasis.opendocument.graphics odg;
44+
application/vnd.oasis.opendocument.presentation odp;
45+
application/vnd.oasis.opendocument.spreadsheet ods;
46+
application/vnd.oasis.opendocument.text odt;
47+
application/vnd.openxmlformats-officedocument.presentationml.presentation
48+
pptx;
49+
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
50+
xlsx;
51+
application/vnd.openxmlformats-officedocument.wordprocessingml.document
52+
docx;
53+
application/vnd.wap.wmlc wmlc;
54+
application/wasm wasm;
55+
application/x-7z-compressed 7z;
56+
application/x-cocoa cco;
57+
application/x-java-archive-diff jardiff;
58+
application/x-java-jnlp-file jnlp;
59+
application/x-makeself run;
60+
application/x-perl pl pm;
61+
application/x-pilot prc pdb;
62+
application/x-rar-compressed rar;
63+
application/x-redhat-package-manager rpm;
64+
application/x-sea sea;
65+
application/x-shockwave-flash swf;
66+
application/x-stuffit sit;
67+
application/x-tcl tcl tk;
68+
application/x-x509-ca-cert der pem crt;
69+
application/x-xpinstall xpi;
70+
application/xhtml+xml xhtml;
71+
application/xspf+xml xspf;
72+
application/zip zip;
73+
74+
application/octet-stream bin exe dll;
75+
application/octet-stream deb;
76+
application/octet-stream dmg;
77+
application/octet-stream iso img;
78+
application/octet-stream msi msp msm;
79+
80+
audio/midi mid midi kar;
81+
audio/mpeg mp3;
82+
audio/ogg ogg;
83+
audio/x-m4a m4a;
84+
audio/x-realaudio ra;
85+
86+
video/3gpp 3gpp 3gp;
87+
video/mp2t ts;
88+
video/mp4 mp4;
89+
video/mpeg mpeg mpg;
90+
video/quicktime mov;
91+
video/webm webm;
92+
video/x-flv flv;
93+
video/x-m4v m4v;
94+
video/x-mng mng;
95+
video/x-ms-asf asx asf;
96+
video/x-ms-wmv wmv;
97+
video/x-msvideo avi;
98+
}

config/nginx.conf.erb config/nginx.conf

+32-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
daemon off;
2-
#Heroku dynos have at least 4 cores.
3-
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;
2+
worker_processes 2;
43

54
events {
65
use epoll;
@@ -15,9 +14,8 @@ http {
1514

1615
server_tokens off;
1716

18-
log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
19-
access_log logs/nginx/access.log l2met;
20-
error_log logs/nginx/error.log;
17+
access_log /tmp/logs/nginx/access.log;
18+
error_log /tmp/logs/nginx/error.log;
2119

2220
include mime.types;
2321
default_type application/octet-stream;
@@ -29,11 +27,11 @@ http {
2927
client_max_body_size 32m;
3028

3129
upstream app_server {
32-
server unix:/tmp/nginx.socket fail_timeout=0;
30+
server unix:/var/run/cabotage/nginx.sock fail_timeout=0;
3331
}
3432

3533
server {
36-
listen <%= ENV["PORT"] %>;
34+
listen unix:/var/run/cabotage/cabotage.sock;
3735
server_name _;
3836
keepalive_timeout 5;
3937

@@ -84,6 +82,10 @@ http {
8482
return 301 https://www.python.org/psf;
8583
}
8684

85+
location ~ ^/community-landing/?(.*)$ {
86+
return 301 https://www.python.org/community/;
87+
}
88+
8789
location /doc/Summary {
8890
return 301 http://legacy.python.org/doc/intros/summary;
8991
}
@@ -204,6 +206,22 @@ http {
204206
return 301 https://www.python.org/download/windows/;
205207
}
206208

209+
location ~ ^/download/$ {
210+
return 301 https://www.python.org/downloads/;
211+
}
212+
213+
location ~ ^/download/source/$ {
214+
return 301 https://www.python.org/downloads/source/;
215+
}
216+
217+
location ~ ^/download/mac/$ {
218+
return 301 https://www.python.org/downloads/macos/;
219+
}
220+
221+
location ~ ^/download/windows/$ {
222+
return 301 https://www.python.org/downloads/windows/;
223+
}
224+
207225
location /Mirrors.html {
208226
return 301 https://www.python.org/mirrors/;
209227
}
@@ -292,18 +310,22 @@ http {
292310
return 302 /blogs/;
293311
}
294312

313+
location /blog/ {
314+
return 301 https://python.org/blogs/;
315+
}
316+
295317
location /static/ {
296-
alias /app/static-root/;
318+
alias /code/static-root/;
297319
add_header Cache-Control "max-age=604800, public"; # 604800 is 7 days
298320
}
299321

300322
location /images/ {
301-
alias /app/static-root/images/;
323+
alias /code/static-root/images/;
302324
add_header Cache-Control "max-age=604800, public"; # 604800 is 7 days
303325
}
304326

305327
location /favicon.ico {
306-
alias /app/static-root/favicon.ico;
328+
alias /code/static-root/favicon.ico;
307329
add_header Cache-Control "max-age=604800, public"; # 604800 is 7 days
308330
}
309331

0 commit comments

Comments
 (0)