aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2021-07-30 01:13:20 +0200
committerpacien2021-07-30 01:13:20 +0200
commit927329de79257d272947e3f883ad574261ff8060 (patch)
tree350602facd2abbddcb60fe252fdcf8e8784e7e7b
parent23fd3609294f6e8a16b6351f1b27f5b6dd2dcc89 (diff)
downloaduge_l2_rdbms_python_proto-927329de79257d272947e3f883ad574261ff8060.tar.gz
docs: add container-based cloud deployment to Heroku
-rw-r--r--flake.nix15
-rw-r--r--readme.md65
2 files changed, 79 insertions, 1 deletions
diff --git a/flake.nix b/flake.nix
index b8616f8..5f63359 100644
--- a/flake.nix
+++ b/flake.nix
@@ -31,6 +31,9 @@
31 develPackagesAndScripts = [ 31 develPackagesAndScripts = [
32 postgresql_13 # PostgreSQL server with the standard admin tools. 32 postgresql_13 # PostgreSQL server with the standard admin tools.
33 python.pkgs.ipython # Interactive Python REPL for experimenting. 33 python.pkgs.ipython # Interactive Python REPL for experimenting.
34 heroku # CLI for the Heroku hosting platform.
35 skopeo # Docker container upload utility.
36 pwgen # Simple random token generator.
34 37
35 # More pleasant alternative to psql, with colours and auto-completion. 38 # More pleasant alternative to psql, with colours and auto-completion.
36 # Custom configuration to suppress irrelevant warnings and messages. 39 # Custom configuration to suppress irrelevant warnings and messages.
@@ -92,7 +95,7 @@
92 95
93 in { 96 in {
94 97
95 packages = { 98 packages = rec {
96 # Minimal production server. 99 # Minimal production server.
97 # This includes only application files tracked by git. 100 # This includes only application files tracked by git.
98 # Using `gunicorn` on top of `uvicorn` is recommended for bigger loads. 101 # Using `gunicorn` on top of `uvicorn` is recommended for bigger loads.
@@ -100,6 +103,16 @@
100 cd ${./.} 103 cd ${./.}
101 ${pythonWithDependencies}/bin/uvicorn --app-dir app app:main "$@" 104 ${pythonWithDependencies}/bin/uvicorn --app-dir app app:main "$@"
102 ''; 105 '';
106
107 # Minimal docker image.
108 # The Heroku hosting service assigns the `$PORT` dynamically.
109 docker = dockerTools.streamLayeredImage {
110 maxLayers = 2;
111 name = "app-docker";
112 config.EntryPoint = writeShellScript "run.sh" ''
113 ${server} --host 0.0.0.0 --port $PORT
114 '';
115 };
103 }; 116 };
104 117
105 devShell = mkShell rec { 118 devShell = mkShell rec {
diff --git a/readme.md b/readme.md
index 569b173..7a16b0d 100644
--- a/readme.md
+++ b/readme.md
@@ -349,6 +349,8 @@ course, asking students to deploy their application on the Internet could be a
349motivational factor. It would also facilitate evaluating and grading projects, 349motivational factor. It would also facilitate evaluating and grading projects,
350avoiding deployment and testing hassles to the teaching staff. 350avoiding deployment and testing hassles to the teaching staff.
351 351
352#### Standard daemon
353
352The Nix Flake provides a Nix package which can be used to run the web 354The Nix Flake provides a Nix package which can be used to run the web
353application in a production context as a [daemon], managed by a standard [init] 355application in a production context as a [daemon], managed by a standard [init]
354system. 356system.
@@ -356,6 +358,69 @@ system.
356[daemon]: https://en.wikipedia.org/wiki/Daemon_(computing) 358[daemon]: https://en.wikipedia.org/wiki/Daemon_(computing)
357[init]: https://en.wikipedia.org/wiki/Init 359[init]: https://en.wikipedia.org/wiki/Init
358 360
361#### Docker container
362
363A [Docker] container can also be derived from this package to be deployed on
364popular cloud hosting services.
365
366[Docker]: https://www.docker.com/resources/what-container
367
368##### Example of container deployment
369
370An example of deployment procedure using the free tier provided by the [Heroku]
371hosting service is given below. This makes use of the [skopeo] tool to upload
372the Docker container to the service.
373
374[Heroku]: https://www.heroku.com/
375[skopeo]: https://github.com/containers/skopeo
376
377```sh
378# Log in to an Heroku account.
379heroku login
380
381# Create a new project with a random name, hosted somewhere in Europe.
382heroku create --region eu
383
384# Set a local environment variable with the assigned name of the project so
385# that the next commands operate on it.
386set --export HEROKU_APP 'name of the created app'
387
388# Set a randomly-generated signed cookie secret key for our application.
389heroku config:set COOKIE_SECRET_KEY=$(pwgen --secure 128 1)
390
391# Attach a PostgreSQL database to the newly created app.
392# This sets a connection URL in "DATABASE_URL" in the server's environment,
393# containing the confidential database username and password.
394heroku addons:create heroku-postgresql:hobby-dev --version=13
395
396# Create the tables in the database.
397heroku psql < ./sql/tables.sql
398
399# Prepare a Docker container.
400# This creates a Docker archive streaming script as `./result`.
401nix build .#docker
402
403# Log in to the Heroku container registry to upload our container.
404skopeo login --username _ --password $(heroku auth:token) registry.heroku.com
405
406# Upload the Docker image to Heroku (uploading about ~200MB).
407./result \
408| gzip --fast \
409| skopeo --insecure-policy copy \
410 docker-archive:/dev/stdin \
411 docker://registry.heroku.com/$HEROKU_APP/web
412
413# Deploy and launch the uploaded container.
414heroku container:release web
415
416# If all went well, the app should now be deployed and accessible on
417# https://$HEROKU_APP.herokuapp.com
418heroku open
419
420# If not, logs can be remotely inspected for debugging.
421heroku logs --tail
422```
423
359 424
360## Copyright and licensing 425## Copyright and licensing
361 426