Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(deployment): Add Docker Image section #17794

Merged
merged 10 commits into from
Feb 24, 2021
Merged

Conversation

armand1m
Copy link
Contributor

@armand1m armand1m commented Oct 11, 2020

Add a Docker Image section into the Deployment Documentation with an example and how to build and run it.

The example is a multi-stage docker image with node modules layer caching for faster builds in development and a result image just with the node_modules and build code needed to run the application within a custom user with restricted access.

The example contains a commented piece of code on how to disable telemetry as well.

This is useful for folks that are deploying to container orchestrators like ECS, Kubernetes (GKE, EKS, AKS) or Hashicorp Nomad, as well as just running a docker container in a single node in some cloud provider.

Add a Docker Image section with an example.
@ijjk
Copy link
Member

ijjk commented Oct 11, 2020

Stats from current PR

Default Server Mode (Decrease detected ✓)
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 13.3s 13.1s -190ms
nodeModulesSize 63.4 MB 63.4 MB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary armand1m/next.js patch-1 Change
/ failed reqs 0 0
/ total time (seconds) 2.477 2.553 ⚠️ +0.08
/ avg req/sec 1009.3 979.36 ⚠️ -29.94
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.398 1.398
/error-in-render avg req/sec 1788.66 1788.42 ⚠️ -0.24
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..133b.js gzip 11.1 kB 11.1 kB
framework.HASH.js gzip 39 kB 39 kB
main-faae5f7..727a.js gzip 7.22 kB 7.22 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 58 kB 58 kB
Client Bundles (main, webpack, commons) Modern
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..dule.js gzip 6.9 kB 6.9 kB
framework.HA..dule.js gzip 39 kB 39 kB
main-d2ce890..dule.js gzip 6.28 kB 6.28 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-409b283..e3ab.js gzip 1.32 kB 1.32 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.73 kB 7.73 kB
Client Pages Modern
vercel/next.js canary armand1m/next.js patch-1 Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-92d3016..dule.js gzip 1.28 kB 1.28 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 323 B 323 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 652 B 652 B
Rendered Page Sizes
vercel/next.js canary armand1m/next.js patch-1 Change
index.html gzip 1 kB 1 kB
link.html gzip 1.01 kB 1.01 kB
withRouter.html gzip 995 B 995 B
Overall change 3.01 kB 3.01 kB

Serverless Mode
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 15.3s 15s -262ms
nodeModulesSize 63.4 MB 63.4 MB
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..133b.js gzip 11.1 kB 11.1 kB
framework.HASH.js gzip 39 kB 39 kB
main-faae5f7..727a.js gzip 7.22 kB 7.22 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 58 kB 58 kB
Client Bundles (main, webpack, commons) Modern
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..dule.js gzip 6.9 kB 6.9 kB
framework.HA..dule.js gzip 39 kB 39 kB
main-d2ce890..dule.js gzip 6.28 kB 6.28 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-409b283..e3ab.js gzip 1.32 kB 1.32 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.73 kB 7.73 kB
Client Pages Modern
vercel/next.js canary armand1m/next.js patch-1 Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-92d3016..dule.js gzip 1.28 kB 1.28 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 323 B 323 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 652 B 652 B
Serverless bundles
vercel/next.js canary armand1m/next.js patch-1 Change
_error.js 1.05 MB 1.05 MB
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.05 MB 1.05 MB
link.js 1.1 MB 1.1 MB
routerDirect.js 1.09 MB 1.09 MB
withRouter.js 1.09 MB 1.09 MB
Overall change 5.41 MB 5.41 MB
Commit: 398037c

@ijjk
Copy link
Member

ijjk commented Oct 12, 2020

Stats from current PR

