Skip to content

Commit 9caf34e

Browse files
inovizzAnanya Maiti
and
Ananya Maiti
authored
Dockerize Junction (#749)
* Initial commit for Dockerization * Fix review comments and dockerignore * Update dev.py.sample with runsslserver * Fixes for using default settings module * Remove Dockerfile.celery and use image from junction web image * Update docker-compose.test.yml to not depend on postgres db * Add static asset compilation in Docker image * Add docker-compose.prod.yml and update server port configuration in application * Add social oauth env vars --------- Co-authored-by: Sanchit Balchandani <balchandani.sanchit@gmail.com> Co-authored-by: Ananya Maiti <Ananya_Maiti@epam.com>
1 parent ca0bf41 commit 9caf34e

20 files changed

+321
-94
lines changed

.dockerignore

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# .dockerignore
2+
3+
# Ignore Python bytecode files
4+
__pycache__/
5+
*.pyc
6+
*.pyo
7+
*.pyd
8+
9+
# Ignore virtual environment directories
10+
venv/
11+
*.virtualenv/
12+
.env/
13+
14+
# Ignore Django migration files
15+
*/migrations/*.pyc
16+
*/migrations/__pycache__/
17+
18+
# Ignore logs
19+
logs/
20+
*.log
21+
22+
# Ignore configuration files
23+
*.ini
24+
25+
# Ignore user-specific files (e.g., editor settings)
26+
*.swp
27+
*.swo
28+
*.swn
29+
*.bak
30+
*.tmp
31+
*.sublime*
32+
*.vscode/
33+
34+
# Ignore local media files
35+
media/
36+
37+
# Ignore local database files (SQLite)
38+
*.sqlite3
39+
*.sqlite3-journal
40+
41+
# Ignore test coverage reports
42+
.coverage
43+
htmlcov/
44+
45+
# Ignore build artifacts and distribution files
46+
build/
47+
dist/
48+
*.egg-info/
49+
*.egg
50+
*.wheel

.env.sample

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
DEBUG=TRUE
2+
POSTGRES_USER=postgres
3+
POSTGRES_PASSWORD=junction
4+
POSTGRES_DB=junction
5+
HOST_NAME=db
6+
DB_PORT=5432
7+
BROKER_URL=redis://redis:6379/0
8+
CELERY_RESULT_BACKEND=redis://redis:6379/0
9+
SITE_NAME=junction
10+
SERVER_PORT=8888
11+
GOOGLE_ANALYTICS_ID=google_analytics_id
12+
FACEBOOK_APP_ID=fb_app_id
13+
EMAIL_HOST_USER=email_host_user
14+
EMAIL_HOST_PASSWORD=email_host_pass
15+
SECRET_KEY=secret_key
16+
GITHUB_CLIENT_ID=github_client_id
17+
GITHUB_CLIENT_SECRET=github_client_secret
18+
GOOGLE_CLIENT_ID=google_oauth_client_id
19+
GOOGLE_CLIENT_SECRET=google_oauth_client_secret
20+
TWITTER_CONSUMER_KEY=twitter_consume_key
21+
TWITTER_CONSUMER_SECRET=twitter_consume_secret
22+
TWITTER_ACCESS_TOKEN_KEY=twitter_access_token
23+
TWITTER_ACCESS_TOKEN_SECRET=twitter_access_token_secret
24+
USE_ASYNC_FOR_EMAIL=boolean

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,7 @@ qr_files/
9090
#VSCode
9191
.vscode/
9292

93-
tmp/
93+
tmp/
94+
95+
# Env
96+
.env

Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM python:3.10-slim-buster
2+
3+
WORKDIR /code
4+
5+
RUN apt-get update && \
6+
apt-get install -y --no-install-recommends \
7+
gcc \
8+
postgresql-client \
9+
build-essential \
10+
nodejs \
11+
npm \
12+
libpq-dev && \
13+
rm -rf /var/lib/apt/lists/*
14+
15+
COPY requirements.txt /code/
16+
RUN pip install --no-cache-dir -r requirements.txt
17+
18+
# Install requirements for running tests
19+
COPY ./tools/requirements-test.txt /code/
20+
RUN pip install --no-cache-dir -r requirements-test.txt
21+
22+
RUN npm install -g yarn
23+
RUN npm install -g grunt-cli
24+
25+
COPY . /code/
26+
27+
RUN chmod +x bin/install-static.sh
28+
RUN bin/install-static.sh
29+
# not getting used at this moment
30+
RUN chmod +x bin/wait-for-it.sh
31+
32+
ENV PYTHONUNBUFFERED=1

bin/install-static.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
cd junction/static
3+
yarn install
4+
grunt less
5+
cd ../..

bin/wait-for-it.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
# wait-for-it.sh: Wait for a service to be ready.
3+
4+
set -e
5+
6+
host="$1"
7+
port="$2"
8+
shift 2
9+
cmd="$@"
10+
11+
until PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$host" -U "$POSTGRES_USER" -c '\q'; do
12+
>&2 echo "Postgres is unavailable - sleeping"
13+
sleep 1
14+
done
15+
16+
>&2 echo "Postgres is up - executing command"
17+
exec $cmd

docker-compose.prod.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
version: '3.8'
2+
3+
services:
4+
db:
5+
image: postgres:15-alpine
6+
ports:
7+
- "5432:5432"
8+
volumes:
9+
- postgres_data:/var/lib/postgresql/data/
10+
env_file:
11+
- .env
12+
13+
redis:
14+
image: redis:latest
15+
ports:
16+
- "6379:6379"
17+
18+
web:
19+
image: ananyo2012/junction:1.1
20+
volumes:
21+
- .:/code
22+
ports:
23+
- "${SERVER_PORT}:${SERVER_PORT}"
24+
depends_on:
25+
- db
26+
env_file:
27+
- .env
28+
command: sh -c 'python manage.py migrate && python manage.py collectstatic --noinput --clear && gunicorn -c gunicorn.conf.py'
29+
30+
celery:
31+
image: ananyo2012/junction:1.1
32+
depends_on:
33+
- db
34+
- redis
35+
- web
36+
env_file:
37+
- .env
38+
command: sh -c 'celery -A junction worker -l info -E'
39+
40+
volumes:
41+
postgres_data:

docker-compose.test.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: '3.8'
2+
3+
services:
4+
test:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
command: sh -c pytest --cov=unit --cov=integrations --cov-report=html -v

docker-compose.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
version: '3.8'
2+
3+
services:
4+
db:
5+
image: postgres:15-alpine
6+
ports:
7+
- "5432:5432"
8+
volumes:
9+
- postgres_data:/var/lib/postgresql/data/
10+
env_file:
11+
- .env
12+
13+
redis:
14+
image: redis:latest
15+
ports:
16+
- "6379:6379"
17+
18+
web:
19+
build:
20+
context: .
21+
dockerfile: Dockerfile
22+
image: junction_local
23+
volumes:
24+
- .:/code
25+
ports:
26+
- "${SERVER_PORT}:${SERVER_PORT}"
27+
depends_on:
28+
- db
29+
env_file:
30+
- .env
31+
command: sh -c 'python manage.py migrate && python manage.py runsslserver 0.0.0.0:${SERVER_PORT}'
32+
33+
celery:
34+
image: junction_local
35+
depends_on:
36+
- db
37+
- redis
38+
- web
39+
env_file:
40+
- .env
41+
command: sh -c 'celery -A junction worker -l info -E'
42+
43+
volumes:
44+
postgres_data:

gunicorn.conf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import os
2+
port = os.environ.get("SERVER_PORT", "8888")
3+
14
wsgi_app = "wsgi"
2-
bind = "0.0.0.0:8001"
5+
bind = f"0.0.0.0:{port}"
36
workers = 2
47
loglevel = "debug"

junction/conferences/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from django.db import models
88
from six import python_2_unicode_compatible
99
from django.utils.timezone import now
10-
from django.utils.translation import ugettext as _
10+
from django.utils.translation import gettext as _
1111
from django_extensions.db.fields import AutoSlugField
1212
from simple_history.models import HistoricalRecords
1313
from slugify import slugify

junction/conferences/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22

3-
from django.conf.urls import url
3+
from django.urls import re_path
44

55
from . import views
66

7-
urlpatterns = [url(r"^$", views.get_conference, name="get-conference")]
7+
urlpatterns = [re_path(r"^$", views.get_conference, name="get-conference")]

junction/profiles/urls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from django.conf.urls import url
1+
from django.urls import re_path
22

33
from . import views
44

55
app_name = "junction.profiles"
66

77
urlpatterns = [
8-
url(r"^$", views.dashboard, name="dashboard"),
9-
url(r"^edit/$", views.profile, name="profile"),
8+
re_path(r"^$", views.dashboard, name="dashboard"),
9+
re_path(r"^edit/$", views.profile, name="profile"),
1010
]

junction/proposals/urls.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,32 @@
22
from __future__ import absolute_import, unicode_literals
33

44
from django.conf.urls import include, url
5+
from django.urls import re_path
56

67
from . import comments_views, dashboard, views, votes_views
78

89
comment_urls = [
9-
url(
10+
re_path(
1011
r"^(?P<proposal_slug>[\w-]+)/create/$",
1112
comments_views.create_proposal_comment,
1213
name="proposal-comment-create",
1314
),
14-
url(
15+
re_path(
1516
r"^(?P<proposal_slug>[\w-]+)/comments/(?P<proposal_comment_id>\d+)/up-vote/$",
1617
votes_views.proposal_comment_up_vote,
1718
name="proposal-comment-up-vote",
1819
),
19-
url(
20+
re_path(
2021
r"^(?P<proposal_slug>[\w-]+)/comments/(?P<proposal_comment_id>\d+)/down-vote/$",
2122
votes_views.proposal_comment_down_vote,
2223
name="proposal-comment-down-vote",
2324
),
24-
url(
25+
re_path(
2526
r"^(?P<proposal_slug>[\w-]+)/comments/(?P<proposal_comment_id>\d+)/mark_spam/$",
2627
comments_views.mark_comment_as_spam,
2728
name="comment_mark_spam",
2829
),
29-
url(
30+
re_path(
3031
r"^(?P<proposal_slug>[\w-]+)/comments/(?P<proposal_comment_id>\d+)/unmark_spam/$",
3132
comments_views.unmark_comment_as_spam,
3233
name="comment_unmark_spam",
@@ -35,56 +36,56 @@
3536

3637
urlpatterns = [
3738
# proposal urls
38-
url(r"^$", views.list_proposals, name="proposals-list"),
39-
url(r"^create/$", views.create_proposal, name="proposal-create"),
40-
url(r"^to_review/$", views.proposals_to_review, name="proposals-to-review"),
41-
url(
39+
re_path(r"^$", views.list_proposals, name="proposals-list"),
40+
re_path(r"^create/$", views.create_proposal, name="proposal-create"),
41+
re_path(r"^to_review/$", views.proposals_to_review, name="proposals-to-review"),
42+
re_path(
4243
r"^second_phase_voting/$",
4344
dashboard.second_phase_voting,
4445
name="second-phase-voting",
4546
),
46-
url(r"^(?P<slug>[\w-]+)/$", views.detail_proposal, name="proposal-detail"),
47-
url(
47+
re_path(r"^(?P<slug>[\w-]+)/$", views.detail_proposal, name="proposal-detail"),
48+
re_path(
4849
r"^(?P<slug>[\w-]+)~(?P<hashid>.*)/$",
4950
views.detail_proposal,
5051
name="proposal-detail",
5152
),
52-
url(r"^(?P<slug>[\w-]+)/delete/$", views.delete_proposal, name="proposal-delete"),
53-
url(r"^(?P<slug>[\w-]+)/update/$", views.update_proposal, name="proposal-update"),
54-
url(
53+
re_path(r"^(?P<slug>[\w-]+)/delete/$", views.delete_proposal, name="proposal-delete"),
54+
re_path(r"^(?P<slug>[\w-]+)/update/$", views.update_proposal, name="proposal-update"),
55+
re_path(
5556
r"^(?P<slug>[\w-]+)/upload-content/$",
5657
views.proposal_upload_content,
5758
name="proposal-upload-content",
5859
),
59-
url(
60+
re_path(
6061
r"^(?P<slug>[\w-]+)/change-proposal-review-state/$",
6162
views.review_proposal,
6263
name="proposal-review",
6364
),
6465
# comment urls
65-
url(r"^comment/", include(comment_urls)),
66+
re_path(r"^comment/", include(comment_urls)),
6667
# Voting
67-
url(
68+
re_path(
6869
r"^(?P<proposal_slug>[\w-]+)/down-vote/$",
6970
votes_views.proposal_vote_down,
7071
name="proposal-vote-down",
7172
),
72-
url(
73+
re_path(
7374
r"^(?P<proposal_slug>[\w-]+)/up-vote/$",
7475
votes_views.proposal_vote_up,
7576
name="proposal-vote-up",
7677
),
77-
url(
78+
re_path(
7879
r"^(?P<proposal_slug>[\w-]+)/remove-vote/$",
7980
votes_views.proposal_vote_remove,
8081
name="proposal-vote-remove",
8182
),
82-
url(
83+
re_path(
8384
r"^(?P<proposal_slug>[\w-]+)/vote/$",
8485
votes_views.proposal_reviewer_vote,
8586
name="proposal-reviewer-vote",
8687
),
87-
url(
88+
re_path(
8889
r"^(?P<proposal_slug>[\w-]+)/second-vote/$",
8990
votes_views.proposal_reviewer_secondary_vote,
9091
name="proposal-reviewer-secondary-vote",

0 commit comments

Comments
 (0)