Skip to content

Commit 3698532

Browse files
authored
Merge pull request #1338 from python-discord/jb3/deployment/gunicorn-from-docker
Update production deployment configuration
2 parents 3ed9fe7 + 23087e9 commit 3698532

File tree

4 files changed

+28
-49
lines changed

4 files changed

+28
-49
lines changed

Dockerfile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ RUN if [ $STATIC_BUILD = "TRUE" ] ; \
3939
then SECRET_KEY=dummy_value poetry run python manage.py distill-local build --traceback --force ; \
4040
fi
4141

42-
# Run web server through custom manager
43-
ENTRYPOINT ["poetry", "run", "python", "manage.py"]
44-
CMD ["run"]
42+
ENTRYPOINT ["poetry", "run"]
43+
CMD ["gunicorn", "--preload", "-b", "0.0.0.0:8000", \
44+
"pydis_site.wsgi:application", "-w", "2", "--statsd-host", \
45+
"graphite.default.svc.cluster.local:8125", "--statsd-prefix", "site", \
46+
"--config", "file:gunicorn.conf.py"]

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ services:
3030
build:
3131
context: .
3232
dockerfile: Dockerfile
33-
command: ["run", "--debug"]
33+
command: ["python", "manage.py", "run"]
3434
networks:
3535
default:
3636
aliases:

manage.py

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,30 @@
2828

2929
class SiteManager:
3030
"""
31-
Manages the preparation and serving of the website.
31+
Manages the preparation and serving of the website for local use.
3232
33-
Handles both development and production environments.
33+
This class is used solely for setting up the development
34+
environment. In production, gunicorn is invoked directly
35+
and migrations are handled in an init container.
3436
3537
Usage:
3638
manage.py run [option]...
3739
3840
Options:
39-
--debug Runs a development server with debug mode enabled.
4041
--silent Sets minimal console output.
4142
--verbose Sets verbose console output.
4243
"""
4344

4445
def __init__(self, args: list[str]):
45-
self.debug = "--debug" in args
4646
self.silent = "--silent" in args
4747

4848
if self.silent:
4949
self.verbosity = 0
5050
else:
5151
self.verbosity = 2 if "--verbose" in args else 1
5252

53-
if self.debug:
54-
os.environ.setdefault("DEBUG", "true")
55-
print("Starting in debug mode.")
53+
os.environ.setdefault("DEBUG", "true")
54+
print("Starting in debug mode.")
5655

5756
@staticmethod
5857
def create_superuser() -> None:
@@ -104,53 +103,31 @@ def prepare_environment(self) -> None:
104103
call_command("migrate", verbosity=self.verbosity)
105104

106105
def prepare_server(self) -> None:
107-
"""Preform runserver-specific preparation tasks."""
108-
if self.debug:
109-
# In Production, collectstatic is ran in the Docker image
110-
print("Collecting static files.")
111-
call_command(
112-
"collectstatic",
113-
interactive=False,
114-
clear=True,
115-
verbosity=self.verbosity - 1
116-
)
106+
"""Perform debug runserver-specific preparation tasks."""
107+
print("Collecting static files.")
108+
call_command(
109+
"collectstatic",
110+
interactive=False,
111+
clear=True,
112+
verbosity=self.verbosity - 1
113+
)
117114

118-
self.set_dev_site_name()
119-
self.create_superuser()
115+
self.set_dev_site_name()
116+
self.create_superuser()
120117

121-
def run_server(self) -> None:
122-
"""Prepare and run the web server."""
118+
def run_debug(self) -> None:
119+
"""Prepare and run the debug web server."""
123120
in_reloader = os.environ.get('RUN_MAIN') == 'true'
124121

125122
# Prevent preparing twice when in dev mode due to reloader
126-
if not self.debug or in_reloader:
123+
if in_reloader:
127124
self.prepare_environment()
128125
self.prepare_server()
129126

130127
print("Starting server.")
131128

132129
# Run the development server
133-
if self.debug:
134-
call_command("runserver", "0.0.0.0:8000")
135-
return
136-
137-
# Import gunicorn only if we aren't in debug mode.
138-
import gunicorn.app.wsgiapp
139-
140-
# Patch the arguments for gunicorn
141-
sys.argv = [
142-
"gunicorn",
143-
"--preload",
144-
"-b", "0.0.0.0:8000",
145-
"pydis_site.wsgi:application",
146-
"-w", "2",
147-
"--statsd-host", "graphite.default.svc.cluster.local:8125",
148-
"--statsd-prefix", "site",
149-
"--config", "file:gunicorn.conf.py"
150-
]
151-
152-
# Run gunicorn for the production server.
153-
gunicorn.app.wsgiapp.run()
130+
call_command("runserver", "0.0.0.0:8000")
154131

155132
def run_tests(self) -> None:
156133
"""Prepare and run the test suite."""
@@ -190,7 +167,7 @@ def main() -> None:
190167
if len(sys.argv) > 1 and sys.argv[1] in ("run", "test"):
191168
manager = SiteManager(sys.argv)
192169
if sys.argv[1] == "run":
193-
manager.run_server()
170+
manager.run_debug()
194171
elif sys.argv[1] == "test":
195172
manager.run_tests()
196173

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ select = ["ANN", "B", "C4", "D", "DJ", "DTZ", "E", "F", "ISC", "INT", "N", "PGH"
7373
"pydis_site/apps/api/models/bot/off_topic_channel_name.py" = ["RUF001"]
7474

7575
[tool.taskipy.tasks]
76-
start = "python manage.py run --debug"
76+
start = "python manage.py run"
7777
makemigrations = "python manage.py makemigrations"
7878
django_shell = "python manage.py shell"
7979
test = "coverage run manage.py test"

0 commit comments

Comments
 (0)