Default Server Mode
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 13.2s 13.6s ⚠️ +391ms
nodeModulesSize 63.4 MB 63.4 MB
Page Load Tests Overall increase ✓
vercel/next.js canary armand1m/next.js patch-1 Change
/ failed reqs 0 0
/ total time (seconds) 2.596 2.616 ⚠️ +0.02
/ avg req/sec 963.06 955.55 ⚠️ -7.51
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.612 1.6 -0.01
/error-in-render avg req/sec 1550.95 1562.75 +11.8
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..133b.js gzip 11.1 kB 11.1 kB
framework.HASH.js gzip 39 kB 39 kB
main-2540b2f..aa10.js gzip 7.22 kB 7.22 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 58 kB 58 kB
Client Bundles (main, webpack, commons) Modern
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..dule.js gzip 6.9 kB 6.9 kB
framework.HA..dule.js gzip 39 kB 39 kB
main-0d1e0b8..dule.js gzip 6.28 kB 6.28 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-409b283..e3ab.js gzip 1.32 kB 1.32 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.73 kB 7.73 kB
Client Pages Modern
vercel/next.js canary armand1m/next.js patch-1 Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-92d3016..dule.js gzip 1.28 kB 1.28 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 323 B 323 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 652 B 652 B
Rendered Page Sizes
vercel/next.js canary armand1m/next.js patch-1 Change
index.html gzip 1 kB 1 kB
link.html gzip 1.01 kB 1.01 kB
withRouter.html gzip 996 B 996 B
Overall change 3.01 kB 3.01 kB

Serverless Mode
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 15.4s 15.2s -180ms
nodeModulesSize 63.4 MB 63.4 MB
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..133b.js gzip 11.1 kB 11.1 kB
framework.HASH.js gzip 39 kB 39 kB
main-2540b2f..aa10.js gzip 7.22 kB 7.22 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 58 kB 58 kB
Client Bundles (main, webpack, commons) Modern
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..dule.js gzip 6.9 kB 6.9 kB
framework.HA..dule.js gzip 39 kB 39 kB
main-0d1e0b8..dule.js gzip 6.28 kB 6.28 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-409b283..e3ab.js gzip 1.32 kB 1.32 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.73 kB 7.73 kB
Client Pages Modern
vercel/next.js canary armand1m/next.js patch-1 Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-92d3016..dule.js gzip 1.28 kB 1.28 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 323 B 323 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 652 B 652 B
Serverless bundles
vercel/next.js canary armand1m/next.js patch-1 Change
_error.js 1.05 MB 1.05 MB
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.05 MB 1.05 MB
link.js 1.1 MB 1.1 MB
routerDirect.js 1.09 MB 1.09 MB
withRouter.js 1.09 MB 1.09 MB
Overall change 5.41 MB 5.41 MB
Commit: 7905403

@mAAdhaTTah
Copy link
Contributor

Using Next.js w/ Docker in has been a bit of a pain, tbh. There are a couple issues in the Discussion section about it, mostly because Next.js is designed assuming all the env vars will be available during the build step, which isn't necessarily the case with Docker (presumably, you'd build it once and deploy to different envs, with different runtime env vars). Next.js + SSG/ISG features don't really play nicely with that set up (in my experience so far).

I would love to see Docker considered as more of a first-class citizen for Next.js, but I can't imagine encouraging people towards a poorly-supported use case is a great idea.

@armand1m
Copy link
Contributor Author

armand1m commented Dec 3, 2020

I think people already use Next.js on Docker nevertheless, as companies and folks really model their ways around differently.
I've been running a few Next.js applications in Kubernetes clusters and it has been working just fine. If SSG is something important for the product, the developer can always build the Dockerfile in a way that it would apply Automatic Static Optimization during startup using environment variables available in container runtime. Creates a slower startup of the container but helps with what you've mentioned.

The developer can always setup their CI system for this as well and still build static docker images as artifacts containing the static builds.

Every platform nowadays is basically running workloads in containers, Next.js will not stop being one of these anytime soon IMO

@mAAdhaTTah
Copy link
Contributor

the developer can always build the Dockerfile in a way that it would apply Automatic Static Optimization during startup using environment variables available in container runtime.

