Skip to content

Commit 64a4fed

Browse files
authored
Add docker-compose file for local development. (#567)
1 parent 397ac26 commit 64a4fed

File tree

10 files changed

+301
-62
lines changed

10 files changed

+301
-62
lines changed

.env.template.docker

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
SECRET_KEY=<####SECRET####>
2+
DEBUG=True
3+
ALLOWED_HOSTS=0.0.0.0,127.0.0.1,localhost
4+
DJANGO_SETTINGS_MODULE=djangosnippets.settings.development
5+
SEARCHBOX_SSL_URL=http://elasticsearch:9200/
6+
SESSION_COOKIE_SECURE=False
7+
DATABASE_URL=postgres://djangosnippets:djangosnippets@db/djangosnippets
8+
POSTGRES_USER=djangosnippets
9+
POSTGRES_PASSWORD=djangosnippets
10+
POSTGRES_DB=djangosnippets
11+
REDISTOGO_URL=redis://redis:6379/0

.env.template.local

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
SECRET_KEY=<####SECRET####>
2+
DEBUG=True
3+
ALLOWED_HOSTS=0.0.0.0,127.0.0.1,localhost
4+
DJANGO_SETTINGS_MODULE=djangosnippets.settings.development
5+
SEARCHBOX_SSL_URL=http://elasticsearch:9200/
6+
SESSION_COOKIE_SECURE=False
7+
DATABASE_URL=postgres://djangosnippets:djangosnippets@db/djangosnippets
8+
REDISTOGO_URL=redis://redis:6379/0

README.rst

Lines changed: 135 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,94 +3,166 @@ djangosnippets.org
33

44
This code is used to power the snippet sharing site, `djangosnippets.org`_
55

6-
Database Setup Using Windows
7-
-----------------------------------
6+
Development Setup
7+
=================
88

9-
Download the latest version of PostgreSQL_. Click on the executable to start the installation setup wizard.
9+
Prerequisites
10+
-------------
1011

11-
Click ``Next``, keeping all the defaults as you work through the wizard. Make a note
12-
of the password you choose for the database superuser (postgres). Select the default port 5432 and the default
13-
locale. After it’s finished installing, you do not need to launch Stack Builder. Un-tick that box if you are asked,
14-
and click ``Finish``.
12+
- Python version 3.11
13+
- PostgreSQL
1514

16-
Open SQL Shell (psql). In the shell, select the default values for Server, Database, Port and Username
17-
(basically, press Enter four times).
15+
Installation
16+
------------
1817

19-
Type in the password you noted earlier and press enter. Run the command below, taking care to include the
20-
semi-colon. ::
18+
Basic Installation
19+
~~~~~~~~~~~~~~~~~~
2120

22-
$ CREATE DATABASE djangosnippets;
21+
1. Clone the repo:
2322

24-
Close SQL Shell (psql).
23+
.. code-block:: console
2524
26-
You need to copy .env.example to env.bat and configure to your needs. Use the template below, taking care to
27-
include ``set`` at the start of each line, and to substitute the password you noted earlier into DATABASE_URL.
28-
For development, DEBUG is set to True. ::
25+
https://github.com/django/djangosnippets.org.git
2926
30-
set REDISTOGO_URL=redis://redis:6379/0
31-
set SECRET_KEY=p_o3vp1rg5)t^lxm9-43%0)s-=1qpeq%o7gfq+e4#*!t+_ev82
32-
set DEBUG=True
33-
set ALLOWED_HOSTS=0.0.0.0,127.0.0.1
34-
set DATABASE_URL=postgres://postgres:your_password@:5432/djangosnippets
35-
set DJANGO_SETTINGS_MODULE=djangosnippets.settings.development
36-
set SEARCHBOX_SSL_URL=http://elasticsearch:9200/
37-
set SESSION_COOKIE_SECURE=False
27+
2. Create your virtual environment:
3828

39-
Go back to your terminal. You will need to run the command below whenever you open a new terminal. ::
29+
.. code-block:: console
4030
41-
$ env.bat
31+
python -m venv venv
4232
43-
Your environment variables are now set and you can proceed with the instructions below.
33+
Activate in Linux:
4434

45-
Development Setup
46-
-----------------
35+
.. code-block:: console
4736
48-
In a Python 3.11 virtual environment::
37+
source venv/bin/activate
4938
50-
$ cd requirements
51-
$ pip install -r development.txt
52-
$ cd ..
53-
$ python manage.py tailwind install
54-
$ python manage.py migrate
39+
Activate in Windows:
5540

