Skip to content

Commit abe3bea

Browse files
authored
Deployment (#234)
* fix deployment * update URL * Add zero downtime cd scripts
1 parent 3d88f0e commit abe3bea

10 files changed

Lines changed: 88 additions & 20 deletions

File tree

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ to cookiecutter and `kakistocracy`_). The alpha version is `here`_ and the
3030
full version doesn't exist yet.
3131

3232
* Homepage:
33-
https://democrasite.herokuapp.com
33+
https://democrasite.dev
3434
* Source code:
3535
https://github.com/mfosterw/cookiestocracy
3636
* Documentation:
3737
https://cookiestocracy.readthedocs.io/en/latest/
3838

39-
.. _`about page`: https://democrasite.herokuapp.com/about/
39+
.. _`about page`: https://democrasite.dev/about/
4040
.. _`kakistocracy`: https://en.wikipedia.org/wiki/Kakistocracy
4141
.. _`here`: https://github.com/mfosterw/democrasite-testing
4242

compose/production/django/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# define an alias for the specific python version used in this file.
2-
FROM docker.io/python:3.12.11-slim-bookworm as python
2+
FROM docker.io/python:3.12.11-slim-bookworm AS python
33

44
# Python build stage
55
FROM python AS python-build-stage
@@ -88,7 +88,8 @@ RUN chown -R django:django ${APP_HOME}
8888

8989
USER django
9090

91-
RUN DJANGO_SETTINGS_MODULE="config.settings.test" \
91+
RUN DATABASE_URL="postgres:///" \
92+
DJANGO_SETTINGS_MODULE="config.settings.test" \
9293
python manage.py compilemessages
9394

9495
ENTRYPOINT ["/entrypoint"]

compose/production/traefik/traefik.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ certificatesResolvers:
2222
letsencrypt:
2323
# https://doc.traefik.io/traefik/https/acme/#lets-encrypt
2424
acme:
25-
email: "matthew-foster-walsh@example.com"
25+
email: "admin@democrasite.dev"
2626
storage: /etc/traefik/acme/acme.json
2727
# https://doc.traefik.io/traefik/https/acme/#httpchallenge
2828
httpChallenge:
@@ -31,7 +31,7 @@ certificatesResolvers:
3131
http:
3232
routers:
3333
web-secure-router:
34-
rule: "Host(`example.com`) || Host(`www.example.com`)"
34+
rule: "Host(`democrasite.dev`)"
3535
entryPoints:
3636
- web-secure
3737
middlewares:
@@ -42,7 +42,7 @@ http:
4242
certResolver: letsencrypt
4343

4444
flower-secure-router:
45-
rule: "Host(`example.com`)"
45+
rule: "Host(`democrasite.dev`)"
4646
entryPoints:
4747
- flower
4848
service: flower
@@ -51,7 +51,7 @@ http:
5151
certResolver: letsencrypt
5252

5353
web-media-router:
54-
rule: "(Host(`example.com`) || Host(`www.example.com`)) && PathPrefix(`/media/`)"
54+
rule: "Host(`democrasite.dev`) && PathPrefix(`/media/`)"
5555
entryPoints:
5656
- web-secure
5757
middlewares:

config/settings/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@
247247
# Django Admin URL.
248248
ADMIN_URL = "admin/"
249249
# https://docs.djangoproject.com/en/dev/ref/settings/#admins
250-
ADMINS = [("Admin", "admin@democrasite.tech")]
250+
ADMINS = [("Admin", "admin@democrasite.dev")]
251251
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
252252
MANAGERS = ADMINS
253253

config/settings/production.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
1010
SECRET_KEY = env("DJANGO_SECRET_KEY")
1111
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
12-
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["democrasite.herokuapp.com"])
12+
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["democrasite.dev"])
1313

1414
# DATABASES
1515
# ------------------------------------------------------------------------------
@@ -72,7 +72,7 @@
7272
# https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email
7373
DEFAULT_FROM_EMAIL = env(
7474
"DJANGO_DEFAULT_FROM_EMAIL",
75-
default="Democrasite <noreply@democrasite.tech>",
75+
default="Democrasite <noreply@democrasite.dev>",
7676
)
7777
# https://docs.djangoproject.com/en/dev/ref/settings/#server-email
7878
SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL)
@@ -144,5 +144,5 @@
144144
# -------------------------------------------------------------------------------
145145
# Tools that generate code samples can use SERVERS to point to the correct domain
146146
SPECTACULAR_SETTINGS["SERVERS"] = [
147-
{"url": "https://democrasite.herokuapp.com", "description": "Production server"},
147+
{"url": "https://democrasite.dev", "description": "Production server"},
148148
]

democrasite/contrib/sites/migrations/0003_set_site_domain_and_name.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def update_site_forward(apps, schema_editor):
1414
Site.objects.update_or_create(
1515
id=settings.SITE_ID,
1616
defaults={
17-
"domain": "democrasite.herokuapp.com",
17+
"domain": "democrasite.dev",
1818
"name": "Democrasite",
1919
},
2020
)

democrasite/templates/pages/privacy.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ <h1>Contact Us</h1>
338338
<p>If you have any questions about this Privacy Policy, You can contact us:</p>
339339
<ul>
340340
<li>
341-
By email: <a href="mailto:admin@democrasite.tech">admin@democrasite.tech</a>
341+
By email: <a href="mailto:admin@democrasite.dev">admin@democrasite.dev</a>
342342
</li>
343343
</ul>
344344
{% endblock content %}