Any chance you could explain this in more depth? We're using Docker and the issues I mentioned above are problems we're having with Next.js + Docker, so if you've worked around them, I'd love to hear how you handled it.

@vercel vercel bot temporarily deployed to Preview December 3, 2020 13:57 Inactive
@armand1m
Copy link
Contributor Author

armand1m commented Dec 3, 2020

@mAAdhaTTah In the case to support proper SSG you would have to defer the build process from nextjs to the startup of the container. The way to do this is to have a customized entry point to your container.

Here is an example of how you could do that with Docker (not covering user permissions):

  • Dockerfile:
FROM node:alpine

# Adds `tini` to be the PID 1 wrapping our entrypoint
RUN apk add --no-cache libc6-compat tini

# Setup dependencies with layer cache for fast builds
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn

# Copy remaining src code to the image fs
COPY . .

# Setup environment and ports
ENV NODE_ENV production
EXPOSE 3000

# Copy entrypoint and wrap it with tini
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["tini", "--", "docker-entrypoint.sh"]
CMD ["start"]
  • docker-entrypoint.sh:

Note: make sure to chmod +x this file in your repository

#!/bin/sh
set -e

if [ "$1" = 'start' ]; then
  exec yarn build && yarn start
fi

if [ "$1" = 'build' ]; then
  exec yarn build
fi

exec "$@"

This will basically make usage of all the environment variables you pass to your container in your deployment environment to build your application and start it.

Your CI process would have to change though so you can properly build and test it, that is why there is a build command as well made available from the docker-entrypoint.sh so you can run this image from your CI to see if you can actually build this application using the environment variables available.

This entrypoint also makes it available for you to access the container through an interactive shell:

docker build . -t my-nextjs-app
docker run -it my-nextjs-app -- sh

There are a few cons on this, like the startup time being definitely slower, but if you're deploying containers you also have the ability to hide them through a Load Balancer with Healthchecks, so you should be fine.

@mAAdhaTTah
Copy link
Contributor

Ok, that makes sense conceptually, but has two other issues besides the startup time:

  1. Technically, you're not shipping the same artifacts to every environment. To some extent this doesn't matter cuz you're kinda doing this already if you're SSG'ing on every container (each container generates its own SSG'ed instance of a given page instead of sharing them), but even in that case, most of the artifact is the same (the JS is all the same), whereas this build-on-startup opens another point where containers could differ from each other.
  2. A bigger issue for us is this makes it impossible for us to upload the build assets (JS, images, fonts, all generated during the build step) to our CDN (S3 + CloudFront). Adding that to the container startup would add both a lot more time + complexity to that step that's currently handled by our CD process.

Appreciate you sharing the approach though!

@armand1m
Copy link
Contributor Author

armand1m commented Dec 3, 2020

@mAAdhaTTah You're welcome. As I've said, there are indeed a lot of cons with the build on startup approach, but they're no different than doing it in an EC2 instance for example. The 1st issue you mentioned basically states that.

Another way you can try to solve this is by just setting the needed env vars in your CI and packing the generated static versions from there in your image. This also has its own drawbacks, as your CI process will depend on other services or anything your build might depend to generate these static assets, bringing the possibility for them to be flaky.

Regarding the 2nd issue, you'd probably have to go through another kind of setup where you can actually mount the static builds in the container. If you're using Kubernetes or any container orchestrator, that can be done quite easily. You'd still have to build your CI/CD pipelines or some kind of cronjob to update these static assets anyway though.

Another way would be to docker commit a layer with the build from the CD to create a "patched" image with the build assets. This can help you change a docker image without having to rebuild it completely.

My point is mainly that these are not issues with Docker itself but architectural decisions based on project needs. Different strategies will have different implementations, but the goal of this PR is just to add the simplest one so people have a place to start with.

@mAAdhaTTah
Copy link
Contributor

My point is mainly that these are not issues with Docker itself but architectural decisions based on project needs.

