diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index df43ed7..2b8887f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,9 +3,10 @@ # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- -FROM mcr.microsoft.com/dotnet/core/sdk:2.2 +ARG DOTNETCORE_VESRION=3.0 +FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNETCORE_VESRION} -## This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux, +# This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux, # this user's GID/UID must match your local user UID/GID to avoid permission issues # with bind mounts. Update USER_UID / USER_GID if yours is not 1000. See # https://aka.ms/vscode-remote/containers/non-root-user for details. @@ -15,7 +16,8 @@ ARG USER_GID=$USER_UID # [Optional] Version of Node.js to install. ARG INSTALL_NODE="true" -ARG NODE_MAJOR_VERSION="10" +ARG NODE_VERSION="lts/*" +ENV NVM_DIR=/home/vscode/.nvm # [Optional] Install the Azure CLI ARG INSTALL_AZURE_CLI="false" @@ -28,22 +30,7 @@ RUN apt-get update \ && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \ # # Verify git, process tools, lsb-release (common in install instructions for CLIs) installed - && apt-get -y install git iproute2 procps lsb-release \ - # - # [Optional] Install Node.js for ASP.NET Core Web Applicationss - && if [ "$INSTALL_NODE" = "true" ]; then \ - curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR_VERSION.x | bash - \ - && apt-get install -y nodejs; \ - fi \ - # - # [Optional] Install the Azure CLI - && if [ "$INSTALL_AZURE_CLI" = "true" ]; then \ - apt-get install -y apt-transport-https curl gnupg2 lsb-release \ - && echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list \ - && curl -sL https://packages.microsoft.com/keys/microsoft.asc | apt-key add - 2>/dev/null \ - && apt-get update \ - && apt-get install -y azure-cli; \ - fi \ + && apt-get -y install git iproute2 procps apt-transport-https gnupg2 curl lsb-release \ # # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. && groupadd --gid $USER_GID $USERNAME \ @@ -53,10 +40,40 @@ RUN apt-get update \ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ && chmod 0440 /etc/sudoers.d/$USERNAME \ # + # [Optional] Install Node.js for ASP.NET Core Web Applicationss + && if [ "$INSTALL_NODE" = "true" ]; then \ + # + # Install nvm and Node + mkdir ${NVM_DIR} \ + && curl -so- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash 2>&1 \ + && chown -R vscode:vscode ${NVM_DIR} \ + && /bin/bash -c "source $NVM_DIR/nvm.sh \ + && nvm install ${NODE_VERSION} \ + && nvm alias default ${NODE_VERSION}" 2>&1 \ + && INIT_STRING='[ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh" && [ -s "$NVM_DIR/bash_completion" ] && \\. "$NVM_DIR/bash_completion"' \ + && echo $INIT_STRING >> /home/vscode/.bashrc \ + && echo $INIT_STRING >> /home/vscode/.zshrc \ + && echo $INIT_STRING >> /root/.zshrc \ + # + # Install yarn + && curl -sS https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/pubkey.gpg | apt-key add - 2>/dev/null \ + && echo "deb https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ + && apt-get update \ + && apt-get -y install --no-install-recommends yarn; \ + fi \ + # + # [Optional] Install the Azure CLI + && if [ "$INSTALL_AZURE_CLI" = "true" ]; then \ + echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list \ + && curl -sL https://packages.microsoft.com/keys/microsoft.asc | apt-key add - 2>/dev/null \ + && apt-get update \ + && apt-get install -y azure-cli; \ + fi \ + # # Clean up && apt-get autoremove -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* # Switch back to dialog for any ad-hoc use of apt-get -ENV DEBIAN_FRONTEND= +ENV DEBIAN_FRONTEND= \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index deeddcc..c6c21d4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,11 +3,7 @@ "dockerFile": "Dockerfile", // Specifies ports to publish - "appPort": [9000], - - // Comment out the next line to run as root instead. Linux users, - // update Dockerfile with your user's UID/GID if not 1000. - "runArgs": [ "-u", "vscode" ], + "appPort": [5000, 5001], // Use 'settings' to set *default* container specific settings.json values on container create. // You can edit these settings after create using File > Preferences > Settings > Remote. @@ -18,6 +14,29 @@ // Uncomment the next line to run commands after the container is created. // "postCreateCommand": "dotnet restore", + "runArgs": [ + // Comment out the next line to run as root instead. Linux users, + // update Dockerfile with your user's UID/GID if not 1000. + "-u", "vscode", + + // You can enable HTTPS in ASP.NET by mounting a local dev cert exported the dotnet CLI locally: + // Windows PowerShell: + // dotnet dev-certs https --trust; dotnet dev-certs https -ep "$env:USERPROFILE/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" + // macOS/Linux terminal: + // dotnet dev-certs https --trust && dotnet dev-certs https -ep "${HOME}/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" + // + // After running the command above, uncomment the lines below and open / rebuild the container. + // "-v", "${env:HOME}${env:USERPROFILE}/.aspnet/https:/home/vscode/.aspnet/https", + // "-e", "ASPNETCORE_Kestrel__Endpoints__Https__Url=https://*:5001", + // "-e", "ASPNETCORE_Kestrel__Certificates__Default__Password=SecurePwdGoesHere", + // "-e", "ASPNETCORE_Kestrel__Certificates__Default__Path=/home/vscode/.aspnet/https/aspnetapp.pfx", + + // Override the default HTTP endpoint - need to listen to '*' for appPort to work + "-e", "ASPNETCORE_Kestrel__Endpoints__Http__Url=http://*:5000" + ], + + + // Add the IDs of extensions you want installed when the container is created in the array below. "extensions": [ "ms-vscode.csharp" ] diff --git a/.vscode/launch.json b/.vscode/launch.json index 63dd51c..e67915c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,15 +9,16 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/netcoreapp2.2/aspnetapp.dll", + "program": "${workspaceFolder}/bin/Debug/netcoreapp3.0/aspnetapp.dll", "args": [], "cwd": "${workspaceFolder}", + "console": "internalConsole", "stopAtEntry": false, - "launchBrowser": { - "enabled": false - }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" } } ] diff --git a/Program.cs b/Program.cs index 5138946..560276e 100644 --- a/Program.cs +++ b/Program.cs @@ -3,30 +3,27 @@ * Licensed under the MIT License. See LICENSE in the project root for license information. *---------------------------------------------------------------------------------------*/ -using System; -using System.Linq; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Builder; -using Newtonsoft.Json; using Microsoft.AspNetCore.Http; -using System.IO; namespace aspnetapp { public class Program { public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseKestrel() - .UseUrls("http://0.0.0.0:9000") - .Configure(app => app.Run(async context => { - await context.Response.WriteAsync("Hello remote world from ASP.NET Core!"); - })) - .Build(); - - host.Run(); + { + var host = Host.CreateDefaultBuilder() + .ConfigureWebHostDefaults(webBuilder => { + webBuilder.Configure(app => { + app.UseHttpsRedirection() + .Run(async context => { + await context.Response.WriteAsync("Hello remote world from ASP.NET Core!"); + }); + }); + }); + host.Build().Run(); } - } } \ No newline at end of file diff --git a/README.md b/README.md index 557c105..6fc9e53 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,11 @@ Follow these steps to open this sample in a container: 2. **Linux users:** Update `USER_UID` and `USER_GID` in `.devcontainer/Dockerfile` with your user UID/GID if not 1000 to avoid creating files as root. -3. If you're not yet in a development container: +3. If you want to enable **HTTPS**, see [enabling HTTPS](#enabling-https) to reuse your local development cert in the container. + +4. This container also runs as a non-root user with sudo access by default. Comment out `"-u", "vscode"` in the `runArgs` property array in `.devcontainer/devcontainer.json` if you'd prefer to run as root. + +5. If you're not yet in a development container: - Clone this repository. - Press F1 and select the **Remote-Containers: Open Folder in Container...** command. - Select the cloned copy of this folder, wait for the container to start, and try things out! @@ -21,8 +25,6 @@ Follow these steps to open this sample in a container: One you have this sample opened in a container, you'll be able to work with it like you would locally. -> **Note:** This container runs as a non-root user with sudo access by default. Comment out `"runArgs": ["-u", "vscode"]` in `.devcontainer/devcontainer.json` if you'd prefer to run as root. - Some things to try: 1. **Restore Packages:** When notified by the C# extension to install packages, click Restore to trigger the process from inside the container! @@ -35,16 +37,52 @@ Some things to try: - Add a breakpoint (e.g. on line 21). - Press F5 to launch the app in the container. - Once the breakpoint is hit, try hovering over variables, examining locals, and more. - - Continue, then open a local browser and go to `http://localhost:9000` and note you can connect to the server in the container. + - Continue, then open a local browser and go to `http://localhost:5000` and note you can connect to the server in the container. 5. **Forward another port:** - Stop debugging and remove the breakpoint. - - Open `Program.cs` - - Change the server port to 5000. (`.UseUrls("http://0.0.0.0:5000")`) + - Open `launch.json` + - Add `"ASPNETCORE_Kestrel__Endpoints__Http__Url": "http://*:9000",` to the `"env"` property array. + + > **Note:** By default, ASP.NET Core only listens to localhost. The challenge is that ASP.NET Core thinks that localhost is inside the container. If you use the `appPort` property in `.devcontainer/devcontainer.json`, the port is [published](https://docs.docker.com/config/containers/container-networking/#published-ports) rather than forwarded. Therefore, listening to `*` or `0.0.0.0` is required for the `appPort` property to function. + > + > This container solves that problem by setting the environment variable `ASPNETCORE_Kestrel__Endpoints__Http__Url` to `http://*:5000` in `.devcontainer/devcontainer.json` to override the application config. Using an environment variable that is only present in the container allows you to keep the application config using `localhost` when running locally - which is why we'll override the variable here. + - Press F5 to launch the app in the container. - Press F1 and run the **Remote-Containers: Forward Port from Container...** command. - - Select port 5000. + - Select port 9000. - Click "Open Browser" in the notification that appears to access the web app on this new port. +### Enabling HTTPS + +To enable HTTPS for this sample, you can mount an exported copy of your local dev certificate. First, export it using the following command: + +**Windows PowerShell** + +```powershell +dotnet dev-certs https --trust; dotnet dev-certs https -ep "$env:USERPROFILE/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" +``` + +**macOS/Linux terminal** + +```powershell +dotnet dev-certs https --trust && dotnet dev-certs https -ep "${HOME}/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere" +``` + +Next, update the `runArgs` array in `.devcontainer/devcontainer.json` as follows: + +```json +"runArgs": [ + "-u", "vscode", + "-e", "ASPNETCORE_Kestrel__Endpoints__Http__Url=http://*:5000", + "-e", "ASPNETCORE_Kestrel__Endpoints__Https__Url=https://*:5001", + "-v", "${env:HOME}${env:USERPROFILE}/.aspnet/https:/home/vscode/.aspnet/https", + "-e", "ASPNETCORE_Kestrel__Certificates__Default__Password=SecurePwdGoesHere", + "-e", "ASPNETCORE_Kestrel__Certificates__Default__Path=/home/vscode/.aspnet/https/aspnetapp.pfx" +] +``` + +Finally, rebuild the container using the **Remote-Containers: Rebuild Container** command from the Command Palette (F1) if you've already opened your folder in a container so the settings take effect. + ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..8f41d8b --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} \ No newline at end of file diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..81ff877 --- /dev/null +++ b/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/aspnetapp.csproj b/aspnetapp.csproj index 58efb6a..41d16da 100644 --- a/aspnetapp.csproj +++ b/aspnetapp.csproj @@ -1,7 +1,7 @@ - netcoreapp2.2 + netcoreapp3.0 31051026529000467138