docker-compose.production.yml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ services:
99
build:
1010
context: .
1111
dockerfile: ./compose/production/django/Dockerfile
12-
image: us-east4-docker.pkg.dev/democrasite/democrasite/django
12+
image: democrasite_production_django
1313
volumes:
1414
- production_django_media:/app/democrasite/media
1515
depends_on:
@@ -19,23 +19,33 @@ services:
1919
- ./.envs/.production/.django
2020
- ./.envs/.production/.postgres
2121
command: /start
22+
deploy:
23+
resources:
24+
limits:
25+
cpus: "0.2"
26+
memory: 500M
2227

2328
postgres:
2429
build:
2530
context: .
2631
dockerfile: ./compose/production/postgres/Dockerfile
27-
image: us-east4-docker.pkg.dev/democrasite/democrasite/postgres
32+
image: democrasite_production_postgres
2833
volumes:
2934
- production_postgres_data:/var/lib/postgresql/data
3035
- production_postgres_data_backups:/backups
3136
env_file:
3237
- ./.envs/.production/.postgres
38+
deploy:
39+
resources:
40+
limits:
41+
cpus: "0.2"
42+
memory: 300M
3343

3444
traefik:
3545
build:
3646
context: .
3747
dockerfile: ./compose/production/traefik/Dockerfile
38-
image: us-east4-docker.pkg.dev/democrasite/democrasite/traefik
48+
image: democrasite_production_traefik
3949
depends_on:
4050
- django
4151
volumes:
@@ -44,23 +54,28 @@ services:
4454
- "0.0.0.0:80:80"
4555
- "0.0.0.0:443:443"
4656
- "0.0.0.0:5555:5555"
57+
deploy:
58+
resources:
59+
limits:
60+
cpus: "0.1"
61+
memory: 100M
4762

4863
redis:
4964
image: docker.io/redis:6
5065

5166
celeryworker:
5267
<<: *django
53-
image: us-east4-docker.pkg.dev/democrasite/democrasite/celeryworker
68+
image: democrasite_production_celeryworker
5469
command: /start-celeryworker
5570

5671
celerybeat:
5772
<<: *django
58-
image: us-east4-docker.pkg.dev/democrasite/democrasite/celerybeat
73+
image: democrasite_production_celerybeat
5974
command: /start-celerybeat
6075

6176
flower:
6277
<<: *django
63-
image: us-east4-docker.pkg.dev/democrasite/democrasite/flower
78+
image: democrasite_production_flower
6479
command: /start-flower
6580

6681
nginx:
@@ -72,3 +87,8 @@ services:
7287
- django
7388
volumes:
7489
- production_django_media:/usr/share/nginx/media:ro
90+
deploy:
91+
resources:
92+
limits:
93+
cpus: "0.1"
94+
memory: 100M

scripts/deploy-cron.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/bash
2+
3+
# Scripts adapted from https://www.youtube.com/watch?v=jFrGhodqC08 by Tom Delande
4+
# Licensed under https://creativecommons.org/licenses/by/4.0/
5+
6+
LOCK_FILE="$(pwd)/build.lock"
7+
cd /home/matthew/democrasite
8+
flock -n $LOCK_FILE scripts/deploy.sh >> build.log 2>&1

scripts/deploy.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/bash
2+
3+
# Scripts adapted from https://www.youtube.com/watch?v=jFrGhodqC08 by Tom Delande
4+
# Licensed under https://creativecommons.org/licenses/by/4.0/
5+
6+
echo "$(date --utc +%FT%TZ): Fetching remote repository..."
7+
git fetch
8+
9+
UPSTREAM=${1:-'@{u}'}
10+
LOCAL=$(git rev-parse @)
11+
REMOTE=$(git rev-parse "$UPSTREAM")
12+
BASE=$(git merge-base @ "$UPSTREAM")
13+
14+
if [ $LOCAL = $REMOTE ]; then
15+
echo "$(date --utc +%FT%TZ): No changes detected in git"
16+
elif [ $LOCAL = $BASE ]; then
17+
git pull
18+
19+
BUILD_VERSION=$(git rev-parse HEAD)
20+
echo "#(date --utc +%FT%TZ): Releasing new server version. $BUILD_VERSION"
21+
22+
echo "$(date --utc +%FT%TZ): Running build..."
23+
COMPOSE_FILE=/home/matthew/democrasite/docker-compose.production.yml
24+
docker compose rm -f
25+
docker compose build
26+
27+
OLD_CONTAINER=$(docker ps -aqf "name=django")
28+
echo "$(date --utc +%FT%TZ): Scaling server up..."
29+
BUILD VERSION=$BUILD VERSION docker compose up -d --no-deps --scale django=2 --no-recreate django
30+
31+
sleep 30
32+
33+
echo "$(date --utc +&FT&TZ): Scaling old server down..." docker container rm -f $OLD_CONTAINER
34+
docker compose up -d --no-deps --scale django=1 --no-recreate django
35+
elif [ $REMOTE = $BASE ]; then
36+
echo "$(date --utc +%FT%TZ): Local changes detected, you may need to stash"
37+
else
38+
echo "$(date --utc +%FT%TZ): Git is diverged, this is unexpected."
39+
fi

0 commit comments

Comments
 (0)