56-
Now you can start the development server::
41+
.. code-block:: console
5742
58-
$ python manage.py runserver
43+
venv\Scripts\activate
5944
60-
Before you can actually use the site, you have to define at least one
61-
language. If you just want to use the ones from djangosnippets.org, they
62-
are included in the fixtures folder. Also included are five snippets to get you started::
45+
3. Connect to PostgreSQL
6346

64-
$ python manage.py createsuperuser
65-
$ python manage.py loaddata fixtures/cab.json
47+
Connect in Linux:
6648

67-
To use Tailwind, you need to start the Tailwind server::
49+
.. code-block:: console
6850
69-
$ python manage.py tailwind start
51+
psql -U $(whoami) -d postgres
7052
71-
Now you should be able to use the development version of djangosnippets
72-
on port 8000.
53+
Connect in Windows:
7354

74-
To run tests::
55+
.. code-block:: console
7556
76-
$ python manage.py test --settings=djangosnippets.settings.testing
57+
psql -U postgres
58+
59+
4. Create a PostgreSQL database and role:
60+
61+
.. code-block:: console
62+
63+
postgres=# CREATE DATABASE djangosnippets;
64+
postgres=# CREATE USER djangosnippets WITH SUPERUSER PASSWORD 'djangosnippets';
65+
postgres=# GRANT ALL PRIVILEGES ON DATABASE djangosnippets TO djangosnippets;
66+
67+
Exit psql shell:
68+
69+
.. code-block:: console
70+
71+
postgres=# exit
72+
73+
5. Install requirements:
74+
75+
.. code-block:: console
76+
77+
pip install -r requirements/development.txt
78+
79+
6. Copy `.env.template.local` file, rename to `.env` and configure variables for your local postgres database.
80+
81+
Copy in Linux:
82+
83+
.. code-block:: console
84+
85+
cp .env.template.local .env
86+
87+
Copy in Windows:
88+
89+
.. code-block:: console
90+
91+
copy .env.template.local .env
92+
93+
7. Run migrations and create superuser:
94+
95+
Migrate:
96+
97+
.. code-block:: console
98+
99+
python manage.py migrate
100+
101+
Optionally load data first:
102+
103+
.. code-block:: console
104+
105+
python manage.py loaddata fixtures/cab.json
106+
107+
Create superuser:
108+
109+
.. code-block:: console
110+
111+
python manage.py createsuperuser
112+
113+
8. Install tailwind (npm is required):
114+
115+
.. code-block:: console
116+
117+
python manage.py tailwind install
118+
119+
9. Run server locally:
120+
121+
.. code-block:: console
122+
123+
python manage.py runserver_plus
124+
125+
10. Run tailwind in another terminal locally:
126+
127+
.. code-block:: console
128+
129+
python manage.py tailwind start
130+
131+
With Docker
132+
~~~~~~~~~~~~~~~~~~~
133+
134+
Using `Docker <https://www.docker.com/products/docker-desktop/>`_ allows you to set up the development environment more quickly if Docker is installed 🐳
135+
136+
1. Build the Docker images:
137+
138+
.. code-block:: console
139+
140+
docker compose -f docker-compose.local.yml build
141+
142+
2. Start the containers:
143+
144+
.. code-block:: console
145+
146+
docker compose -f docker-compose.local.yml up -d
147+
148+
3. Go to: http://127.0.0.1:8000/ and enjoy 🙌
77149

78150
Docker
79-
------
151+
======
80152
You need to copy .env.example to .env and configure to your needs. The example is fine to start with development.
81153

82154
You may wish to use docker locally for production dependency testing and development; here are the setup instructions::
83155

84-
$ docker-compose -f docker-compose.yml build
85-
$ docker-compose -f docker-compose.yml up -d
156+
$ docker-compose -f docker-compose.production.yml build
157+
$ docker-compose -f docker-compose.production.yml up -d
86158

87159
-d denotes running docker in a detached state::
88160

89-
$ docker-compose -f docker-compose.yml run web python manage.py migrate
90-
$ docker-compose -f docker-compose.yml run web python manage.py createsuperuser
91-
$ docker-compose -f docker-compose.yml run web python manage.py loaddata fixtures/cab.json
161+
$ docker-compose -f docker-compose.production.yml run web python manage.py migrate
162+
$ docker-compose -f docker-compose.production.yml run web python manage.py createsuperuser
163+
$ docker-compose -f docker-compose.production.yml run web python manage.py loaddata fixtures/cab.json
92164
$ npm run build
93-
$ docker-compose -f docker-compose.yml run web python manage.py collectstatic
165+
$ docker-compose -f docker-compose.production.yml run web python manage.py collectstatic
94166

95167

