Skip to content

Commit a886cf8

Browse files
Dockerizing the pythondotorg codebase: (#2130)
* Dockerizing the pythondotorg codebase: This commit will add the appropriate Dockerfile and docker-compose.yml file to begin the process of dockerizing the pythondotorg codebase. Next steps include completeing a Makefile. * remove use of wait-for.sh and entrypoint.sh which are unnecessary because a health check is already configured. * Add Makefile * Adding suggested refinements to Makefile * Resolve changes around @ewdurbin's most previous comment * Address noted changes including comment convetion and adding .state/db-initialized when needed. * Ridding redundancies * Begin docs conversion from restructured text to markdown * Begin editing documentation aroud working with Pythondotorg locally. * Continue editing documentation around working with Pythondotorg locallay * clarify steps in `make serve` * Clarify expected output of `make serve` * Clarify `make migrate` * Clarify `make migrations` * Document `make manage` Co-authored-by: Ee Durbin <[email protected]>
1 parent 8e9dedc commit a886cf8

File tree

6 files changed

+331
-149
lines changed

6 files changed

+331
-149
lines changed

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.9-bullseye
2+
ENV PYTHONUNBUFFERED=1
3+
ENV PYTHONDONTWRITEBYTECODE=1
4+
RUN mkdir /code
5+
WORKDIR /code
6+
COPY dev-requirements.txt /code/
7+
COPY base-requirements.txt /code/
8+
RUN pip install -r dev-requirements.txt
9+
COPY . /code/

Makefile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
default:
2+
@echo "Call a specific subcommand:"
3+
@echo
4+
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null\
5+
| awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}'\
6+
| sort\
7+
| egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
8+
@echo
9+
@exit 1
10+
11+
.state/docker-build-web: Dockerfile dev-requirements.txt base-requirements.txt
12+
# Build web container for this project
13+
docker-compose build --force-rm web
14+
15+
# Mark the state so we don't rebuild this needlessly.
16+
mkdir -p .state && touch .state/docker-build-web
17+
18+
.state/db-migrated:
19+
# Call migrate target
20+
make migrate
21+
22+
# Mark the state so we don't rebuild this needlessly.
23+
mkdir -p .state && touch .state/db-migrated
24+
25+
.state/db-initialized: .state/docker-build-web .state/db-migrated
26+
# Load all fixtures
27+
docker-compose run --rm web ./manage.py loaddata fixtures/*.json
28+
29+
# Mark the state so we don't rebuild this needlessly.
30+
mkdir -p .state && touch .state/db-initialized
31+
32+
serve: .state/db-initialized
33+
docker-compose up --remove-orphans
34+
35+
migrations: .state/db-initialized
36+
# Run Django makemigrations
37+
docker-compose run --rm web ./manage.py makemigrations
38+
39+
migrate: .state/docker-build-web
40+
# Run Django migrate
41+
docker-compose run --rm web ./manage.py migrate
42+
43+
manage: .state/db-initialized
44+
# Run Django manage to accept arbitrary arguments
45+
docker-compose run --rm web ./manage.py $(filter-out $@,$(MAKECMDGOALS))
46+
47+
shell: .state/db-initialized
48+
docker-compose run --rm web ./manage.py shell
49+
50+
clean:
51+
docker-compose down -v
52+
rm -f .state/docker-build-web .state/db-initialized .state/db-migrated

docker-compose.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
version: "3.9"
2+
3+
services:
4+
postgres:
5+
image: postgres:10-bullseye
6+
ports:
7+
- "5433:5432"
8+
environment:
9+
POSTGRES_USER: pythondotorg
10+
POSTGRES_PASSWORD: pythondotorg
11+
POSTGRES_DB: pythondotorg
12+
POSTGRES_HOST_AUTH_METHOD: trust # never do this in production!
13+
healthcheck:
14+
test: ["CMD", "pg_isready", "-U", "pythondotorg", "-d", "pythondotorg"]
15+
interval: 1s
16+
17+
web:
18+
build: .
19+
command: python manage.py runserver 0.0.0.0:8000
20+
volumes:
21+
- .:/code
22+
ports:
23+
- "8000:8000"
24+
environment:
25+
DATABASE_URL: postgresql://pythondotorg:pythondotorg@postgres:5432/pythondotorg
26+
DJANGO_SETTINGS_MODULE: pydotorg.settings.local
27+
depends_on:
28+
postgres:
29+
condition: service_healthy

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Contents:
2323
:maxdepth: 2
2424
:glob:
2525

26-
install
26+
install.md
2727
contributing
2828
administration
2929
pep_generation

docs/source/install.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
Installing
2+
==========
3+
4+
As a prerequisite to working on Pythondotorg, Docker, Docker Compose and `make` will need to be installed locally.
5+
6+
```{note}
7+
Docker Compose will be installed by [Docker Mac](https://docs.docker.com/desktop/install/mac-install/) and [Docker for Windows](https://docs.docker.com/desktop/install/windows-install/) automatically.
8+
9+
`make` is a build automation tool that automatically builds executebale programs and libraries from source code by reading files called Makefiles. The [`make`](https://www.gnu.org/software/make/) utility comes defaulted with most unix distributions.
10+
```
11+
12+
Getting started
13+
---------------
14+
15+
To get the Pythondotorg source code, [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the repository on [GitHub](https://github.com/python/pythondotorg) and [clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) it to your local machine:
16+
17+
```
18+
git clone [email protected]:YOUR-USERNAME/pythondotorg.git
19+
```
20+
21+
Add a [remote](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/configuring-a-remote-for-a-fork) and [sync](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) regularly to stay current with the repository.
22+
23+
```
24+
git remote add upstream https://github.com/python/pythondotorg
25+
git checkout main
26+
git fetch upstream
27+
git merge upstream/main
28+
```
29+
30+
Installing Docker
31+
-----------------
32+
33+
Install [Docker Engine](https://docs.docker.com/engine/install/)
34+
35+
```{note}
36+
The best experience for building Pythondotorg on Windows is to use the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/)(WSL) in combination with both [Docker for Windows](https://docs.docker.com/desktop/install/windows-install/) and [Docker for Linux](https://docs.docker.com/engine/install/).
37+
```
38+
39+
Verify that the Docker installation is successful by running: `docker -v`
40+
41+
Running pythondotorg locally
42+
----------------------------
43+
Once you have Docker and Docker Compose installed, run:
44+
45+
```
46+
make serve
47+
```
48+
49+
This will pull down all the required docker containers, build the environment for pythondotorg, run migrations, load development fixtures, and start all of the necessary services.
50+
51+
Once complete, you will see the following in your terminal output:
52+
53+
```
54+
web_1 | Starting development server at http://0.0.0.0:8000/
55+
web_1 | Quit the server with CONTROL-C.
56+
```
57+
58+
You can view these results in your local web browser at: `http://localhost:8000`
59+
60+
To reset your local environment, run:
61+
62+
```
63+
make clean
64+
```
65+
66+
To apply migrations, run:
67+
68+
```
69+
make migrate
70+
```
71+
72+
To generate new migrations, run:
73+
74+
```
75+
make migrations
76+
```
77+
78+
You can also run arbitrary Django management commands via:
79+
80+
```
81+
make manage <NAME_OF_COMMAND>
82+
```
83+
84+
This is a simple wrapper around running `python manage.py` in the container, all arguments passed to `make manage` will be passed through.
85+
86+
87+
88+
Manual setup
89+
------------
90+
91+
First, install [PostgreSQL](https://www.postgresql.org/download/) on your machine and run it. *pythondotorg* currently uses Postgres 10.21.
92+
93+
Then clone the repository:
94+
95+
```
96+
$ git clone git://github.com/python/pythondotorg.git
97+
```
98+
99+
Then create a virtual environment:
100+
101+
```
102+
$ python3.9 -m venv venv
103+
```
104+
105+
And then you'll need to install dependencies. You don't need to use `pip3` inside a Python 3 virtual environment:
106+
107+
```
108+
$ pip install -r dev-requirements.txt
109+
```
110+
111+
*pythondotorg* will look for a PostgreSQL database named `pythondotorg` by default. Run the following command to create a new database:
112+
113+
```
114+
$ createdb pythondotorg -E utf-8 -l en_US.UTF-8
115+
```
116+
117+
````{note}
118+
If the above command fails to create a database and you see an error message similar to:
119+
120+
```
121+
createdb: database creation failed: ERROR: permission denied to create database
122+
```
123+
124+
Use the following command to create a database with *postgres* user as the owner:
125+
126+
```
127+
$ sudo -u postgres createdb pythondotorg -E utf-8 -l en_US.UTF-8
128+
```
129+
130+
Note that this solution may not work if you've installed PostgreSQL via Homebrew.
131+
132+
If you get an error like this:
133+
134+
```
135+
createdb: database creation failed: ERROR: new collation (en_US.UTF-8) is incompatible with the collation of the template database (en_GB.UTF-8)
136+
```
137+
138+
Then you will have to change the value of the `-l` option to what your database was set up with initially.
139+
````
140+
141+
To change database configuration, you can add the following setting to `pydotorg/settings/local.py` (or you can use the `DATABASE_URL` environment variable):
142+
143+
```
144+
DATABASES = {
145+
'default': dj_database_url.parse('postgres:///your_database_name'),
146+
}
147+
```
148+
149+
If you prefer to use a simpler setup for your database you can use SQLite. Set the `DATABASE_URL` environment variable for the current terminal session:
150+
151+
```
152+
$ export DATABASE_URL="sqlite:///pythondotorg.db"
153+
```
154+
155+
```{note}
156+
If you prefer to set this variable in a more permanent way add the above line in your `.bashrc` file. Then it will be set for all terminal sessions in your system.
157+
```
158+
159+
Whichever database type you chose, now it's time to run migrations:
160+
161+
```
162+
$ ./manage.py migrate
163+
```
164+
165+
To compile and compress static media, you will need *compass* and *yui-compressor*:
166+
167+
```
168+
$ gem install bundler
169+
$ bundle install
170+
```
171+
172+
```{note}
173+
To install *yui-compressor*, use your OS's package manager or download it directly then add the executable to your `PATH`.
174+
```
175+
176+
To create initial data for the most used applications, run:
177+
178+
```
179+
$ ./manage.py create_initial_data
180+
```
181+
182+
See [create_initial_data](https://pythondotorg.readthedocs.io/commands.html#command-create-initial-data) for the command options to specify while creating initial data.
183+
184+
Finally, start the development server:
185+
186+
```
187+
$ ./manage.py runserver
188+
```
189+
190+
Optional: Install Elasticsearch
191+
-------------------------------
192+
193+
The search feature in Python.org uses Elasticsearch engine. If you want to test out this feature, you will need to install [Elasticsearch](https://www.elastic.co/downloads/elasticsearch).
194+
195+
Once you have it installed, update the URL value of `HAYSTACK_CONNECTIONS` settings in `pydotorg/settings/local.py` to your local ElasticSearch server.
196+
197+
Generating CSS files automatically
198+
----------------------------------
199+
200+
Due to performance issues of [django-pipeline](https://github.com/cyberdelia/django-pipeline/issues/313), we are using a dummy compiler `pydotorg.compilers.DummySASSCompiler` in development mode. To generate CSS files, use `sass` itself in a separate terminal window:
201+
202+
```
203+
$ cd static
204+
$ sass --compass --scss -I $(dirname $(dirname $(gem which susy))) --trace --watch sass/style.scss:sass/style.css
205+
```
206+
207+
Running tests
208+
-------------
209+
210+
To run the test suite:
211+
212+
```
213+
$ ./manage.py test
214+
```
215+
216+
To generate coverage report:
217+
218+
```
219+
$ coverage run manage.py test
220+
$ coverage report
221+
```
222+
223+
Generate an HTML report with `coverage html` if you like.
224+
225+
Useful commands
226+
---------------
227+
228+
- Create a super user (for a new DB):
229+
230+
```
231+
$ ./manage.py createsuperuser
232+
```
233+
234+
- Want to save some data from your DB before nuking it, and then load it back in?:
235+
236+
```
237+
$ ./manage.py dumpdata --format=json --indent=4 $APPNAME > fixtures/$APPNAME.json
238+
```
239+
240+

0 commit comments

Comments
 (0)