You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: blog/2024-10-8-self-hosting-reflex-with-docker.md
+8-4Lines changed: 8 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,6 +30,10 @@ meta: [
30
30
]
31
31
---
32
32
33
+
```python exec
34
+
from pcweb.flexdown import markdown_with_shiki
35
+
```
36
+
33
37
Reflex offers a powerful way to build reactive web apps in pure Python, complete with one-line deployment for easy hosting. For those who want to self host on their own infra we'll explore how to leverage Docker to containerize and deploy your app, taking your Reflex app from development to production.
34
38
35
39
@@ -100,7 +104,7 @@ import reflex as rx
100
104
rx.accordion.root(
101
105
rx.accordion.item(
102
106
header=rx.text("Explanation of the compose.yml file", color=rx.color("slate", 12), weight="regular"),
103
-
content=rx.markdown("""Here we define three services: `backend`, `frontend`, and `redis`. The `backend` service will run the Reflex app, the `frontend` service will run the web server, and the `redis` service will run the Redis server. The `depends_on` key specifies the order in which the services will be started.
107
+
content=markdown_with_shiki("""Here we define three services: `backend`, `frontend`, and `redis`. The `backend` service will run the Reflex app, the `frontend` service will run the web server, and the `redis` service will run the Redis server. The `depends_on` key specifies the order in which the services will be started.
104
108
105
109
The first to be run is the `redis` service. We use Redis for the state manager and it is good to put in its own container, so that its easy to differenatiate the resource usage from a cache and the actual web server. It pulls the docker image for redis and runs the image as a container. If we wanted a specific tag then we can specify it in the image key, i.e. `image: redis:7.4.0`.
header=rx.text("Explanation of the Dockerfile file", color=rx.color("slate", 12), weight="regular"),
141
-
content=rx.markdown("""We start from the python image of 3.12.
145
+
content=markdown_with_shiki("""We start from the python image of 3.12.
142
146
143
147
Docker compose makes all the services accessible to each via their service name. Therefore `redis://` is the protocol, `redis` is the url and is easily accessible to all other services and therefore we access the redis container. If you are using a self hosted redis then you would put the actual url here instead of redis i.e. `REDIS_URL=redis://sjc04rdsdb01.your.cloud.provider.com`. `PYTHONUNBUFFERED=1` ensures that stdout and stderr go to the terminal.
header=rx.text("Explanation of the web.Dockerfile file", color=rx.color("slate", 12), weight="regular"),
178
-
content=rx.markdown("""We import `python:3.12` and build on top of it and the name of this build step is `builder` which we can then reference later as needed. The `WORKDIR`, `COPY`, `RUN pip install` commands are the same as in the `Dockerfile`. The `reflex export --frontend-only --no-zip` command exports the frontend assets to the `.web/_static` directory. The `builder` step encompasses all lines until we reach the next `FROM` statement. After this the `builder` step is complete and ready to be used in later steps.
182
+
content=markdown_with_shiki("""We import `python:3.12` and build on top of it and the name of this build step is `builder` which we can then reference later as needed. The `WORKDIR`, `COPY`, `RUN pip install` commands are the same as in the `Dockerfile`. The `reflex export --frontend-only --no-zip` command exports the frontend assets to the `.web/_static` directory. The `builder` step encompasses all lines until we reach the next `FROM` statement. After this the `builder` step is complete and ready to be used in later steps.
179
183
180
184
`nginx` is an image that we import and there is no need for an entrypoint as we plan to utilize the existing one that comes with the image.
181
185
@@ -234,7 +238,7 @@ server {
234
238
rx.accordion.root(
235
239
rx.accordion.item(
236
240
header=rx.heading("Explanation of the nginx.conf file", color=rx.color("slate", 12), weight="regular", size='5'),
237
-
content=rx.markdown("""The `listen 80;` and `listen [::]:80;` lines specify that the server should listen on port 80 ([::] is for ipv6).
241
+
content=markdown_with_shiki("""The `listen 80;` and `listen [::]:80;` lines specify that the server should listen on port 80 ([::] is for ipv6).
238
242
239
243
The `location /_event` block is used to proxy websocket connections to the backend server. The `proxy_pass http://backend:8000;` line specifies that the requests should be forwarded to the `backend` service on port 8000. Anything that hits the frontend on the 3 pages (`/_event`, `/ping`, `/_upload`) are passed on to the backend and then the backend will respond and the front end will pass that straight back to the user.
Copy file name to clipboardExpand all lines: docs/custom-components/command-reference.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ The `init` command uses the current enclosing folder name to construct a python
61
61
The `init` command creates a set of files and folders prefilled with the package name and other details. During the init, the `custom_component` folder is installed locally in editable mode, so a developer can incrementally develop and test with ease. The changes in component implementation is automatically reflected where it is used. Below is the folder structure after the `init` command.
Copy file name to clipboardExpand all lines: docs/getting_started/introduction.md
+9-8Lines changed: 9 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,10 +4,11 @@ from pcweb import constants, styles
4
4
from pcweb.pages.docs import getting_started
5
5
from pcweb.pages.docs import wrapping_react
6
6
from pcweb.pages.docs.library import library
7
-
from pcweb.pages.docs importpages
7
+
from pcweb.pages.docs import pages
8
8
from pcweb.pages.docs importvars
9
9
from pcweb.styles.colors import c_color
10
10
from pcweb.styles.fonts import base
11
+
from pcweb.flexdown import markdown_with_shiki
11
12
```
12
13
13
14
<!-- TODO how do we consistently rename page title? -->
@@ -79,7 +80,7 @@ def tabs():
79
80
),
80
81
),
81
82
rx.tabs.content(
82
-
rx.markdown(
83
+
markdown_with_shiki(
83
84
"""The frontend is built declaratively using Reflex components. Components are compiled down to JS and served to the users browser, therefore:
84
85
85
86
- Only use Reflex components, vars, and var operations when building your UI. Any other logic should be put in your `State` (backend).
@@ -91,15 +92,15 @@ def tabs():
91
92
class_name="pt-4"
92
93
),
93
94
rx.tabs.content(
94
-
rx.markdown(
95
+
markdown_with_shiki(
95
96
"""Write your backend in the `State` class. Here you can define functions and variables that can be referenced in the frontend. This code runs directly on the server and is not compiled, so there are no special caveats. Here you can use any Python external library and call any method/function.
96
97
""",
97
98
),
98
99
value="tab2",
99
100
class_name="pt-4"
100
101
),
101
102
rx.tabs.content(
102
-
rx.markdown(
103
+
markdown_with_shiki(
103
104
f"""Each page is a Python function that returns a Reflex component. You can define multiple pages and navigate between them, see the [Routing]({pages.routes.path}) section for more information.
104
105
105
106
- Start with a single page and scale to 100s of pages.
0 commit comments