I'm not suggesting it's an issue w/ Docker so much as an issue Next.js, which is being designed for an environment where env vars are available during build, which conflicts w/ "standard" build-once, run-everywhere Docker philosophy. All of those are feasible workarounds but feel like hacks due to a fundamental difference in design philosophy (so maybe not an "issue" with Next.js so much as a conflict).

@vercel vercel bot temporarily deployed to Preview December 4, 2020 14:15 Inactive
@armand1m
Copy link
Contributor Author

armand1m commented Dec 4, 2020

These workarounds may feel like a hack but they're actually a feature. They're not that different from what the postgres image does for example.

#!/bin/bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

Note: it is a bit more complex than this example, but it pictures enough.

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#entrypoint

@ijjk
Copy link
Member

ijjk commented Dec 4, 2020

Stats from current PR

Default Server Mode (Decrease detected ✓)
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 10.1s 9.8s -360ms
nodeModulesSize 82.4 MB 82.4 MB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary armand1m/next.js patch-1 Change
/ failed reqs 0 0
/ total time (seconds) 2.43 2.406 -0.02
/ avg req/sec 1028.73 1038.88 +10.15
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.246 1.257 ⚠️ +0.01
/error-in-render avg req/sec 2005.89 1989.38 ⚠️ -16.51
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..34b9.js gzip 12.8 kB 12.8 kB
framework.HASH.js gzip 39 kB 39 kB
main-3c9ff84..1d7c.js gzip 6.56 kB 6.56 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 59 kB 59 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-7231d4b..5856.js gzip 1.28 kB 1.28 kB
_error-01375..90b6.js gzip 3.69 kB 3.69 kB
hooks-d4591d..e7c2.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-db223d9..dbd7.js gzip 1.61 kB 1.61 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 8.27 kB 8.27 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 322 B 322 B
Overall change 322 B 322 B
Rendered Page Sizes
vercel/next.js canary armand1m/next.js patch-1 Change
index.html gzip 615 B 615 B
link.html gzip 621 B 621 B
withRouter.html gzip 608 B 608 B
Overall change 1.84 kB 1.84 kB

Serverless Mode
General
vercel/next.js canary armand1m/next.js patch-1 Change
buildDuration 11.8s 11.7s -91ms
nodeModulesSize 82.4 MB 82.4 MB
Client Bundles (main, webpack, commons)
vercel/next.js canary armand1m/next.js patch-1 Change
677f882d2ed8..34b9.js gzip 12.8 kB 12.8 kB
framework.HASH.js gzip 39 kB 39 kB
main-3c9ff84..1d7c.js gzip 6.56 kB 6.56 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 59 kB 59 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary armand1m/next.js patch-1 Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary armand1m/next.js patch-1 Change
_app-7231d4b..5856.js gzip 1.28 kB 1.28 kB
_error-01375..90b6.js gzip 3.69 kB 3.69 kB
hooks-d4591d..e7c2.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-db223d9..dbd7.js gzip 1.61 kB 1.61 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 8.27 kB 8.27 kB
Client Build Manifests
vercel/next.js canary armand1m/next.js patch-1 Change
_buildManifest.js gzip 322 B 322 B
Overall change 322 B 322 B
Serverless bundles
vercel/next.js canary armand1m/next.js patch-1 Change
_error.js 1 MB 1 MB
404.html 2.67 kB 2.67 kB
hooks.html 1.92 kB 1.92 kB
index.js 1 MB 1 MB
link.js 1.06 MB 1.06 MB
routerDirect.js 1.05 MB 1.05 MB
withRouter.js 1.05 MB 1.05 MB
Overall change 5.16 MB 5.16 MB
Commit: b2e8338

docs/deployment.md Outdated Show resolved Hide resolved
@yordis
Copy link
Contributor

yordis commented Feb 8, 2021

I would suggest taking some inspiration from #16995 (comment) related to multi-stage since it will be a common use case out there in the wild.

This was referenced Mar 8, 2021
@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants