├── 0-CLIs ├── vueapp │ ├── .browserslistrc │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── img │ │ │ └── icons │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ ├── msapplication-icon-144x144.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── manifest.json │ │ └── index.html │ ├── babel.config.js │ ├── postcss.config.js │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── ApiValues.vue │ │ │ └── HelloWorld.vue │ │ └── registerServiceWorker.js │ ├── vue.config.js │ ├── .gitignore │ ├── .eslintrc.js │ ├── README.md │ └── package.json ├── NetApi │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── NetApi.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Controllers │ │ └── ValuesController.cs │ └── Startup.cs └── README.md ├── server-rendered-spa ├── WebApplication1 │ ├── ClientApp │ │ ├── scss │ │ │ └── custom.scss │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── components │ │ │ │ ├── NavMenu.css │ │ │ │ ├── Layout.js │ │ │ │ ├── Counter.js │ │ │ │ ├── FetchData.js │ │ │ │ ├── NavMenu.js │ │ │ │ └── Home.js │ │ │ ├── App.test.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ └── registerServiceWorker.js │ │ ├── .gitignore │ │ └── package.json │ ├── Pages │ │ ├── _ViewImports.cshtml │ │ ├── Error.cshtml.cs │ │ └── Error.cshtml │ ├── appsettings.json │ ├── appsettings.Development.json │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Controllers │ │ └── SampleDataController.cs │ ├── Startup.cs │ ├── WebApplication1.csproj │ └── .gitignore ├── README.md └── WebApplication1.sln ├── 1-container-1-domain ├── vueapp │ ├── .browserslistrc │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── img │ │ │ └── icons │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ ├── msapplication-icon-144x144.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── manifest.json │ │ └── index.html │ ├── babel.config.js │ ├── .dockerignore │ ├── postcss.config.js │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── ApiValues.vue │ │ │ └── HelloWorld.vue │ │ └── registerServiceWorker.js │ ├── vue.config.js │ ├── .gitignore │ ├── .eslintrc.js │ ├── README.md │ └── package.json ├── NetApi │ ├── .dockerignore │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── NetApi.csproj │ ├── Controllers │ │ ├── SpaController.cs │ │ └── ValuesController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── Startup.cs ├── Dockerfile └── README.md ├── 2-containers-1-domain ├── vueapp │ ├── .browserslistrc │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── img │ │ │ └── icons │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ ├── msapplication-icon-144x144.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── manifest.json │ │ └── index.html │ ├── babel.config.js │ ├── .dockerignore │ ├── postcss.config.js │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── ApiValues.vue │ │ │ └── HelloWorld.vue │ │ └── registerServiceWorker.js │ ├── vue.config.js │ ├── nginx.conf │ ├── .gitignore │ ├── Dockerfile │ ├── .eslintrc.js │ ├── README.md │ └── package.json ├── NetApi │ ├── .dockerignore │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── NetApi.csproj │ ├── Dockerfile │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Controllers │ │ └── ValuesController.cs │ └── Startup.cs ├── Kubernetes │ ├── vueapp-service.yaml │ ├── netapi-service.yaml │ ├── vueapp-deployment.yaml │ ├── netapi-deployment.yaml │ └── kubernetes-ingress.yaml └── README.md ├── 0-Dockerfiles-for-each ├── vueapp │ ├── .browserslistrc │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── img │ │ │ └── icons │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ ├── msapplication-icon-144x144.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── manifest.json │ │ └── index.html │ ├── babel.config.js │ ├── .dockerignore │ ├── postcss.config.js │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── ApiValues.vue │ │ │ └── HelloWorld.vue │ │ └── registerServiceWorker.js │ ├── nginx.conf │ ├── .gitignore │ ├── Dockerfile │ ├── .eslintrc.js │ ├── README.md │ └── package.json ├── NetApi │ ├── .dockerignore │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── NetApi.csproj │ ├── Dockerfile │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Controllers │ │ └── ValuesController.cs │ └── Startup.cs └── README.md ├── 2-containers-2-domains ├── vueapp │ ├── .browserslistrc │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── img │ │ │ └── icons │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-512x512.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ └── msapplication-icon-144x144.png │ │ ├── manifest.json │ │ └── index.html │ ├── babel.config.js │ ├── .dockerignore │ ├── postcss.config.js │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── main.js │ │ ├── App.vue │ │ ├── components │ │ │ ├── ApiValues.vue │ │ │ └── HelloWorld.vue │ │ └── registerServiceWorker.js │ ├── .env.production │ ├── nginx.conf │ ├── .gitignore │ ├── Dockerfile │ ├── .eslintrc.js │ ├── README.md │ └── package.json ├── NetApi │ ├── .dockerignore │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── NetApi.csproj │ ├── Dockerfile │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Controllers │ │ └── ValuesController.cs │ └── Startup.cs └── README.md ├── .gitignore └── README.md /0-CLIs/vueapp/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/scss/custom.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .vs 4 | .vsignore 5 | *.log 6 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .vs 4 | .vsignore 5 | *.log 6 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .vs 4 | .vsignore 5 | *.log 6 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .vs 4 | .vsignore 5 | *.log 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.user 4 | *.suo 5 | .vs 6 | .vscode 7 | .idea 8 | node_modules 9 | package-lock.json 10 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/favicon.ico -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/src/assets/logo.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/.dockerignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.user 4 | launchSettings.json 5 | *.suo 6 | .vs 7 | .vsignore 8 | *.log 9 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/.dockerignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.user 4 | launchSettings.json 5 | *.suo 6 | .vs 7 | .vsignore 8 | *.log 9 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/.dockerignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.user 4 | launchSettings.json 5 | *.suo 6 | .vs 7 | .vsignore 8 | *.log 9 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/.dockerignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.user 4 | launchSettings.json 5 | *.suo 6 | .vs 7 | .vsignore 8 | *.log 9 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/favicon.ico -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/src/assets/logo.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/favicon.ico -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/favicon.ico -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/src/assets/logo.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/src/assets/logo.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/favicon.ico -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/src/assets/logo.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using WebApplication1 2 | @namespace WebApplication1.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-CLIs/vueapp/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/server-rendered-spa/WebApplication1/ClientApp/public/favicon.ico -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/.env.production: -------------------------------------------------------------------------------- 1 | # must start with VUE_APP_ to get bundled 2 | # ApiValues.vue assumes this doesn't include the trailing slash 3 | VUE_APP_BASE_URL=http://minikube:5000 4 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/0-Dockerfiles-for-each/vueapp/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/1-container-1-domain/vueapp/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-1-domain/vueapp/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robrich/docker-vue-and-aspnetcore/HEAD/2-containers-2-domains/vueapp/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /0-CLIs/NetApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | proxy: { 4 | "/api/*": { 5 | target: "https://localhost:5001", 6 | secure: false 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | proxy: { 4 | '/api/*': { 5 | target: 'https://localhost:5001', 6 | secure: false 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | proxy: { 4 | '/api/*': { 5 | target: 'https://localhost:5001', 6 | secure: false 7 | } 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | 5 | Vue.config.productionTip = false; 6 | 7 | new Vue({ 8 | render: h => h(App) 9 | }).$mount("#app"); 10 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name vue-app; 4 | 5 | location / { 6 | root /usr/share/nginx/html; 7 | try_files $uri $uri/ /index.html; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name vue-app; 4 | 5 | location / { 6 | root /usr/share/nginx/html; 7 | try_files $uri $uri/ /index.html; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name vue-app; 4 | 5 | location / { 6 | root /usr/share/nginx/html; 7 | try_files $uri $uri/ /index.html; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | 5 | Vue.config.productionTip = false; 6 | 7 | new Vue({ 8 | render: h => h(App) 9 | }).$mount("#app"); 10 | -------------------------------------------------------------------------------- /2-containers-1-domain/Kubernetes/vueapp-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: vue-app 5 | spec: 6 | type: NodePort 7 | selector: 8 | app: vue-app 9 | ports: 10 | - port: 80 11 | targetPort: 80 12 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | 5 | Vue.config.productionTip = false; 6 | 7 | new Vue({ 8 | render: h => h(App) 9 | }).$mount("#app"); 10 | -------------------------------------------------------------------------------- /2-containers-1-domain/Kubernetes/netapi-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: net-api 5 | spec: 6 | type: NodePort 7 | selector: 8 | app: net-api 9 | ports: 10 | - port: 5000 11 | targetPort: 5000 12 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | 5 | Vue.config.productionTip = false; 6 | 7 | new Vue({ 8 | render: h => h(App) 9 | }).$mount("#app"); 10 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | 5 | Vue.config.productionTip = false; 6 | 7 | new Vue({ 8 | render: h => h(App) 9 | }).$mount("#app"); 10 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/NetApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/NetApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/NetApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/NetApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/NetApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/NavMenu.css: -------------------------------------------------------------------------------- 1 | a.navbar-brand { 2 | white-space: normal; 3 | text-align: center; 4 | word-break: break-all; 5 | } 6 | 7 | html { 8 | font-size: 14px; 9 | } 10 | @media (min-width: 768px) { 11 | html { 12 | font-size: 16px; 13 | } 14 | } 15 | 16 | .box-shadow { 17 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 18 | } 19 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY package.json . 6 | RUN npm install 7 | 8 | # webpack build 9 | COPY . . 10 | RUN npm run build 11 | 12 | 13 | FROM nginx:alpine 14 | 15 | COPY nginx.conf /etc/nginx/conf.d/default.conf 16 | 17 | WORKDIR /usr/share/nginx/html 18 | COPY --from=build /src/dist . 19 | 20 | # nginx already has `CMD [...]` 21 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY package.json . 6 | RUN npm install 7 | 8 | # webpack build 9 | COPY . . 10 | RUN npm run build 11 | 12 | 13 | FROM nginx:alpine 14 | 15 | COPY nginx.conf /etc/nginx/conf.d/default.conf 16 | 17 | WORKDIR /usr/share/nginx/html 18 | COPY --from=build /src/dist . 19 | 20 | # nginx already has `CMD [...]` 21 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY package.json . 6 | RUN npm install 7 | 8 | # webpack build 9 | COPY . . 10 | RUN npm run build 11 | 12 | 13 | FROM nginx:alpine 14 | 15 | COPY nginx.conf /etc/nginx/conf.d/default.conf 16 | 17 | WORKDIR /usr/share/nginx/html 18 | COPY --from=build /src/dist . 19 | 20 | # nginx already has `CMD [...]` 21 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "WebApplication1", 3 | "name": "WebApplication1", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { MemoryRouter } from 'react-router-dom'; 4 | import App from './App'; 5 | 6 | it('renders without crashing', async () => { 7 | const div = document.createElement('div'); 8 | ReactDOM.render( 9 | 10 | 11 | , div); 12 | await new Promise(resolve => setTimeout(resolve, 1000)); 13 | }); 14 | -------------------------------------------------------------------------------- /2-containers-1-domain/Kubernetes/vueapp-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: vue-app-deployment 5 | spec: 6 | replicas: 2 7 | selector: 8 | matchLabels: 9 | app: vue-app 10 | template: 11 | metadata: 12 | labels: 13 | app: vue-app 14 | version: 2c1d 15 | spec: 16 | containers: 17 | - name: vue-app 18 | image: vue-app:2c1d 19 | ports: 20 | - containerPort: 80 21 | -------------------------------------------------------------------------------- /2-containers-1-domain/Kubernetes/netapi-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: net-api-deployment 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: net-api 10 | template: 11 | metadata: 12 | labels: 13 | app: net-api 14 | version: 2c1d 15 | spec: 16 | containers: 17 | - name: net-api 18 | image: net-api:2c1d 19 | ports: 20 | - containerPort: 5000 21 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/Layout.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Container } from 'reactstrap'; 3 | import { NavMenu } from './NavMenu'; 4 | 5 | export class Layout extends Component { 6 | static displayName = Layout.name; 7 | 8 | render () { 9 | return ( 10 |
11 | 12 | 13 | {this.props.children} 14 | 15 |
16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/README.md: -------------------------------------------------------------------------------- 1 | # vueapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/Controllers/SpaController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace MusicRank.Controllers 4 | { 5 | public class SpaController : Controller 6 | { 7 | // Enumerate all SPA urls so we boot the Vue app correctly 8 | // Alternatively, use this as the 404 page so any unhandled url will boot the vue app 9 | [HttpGet("/")] 10 | [HttpGet("/about")] 11 | public ActionResult Index(string id) => File("/index.html", "text/html"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/README.md: -------------------------------------------------------------------------------- 1 | # vueapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/README.md: -------------------------------------------------------------------------------- 1 | # vueapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/README.md: -------------------------------------------------------------------------------- 1 | # vueapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/README.md: -------------------------------------------------------------------------------- 1 | # vueapp 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "short_name": "vueapp", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /2-containers-1-domain/Kubernetes/kubernetes-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: spa-and-api 5 | annotations: 6 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 7 | spec: 8 | rules: 9 | - http: 10 | # TODO: add `host: example.com` 11 | paths: 12 | - path: /api 13 | backend: 14 | serviceName: net-api 15 | servicePort: 5000 16 | - path: / 17 | backend: 18 | serviceName: vue-app 19 | servicePort: 80 20 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "short_name": "vueapp", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "short_name": "vueapp", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "short_name": "vueapp", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "short_name": "vueapp", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY NetApi.csproj . 6 | RUN dotnet restore 7 | 8 | COPY . . 9 | RUN dotnet build -c Release 10 | 11 | # RUN dotnet test ... 12 | 13 | RUN dotnet publish -c Release -o /dist 14 | 15 | 16 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine 17 | 18 | WORKDIR /app 19 | 20 | ENV ASPNETCORE_ENVIRONMENT Production 21 | ENV ASPNETCORE_URLS http://+:5000 22 | EXPOSE 5000 23 | 24 | COPY --from=build /dist . 25 | 26 | CMD ["dotnet", "NetApi.dll"] 27 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY NetApi.csproj . 6 | RUN dotnet restore 7 | 8 | COPY . . 9 | RUN dotnet build -c Release 10 | 11 | # RUN dotnet test ... 12 | 13 | RUN dotnet publish -c Release -o /dist 14 | 15 | 16 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine 17 | 18 | WORKDIR /app 19 | 20 | ENV ASPNETCORE_ENVIRONMENT Production 21 | ENV ASPNETCORE_URLS http://+:5000 22 | EXPOSE 5000 23 | 24 | COPY --from=build /dist . 25 | 26 | CMD ["dotnet", "NetApi.dll"] 27 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/index.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.css'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import { BrowserRouter } from 'react-router-dom'; 5 | import App from './App'; 6 | import registerServiceWorker from './registerServiceWorker'; 7 | 8 | const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href'); 9 | const rootElement = document.getElementById('root'); 10 | 11 | ReactDOM.render( 12 | 13 | 14 | , 15 | rootElement); 16 | 17 | registerServiceWorker(); 18 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vueapp 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vueapp 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vueapp 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vueapp 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vueapp 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine as build 2 | 3 | WORKDIR /src 4 | 5 | COPY NetApi.csproj . 6 | RUN dotnet restore 7 | 8 | COPY . . 9 | RUN dotnet build -c Release 10 | 11 | # RUN dotnet test ... 12 | 13 | RUN dotnet publish -c Release -o /dist 14 | 15 | 16 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine 17 | 18 | WORKDIR /app 19 | 20 | ENV ASPNETCORE_ENVIRONMENT Production 21 | ENV ASPNETCORE_URLS http://+:5000 22 | EXPOSE 5000 23 | 24 | # does not contain the trailing slash 25 | ENV CORS_DOMAIN http://minikube:3000 26 | 27 | COPY --from=build /dist . 28 | 29 | CMD ["dotnet", "NetApi.dll"] 30 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace WebApplication1 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateWebHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 20 | WebHost.CreateDefaultBuilder(args) 21 | .UseStartup(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Route } from 'react-router'; 3 | import { Layout } from './components/Layout'; 4 | import { Home } from './components/Home'; 5 | import { FetchData } from './components/FetchData'; 6 | import { Counter } from './components/Counter'; 7 | 8 | export default class App extends Component { 9 | static displayName = App.name; 10 | 11 | render () { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.RazorPages; 8 | 9 | namespace WebApplication1.Pages 10 | { 11 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 12 | public class ErrorModel : PageModel 13 | { 14 | public string RequestId { get; set; } 15 | 16 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 17 | 18 | public void OnGet() 19 | { 20 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "register-service-worker": "^1.6.2", 13 | "vue": "^2.6.10" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.8.0", 17 | "@vue/cli-plugin-eslint": "^3.8.0", 18 | "@vue/cli-plugin-pwa": "^3.8.0", 19 | "@vue/cli-service": "^3.8.0", 20 | "@vue/eslint-config-prettier": "^4.0.1", 21 | "babel-eslint": "^10.0.1", 22 | "eslint": "^5.16.0", 23 | "eslint-plugin-vue": "^5.0.0", 24 | "vue-template-compiler": "^2.6.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "register-service-worker": "^1.6.2", 13 | "vue": "^2.6.10" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.8.0", 17 | "@vue/cli-plugin-eslint": "^3.8.0", 18 | "@vue/cli-plugin-pwa": "^3.8.0", 19 | "@vue/cli-service": "^3.8.0", 20 | "@vue/eslint-config-prettier": "^4.0.1", 21 | "babel-eslint": "^10.0.1", 22 | "eslint": "^5.16.0", 23 | "eslint-plugin-vue": "^5.0.0", 24 | "vue-template-compiler": "^2.6.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "register-service-worker": "^1.6.2", 13 | "vue": "^2.6.10" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.8.0", 17 | "@vue/cli-plugin-eslint": "^3.8.0", 18 | "@vue/cli-plugin-pwa": "^3.8.0", 19 | "@vue/cli-service": "^3.8.0", 20 | "@vue/eslint-config-prettier": "^4.0.1", 21 | "babel-eslint": "^10.0.1", 22 | "eslint": "^5.16.0", 23 | "eslint-plugin-vue": "^5.0.0", 24 | "vue-template-compiler": "^2.6.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "register-service-worker": "^1.6.2", 13 | "vue": "^2.6.10" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.8.0", 17 | "@vue/cli-plugin-eslint": "^3.8.0", 18 | "@vue/cli-plugin-pwa": "^3.8.0", 19 | "@vue/cli-service": "^3.8.0", 20 | "@vue/eslint-config-prettier": "^4.0.1", 21 | "babel-eslint": "^10.0.1", 22 | "eslint": "^5.16.0", 23 | "eslint-plugin-vue": "^5.0.0", 24 | "vue-template-compiler": "^2.6.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vueapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "register-service-worker": "^1.6.2", 13 | "vue": "^2.6.10" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.8.0", 17 | "@vue/cli-plugin-eslint": "^3.8.0", 18 | "@vue/cli-plugin-pwa": "^3.8.0", 19 | "@vue/cli-service": "^3.8.0", 20 | "@vue/eslint-config-prettier": "^4.0.1", 21 | "babel-eslint": "^10.0.1", 22 | "eslint": "^5.16.0", 23 | "eslint-plugin-vue": "^5.0.0", 24 | "vue-template-compiler": "^2.6.10" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:35700", 7 | "sslPort": 44349 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "WebApplication1": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetApi 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/components/ApiValues.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/components/ApiValues.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/components/ApiValues.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/components/ApiValues.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/Counter.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export class Counter extends Component { 4 | static displayName = Counter.name; 5 | 6 | constructor (props) { 7 | super(props); 8 | this.state = { currentCount: 0 }; 9 | this.incrementCounter = this.incrementCounter.bind(this); 10 | } 11 | 12 | incrementCounter () { 13 | this.setState({ 14 | currentCount: this.state.currentCount + 1 15 | }); 16 | } 17 | 18 | render () { 19 | return ( 20 |
21 |

