{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Edge & Performance Optimization with Layer0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Layer0 extends the capabilities of a traditional CDN by not only hosting your static content, but also providing server-side rendering for progressive web applications. Layer0 allows caching both your APIs and HTML at the network edge to provide your users with the fastest browsing experience. Teams can ship faster leveraging an enhanced developer experience to deploy code faster and with more frequency, view their code quickly in atomically deployed environments, and integrating their CDN configuration to the overall build process. Layer0 provides the tools needed to build the modern apps capable of providing the performance expected by modern consumers. \n", "\n", "Among the benefits offered by Layer0, a few offered are: \n", "\n", "- Prefetching and Deep-fetching\n", "- Prerendering\n", "- Service worker caching\n", "- Split testing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![images/AWS_RDS.jpg](images/AWS_RDS.jpg)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this workshop you will build and deploy retail demo store web-UI on layer0 infrastructure with above benefits. You will first need to have retail demo store running in your AWS account for backend APIs. You will deploy web-ui/frontend app in layer0 and access the APIs / services in your AWS account.\n", "You will also review pre-created caching configuration code [here](https://github.com/aws-samples/retail-demo-store/tree/master/src/web-ui/layer0) and see it working in your browser." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create Layer0 Account\n", "\n", "To work with AWS Retail Demo Store you need to [sign up](https://app.layer0.co/signup) on Layer0. Pick a site name for deployment, for example retail-demo-yourID. Note down your deployment token to add in `.env` file.\n", "\n", "Accounts on Layer0 are free and come with a generous community tier for testing and getting your project off the ground. \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Prerequisites\n", "\n", "Make sure you have Retail Demo Store (RDS) deployed in your AWS account before proceeding. These instructions will allow you to run a Layer0 enabled version of the `web-ui` on local OR on Layer0 AWS infrastructure for the RDS front-end, connecting to the APIs deployed in your account.\n", "\n", "Layer0 application works with the Vue application production build files.\n", "\n", "To create it, follow the next steps.\n", "\n", "0. Clone the AWS Retail Demo Store repository to either your local computer or Cloud9\n", "1. Make sure your terminal is open in `%project_root%/src/web-ui folder`. You can use your local computer or Cloud9.\n", "2. Set NodeJS version to 14. To check your version use `node -v`. If using [nvm](https://github.com/nvm-sh/nvm) to manage node installation versions, set to 14.x using `nvm use `. `nvm ls` will show you your locally available node versions and if needed install a 14.x version to use. Layer0 is using AWS Lambda to run frontend and at this time Lambda doesn't support higher version of node. \n", "3. Install packages: run `npm install` (or just `npm i`)\n", "4. Run `./gen_env.sh` to generate the `.env` file.\n", "5. Set `VITE_LAYER0_ENABLED` environment variable to `true` in `.env` file.\n", "6. Update your `.env` file for either local or layer0 prod deployment variables.\n", "7. Use `source .env` to make sure `.env` variables are available in the terminal environment you are working in.\n", "8. Build Vue application: `npm run build` (build files will appear in `dist` folder).\n", "\n", "## Development\n", "\n", "For local development, API endpoints set via your `.env` file should be pointed to the `localhost` Docker container instances. \n", "\n", "Local development is optional, you can skip this step and go directly to build the project with production values in your `.env` file.\n", "\n", "An example is as follows:\n", "\n", "```\n", "VITE_PRODUCTS_SERVICE_DOMAIN=http://localhost\n", "VITE_PRODUCTS_SERVICE_PORT=8001\n", "VITE_USERS_SERVICE_DOMAIN=http://localhost\n", "VITE_USERS_SERVICE_PORT=8002\n", "VITE_CARTS_SERVICE_DOMAIN=http://localhost\n", "VITE_CARTS_SERVICE_PORT=8003\n", "VITE_ORDERS_SERVICE_DOMAIN=http://localhost\n", "VITE_ORDERS_SERVICE_PORT=8004\n", "VITE_RECOMMENDATIONS_SERVICE_DOMAIN=http://localhost\n", "VITE_RECOMMENDATIONS_SERVICE_PORT=8005\n", "VITE_SEARCH_SERVICE_DOMAIN=http://localhost\n", "VITE_SEARCH_SERVICE_PORT=8006\n", "VITE_VIDEOS_SERVICE_DOMAIN=http://localhost\n", "VITE_VIDEOS_SERVICE_PORT=8007\n", "VITE_LOCATION_SERVICE_DOMAIN=http://localhost\n", "VITE_LOCATION_SERVICE_PORT=8009\n", "AWS_IMAGE_SERVICE_DOMAIN=d28z1nhxyoq0l5.cloudfront.net # change to your deployed RDS\n", "```\n", "\n", "Once your `.env` file is configured, and your terminal environment is loaded with those variables, run Layer0 locally using one of the following modes:\n", "\n", "1. `npm run layer0:start` - default run\n", "2. `npm run layer0:start:cache` - run with cache\n", "3. `npm run layer0:start:prod` - serve production files (requires Layer0 build before, see next section)\n", "\n", "## Build\n", "\n", "Make sure all the steps of [Prerequisites](#Prerequisites) section are done before building Layer0 files!\n", "\n", "Update your `.env` file to point to the deployed RDS instance urls. \n", "\n", "To build Layer0 production files run `npm run layer0:build` (Layer0 build files will appear in `.layer0` & `dist-layer0` folders, main app build files appear in `dist`).\n", "\n", "You will need to set up your deployed RDS instance with a few tweaks:\n", "\n", "- Configure the local `.env` file with urls and paths set to the deployed RDS instance.\n", "\n", "These point to the example Layer0 RDS deployment. Change these values to your own RDS links.\n", "VITE_PRODUCTS_SERVICE_DOMAIN is the domain you created in Layer0.\n", "\n", "For AWS_XYZ_SERVICE_DOMAIN, Individual Severice ELB / Domains are in output of RDS Clouldformation. See example of Cart Service below.\n", "\n", "![images/RetailDemoStore-CFN-output-serviceDomain.png](images/RetailDemoStore-CFN-output-serviceDomain.png)\n", "\n", "\n", "```\n", "VITE_PRODUCTS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_PRODUCTS_SERVICE_DOMAIN=retai-loadb-1riqp3qcaf983-1507012174.us-east-1.elb.amazonaws.com\n", "VITE_PRODUCTS_SERVICE_PATH=/products-service\n", "\n", "VITE_USERS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_USERS_SERVICE_DOMAIN=retai-loadb-eyuieam5ifpn-1823664657.us-east-1.elb.amazonaws.com\n", "VITE_USERS_SERVICE_PATH=/users-service\n", "\n", "VITE_CARTS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_CARTS_SERVICE_DOMAIN=retai-loadb-10bjeuwdanbi-1224031705.us-east-1.elb.amazonaws.com\n", "VITE_CARTS_SERVICE_PATH=/\n", "\n", "VITE_ORDERS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_ORDERS_SERVICE_DOMAIN=retai-LoadB-1U6KE7LXOQ5VU-1311015454.us-east-1.elb.amazonaws.com\n", "VITE_ORDERS_SERVICE_PATH=/orders-service\n", "\n", "VITE_RECOMMENDATIONS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_RECOMMENDATIONS_SERVICE_DOMAIN=retai-LoadB-1USGZMQVWHN1T-2000232934.us-east-1.elb.amazonaws.com\n", "VITE_RECOMMENDATIONS_SERVICE_PATH=/recommendations-service\n", "\n", "VITE_VIDEOS_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_VIDEOS_SERVICE_DOMAIN=retai-LoadB-F2U2MQ3CXPD8-471493329.us-east-1.elb.amazonaws.com\n", "VITE_VIDEOS_SERVICE_SERVICE_PATH=/videos-service\n", "\n", "VITE_SEARCH_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_SEARCH_SERVICE_DOMAIN=retai-LoadB-18LUF1ATZNQNH-1395658750.us-east-1.elb.amazonaws.com\n", "VITE_SEARCH_SERVICE_PATH=/search-service\n", "\n", "VITE_LOCATION_SERVICE_DOMAIN=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link\n", "AWS_LOCATION_SERVICE_DOMAIN=retai-loadb-do2tp4pr6ejv-357775208.us-east-1.elb.amazonaws.com\n", "VITE_LOCATION_SERVICE_PATH=/location-service\n", "\n", "# Change to your Layer0 domain URL. You will see this in Layer0 admin UI\n", "VITE_IMAGE_ROOT_URL=https://layer0-docs-layer0-aws-store-example-default.layer0-limelight.link \n", "\n", "# Change to your deployed RDS\n", "AWS_IMAGE_SERVICE_DOMAIN=d28z1nhxyoq0l5.cloudfront.net\n", "```\n", "\n", "## Deployment\n", "\n", "Make sure all the steps of [Build](#Build) section are done before deployment!\n", "\n", "To check if everything is OK you can try running production build via `npm run layer0:start:prod`.\n", "\n", "To deploy files on Layer0 run `npm run layer0:deploy`. If this is the first deployment, the project will be automatically created for you in the Layer0 platform. \n", "\n", "To summarize, make sure all of these commands are run to ensure all changes are picked up.\n", "\n", "```bash\n", "# Build app\n", "npm run build\n", "\n", "# Build Layer0 configurations\n", "npm run layer0:build\n", "\n", "# Deploy to Layer0\n", "npm run layer0:deploy\n", "\n", "# Deploy to Layer0 if using Cloud9\n", "npx layer0 deploy --site=your-site-name-from-layer0 --skip-build --token=$LAYER0_DEPLOY_TOKEN\n", "```\n", "\n", "Note: The `$LAYER0_DEPLOY_TOKEN` can be generated inside your site inside Layer0.\n", "\n", "## Going further\n", "\n", "Please refer to the [Layer0 docs](https://docs.layer0.co) to better understand the possibilities available when working with Layer0. There are additional framework guides available to further test your implementations. \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Review offload by EDGE and Browser\n", "Layer0 Devtools is your friend. It shows offload based on caching configuration done in JS found in layer0 folder in web-ui code [here](https://github.com/aws-samples/retail-demo-store/tree/master/src/web-ui/layer0)\n", "\n", "Devtools shows What content is coming from browser. It also shows what is being prefetched. Prefetching helps with quickly loading next user might click on. Layer0 will only pre-fetch content from Edge. It will not over load origin.\n", "\n", "Check that you see Devtool in Chrome as below.\n", "\n", "![images/layer0-dev-tool.png](images/layer0-dev-tool.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clean Up\n", "Delete your layer0 deployment and site by login to layer0 account you have created and navigating to your site settings\n", "\n", "![images/DeleteLayer0Deployment.png](images/DeleteLayer0Deployment.png)\n", "\n", "Delete the retail demo store by Deleting Cloudformation template." ] } ], "metadata": { "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": 3 }, "orig_nbformat": 2 }, "nbformat": 4, "nbformat_minor": 2 }