@@ -28,14 +28,20 @@ and a WebSocket server on ``ws://localhost:8001/`` with:
28
28
Now you want to deploy these servers on the Internet. There's a vast range of
29
29
hosting providers to choose from. For the sake of simplicity, we'll rely on:
30
30
31
- * GitHub Pages for the HTTP server;
32
- * Heroku for the WebSocket server.
31
+ * `GitHub Pages `_ for the HTTP server;
32
+ * Koyeb _ for the WebSocket server.
33
+
34
+ .. _GitHub Pages : https://pages.github.com/
35
+ .. _Koyeb : https://www.koyeb.com/
36
+
37
+ Koyeb is a modern Platform as a Service provider whose free tier allows you to
38
+ run a web application, including a WebSocket server.
33
39
34
40
Commit project to git
35
41
---------------------
36
42
37
43
Perhaps you committed your work to git while you were progressing through the
38
- tutorial. If you didn't, now is a good time, because GitHub and Heroku offer
44
+ tutorial. If you didn't, now is a good time, because GitHub and Koyeb offer
39
45
git-based deployment workflows.
40
46
41
47
Initialize a git repository:
@@ -45,15 +51,15 @@ Initialize a git repository:
45
51
$ git init -b main
46
52
Initialized empty Git repository in websockets-tutorial/.git/
47
53
$ git commit --allow-empty -m "Initial commit."
48
- [main (root-commit) ... ] Initial commit.
54
+ [main (root-commit) 8195c1d ] Initial commit.
49
55
50
56
Add all files and commit:
51
57
52
58
.. code-block :: console
53
59
54
60
$ git add .
55
61
$ git commit -m "Initial implementation of Connect Four game."
56
- [main ... ] Initial implementation of Connect Four game.
62
+ [main 7f0b2c4 ] Initial implementation of Connect Four game.
57
63
6 files changed, 500 insertions(+)
58
64
create mode 100644 app.py
59
65
create mode 100644 connect4.css
@@ -62,32 +68,58 @@ Add all files and commit:
62
68
create mode 100644 index.html
63
69
create mode 100644 main.js
64
70
65
- Prepare the WebSocket server
66
- ----------------------------
71
+ Sign up or log in to GitHub.
67
72
68
- Before you deploy the server, you must adapt it to meet requirements of
69
- Heroku's runtime. This involves two small changes:
73
+ Create a new repository. Set the repository name to `` websockets-tutorial ``,
74
+ the visibility to Public, and click ** Create repository **.
70
75
71
- 1. Heroku expects the server to ` listen on a specific port `_, provided in the
72
- `` $PORT `` environment variable.
76
+ Push your code to this repository. You must replace `` python-websockets `` by
77
+ your GitHub username in the following command:
73
78
74
- 2. Heroku sends a ``SIGTERM `` signal when `shutting down a dyno `_, which
75
- should trigger a clean exit.
79
+ .. code-block :: console
76
80
77
- .. _listen on a specific port : https://devcenter.heroku.com/articles/preparing-a-codebase-for-heroku-deployment#4-listen-on-the-correct-port
81
+ $ git remote add origin git@github.com:python-websockets/websockets-tutorial.git
82
+ $ git branch -M main
83
+ $ git push -u origin main
84
+ ...
85
+ To github.com:python-websockets/websockets-tutorial.git
86
+ * [new branch] main -> main
87
+ Branch 'main' set up to track remote branch 'main' from 'origin'.
88
+
89
+ Adapt the WebSocket server
90
+ --------------------------
78
91
79
- .. _shutting down a dyno : https://devcenter.heroku.com/articles/dynos#shutdown
92
+ Before you deploy the server, you must adapt it for Koyeb's environment. This
93
+ involves three small changes:
94
+
95
+ 1. Koyeb provides the port on which the server should listen in the ``$PORT ``
96
+ environment variable.
97
+
98
+ 2. Koyeb requires a health check to verify that the server is running. We'll add
99
+ a HTTP health check.
100
+
101
+ 3. Koyeb sends a ``SIGTERM `` signal when terminating the server. We'll catch it
102
+ and trigger a clean exit.
80
103
81
104
Adapt the ``main() `` coroutine accordingly:
82
105
83
106
.. code-block :: python
84
107
108
+ import http
85
109
import os
86
110
import signal
87
111
112
+ .. literalinclude :: ../../example/tutorial/step3/app.py
113
+ :pyobject: health_check
114
+
88
115
.. literalinclude :: ../../example/tutorial/step3/app.py
89
116
:pyobject: main
90
117
118
+ The ``process_request `` parameter of :func: `~asyncio.server.serve ` is a callback
119
+ that runs for each request. When it returns an HTTP response, websockets sends
120
+ that response instead of opening a WebSocket connection. Here, requests to
121
+ ``/healthz `` return an HTTP 200 status code.
122
+
91
123
To catch the ``SIGTERM `` signal, ``main() `` creates a :class: `~asyncio.Future `
92
124
called ``stop `` and registers a signal handler that sets the result of this
93
125
future. The value of the future doesn't matter; it's only for waiting for
@@ -97,8 +129,6 @@ Then, by using :func:`~asyncio.server.serve` as a context manager and exiting
97
129
the context when ``stop `` has a result, ``main() `` ensures that the server
98
130
closes connections cleanly and exits on ``SIGTERM ``.
99
131
100
- The app is now fully compatible with Heroku.
101
-
102
132
Deploy the WebSocket server
103
133
---------------------------
104
134
@@ -108,79 +138,65 @@ when building the image:
108
138
.. literalinclude :: ../../example/tutorial/step3/requirements.txt
109
139
:language: text
110
140
111
- .. admonition :: Heroku treats ``requirements.txt`` as a signal to `detect a Python app`_ .
141
+ .. admonition :: Koyeb treats ``requirements.txt`` as a signal to `detect a Python app`__ .
112
142
:class: tip
113
143
114
144
That's why you don't need to declare that you need a Python runtime.
115
145
116
- .. _ detect a Python app : https://devcenter.heroku .com/articles/python-support#recognizing-a-python-app
146
+ __ https://www.koyeb .com/docs/build-and-deploy/build-from-git/python#detection
117
147
118
148
Create a ``Procfile `` file with this content to configure the command for
119
149
running the server:
120
150
121
151
.. literalinclude :: ../../example/tutorial/step3/Procfile
122
152
:language: text
123
153
124
- Commit your changes:
154
+ Commit and push your changes:
125
155
126
156
.. code-block :: console
127
157
128
158
$ git add .
129
- $ git commit -m "Deploy to Heroku ."
130
- [main ... ] Deploy to Heroku .
131
- 3 files changed, 12 insertions(+), 2 deletions(-)
159
+ $ git commit -m "Deploy to Koyeb ."
160
+ [main ac96d65 ] Deploy to Koyeb .
161
+ 3 files changed, 18 insertions(+), 2 deletions(-)
132
162
create mode 100644 Procfile
133
163
create mode 100644 requirements.txt
164
+ $ git push
165
+ ...
166
+ To github.com:python-websockets/websockets-tutorial.git
167
+ + 6bd6032...ac96d65 main -> main
134
168
135
- Follow the `set-up instructions `_ to install the Heroku CLI and to log in, if
136
- you haven't done that yet.
137
-
138
- .. _set-up instructions : https://devcenter.heroku.com/articles/getting-started-with-python#set-up
139
-
140
- Create a Heroku app. You must choose a unique name and replace
141
- ``websockets-tutorial `` by this name in the following command:
169
+ Sign up or log in to Koyeb.
142
170
143
- .. code-block :: console
144
-
145
- $ heroku create websockets-tutorial
146
- Creating ⬢ websockets-tutorial... done
147
- https://websockets-tutorial.herokuapp.com/ | https://git.heroku.com/websockets-tutorial.git
148
-
149
- If you reuse a name that someone else already uses, you will receive this
150
- error; if this happens, try another name:
171
+ In the Koyeb control panel, create a web service with GitHub as the deployment
172
+ method. `Install and authorize Koyeb's GitHub app `__ if you haven't done that yet.
151
173
152
- .. code-block :: console
153
-
154
- $ heroku create websockets-tutorial
155
- Creating ⬢ websockets-tutorial... !
156
- ▸ Name websockets-tutorial is already taken
174
+ __ https://www.koyeb.com/docs/build-and-deploy/deploy-with-git#connect-your-github-account-to-koyeb
157
175
158
- Deploy by pushing the code to Heroku :
176
+ Follow the steps to create a new service :
159
177
160
- .. code-block :: console
178
+ 1. Select the ``websockets-tutorial `` repository in the list of your repositories.
179
+ 2. Confirm that the **Free ** instance type is selected. Click **Next **.
180
+ 3. Configure health checks: change the protocol from TCP to HTTP and set the
181
+ path to ``/healthz ``. Review other settings; defaults should be correct.
182
+ Click **Deploy **.
161
183
162
- $ git push heroku
163
-
164
- ... lots of output...
165
-
166
- remote: Released v1
167
- remote: https://websockets-tutorial.herokuapp.com/ deployed to Heroku
168
- remote:
169
- remote: Verifying deploy... done.
170
- To https://git.heroku.com/websockets-tutorial.git
171
- * [new branch] main -> main
184
+ Koyeb builds the app, deploys it, verifies that the health checks passes, and
185
+ makes the deployment active.
172
186
173
187
You can test the WebSocket server with the interactive client exactly like you
174
- did in the first part of the tutorial. Replace ``websockets-tutorial `` by the
175
- name of your app in the following command:
188
+ did in the first part of the tutorial. The Koyeb control panel provides the URL
189
+ of your app in the format: ``https://<app>-<user>-<id>.koyeb.app/ ``. Replace
190
+ ``https `` with ``wss `` in the URL and connect the interactive client:
176
191
177
192
.. code-block :: console
178
193
179
- $ python -m websockets wss://websockets-tutorial.herokuapp.com /
180
- Connected to wss://websockets-tutorial.herokuapp.com /.
194
+ $ python -m websockets wss://<app>-<user>-<id>.koyeb.app /
195
+ Connected to wss://<app>-<user>-<id>.koyeb.app /.
181
196
> {"type": "init"}
182
197
< {"type": "init", "join": "54ICxFae_Ip7TJE2", "watch": "634w44TblL5Dbd9a"}
183
- Connection closed: 1000 (OK).
198
+
199
+ Press Ctrl-D to terminate the connection.
184
200
185
201
It works!
186
202
@@ -199,7 +215,7 @@ You can take this strategy one step further by checking the address of the
199
215
HTTP server and determining the address of the WebSocket server accordingly.
200
216
201
217
Add this function to ``main.js ``; replace ``python-websockets `` by your GitHub
202
- username and ``websockets-tutorial `` by the name of your app on Heroku :
218
+ username and ``websockets-tutorial `` by the name of your app on Koyeb :
203
219
204
220
.. literalinclude :: ../../example/tutorial/step3/main.js
205
221
:language: js
@@ -218,42 +234,27 @@ Commit your changes:
218
234
219
235
$ git add .
220
236
$ git commit -m "Configure WebSocket server address."
221
- [main ... ] Configure WebSocket server address.
237
+ [main 0903526 ] Configure WebSocket server address.
222
238
1 file changed, 11 insertions(+), 1 deletion(-)
239
+ $ git push
240
+ ...
241
+ To github.com:python-websockets/websockets-tutorial.git
242
+ + ac96d65...0903526 main -> main
223
243
224
244
Deploy the web application
225
245
--------------------------
226
246
227
- Go to GitHub and create a new repository called ``websockets-tutorial ``.
228
-
229
- Push your code to this repository. You must replace ``python-websockets `` by
230
- your GitHub username in the following command:
231
-
232
- .. code-block :: console
233
-
234
- $ git remote add origin git@github.com:python-websockets/websockets-tutorial.git
235
- $ git push -u origin main
236
- Enumerating objects: 11, done.
237
- Counting objects: 100% (11/11), done.
238
- Delta compression using up to 8 threads
239
- Compressing objects: 100% (10/10), done.
240
- Writing objects: 100% (11/11), 5.90 KiB | 2.95 MiB/s, done.
241
- Total 11 (delta 0), reused 0 (delta 0), pack-reused 0
242
- To github.com:<username>/websockets-tutorial.git
243
- * [new branch] main -> main
244
- Branch 'main' set up to track remote branch 'main' from 'origin'.
245
-
246
247
Go back to GitHub, open the Settings tab of the repository and select Pages in
247
248
the menu. Select the main branch as source and click Save. GitHub tells you
248
249
that your site is published.
249
250
250
- Follow the link and start a game!
251
+ Open https://<your-username>.github.io/websockets-tutorial/ and start a game!
251
252
252
253
Summary
253
254
-------
254
255
255
256
In this third part of the tutorial, you learned how to deploy a WebSocket
256
- application with Heroku .
257
+ application with Koyeb .
257
258
258
259
You can start a Connect Four game, send the JOIN link to a friend, and play
259
260
over the Internet!
0 commit comments