This is a container image to package a Matrix widget.
The container has the following features:
- Based on the official
nginx
image in thealpine
variant. - Prepared for Single Page Applications (including history API).
- Sane
Cache-Control
defaults. - Sane
Content-Security-Policy
defaults. - Injects a
NONCE
into theindex.html
file. - Injects
REACT_APP_*
environment variables into theindex.html
file. - Uses a non privileged user (
runAsNonRoot: true
). - Supports read-only file systems (
docker run --read-only ...
orreadOnlyRootFilesystem: true
). - Exposes the application on port
8080
. - Allows for IPv4-only deployments.
-
Add
<!--#echo var="__INJECT_SCRIPT_TAG__" encoding="none"-->
before the</head>
tag in yourindex.html
:<html> <head> <!-- ... --> + <!--#echo var="__INJECT_SCRIPT_TAG__" encoding="none"--> </head> <body> <!-- ... --> </body> </html>
-
Depending on the libraries in use it may be necessary to pass the CSP nonce to them. See the example widget's index page.
-
Create a new Dockerfile in your repository:
# Use the latest version of the base image FROM ghcr.io/nordeck/matrix-widget-toolkit/widget-server:0 ARG BUILD_DATE ARG VCS_REF ARG VERSION LABEL \ org.opencontainers.image.created=$BUILD_DATE \ org.opencontainers.image.title="<your widget name>" \ org.opencontainers.image.description="<your description>" \ org.opencontainers.image.url="https://github.com/<org>/<repo>" \ org.opencontainers.image.revision=$VCS_REF \ org.opencontainers.image.source="https://github.com/<org>/<repo>" \ org.opencontainers.image.vendor="<your company>" \ org.opencontainers.image.version=$VERSION # Add your build output to the `/usr/share/nginx/html/`. # This example assumes `build/`, but it can differ in your environment ADD build /usr/share/nginx/html/
-
Create a production build of your widget:
yarn build
. -
Build (
docker build .
).The project CI should provide variables for
BUILD_DATE
,VCS_REF
(=commit sha), andVERSION
during build time. Example: Export them as environment variables and calldocker build --build-arg BUILD_DATE --build-arg VCS_REF --build-arg VERSION .
-
Run the image 🎉.
The image uses the following caching strategy:
Uniquely Named Files:
All files that have a unique content hash in it's name (example: [name].[contenthash].js
) should be located in the static/
folder and are cached by the browser.
Mutable Files:
Files like index.html
, manifest.json
, or translation files will change on every image update and might reference uniquely named files.
They should always be refreshed.
We use a public, max-age=0, must-revalidate
configuration, so the browser will always try to revalidate if the files are still fresh on each load.
The image makes selected environment variables that are provided in the deployment of the container (for example in Kubernetes) available to the widget.
They are available in the window.__ENVIRONMENT__
variable as a base64 encoded JSON file (example: eyJSRUFDVF9BUFBfRVhBTVBMRSI6ICJteS12YWx1ZSJ9 === base64({"REACT_APP_EXAMPLE": "my-value"})
).
In addition to the environment variables, the image provides the $cspNonce
to the module that is unique per request.
It is supported by a number of different libraries (example: styled-components
) and can also be provided to Webpack.
The nonce can be read from the window.NONCE
variable.
The default Content-Security-Policy
can be replaced if needed.
Simply replace the /etc/nginx/conf.d/custom/content-security-policy.conf
file when building your container image or in the deployment.
Note that the $__STYLE_CSP_NONCE__
will be used to add the unique nonce to each request.
It is also possible to extend the existing CSP with additional values:
The values of the CSP_FONT_SRC
, CSP_STYLE_SRC
, CSP_SCRIPT_SRC
, CSP_IMG_SRC
, CSP_CONNECT_SRC
environment variables will be appended to the respecting policy.
Environment variable references can be added as string, e.g. export CSP_IMG_SRC='${REACT_APP_HOME_SERVER_URL}'
.
Note that it is not possible to remove existing entries without replacing the content-security-policy.conf
file.
By default, the container will be built with nginx
configured to accept both IPv6 and IPv4 network requests.
If you need to change this, for example to set up an IPv4-only deployment, you can replace the /etc/nginx/conf.d/custom/listen.conf
file within the container at build time or by mounting an alternative configuration file.
We provide an IPv4-only example in the files/listen.ipv4.conf
file.
The default mime.types
can also be replaced.
Provide an alternative /etc/nginx/conf.d/custom/mimetypes.conf
file when building the container or in your deployment.
As the sections above show, you can use the /etc/nginx/conf.d/custom/
folder to add any additional custom configuration that might be required for your deployment.
All nginx
configuration directives that are specified within files placed in this folder will be added to the widget server block.