Counter

22 | 23 |

This is a simple example of a React component.

24 | 25 |

Current count: {this.state.currentCount}

26 | 27 | 28 |
29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/components/ApiValues.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41323", 8 | "sslPort": 44386 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NetApi": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41323", 8 | "sslPort": 44386 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NetApi": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41323", 8 | "sslPort": 44386 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NetApi": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41323", 8 | "sslPort": 44386 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NetApi": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:41323", 8 | "sslPort": 44386 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "NetApi": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development", 27 | "CORS_DOMAIN": "http://localhost:8080" 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /1-container-1-domain/Dockerfile: -------------------------------------------------------------------------------- 1 | # build .NET app: 2 | FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine as buildnet 3 | 4 | WORKDIR /src 5 | 6 | COPY NetApi/NetApi.csproj . 7 | RUN dotnet restore 8 | 9 | COPY NetApi . 10 | RUN dotnet build -c Release 11 | 12 | # RUN dotnet test ... 13 | 14 | RUN dotnet publish -c Release -o /dist 15 | 16 | 17 | # build Vue app: 18 | FROM node:alpine as buildvue 19 | 20 | WORKDIR /src 21 | 22 | COPY vueapp/package.json . 23 | RUN npm install 24 | 25 | # webpack build 26 | COPY vueapp . 27 | RUN npm run build 28 | 29 | 30 | # Copy results from both places into production container: 31 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine 32 | 33 | WORKDIR /app 34 | 35 | ENV ASPNETCORE_ENVIRONMENT Production 36 | ENV ASPNETCORE_URLS http://+:5000 37 | EXPOSE 5000 38 | 39 | # copy .net content 40 | COPY --from=buildnet /dist . 41 | # copy vue content into .net's static files folder: 42 | COPY --from=buildvue /src/dist /app/wwwroot 43 | 44 | CMD ["dotnet", "NetApi.dll"] 45 | -------------------------------------------------------------------------------- /0-CLIs/README.md: -------------------------------------------------------------------------------- 1 | Create the Apps 2 | =============== 3 | 4 | The first step is to create the apps using each product's CLI: 5 | 6 | 1. Download .NET Core SDK from https://dotnet.microsoft.com/download/dotnet-core 7 | 8 | 2. Download Vue.js CLI from NPM using `npm` or `yarn`: 9 | 10 | `npm install -g @vue/cli` 11 | 12 | Install Node from https://nodejs.org/ if needed. 13 | 14 | 3. Scaffold the .NET project: 15 | 16 | `dotnet new webapi -n NetApi` 17 | 18 | 4. Scaffold the Vue app using the Vue cli: 19 | 20 | `vue create vueapp` 21 | 22 | This will walk you through a wizard allowing you to pick your favorite options. 23 | 24 | 5. To call the backend, we added `src/components/ApiValues.vue`, referenced it from `src/App.vue`, and created `vue.config.js` to proxy requests to the back-end. 25 | 26 | 27 | Results 28 | ------- 29 | 30 | The contents of this folder are the results of doing these steps. 31 | 32 | We'll copy this content into each other scenario as we build `Dockerfile`s for each technique. 33 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /server-rendered-spa/README.md: -------------------------------------------------------------------------------- 1 | Server-rendered SPA 2 | =================== 3 | 4 | Server-rendering produces the SPA's first render cycle on the server, and ships this customized html to the browser. The SPA boots up on the browser, and continues the interactions from here. 5 | 6 | 7 | Technique 8 | --------- 9 | 10 | Inside Visual Studio, choose File -> New -> ASP.NET Core Website, then choose the Angular or React template. (Sadly no Vue template.) It uses the same "host both front-end and back-end in one site" solution we saw in chapter 4. In addition, it includes server-rendered content. Check the "Add Docker Support" check-box in the new project dialog, and it'll scaffold out the Dockerfile too. 11 | 12 | 13 | Results 14 | ------- 15 | 16 | The SPA page is first rendered on the server, producing great SEO-worthy pages on first paint. Then the SPA boots up and continues the interaction. This is great when Search Engine Optimization is key, and works well for users with JavaScript disabled. It requires a server-platform that supports this though (usually Node.js), and generally strays far from the SPA's CLI tools. 17 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace NetApi.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { ".NET", "Backend" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace NetApi.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { ".NET", "Backend" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace NetApi.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { ".NET", "Backend" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace NetApi.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { ".NET", "Backend" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace NetApi.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class ValuesController : ControllerBase 12 | { 13 | // GET api/values 14 | [HttpGet] 15 | public ActionResult> Get() 16 | { 17 | return new string[] { ".NET", "Backend" }; 18 | } 19 | 20 | // GET api/values/5 21 | [HttpGet("{id}")] 22 | public ActionResult Get(int id) 23 | { 24 | return "value"; 25 | } 26 | 27 | // POST api/values 28 | [HttpPost] 29 | public void Post([FromBody] string value) 30 | { 31 | } 32 | 33 | // PUT api/values/5 34 | [HttpPut("{id}")] 35 | public void Put(int id, [FromBody] string value) 36 | { 37 | } 38 | 39 | // DELETE api/values/5 40 | [HttpDelete("{id}")] 41 | public void Delete(int id) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WebApplication1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "bootstrap": "^4.1.3", 7 | "jquery": "3.5.1", 8 | "merge": "^1.2.1", 9 | "oidc-client": "^1.6.1", 10 | "react": "^16.0.0", 11 | "react-dom": "^16.0.0", 12 | "react-router-bootstrap": "^0.24.4", 13 | "react-router-dom": "^4.2.2", 14 | "react-scripts": "^2.1.8", 15 | "reactstrap": "^6.3.0", 16 | "rimraf": "^2.6.2" 17 | }, 18 | "devDependencies": { 19 | "ajv": "^6.9.1", 20 | "babel-eslint": "^9.0.0", 21 | "cross-env": "^5.2.0", 22 | "eslint": "^5.12.0", 23 | "eslint-config-react-app": "^3.0.8", 24 | "eslint-plugin-flowtype": "^3.5.1", 25 | "eslint-plugin-import": "^2.14.0", 26 | "eslint-plugin-jsx-a11y": "^5.1.1", 27 | "eslint-plugin-react": "^7.11.1" 28 | }, 29 | "eslintConfig": { 30 | "extends": "react-app" 31 | }, 32 | "scripts": { 33 | "start": "rimraf ./build && react-scripts start", 34 | "build": "react-scripts build", 35 | "test": "cross-env CI=true react-scripts test --env=jsdom", 36 | "eject": "react-scripts eject", 37 | "lint": "eslint ./src/" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28922.388 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication1", "WebApplication1\WebApplication1.csproj", "{B54AD0D5-24DC-4B16-B242-7E44E7A9A3CA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B54AD0D5-24DC-4B16-B242-7E44E7A9A3CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B54AD0D5-24DC-4B16-B242-7E44E7A9A3CA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B54AD0D5-24DC-4B16-B242-7E44E7A9A3CA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B54AD0D5-24DC-4B16-B242-7E44E7A9A3CA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {AAC911BE-C587-4AE2-9D07-F57F508BC88B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Controllers/SampleDataController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace WebApplication1.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | public class SampleDataController : Controller 11 | { 12 | private static string[] Summaries = new[] 13 | { 14 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 15 | }; 16 | 17 | [HttpGet("[action]")] 18 | public IEnumerable WeatherForecasts() 19 | { 20 | var rng = new Random(); 21 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 22 | { 23 | DateFormatted = DateTime.Now.AddDays(index).ToString("d"), 24 | TemperatureC = rng.Next(-20, 55), 25 | Summary = Summaries[rng.Next(Summaries.Length)] 26 | }); 27 | } 28 | 29 | public class WeatherForecast 30 | { 31 | public string DateFormatted { get; set; } 32 | public int TemperatureC { get; set; } 33 | public string Summary { get; set; } 34 | 35 | public int TemperatureF { 36 | get { 37 | return 32 + (int)(TemperatureC / 0.5556); 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Docker Isn't All Hype; Create Robust Deployments for Vue.js and ASP.NET Core 2 | ============================================================================ 3 | 4 | This demonstrates various approaches to building a SPA application and supporting backend in Docker. It is the companion code to the [Docker Isn't All Hype](https://robrich.org/slides/docker-vue-and-aspnetcore/#/) presentation. 5 | 6 | Vue and ASP.NET were used here purely for demonstration. The same principles apply to Angular or React, Java or Python, or any technology with a single page app and a supporting back-end. 7 | 8 | In each folder, we demonstrate one approach: 9 | 10 | - 0-CLIs - Let's scaffold out both projects. 11 | 12 | - 0-Dockerfiles-for-each - Classic Dockerfiles for each piece. Here's where most tutorials stop. 13 | 14 | - 2-containers-2-domains - We put our website on https://www.example.com/ and our api on https://api.example.com/. 15 | 16 | - 2-containers-1-domain - We put both front-end and back-end into separate containers, but stitch them together into a single URL via a Kubernetes Ingress controller. 17 | 18 | - 1-container-1-domain - Deploy both SPA and back-end into a single container, using the back-end to host the front-end's static files. 19 | 20 | - server-rendered-spa - Visual Studio's New Project template hosts both pieces together and includes server-rendered components. 21 | 22 | 23 | LICENSE: MIT, Copyright Richardson & Sons, LLC. 24 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/README.md: -------------------------------------------------------------------------------- 1 | Dockerfiles for each step 2 | ========================= 3 | 4 | In this chapter we'll copy the content from `0-CLIs` and add the typical `Dockerfile`s for each project. When we're done, we'll have fully functional containers, but they won't interact with each other. 5 | 6 | New content since Chapter 0 7 | --------------------------- 8 | 9 | 1. `NetApi/Dockerfile` is the file used to package a .NET app, and represents a typical `Dockerfile`. 10 | 11 | 2. `vueapp/Dockerfile` is the file used to package the Vue.js app. 12 | 13 | 3. Each folder has a `.dockerignore` file. Like the `.gitignore` file, these files are not copied into the Docker image. 14 | 15 | 4. `vueapp/nginx.conf` is a config file for Nginx to serve the index.html file as the 404 page. 16 | 17 | 18 | Use it 19 | ------ 20 | 21 | 1. Build the .NET image: 22 | 23 | ```bash 24 | cd NetApi 25 | docker build -t net-api:step0 . 26 | cd .. 27 | ``` 28 | 29 | 2. Build the Vue.js image: 30 | 31 | ```bash 32 | cd vueapp 33 | docker build -t vue-app:step0 . 34 | cd .. 35 | ``` 36 | 37 | Results 38 | ------- 39 | 40 | This is the typical result we'd get if we followed a "Docker for Vue.js" and a "Docker for ASP.NET Core" tutorial. Each system is working fine, but they're not working together. 41 | 42 | Digging into each technique, we'll see how we can customize the `Dockerfile`s and applications to meet the needs of each hosting and container strategy. 43 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/FetchData.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export class FetchData extends Component { 4 | static displayName = FetchData.name; 5 | 6 | constructor(props) { 7 | super(props); 8 | this.state = { forecasts: [], loading: true }; 9 | } 10 | 11 | componentDidMount() { 12 | this.populateWeatherData(); 13 | } 14 | 15 | static renderForecastsTable(forecasts) { 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {forecasts.map(forecast => 28 | 29 | 30 | 31 | 32 | 33 | 34 | )} 35 | 36 |
DateTemp. (C)Temp. (F)Summary
{forecast.dateFormatted}{forecast.temperatureC}{forecast.temperatureF}{forecast.summary}
37 | ); 38 | } 39 | 40 | render() { 41 | let contents = this.state.loading 42 | ?

Loading...

43 | : FetchData.renderForecastsTable(this.state.forecasts); 44 | 45 | return ( 46 |
47 |

Weather forecast

48 |

This component demonstrates fetching data from the server.

49 | {contents} 50 |
51 | ); 52 | } 53 | 54 | async populateWeatherData() { 55 | const response = await fetch('api/SampleData/WeatherForecasts'); 56 | const data = await response.json(); 57 | this.setState({ forecasts: data, loading: false }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/NavMenu.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap'; 3 | import { Link } from 'react-router-dom'; 4 | import './NavMenu.css'; 5 | 6 | export class NavMenu extends Component { 7 | static displayName = NavMenu.name; 8 | 9 | constructor (props) { 10 | super(props); 11 | 12 | this.toggleNavbar = this.toggleNavbar.bind(this); 13 | this.state = { 14 | collapsed: true 15 | }; 16 | } 17 | 18 | toggleNavbar () { 19 | this.setState({ 20 | collapsed: !this.state.collapsed 21 | }); 22 | } 23 | 24 | render () { 25 | return ( 26 |
27 | 28 | 29 | WebApplication1 30 | 31 | 32 |
    33 | 34 | Home 35 | 36 | 37 | Counter 38 | 39 | 40 | Fetch data 41 | 42 |
43 |
44 |
45 |
46 |
47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 23 | WebApplication1 24 | 25 | 26 | 29 |
30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export class Home extends Component { 4 | static displayName = Home.name; 5 | 6 | render () { 7 | return ( 8 |
9 |

Hello, world!

10 |

Welcome to your new single-page application, built with:

11 | 16 |

To help you get started, we have also set up:

17 |
    18 |
  • Client-side navigation. For example, click Counter then Back to return here.
  • 19 |
  • Development server integration. In development mode, the development server from create-react-app runs in the background automatically, so your client-side resources are dynamically built on demand and the page refreshes when you modify any file.
  • 20 |
  • Efficient production builds. In production mode, development-time features are disabled, and your dotnet publish configuration produces minified, efficiently bundled JavaScript files.
  • 21 |
22 |

The ClientApp subdirectory is a standard React application based on the create-react-app template. If you open a command prompt in that directory, you can run npm commands such as npm test or npm install.

23 |
24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0-CLIs/NetApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace NetApi 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers() 29 | .AddNewtonsoftJson(); 30 | } 31 | 32 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 33 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 34 | { 35 | if (env.IsDevelopment()) 36 | { 37 | app.UseDeveloperExceptionPage(); 38 | } 39 | else 40 | { 41 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseHttpsRedirection(); 46 | 47 | app.UseRouting(); 48 | 49 | app.UseAuthorization(); 50 | 51 | app.UseEndpoints(endpoints => 52 | { 53 | endpoints.MapControllers(); 54 | }); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/NetApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace NetApi 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers() 29 | .AddNewtonsoftJson(); 30 | } 31 | 32 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 33 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 34 | { 35 | if (env.IsDevelopment()) 36 | { 37 | app.UseDeveloperExceptionPage(); 38 | } 39 | else 40 | { 41 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseHttpsRedirection(); 46 | 47 | app.UseRouting(); 48 | 49 | app.UseAuthorization(); 50 | 51 | app.UseEndpoints(endpoints => 52 | { 53 | endpoints.MapControllers(); 54 | }); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /2-containers-1-domain/NetApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace NetApi 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers() 29 | .AddNewtonsoftJson(); 30 | } 31 | 32 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 33 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 34 | { 35 | if (env.IsDevelopment()) 36 | { 37 | app.UseDeveloperExceptionPage(); 38 | } 39 | else 40 | { 41 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseHttpsRedirection(); 46 | 47 | app.UseRouting(); 48 | 49 | app.UseAuthorization(); 50 | 51 | app.UseEndpoints(endpoints => 52 | { 53 | endpoints.MapControllers(); 54 | }); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /1-container-1-domain/README.md: -------------------------------------------------------------------------------- 1 | 1 Container, 1 Domain 2 | ===================== 3 | 4 | In this technique, both front-end and back-end run from the same container built from a single `Dockerfile`. We can't scale them separately, but we deploy changes in either simultaniously. 5 | 6 | 7 | New content since Chapter 0 8 | --------------------------- 9 | 10 | 1. `NetApi/Startup.cs` adds `DefaultFiles` and `StaticFiles` references so .NET can serve the JavaScript, CSS, and images. 11 | 12 | 2. `NetApi/Controllers/SpaController.cs` serves the `index.html` page for each route in the Vue app. 13 | 14 | 3. `vueapp/vue.config.js` is for development only, and hooks up Webpack development server. It looks for requests to `/api/any/path/here` and forwards it to the backend. 15 | 16 | 4. `vueapp/nginx.conf` is gone. We use .NET's Kestrel web server for that now. 17 | 18 | 5. `Dockerfile` at the root of the solution replaces the files in each project. This single file builds stages for each application. 19 | 20 | 21 | Use it: dev 22 | ----------- 23 | 24 | 1. Run the backend outside the container: 25 | 26 | ``` 27 | cd NetApi 28 | dotnet run 29 | ``` 30 | 31 | 2. Run the frontend outside the container: 32 | 33 | ``` 34 | cd vueapp 35 | npm install 36 | npm run serve 37 | ``` 38 | 39 | 3. Open the browser to the frontend: 40 | 41 | `http://localhost:8080/` 42 | 43 | 44 | Use it: production 45 | ------------------ 46 | 47 | 1. Build and run the single container: 48 | 49 | ``` 50 | docker build -t spa-and-api:1c1d . 51 | docker run -p 5000:5000 -d spa-and-api:1c1d 52 | ``` 53 | 54 | 2. Launch your browser to the app: 55 | 56 | `http://localhost:5000/` 57 | 58 | 59 | Results 60 | ------- 61 | 62 | In dev, we leverage Webpack Dev Server to proxy through the front-end to the back-end. In Production, we deploy the SPA's static files into the back-end's static files directory (`public` or `wwwroot` or similar). 63 | -------------------------------------------------------------------------------- /1-container-1-domain/NetApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace NetApi 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers() 29 | .AddNewtonsoftJson(); 30 | } 31 | 32 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 33 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 34 | { 35 | if (env.IsDevelopment()) 36 | { 37 | app.UseDeveloperExceptionPage(); 38 | } 39 | else 40 | { 41 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 42 | app.UseHsts(); 43 | } 44 | 45 | app.UseHttpsRedirection(); 46 | 47 | app.UseDefaultFiles(); 48 | app.UseStaticFiles(); 49 | 50 | app.UseRouting(); 51 | 52 | app.UseAuthorization(); 53 | 54 | app.UseEndpoints(endpoints => 55 | { 56 | endpoints.MapControllers(); 57 | }); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.HttpsPolicy; 4 | using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | 9 | namespace WebApplication1 10 | { 11 | public class Startup 12 | { 13 | public Startup(IConfiguration configuration) 14 | { 15 | Configuration = configuration; 16 | } 17 | 18 | public IConfiguration Configuration { get; } 19 | 20 | // This method gets called by the runtime. Use this method to add services to the container. 21 | public void ConfigureServices(IServiceCollection services) 22 | { 23 | services.AddMvc(options => options.EnableEndpointRouting = false) 24 | .AddNewtonsoftJson(); 25 | 26 | // In production, the React files will be served from this directory 27 | services.AddSpaStaticFiles(configuration => 28 | { 29 | configuration.RootPath = "ClientApp/build"; 30 | }); 31 | } 32 | 33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 34 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 35 | { 36 | if (env.IsDevelopment()) 37 | { 38 | app.UseDeveloperExceptionPage(); 39 | } 40 | else 41 | { 42 | app.UseExceptionHandler("/Error"); 43 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 44 | app.UseHsts(); 45 | } 46 | 47 | app.UseHttpsRedirection(); 48 | app.UseStaticFiles(); 49 | app.UseSpaStaticFiles(); 50 | 51 | app.UseMvc(routes => 52 | { 53 | routes.MapRoute( 54 | name: "default", 55 | template: "{controller}/{action=Index}/{id?}"); 56 | }); 57 | 58 | app.UseSpa(spa => 59 | { 60 | spa.Options.SourcePath = "ClientApp"; 61 | 62 | if (env.IsDevelopment()) 63 | { 64 | spa.UseReactDevelopmentServer(npmScript: "start"); 65 | } 66 | }); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /2-containers-2-domains/NetApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace NetApi 15 | { 16 | public class Startup 17 | { 18 | 19 | public Startup(IConfiguration configuration) 20 | { 21 | Configuration = configuration; 22 | } 23 | 24 | public IConfiguration Configuration { get; } 25 | 26 | // This method gets called by the runtime. Use this method to add services to the container. 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | // CORS configuration for ASP.NET Core: 30 | // https://docs.microsoft.com/en-us/aspnet/core/security/cors 31 | // must not have a trailing slash 32 | string CORS_DOMAIN = Configuration.GetValue("CORS_DOMAIN"); 33 | Console.WriteLine($"CORS_DOMAIN: {CORS_DOMAIN}"); 34 | 35 | services.AddCors(options => 36 | { 37 | options.AddDefaultPolicy(builder => 38 | { 39 | builder.WithOrigins(CORS_DOMAIN); 40 | }); 41 | }); 42 | 43 | services.AddControllers() 44 | .AddNewtonsoftJson(); 45 | } 46 | 47 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 48 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 49 | { 50 | if (env.IsDevelopment()) 51 | { 52 | app.UseDeveloperExceptionPage(); 53 | } 54 | else 55 | { 56 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 57 | app.UseHsts(); 58 | } 59 | 60 | app.UseCors(); 61 | 62 | app.UseHttpsRedirection(); 63 | 64 | app.UseRouting(); 65 | 66 | app.UseAuthorization(); 67 | 68 | app.UseEndpoints(endpoints => 69 | { 70 | endpoints.MapControllers(); 71 | }); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /2-containers-1-domain/README.md: -------------------------------------------------------------------------------- 1 | 2 Containers, 1 Domain 2 | ====================== 3 | 4 | In this technique, we assume both website and api are running on the same subdomain -- both on https://www.example.com/. Yet they're deployed as separate containers so we can scale each differently. 5 | 6 | In production, a Kubernetes [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) links the two sites together. (We could also use an Nginx or HAProxy.) 7 | 8 | In development, [Webpack](https://stackoverflow.com/a/49846977/702931) proxies content through the Webpack development server to the api. 9 | 10 | We assume here that all resources on `/api/*` are to go to the backend, and all other urls go to the frontend. 11 | 12 | 13 | New content since Chapter 0 14 | --------------------------- 15 | 16 | 1. `Kubernetes` folder contains all the files used to install both docker images into the cluster, and rig them behind the ingress controller. 17 | 18 | 2. `vueapp/vue.config.js` is for development only, and hooks up Webpack development server. It looks for requests to `/api/any/path/here` and forwards it to the backend. 19 | 20 | 21 | Use it: dev 22 | ----------- 23 | 24 | 1. Run the backend outside the container: 25 | 26 | ``` 27 | cd NetApi 28 | dotnet run 29 | ``` 30 | 31 | 2. Run the frontend outside the container: 32 | 33 | ``` 34 | cd vueapp 35 | npm install 36 | npm run serve 37 | ``` 38 | 39 | 3. Open the browser to the frontend: 40 | 41 | `http://localhost:8080/` 42 | 43 | 44 | Use it: production 45 | ------------------ 46 | 47 | 1. Build both the backend and frontend images: 48 | 49 | ``` 50 | cd NetApi 51 | docker build -t net-api:2c1d . 52 | cd .. 53 | cd vueapp 54 | docker build -t vue-app:2c1d . 55 | cd .. 56 | ``` 57 | 58 | 2. Install the kubernetes content: 59 | 60 | ``` 61 | kubectl apply -f Kubernetes 62 | ``` 63 | 64 | kubectl will loop through all the files, installing each one. 65 | 66 | 3. Get the IP for the ingress controller: 67 | 68 | ``` 69 | kubectl get ingress spa-and-api 70 | ``` 71 | 72 | 4. Launch your browser to the Kubernetes Cluster IP: 73 | 74 | `http://localhost:80/` 75 | 76 | 77 | Results 78 | ------- 79 | 80 | We have the best of both worlds. We don't have the complexity of `CORS` headers or `BASE_URL` environment variables, yet we can scale each container separately. The price for this solution: we need a complex container orchestrator such as Kubernetes to proxy traffic from a single load balancer to the proper container. 81 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/WebApplication1.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.0 5 | true 6 | Latest 7 | false 8 | ClientApp\ 9 | $(DefaultItemExcludes);$(SpaRoot)node_modules\** 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | %(DistFiles.Identity) 44 | PreserveNewest 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /2-containers-2-domains/README.md: -------------------------------------------------------------------------------- 1 | 2 Containers, 2 Domains 2 | ======================= 3 | 4 | Let's imagine we'll deploy the SPA to https://www.example.com/ and the back-end API to https://api.example.com/ 5 | 6 | Because they're separate, each can grow and evolve separately. This has some up-sides and some downsides. 7 | 8 | 9 | New content since Chapter 0 10 | --------------------------- 11 | 12 | 1. `NetApi/Dockerfile` and `NetApi/Startup.cs` have references to CORS headers using the `CORS_DOMAIN` environment variable. We can override this as we launch the container: 13 | 14 | `docker run -e CORS_DOMAIN=https://foo -p 5000:5000 -d net-api` 15 | 16 | The variable we're specifying here is the allowed domain(s) that can use this service. 17 | 18 | 2. `vueapp/.env.production` and `vueapp/src/components/ApiValues.vue` reference `VUE_APP_BASE_URL` environment variable. This is the api's domain, and gets baked into the image, so we can't override this at runtime. 19 | 20 | Because these two environment variables will be different in each environment, we need to carefully adjust these files **each time we build** to link the environments back together. 21 | 22 | Note that these URLs aren't between the containers, but rather how the browser referrs to each. This is because the browser is running the SPA, and making the call to the backend. 23 | 24 | 25 | Use it: dev 26 | ----------- 27 | 28 | 1. Set the `CORS_DOMAIN` environment variable in `NetApi/Properties/launchSettings.json` or in the Properties pages inside Visual Studio. 29 | 30 | 2. Set the `VUE_APP_BASE_URL` environment variable in `vueapp/.env.local`. 31 | 32 | 3. Run the backend outside the container: 33 | 34 | ``` 35 | cd NetApi 36 | dotnet run 37 | ``` 38 | 39 | 4. Run the frontend outside the container: 40 | 41 | ``` 42 | cd vueapp 43 | npm install 44 | npm run serve 45 | ``` 46 | 47 | 5. Open the browser to the frontend: 48 | 49 | `http://localhost:8080/` 50 | 51 | 52 | Use it: production 53 | ------------------ 54 | 55 | 1. Adjust the `CORS_DOMAIN` line in `NetApi/Dockerfile`. 56 | 57 | 2. Adjust the `VUE_APP_BASE_URL` line in `vueapp/.env.production`. 58 | 59 | 3. Build the .NET image: 60 | 61 | ```bash 62 | cd NetApi 63 | docker build -t net-api:2c2d . 64 | cd .. 65 | ``` 66 | 67 | 4. Build the Vue.js image: 68 | 69 | ```bash 70 | cd vueapp 71 | docker build -t vue-app:2c2d . 72 | cd .. 73 | ``` 74 | 75 | 5. Run both containers: 76 | 77 | ```bash 78 | docker run -p 5000:5000 -d net-api:2c2d 79 | docker run -p 3000:80 -d vue-app:2c2d 80 | ``` 81 | 82 | 6. Launch your browser to the vue app: 83 | 84 | `http://localhost:3000/` 85 | 86 | 87 | Results 88 | ------- 89 | 90 | Each side can grow independently, they can get deployed independently -- even to different hosting platforms or vendors. But we need to carefully configure `CORS` headers in the API, and carefully configure the API's `BASE_URL` in the front-end. This configuration must be unique per environment, and may be different for different developers depending on their tools (Docker Desktop vs Minikube vs K3s). 91 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /2-containers-2-domains/vueapp/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/ClientApp/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register () { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | } else { 39 | // Is not local host. Just register service worker 40 | registerValidSW(swUrl); 41 | } 42 | }); 43 | } 44 | } 45 | 46 | function registerValidSW (swUrl) { 47 | navigator.serviceWorker 48 | .register(swUrl) 49 | .then(registration => { 50 | registration.onupdatefound = () => { 51 | const installingWorker = registration.installing; 52 | installingWorker.onstatechange = () => { 53 | if (installingWorker.state === 'installed') { 54 | if (navigator.serviceWorker.controller) { 55 | // At this point, the old content will have been purged and 56 | // the fresh content will have been added to the cache. 57 | // It's the perfect time to display a "New content is 58 | // available; please refresh." message in your web app. 59 | console.log('New content is available; please refresh.'); 60 | } else { 61 | // At this point, everything has been precached. 62 | // It's the perfect time to display a 63 | // "Content is cached for offline use." message. 64 | console.log('Content is cached for offline use.'); 65 | } 66 | } 67 | }; 68 | }; 69 | }) 70 | .catch(error => { 71 | console.error('Error during service worker registration:', error); 72 | }); 73 | } 74 | 75 | function checkValidServiceWorker (swUrl) { 76 | // Check if the service worker can be found. If it can't reload the page. 77 | fetch(swUrl) 78 | .then(response => { 79 | // Ensure service worker exists, and that we really are getting a JS file. 80 | if ( 81 | response.status === 404 || 82 | response.headers.get('content-type').indexOf('javascript') === -1 83 | ) { 84 | // No service worker found. Probably a different app. Reload the page. 85 | navigator.serviceWorker.ready.then(registration => { 86 | registration.unregister().then(() => { 87 | window.location.reload(); 88 | }); 89 | }); 90 | } else { 91 | // Service worker found. Proceed as normal. 92 | registerValidSW(swUrl); 93 | } 94 | }) 95 | .catch(() => { 96 | console.log( 97 | 'No internet connection found. App is running in offline mode.' 98 | ); 99 | }); 100 | } 101 | 102 | export function unregister () { 103 | if ('serviceWorker' in navigator) { 104 | navigator.serviceWorker.ready.then(registration => { 105 | registration.unregister(); 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /server-rendered-spa/WebApplication1/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | bin/ 23 | Bin/ 24 | obj/ 25 | Obj/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | /wwwroot/dist/ 30 | 31 | # MSTest test Results 32 | [Tt]est[Rr]esult*/ 33 | [Bb]uild[Ll]og.* 34 | 35 | # NUNIT 36 | *.VisualState.xml 37 | TestResult.xml 38 | 39 | # Build Results of an ATL Project 40 | [Dd]ebugPS/ 41 | [Rr]eleasePS/ 42 | dlldata.c 43 | 44 | *_i.c 45 | *_p.c 46 | *_i.h 47 | *.ilk 48 | *.meta 49 | *.obj 50 | *.pch 51 | *.pdb 52 | *.pgc 53 | *.pgd 54 | *.rsp 55 | *.sbr 56 | *.tlb 57 | *.tli 58 | *.tlh 59 | *.tmp 60 | *.tmp_proj 61 | *.log 62 | *.vspscc 63 | *.vssscc 64 | .builds 65 | *.pidb 66 | *.svclog 67 | *.scc 68 | 69 | # Chutzpah Test files 70 | _Chutzpah* 71 | 72 | # Visual C++ cache files 73 | ipch/ 74 | *.aps 75 | *.ncb 76 | *.opendb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | *.sap 86 | 87 | # TFS 2012 Local Workspace 88 | $tf/ 89 | 90 | # Guidance Automation Toolkit 91 | *.gpState 92 | 93 | # ReSharper is a .NET coding add-in 94 | _ReSharper*/ 95 | *.[Rr]e[Ss]harper 96 | *.DotSettings.user 97 | 98 | # JustCode is a .NET coding add-in 99 | .JustCode 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | _NCrunch_* 109 | .*crunch*.local.xml 110 | nCrunchTemp_* 111 | 112 | # MightyMoose 113 | *.mm.* 114 | AutoTest.Net/ 115 | 116 | # Web workbench (sass) 117 | .sass-cache/ 118 | 119 | # Installshield output folder 120 | [Ee]xpress/ 121 | 122 | # DocProject is a documentation generator add-in 123 | DocProject/buildhelp/ 124 | DocProject/Help/*.HxT 125 | DocProject/Help/*.HxC 126 | DocProject/Help/*.hhc 127 | DocProject/Help/*.hhk 128 | DocProject/Help/*.hhp 129 | DocProject/Help/Html2 130 | DocProject/Help/html 131 | 132 | # Click-Once directory 133 | publish/ 134 | 135 | # Publish Web Output 136 | *.[Pp]ublish.xml 137 | *.azurePubxml 138 | # TODO: Comment the next line if you want to checkin your web deploy settings 139 | # but database connection strings (with potential passwords) will be unencrypted 140 | *.pubxml 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Microsoft Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Microsoft Azure Emulator 157 | ecf/ 158 | rcf/ 159 | 160 | # Microsoft Azure ApplicationInsights config file 161 | ApplicationInsights.config 162 | 163 | # Windows Store app package directory 164 | AppPackages/ 165 | BundleArtifacts/ 166 | 167 | # Visual Studio cache files 168 | # files ending in .cache can be ignored 169 | *.[Cc]ache 170 | # but keep track of directories ending in .cache 171 | !*.[Cc]ache/ 172 | 173 | # Others 174 | ClientBin/ 175 | ~$* 176 | *~ 177 | *.dbmdl 178 | *.dbproj.schemaview 179 | *.pfx 180 | *.publishsettings 181 | orleans.codegen.cs 182 | 183 | /node_modules 184 | 185 | # RIA/Silverlight projects 186 | Generated_Code/ 187 | 188 | # Backup & report files from converting an old project file 189 | # to a newer Visual Studio version. Backup files are not needed, 190 | # because we have git ;-) 191 | _UpgradeReport_Files/ 192 | Backup*/ 193 | UpgradeLog*.XML 194 | UpgradeLog*.htm 195 | 196 | # SQL Server files 197 | *.mdf 198 | *.ldf 199 | 200 | # Business Intelligence projects 201 | *.rdl.data 202 | *.bim.layout 203 | *.bim_*.settings 204 | 205 | # Microsoft Fakes 206 | FakesAssemblies/ 207 | 208 | # GhostDoc plugin setting file 209 | *.GhostDoc.xml 210 | 211 | # Node.js Tools for Visual Studio 212 | .ntvs_analysis.dat 213 | 214 | # Visual Studio 6 build log 215 | *.plg 216 | 217 | # Visual Studio 6 workspace options file 218 | *.opt 219 | 220 | # Visual Studio LightSwitch build output 221 | **/*.HTMLClient/GeneratedArtifacts 222 | **/*.DesktopClient/GeneratedArtifacts 223 | **/*.DesktopClient/ModelManifest.xml 224 | **/*.Server/GeneratedArtifacts 225 | **/*.Server/ModelManifest.xml 226 | _Pvt_Extensions 227 | 228 | # Paket dependency manager 229 | .paket/paket.exe 230 | 231 | # FAKE - F# Make 232 | .fake/ 233 | -------------------------------------------------------------------------------- /0-CLIs/vueapp/public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /0-Dockerfiles-for-each/vueapp/public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /1-container-1-domain/vueapp/public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /2-containers-1-domain/vueapp/public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | --------------------------------------------------------------------------------