96168
The docker setup is running as close as possible to the production setup in Heroku:
@@ -103,8 +175,14 @@ To run our tests with docker::
103175

104176
$ docker-compose -f docker-compose.yml run web python manage.py test --settings=djangosnippets.settings.testing
105177

178+
Test
179+
======
180+
To run tests::
181+
182+
$ python manage.py test --settings=djangosnippets.settings.testing
183+
106184
Styling Contributor?
107-
--------------------
185+
====================
108186

109187
DjangoSnippets uses the Foundation_ framework as the core of its visual style. To
110188
get this working on your local machine you need compass_ and bower_ to compile
@@ -126,7 +204,7 @@ configuration inside `djangosnippets/static/config.rb` is
126204

127205

128206
Production Setup
129-
----------------
207+
================
130208

131209
The production setup is currently tailored to Heroku and, therefore, mostly
132210
automatic. The difference between these two setups is configured in

compose/local/django/Dockerfile

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# define an alias for the specific python version used in this file.
2+
FROM docker.io/python:3.11-slim-bookworm AS python
3+
4+
# Python build stage
5+
FROM python AS python-build-stage
6+
7+
# Install apt packages
8+
RUN apt-get update && apt-get install --no-install-recommends -y \
9+
# dependencies for building Python packages
10+
build-essential \
11+
# psycopg dependencies
12+
libpq-dev
13+
14+
# Requirements are installed here to ensure they will be cached.
15+
COPY ./requirements .
16+
17+
# Create Python Dependency and Sub-Dependency Wheels.
18+
RUN pip wheel --wheel-dir /usr/src/app/wheels \
19+
-r development.txt
20+
21+
# Python 'run' stage
22+
FROM python AS python-run-stage
23+
24+
ENV PYTHONUNBUFFERED=1
25+
ENV PYTHONDONTWRITEBYTECODE=1
26+
27+
WORKDIR /app
28+
29+
ARG NODE_MAJOR=20
30+
31+
RUN apt-get update \
32+
&& apt-get install -y ca-certificates curl gnupg \
33+
&& mkdir -p /etc/apt/keyrings \
34+
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
35+
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
36+
&& apt-get update \
37+
&& apt-get install nodejs -y \
38+
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
39+
&& apt-get clean
40+
41+
# devcontainer dependencies and utils
42+
RUN apt-get update && apt-get install --no-install-recommends -y \
43+
sudo git bash-completion nano ssh
44+
45+
# Create devcontainer user and add it to sudoers
46+
RUN groupadd --gid 1000 dev-user \
47+
&& useradd --uid 1000 --gid dev-user --shell /bin/bash --create-home dev-user \
48+
&& echo dev-user ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/dev-user \
49+
&& chmod 0440 /etc/sudoers.d/dev-user
50+
51+
# Install required system dependencies
52+
RUN apt-get update && apt-get install --no-install-recommends -y \
53+
# psycopg dependencies
54+
libpq-dev \
55+
wait-for-it \
56+
# Translations dependencies
57+
gettext \
58+
# cleaning up unused files
59+
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
60+
&& rm -rf /var/lib/apt/lists/*
61+
62+
# All absolute dir copies ignore workdir instruction. All relative dir copies are wrt to the workdir instruction
63+
# copy python dependency wheels from python-build-stage
64+
COPY --from=python-build-stage /usr/src/app/wheels /wheels/
65+
66+
# use wheels to install python dependencies
67+
RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \
68+
&& rm -rf /wheels/
69+
70+
COPY ./compose/local/django/start /start
71+
RUN sed -i 's/\r$//g' /start
72+
RUN chmod +x /start
73+
74+
CMD ["/start"]

compose/local/django/start

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
set -o nounset
6+
7+
python manage.py migrate
8+
python manage.py tailwind install
9+
python manage.py runserver_plus 0.0.0.0:8000

djangosnippets/settings/base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import dj_database_url
44
from django.contrib import messages
55
from django.urls import reverse
6+
from dotenv import load_dotenv
7+
8+
load_dotenv()
69

710

811
def user_url(user):
@@ -178,10 +181,9 @@ def user_url(user):
178181
}
179182

180183

181-
DATABASES = {"default": dj_database_url.config(default="postgres:///djangosnippets")}
184+
DATABASES = {"default": dj_database_url.config(conn_max_age=600, conn_health_checks=True)}
182185
DATABASES["default"]["ATOMIC_REQUESTS"] = True
183186

184-
185187
REST_FRAMEWORK = {
186188
# Use Django's standard `django.contrib.auth` permissions,
187189
# or allow read-only access for unauthenticated users.

0 commit comments

Comments
 (0)