Publishing and Hosting Apps Developed in SnapDevelop

    Last Updated: March 2020

    Introduction

    SnapDevelop currently offers three methods to publish your projects:

    • File System
    • Web Deploy
    • Docker

    The following table lists the available publication methods and publication results for all SnapDevelop projects.

    Project Available Publication Method Publication Result
    ASP .NET Core Web API File System Application files created in the target folder ready for deployment.
    Web Deploy Application deployed to the target Web server.
    Docker Application image deployed to the target Docker registry.
    Console App (.NET Core) File System Application files created in the target folder ready for deployment.
    Class Library (.NET Core) File System All library assembly files, including their dependency files, created in the target folder.
    Class Library (.NET Standard) File System All library assembly files, including their dependency files, created in the target folder.
    Shared Project None N/A.
    xUnit Test (.NET Core) File System Application files created in the target folder.

    Publishing a Project to a Local Folder with File System

    Prerequisites:

    • SnapDevelop 2019 installed with the appropriate workloads:

      • Universal C Runtime (CRT)

        Universal CRT is installed by default on Windows 10. On the other supported Windows platforms, you can follow the on-screen instructions to download and install the package when you install SnapDevelop. See Downloading and Installing UCRT.

      • Microsoft .NET Framework 4.6.1 SDK

      • Microsoft .NET Core SDK 2.1.6

      • TypeScript SDK 3.1

        These three prerequisites will be automatically installed if the installer detects that they are not installed on the current machine. If your current machine runs on Windows 7, make sure that Service Pack 1 (KB976932) has already been installed; if your current machine runs on Windows 8.1, make sure that KB 2919355 has already been installed.

    • A project to publish

    Publishing to a Local Folder

    1. In Solution Explorer, right-click the project node and choose Publish (or use the Build > Publish menu item).

    2. On the popup window, select File System, click Start, specify the target location of publication and click Next to continue.

    3. You can check the "Use this connection string at runtime" if that applies to you. Then click Finish.

    4. Check the publication status in the Output window.

    5. Click Run on the toolbar or press Ctrl + F5 to run the application.

    Publishing a Project to IIS with Web Deploy

    Prerequisites

    Before you use Web Deploy to publish an application, some requirements need to be satisfied on the server side and client side respectively.

    Requirements for Server Side

    • Windows Server 2012 or 2016

      Windows Server 2012 or 2016 is recommended. If your operating system is Windows 10, for example, you can use File System, rather than Web Deploy, to publish your project to your local folder.

      Make sure that your Windows installation is up-to-date and includes KB2999226, which can be installed through Windows Update. If you don't have this update installed, you'll see an error like the following when you launch a .NET Core application: The program can't start because api-ms-win-crt-runtime-1-1-0.dll is missing from your computer. Try reinstalling the program to fix this problem.

    • Web Deploy 3.6 or higher

      Download link for Web Deploy: https://www.iis.net/downloads/microsoft/web-deploy (32-bit and 64-bit versions of Web Deploy are available; install according to the version of your operating system)

    • Runtime & Hosting Bundle

      Download link for Runtime & Hosting Bundle: https://dotnet.microsoft.com/download/dotnet-core/2.1 (Runtime 2.1.* | Windows | ASP.NET Core/.NET Core: Runtime & Hosting Bundle)

    • .NET Core Installer

      Download link for .NET Core Installer: https://dotnet.microsoft.com/download/dotnet-core/2.1 (SDK 2.1.* | Windows | .NET Core Installer: x64 | x86; install according to the version of your operating system). Note that .NET SDK 2.1.* needs to be installed when SnapDevelop is not installed on the server side.

    Requirements for Client Side

    • Windows 7/8.1/10

      Make sure that your Windows installation is up-to-date and includes KB2999226, which can be installed through Windows Update. If you don't have this update installed, you'll see an error like the following when you launch a .NET Core application: The program can't start because api-ms-win-crt-runtime-1-1-0.dll is missing from your computer. Try reinstalling the program to fix this problem.

    • Web Deploy 3.6 or higher

      Download link for Web Deploy: https://www.iis.net/downloads/microsoft/web-deploy (32-bit and 64-bit versions of Web Deploy are available; install according to the version of your operating system). Note that versions of Web Deploy must be the same on the server and client sides.

    Configuring Server Side

    Configuring IIS

    To configure IIS, you should:

    1. Launch Server Manager.

    2. Use the Add Roles and Features wizard from the Manage menu or the link in Server Manager. On the Server Roles step, check the boxes for Web Server (IIS) and Management Tools.

    3. On the Features step, check the boxes for .NET Framework 3.5 Features and .NET Framework 4.6 Features.

    4. Confirm the roles and features you select and then click Install to continue.

    5. View the results of the installations. Click Close if the installations are successful.

    Installing and Configuring Web Deploy

    Click the download link (https://www.iis.net/downloads/microsoft/web-deploy) to install Web Deploy. Enable the Web Management Service and Web Deployment Agent Service after Web Deploy is properly installed. To do so, you should:

    1. Launch the desktop application Services.

    2. Locate Web Management Service and Web Deployment Agent Service and, if necessary, right-click any one of them and then select Start.

    Enabling Remote Connections

    To enable remote connections, you should:

    1. Launch IIS Manager, select the name of your computer in the left column, and then double-click Management Service on the right side.

    2. Launch the Management Service. Click Stop first, select Enable remote connections and then click Apply.

    Configuring IIS Users

    There are two ways of user configuration, which are configuration of IIS Manager users and configuration of Windows users. Windows users are granted more permissions for publishing an application.

    Configuring IIS Manager Users

    To configure IIS Manager users, you should:

    1. Double-click IIS Manager Users so that you can go to the IIS Manager Users page.

    2. Add a user and then enter the user name and password.

    3. In IIS Manager, open the server's node in the Connections panel. Right-click the Sites folder. Select Add Website from the context menu.

    4. Provide a Site name and change the Physical path. Provide the Binding configuration and create the website by clicking OK.

    5. Expand the Sites folder. Select the newly created website and then double-click IIS Manager Permissions.

    6. In the IIS Manager Permissions dialog box, click Allow User so that a popup window appears. Choose IIS Manager and then click Select to select a desired user you added previously.

    Configuring Windows Users

    To configure Windows users, you should:

    1. Right-click the Sites folder in the Connections panel. Select Add Website from the contextual menu.

    2. Provide the Site name and change the Physical path. Provide the Binding configuration and create the website by clicking OK.

    3. Expand the Sites folder. Select the newly created website and double-click IIS Manager Permissions.

    4. On the IIS Manager Permissions page, click Allow User so that a popup window appears. Choose Windows and then click Select to continue.

    5. Specify the object type and location and enter the object name to select. Check the object name after you enter it.

    6. Select Basic Settings.

    7. Choose Connect as > Specific user > Set and then enter the user name and password.

    8. View the result of connection test by clicking Test Settings in step 7.

    9. Click OK to continue if the specified user credentials are valid.

    Performing the Publish Operations

    Take the following steps to deploy your application:

    1. Right-click the project you create and then select Publish to launch the publish wizard.

    2. Select Web Deploy and enter the corresponding information (including server IP address, site name, user name and password). Note that the user name can be either the IIS Web Deploy user name or the Windows user name.

    3. Click Validate Connection after the information is entered. Note that a green tick will appear if IIS and Web Deploy users are configured correctly.

    4. Click Save to continue.

    5. Check the configuration information and modify if necessary.

    6. Click Publish to publish your application to a local host or a remote server.

    7. Check the output message to see if the publication succeeds.

    Troubleshooting

    There are some common errors that may appear during server configuration. These errors are listed in the following paragraphs and corresponding solutions are offered.

    1. "the site does not exist" error

    When the plug-in Web Deploy required for publication is to be installed, the Complete setup type must be installed so that SnapDevelop can successfully publish the application. Otherwise, the "the site does not exist" error will be reported since Web deployment agent service is not enabled in the other setup types of Web Deploy.

    Solution:

    Uninstall the current version of Web Deploy and then reinstall the Complete version.

    2. "The Web server is configured to not list the contents of this directory" error

    ​

    Solution:

    Launch IIS -> select your website -> click Directory Browsing -> click Enable on the top right corner of the page.

    3. Issues concerning IIS application pool permission

    There is sometimes the situation where data cannot be available after the publication of an application and the error code 500 is returned. This is due to the fact that the IIS application pool does not have permission to log in to the database.

    Solution 1:

    Change the application pool identifier and select a user who has permission.

    Solution 2:

    Change stdoutLogEnabled="false" to stdoutLogEnabled="true" in the web.config file that appears after the publication.

    4. Error indicating that files are locked when an application is published to a remote site where an application has previously been published

    Solution 1:

    Close down the site and then launch the site after publication.

    Solution 2:

    Check the box for Remove additional files at destination when publishing.

    5. Runtime error 500.30 with .NET Core 2.2d application published to IIS

    Solution:

    Change the method: Change InProcess to OutOfProcess in PropertyGroup in the application configuration file and then add ModelName.

    Error 502.5 may occur after the change of method. To resolve Error 502.5, you can change the .NET path of Web API as an absolute path and restart your computer.

    If Error 502.5 still remains, you can check the event log. If the log indicates that the startup process fails, this error can be caused by the lack of permissions. Change the permissions under the IIS application pool, right-click the website and click Advanced Settings. Choose Identity in Process Model and then check the radio button for the Custom account to enter the local administrator's user name and password.

    Publishing a Project with Docker

    Understanding Docker Basics

    Before you use Docker to publish your projects, you should have mastered the basics of Docker publication.

    Concepts Related to Docker

    You should first familiarize yourself with a variety of Docker-related concepts that will be used in this tutorial.

    Image

    An image is a read-only template that contains instructions for creating a Docker container.

    Container

    A container is an executable instance of an image, and it is used to wrap up an application into its own isolated package. The major difference between an image and a container is that a container contains top readable and writable layers.

    Registry

    A registry is where Docker images are stored. You can have your own private registry, or just use Docker Hub, a public registry that anyone can use. Docker is configured to automatically look for images on Docker Hub.

    When you execute such commends as docker pull or docker run, the required images are pulled from the configured registry. When you execute the docker push command, your image is pushed to the configured registry.

    Docker Engine

    Docker engine is a client-server application, which primarily consists of the following three components:

    • A Command Line Interface (CLI) client.

    • A REST API which specifies interfaces that applications can use to communicate with daemon and instruct it what to do.

    • A server named daemon.

    Docker Daemon

    Docker daemon is a server that continuously runs on your host operating system. It listens for Docker API requests and manages such Docker objects as images and containers. You can connect a Docker client to a Docker daemon on the same computer, or to a Docker daemon on a remote computer.

    Engine API

    The Engine API is an HTTP API served by Docker Engine. It is used by the Docker client to communicate with the Engine. What the Docker client can do can be done with the API.

    Docker Host

    Docker host refers to a computer that runs the Docker engine.

    For detailed information about Docker and its related concepts, please visit Docker’s official website at https://docs.docker.com/engine/docker-overview/.

    Benefits of Docker

    Docker enjoys a variety of advantages over the other deployment modes:

    • Isolation; Dependencies in a container are independent of any other container that may be running and will not affect any installations on your computer.

    • Docker Hub; Docker Hub accommodates a large number of available images that can be pulled very quickly, making the build process fast and simple.

    • Reproducibility; The various specifications of a Docker container are stored in a Dockerfile. All images built from the same Dockerfile will work identically.

    • Security; Isolating the various components of a large application into different containers can have security benefits.

    Common Docker Commands

    The following table lists some common Docker commands that you can run using the Command Prompt tool and explains the meanings of individual commands.

    Command Description
    docker images Views information about images included in Docker.
    docker ps Views information about the running container.
    docker build Builds an image from a Dockerfile.
    docker run Runs a command in a new container.
    docker rmi Removes an image via image name or image ID.
    docker rm Removes a container via container name or container ID.
    docker pull Pulls an image or a repository from a registry.
    docker push Pushes an image or a repository to a registry.
    docker network Manages network configuration.
    docker save Packs an image.
    docker load Loads an image.
    docker-compose build Turns services into images.
    docker-compose up Launches the already available images so that they run as containers.
    docker-compose down Stops and deletes everything created using the docker-compose up command.
    docker inspect network name Inspects network details.
    docker attach Attaches local standard input, output, and error streams to a running container

    Note

    You can view all necessary information about docker image or container if you add ‘-a’ to command ‘docker images’ or ‘docker ps’, and you can forcefully delete anything by adding ‘-f’ to command ‘docker rmi’ or ‘docker rm’. For more information about docker commands, please visit Docker’s official website at https://docs.docker.com/engine/reference/commandline/docker/.

    Publishing a Project with Docker Engine

    When your project is ready for deployment, you can choose to publish the project in a Docker container. To publish with Docker, right-click on the project, select Publish from the context menu, and then select Docker. On the pop-up page, select Start to configure the various settings for Docker publication.

    Preparing for Docker Publication

    Docker supports publication using:

    • Local Docker engine;

    • Remote Docker engine.

    You can select either way to publish your project, depending on whether Docker is installed on your local computer.

    After you have made a decision on the way of publication, you must then decide where you want to publish your project. Currently Docker supports publication to:

    • Docker Hub;

    • Self-hosted registry.

    Once you have made all the decisions, you need to make preparations for publication accordingly.

    Preparing the Operating System
    • Windows 10 (64-bit) with Hyper-V enabled (for local computer);

    • CentOS Linux 7 or later (for remote computer).

    Preparing a Docker Engine

    You can choose to prepare a local Docker engine or a remote Docker engine, depending on whether you want to install Docker Desktop on your local computer.

    Local Docker Engine

    To use a local Docker engine to publish your project, you need to:

    • Sign up for Docker Hub;

    • Download Docker Desktop;

    • Install Docker Desktop on your local computer.

    Signing up for Docker Hub

    Before you can download Docker Desktop, you are required to sign up for Docker Hub first. Go to Docker’s official website (https://www.hub.docker.com) and follow the on-screen instructions to sign up for Docker Hub.

    Downloading Docker Desktop

    After you have successfully signed up for Docker Hub, you can download Docker Desktop at https://www.docker.com/products/docker-desktop.

    Installing Docker Desktop

    When you have downloaded Docker Desktop successfully, you need to install Docker Desktop on your local computer.

    Remote Docker Engine

    If you want to use a remote Docker engine to publish your project, you need to use a remote computer installed with CentOS Linux to:

    • Install Docker;

    • Register for a Docker ID (optional);

    • Enable remote access to Docker;

    • Generate certificates (optional).

    Installing Docker

    Refer to Get Docker Engine – Community for CentOS for instructions on how to install Docker.

    Registering for a Docker ID (Optional)

    If you want to publish your project to Docker Hub, you need to register for a Docker ID. Refer to How do you register for a Docker ID? for instructions on how to register for a Docker ID.

    Enabling Remote Access to Docker

    Refer to How do I enable the remote API for dockerd for instructions on how to enable remote access to Docker.

    Generating Certificates (Optional)

    If you want your Docker to be accessible through the network in a safe manner, you can enable TLS by specifying the tlsverify flag and pointing Docker’s tlscacert flag to a trusted CA certificate. Refer to the Create a CA, server and client keys with OpenSSL section in Protect the Docker daemon socket for instructions on how to generate certificates.

    Preparing a Docker Registry

    After you have installed Docker, you must then decide where you want to publish your project. You can publish your project to Docker Hub, or to a self-hosted Docker registry. Publishing a project to Docker Hub may raise security concerns since Docker Hub is a public registry. If you have such concerns, you can publish your project to a private registry URL.

    Self-hosted Docker Registry

    To publish your project to a self-hosted Docker registry, you need to:

    • Pull a Docker registry from Docker Hub;

    • Start the Docker registry;

    • Configure Docker daemon;

    • Configure user name and password for connection to registry.

    Pulling Docker Registry

    You can use the docker pull or docker run command to pull a registry from Docker Hub, or to load a registry if the registry already exists on your computer.

    Run the following command to pull a registry from Docker Hub:

    docker pull registry
    

    Run the following command to load a registry from a local computer:

    docker load –i
    

    For example, docker load –i\\172.16.0.95\share\docker\linux\registry.rar

    Starting Docker Registry

    When a registry is successfully pulled or loaded, you need to run the following command to start the registry.

    docker run -d -v /registry:/home/docker-registry -p 5000:5000 --restart=always --privileged=true --name registry registry:latest
    

    Configuring Docker Daemon

    You need to configure Docker daemon differently, depending on the operating system of the computer installed with Docker.

    Configuring Docker Daemon (for Windows 10)

    To configure Docker daemon, you need to:

    1. Run Docker Desktop.

    2. Click the Docker icon at the bottom right corner of the desktop and then select Settings.

    3. Select Daemon on the Settings page.

    4. Configure Insecure Registries.

      Here, you need to configure the registry URL to which you want to publish your project. For example, you can enter registry.hub.docker.com if you want to publish your project to Docker Hub. For security considerations, it is recommended that you publish your project to a private registry URL. When you pulled a registry to a computer by running the docker pull registry command, the registry URL is the IP of the computer (e.g., 172.16.100.73:5000).

    5. Select Apply to validate daemon configurations.

    Configuring Docker Daemon (for CentOS Linux)

    Refer to the Configure the Docker daemon section of Configure and troubleshoot the Docker daemon for instructions on how to configure the Docker daemon.

    Configuring Docker Proxy

    You need to configure Docker proxy because Internet connection is required when you pull images from or push images to the registry, and when you download the NuGet packages on which your project depends.

    Note

    When your project is built inside the Docker container, Docker needs to download the dependencies of your project, even if these dependencies already exist on your local computer.

    Configuring Docker Proxy (for Windows 10)

    To configure Docker proxy, you need to:

    1. Run Docker Desktop.

    2. Click the Docker icon at the bottom right corner of the desktop and then select Settings.

    3. Select Proxies on the Settings page.

    4. Configure the Web server proxy.

    5. Select Apply to validate proxy configurations.

    Configuring Docker Daemon (for CentOS Linux)

    Refer to Configure Docker to use a proxy server for instructions on how to configure the Docker proxy.

    Configuring User Name and Password for Connection to Registry

    Refer to the Native basic auth section in Deploy a registry server for instructions on how to configure user name and password for connection to your private registry.

    Docker Hub

    To publish your project to Docker Hub, you need only to configure Docker daemon and Docker proxy.

    Configuring Docker Daemon

    Refer to the Self-hosted Docker Registry section in this tutorial for information about Docker daemon configuration.

    Configuring Docker Proxy

    Refer to the Self-hosted Docker Registry section in this tutorial for instructions on how to configure Docker proxy.

    Connecting to a Docker Daemon

    You can connect to a local Docker daemon or to a remote Docker daemon, depending on whether your local computer is installed with Docker Desktop.

    Local Docker

    If your local computer is installed with Docker Desktop, you can select the Local Docker radio button to publish your project with the local Docker engine.

    Note

    Make sure your local Docker Desktop is running before you can continue to configure the various Docker settings.

    Remote Docker

    If your local computer is not installed with Docker Desktop, you can select the Remote Docker radio button to publish your project with a remote Docker engine.

    Likewise, you should make sure the remote Docker is running. In addition, you need to provide the following information: engine API URL, and certificates (optional).

    Engine API URL

    The engine API URL refers to the IP of the remote computer installed with Docker.

    Certificates Folder

    Contains the certificates (ca.pem, cert.pem and key.pem) generated in the Remote Docker Engine section for authentication by the remote Docker server.

    Connecting to a Docker Registry

    After you have connected to a Docker daemon, you can continue to configure the Docker connection settings.

    Registry URL

    Enter the registry URL (the IP of the computer that hosts the registry, for example, 172.16.100.73:5000). If you want to publish your project to Docker Hub, you can select the default registry URL (registry.hub.docker.com) from the drop-down list.

    User Name and Password

    Enter the user name and password you have configured in the Self-hosted Docker Registry section . If you use registry.hub.docker.com as the registry URL, you just enter the Docker ID and password you use to sign in.

    After you have provided the registry URL and user name and password, you can click Next to verify whether this connection succeeds. If the connection fails, you will see a message box displaying the error message.

    In this case, you need to re-configure the Docker connection according to the error message.

    If the connection succeeds, you will be able to configure the various Docker settings.

    Configuring Publish Settings

    When you have successfully connected to a Docker registry, you need then to configure the publish settings, including the mode of configuration, target framework, deployment mode, and target runtime.

    Configuration

    Specifies the configuration for building your .NET project. The Debug mode is used for debugging the .NET project step by step, while the Release mode is used for the final build of the Assembly file (.dll or .exe).

    Target Framework

    Specifies the version of the .NET that you want your project to target.

    Deployment Mode

    Framework-dependent deployment is the default deployment option. It means that you can deploy portable code that is ready to run in any compatible environment, provided .NET Core is installed.

    Target Runtime

    There are five different target platforms where the application runs:

    • Portable

    • Win-x86

    • Win-x64

    • Osx-x64

    • Linux-x64

    They are runtime identifiers used by .NET packages to represent platform-specific assets in NuGet packages.

    Configuring Docker Settings

    After you have configured the publish settings, you need to configure the Docker settings, including the image name, custom tag, and container port(s) to be exposed.

    Image Name

    Specifies a name for your image.

    Tag

    Allows you to add a tag for your image to distinguish it from the various other images (if any).

    Expose Ports

    Allows you to specify one or more container ports that can be exposed to be outside world. Note that container ports must be exposed so that they can be used for port mapping, and the exposed container ports will appear in the Container Port dropdown list. It is recommended that you expose port 80.

    Configuring Publish Options

    Deleting Intermediate Images

    Removes the cached images that can be used for subsequent builds. Examples of intermediate images are images named <none>, and useless images (e.g., 172.16.100.18:5000/smm).

    Running the Container after Publishing

    Specifies whether to run the container immediately after you deploy your project to the target registry. If you enable this option, you need then to configure port mapping.

    By default, the published container does not have any port accessible to the outside world. To enable the container to accept incoming connections, you need to select an exposed container port, and specify a host port to which the container port will map.

    • Container port: it is the port you exposed in Expose Ports.

    • Host port: this is the port to be used by the Docker host to access the container. Make sure you specify a port number that has not been assigned to any other service yet.

    Note:

    If you don’t enable the Run the container after publishing option, when you later run the container manually with the command line arguments, make sure you will specify the port mapping as well. The basic command line syntax is as follows:

    docker run -d -p host port:container port --name container name image
    

    For example:

    docker run -d -p 8080:80 --name dockertest 172.16.100.73:5000/dockertest:latest
    

    Executing the Publish Operations

    When you have properly configured the various Docker settings and then click Finish, you will see the Dockerfile in your project in Solution Explorer. Dockerfile contains all the commands used by a user to assemble the image.

    The following table presents a brief introduction to the various commands in the Dockerfile.

    Command Description
    FROM The FROM instruction initializes a new build stage and sets the base image for subsequent instructions.
    : Marks the version of an image.
    AS Specifies an alias.
    RUN The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
    COPY The COPY instruction copies new files or directories from “ForDockerTest/ForDockerTest.csproj” and adds them to the filesystem of the container at the path “ForDockerTest/”.
    WORKDIR Sets a working directory for other Dockerfile directives (such as RUN, CMD) and sets up a working directory for running container image instances.
    ENTRYPOINT An ENTRYPOINT instruction allows you to configure a container that will run as an executable.
    EXPOSE The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

    Refer to Dockerfile reference for more information about the commands that may be used in the Dockerfile.

    When you click Finish, the publication process launches immediately. In the Output pane, you can check if the commands in the Dockerfile are being executed correctly. If an error occurs, you can view the error message and then correct the error accordingly. If no error occurs, it is recommended that you do not interrupt the publication process until the publication succeeds.

    If you have enabled the Run the container after publishing option, the Docker host will run the published container, which means that the project will launch on the launchURL configured in the project launchSettings.json file.

    For example, if the launchSettings.json file is as follows:

    The deployed project in the container will run:

    Finally, you can check whether your project is successfully published to the target registry URL.

    Publishing and Hosting an ASP.NET Core Application on Linux

    In this section, we create a Web API application, publish it using the File System method, and then host the app on Linux CentOS7 operating system following these steps:

    • In SnapDevelop, publish the Web API application with middleware configured to support reverse proxy

    • Copy over the Web API application from the local published folder to CentOS server

    • In CentOS, host Web API application on CentOS with reverse proxy (Apache) configured

      For more information on how to set up Apache as a reverse proxy on CentOS 7, you can further read the Microsoft article: Host ASP.NET Core on Linux with Apache.

    Prerequisites

    • SnapDevelop 2019
    • Server running CentOS 7 with a standard sudo user account
    • .NET Core Runtime is installed on CentOS 7 with the following instructions

    Install .NET Core Runtime on CentOS 7

    Before installing .NET Runtime, you need to register the Microsoft key, register the product repository, and install required dependencies. These only need to be done once per machine. Open a terminal and run the following commands:

    # Install repository configuration
    curl https://packages.microsoft.com/config/rhel/7/prod.repo > ./microsoft-prod.repo
    sudo cp ./microsoft-prod.repo /etc/yum.repos.d/
    
    # Install Microsoft's GPG public key
    curl https://packages.microsoft.com/keys/microsoft.asc > ./microsoft.asc
    sudo rpm --import ./microsoft.asc
    

    Install the latest available updates for the product, then install the .NET Runtime.

    In your terminal, run the following commands:

    # Install the latest available updates for the product
    sudo yum update
    
    # Install the ASP.NET Core 2.1 runtime
    sudo yum install aspnetcore-runtime-2.1
    

    The previous command will install the .NET Core Runtime Bundle, which includes the .NET Core runtime and the ASP.NET Core 2.1 runtime. To install just the .NET Core runtime, use the dotnet-runtime-2.1 package.

    Publishing an ASP.NET Core Application to Server

    Preparation for the Application

    In SnapDevelop, select File from the menu bar and then choose New > Project. In the dialog box, select C# > .NET Core and then select ASP.NET Core Web API. Then, fill in the project information to create a .NET Core project named WebAPI1 by clicking OK.

    Some configurations for reverse proxy and Kestrel server need to be made before publishing.

    Configuration for Forwarded Headers Middleware

    Because requests are forwarded by reverse proxy, use the Forwarded Headers Middleware from the Microsoft.AspNetCore.HttpOverrides package. The middleware updates the Request.Scheme, using the X-Forwarded-Proto header, so that redirect URIs and other security policies work correctly.

    Any component that depends on the scheme, such as authentication, link generation, redirects, and geolocation, must be placed after invoking the Forwarded Headers Middleware. As a general rule, Forwarded Headers Middleware should run before other middleware except for diagnostics and error handling middleware. This running order ensures that the middleware relying on forwarded headers information can consume the header values for processing.

    Invoke the UseForwardedHeaders method in Startup.Configure before calling UseAuthentication or similar authentication scheme middleware. Configure the middleware to forward the X-Forwarded-For and X-Forwarded-Proto headers:

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });
    
    app.UseAuthentication();
    

    If no ForwardedHeadersOptions are specified to the middleware, the default forwarded headers are None.

    Proxies running on loopback addresses (127.0.0.0/8, [::1]), including the standard localhost address (127.0.0.1), are trusted by default. For other trusted proxies or networks within the organization handling requests between the Internet and the web server, add them to the list of KnownProxies or KnownNetworks as options in ForwardedHeadersOptions. The following example adds a trusted proxy server at IP address 10.0.0.100 to the KnownProxies of Forwarded Headers Middleware in Startup.ConfigureServices:

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
    });
    

    For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

    Configuration for Secure (HTTPS) Local Connections

    It is important for the application to make secure connections (HTTPS), configure the application to use a certificate for your development using one of the following approaches:

    • Replace the default certificate from configuration (Recommended)
    • KestrelServerOptions.ConfigureHttpsDefaults

    The configuration for the application to listen to the URLs is in applicationUrl property in the Properties/launchSettings.json file, for example, https://localhost:5001;http://localhost:5000.

    The app runs locally, so it is optional to configure the web server (Kestrel) with secure (HTTPS) local connections. You can remove https://localhost:5001 (if present) from the configuration.

    Publishing the Application to a Local Folder

    • In Solution Explorer, right-click the project and choose Publish.

    • On the popup window, select File System.

    • Specify the target location of publication.

    • Go to Settings tab, change Target Runtime to linux-64.

      Note that the application is configured for a framework-dependent deployment by default.

    • Click Save to continue.

    • Click Publish, then check the publication status in the Output window.

    Copying the Application to the Server

    Once the Web API application is published, copy the application from the published folder to the CentOS server using a tool that integrates into the organization's workflow (for example, SCP, SFTP). It's common to locate web applications under the var directory (for example, var/www/WebAPI1).

    Hosting ASP.NET Core on CentOS with Apache

    Configuring a Proxy Server

    A reverse proxy is a common setup for serving dynamic web applications. The reverse proxy terminates the HTTP request and forwards it to the Web API application. In this example, Apache is configured as a reverse proxy, and Kestrel serves the Web API application. Apache forwards client requests to the Web API application running on Kestrel instead of fulfilling requests itself.

    Installing Apache

    Update CentOS packages to the latest stable versions:

    sudo yum update -y
    

    Install the Apache web server on CentOS with a single yum command:

    sudo yum -y install httpd mod_ssl
    

    To verify where Apache is installed, run whereis httpd from a command prompt.

    Configuring Apache

    Open the /etc/httpd/conf/httpd.conf file and set the ServerName directive globally:

    sudo nano /etc/httpd/conf/httpd.conf
    
    # Set ServerName in this configuration file
    ServerName www.example.com:80
    

    The configuration files for Apache are located in the /etc/httpd/conf.d/ directory. Any file with the .conf extension is processed in alphabetical order in addition to the module configuration files in /etc/httpd/conf.modules.d/, which contains all the necessary configuration files to load modules.

    Create a configuration file:

    sudo nano /etc/httpd/conf.d/WebAPI1.conf
    

    An example of configuration files for the application:

    <VirtualHost *:*>
        RequestHeader set "X-Forwarded-Proto" expr=$scheme
    </VirtualHost>
    
    <VirtualHost *:80>
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
        ServerName www.example.com
        ServerAlias *.example.com
        ErrorLog /var/log/httpd/WebAPI1-error.log
        CustomLog /var/log/httpd/WebAPI1-access.log common
    </VirtualHost>
    

    The VirtualHost block can appear multiple times in one or more files on a server. In the preceding configuration file, Apache accepts public traffic on port 80. The domain www.example.com is being served, and the *.example.com alias resolves to the same domain. See Name-based virtual host support for more information. Requests are proxied at the root to port 5000 of the server at 127.0.0.1. For bi-directional communication, ProxyPass and ProxyPassReverse are required. To change Kestrel's IP/port, see Kestrel: Endpoint configuration.

    Warning: Failure to specify a proper ServerName directive in the VirtualHost block exposes your application to security vulnerabilities. Subdomain wildcard binding (for example, *.example.com) doesn't pose this security risk if you control the entire parent domain (as opposed to .com, which is vulnerable). See rfc7230 section-5.4 for more information.

    Logging can be configured per VirtualHost using ErrorLog and CustomLog directives. ErrorLog is the location where the server logs errors, and CustomLog sets the filename and format of log file. In this case, this is where request information is logged. There's one line for each request.

    Save the file and test the configuration. If everything passes, the response should be Syntax [OK].

    sudo service httpd configtest
    

    Restart Apache:

    sudo systemctl restart httpd
    sudo systemctl enable httpd
    

    Monitoring the Application

    Apache is now setup to forward requests made to http://localhost:80 to the Web API application running on Kestrel at http://127.0.0.1:5000. However, Apache isn't set up to manage the Kestrel process. Use systemd and create a service file to start and monitor the underlying web application. systemd is an init system that provides many powerful features for starting, stopping, and managing processes.

    Creating the Service File

    Create the service definition file:

    sudo nano /etc/systemd/system/kestrel-webapi1.service
    

    An example of service files for the application:

    [Unit]
    Description=Example .NET Web API application running on CentOS 7
    
    [Service]
    WorkingDirectory=/var/www/WebAPI1
    ExecStart=/usr/share/dotnet /var/www/WebAPI1/WebAPI1.dll
    Restart=always
    # Restart service after 10 seconds if the dotnet service crashes:
    RestartSec=10
    KillSignal=SIGINT
    SyslogIdentifier=dotnet-example
    User=apache
    Environment=ASPNETCORE_ENVIRONMENT=Production 
    
    [Install]
    WantedBy=multi-user.target
    

    If the user apache isn't used by the configuration, the user must be created first and given proper ownership of the files.

    Use TimeoutStopSec to configure the duration of time to wait for the application to shut down after it receives the initial interrupt signal. If the application doesn't shut down in this period, SIGKILL is issued to terminate the application. Provide the value as unitless seconds (for example, 150), a time span value (for example, 2min 30s), or infinity to disable the timeout. TimeoutStopSec defaults to the value of DefaultTimeoutStopSec in the manager configuration file (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). The default timeout for most distributions is 90 seconds.

    # The default value is 90 seconds for most distributions.
    TimeoutStopSec=90
    

    Save the file and enable the service:

    sudo systemctl enable kestrel-webapi1.service
    

    Start the service and verify that it's running:

    # Start the service
    sudo systemctl start kestrel-webapi1.service
    
    # Verify the service
    sudo systemctl status kestrel-webapi1.service
    
    ● kestrel-webapi1.service - Example .NET Web API application running on CentOS 7
       Loaded: loaded (/etc/systemd/system/kestrel-webapi1.service; enabled; vendor preset: disabled)
       Active: active (running) since Tue 2019-08-06 13:46:27 CST; 5s ago
     Main PID: 46668 (dotnet)
        Tasks: 16
       CGroup: /system.slice/kestrel-webapi1.service
               └─46668 /usr/share/dotnet/dotnet /var/www/WebAPI1/WebAPI1.dll
    

    With the reverse proxy configured and Kestrel managed through systemd, the web application is fully configured and can be accessed from a browser on a local machine at http://localhost/api/sample/load. Inspecting the response headers, the Server header indicates that the Web API application is served by Kestrel:

    HTTP/1.1 200 OK
    Date: Tue, 06 Aug 2019 05:52:17 GMT
    Server: Kestrel
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    
    Viewing Logs

    Since the web application using Kestrel is managed using systemd, events and processes are logged to a centralized journal. However, this journal includes all of the entries for services and processes managed by systemd. View the specific items of kestrel-webapi1.service with the following command:

    sudo journalctl -fu kestrel-webapi1.service
    

    For time filtering, specify time options with the command. For example, use --since today to filter for the current day or --until 1 hour ago to see the previous hour's entries. For more information, see man page for journalctl.

    sudo journalctl -fu kestrel-webapi1.service --since "2019-08-06" --until "2019-08-06 23:00"
    

    Configuring the Reverse Proxy for Secure (HTTPS) Client Connections

    To configure Apache for HTTPS, the mod_ssl module is used. When the httpd module was installed, the mod_ssl module was also installed. If it wasn't installed, use yum to add it to the configuration.

    sudo yum install mod_ssl
    

    To enforce HTTPS, install the mod_rewrite module to enable URL rewriting:

    sudo yum install mod_rewrite
    

    Modify the /etc/httpd/conf.d/WebAPI1.conf file to enable URL rewriting and secure communication on port 443:

    <VirtualHost *:*>
        RequestHeader set "X-Forwarded-Proto" expr=$scheme
    </VirtualHost>
    
    <VirtualHost *:80>
        RewriteEngine On
        RewriteCond %{HTTPS} !=on
        RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
    </VirtualHost>
    
    <VirtualHost *:443>
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:5000/
        ProxyPassReverse / http://127.0.0.1:5000/
        ErrorLog /var/log/httpd/WebAPI1-error.log
        CustomLog /var/log/httpd/WebAPI1-access.log common
        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
        SSLCertificateFile /etc/pki/tls/certs/localhost.crt
        SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    </VirtualHost>
    

    This example is using a locally-generated certificate. SSLCertificateFile should be the primary certificate file for the domain name. SSLCertificateKeyFile should be the key file generated when CSR is created. SSLCertificateChainFile should be the intermediate certificate file (if present) that was supplied by the certificate authority.

    Save the file and test the configuration:

    sudo service httpd configtest
    

    Restart Apache:

    sudo systemctl restart httpd
    

    After HTTPS is fully configured, the web application can be accessed from a browser on a local machine at https://localhost/api/sample/load. Please pay attention here, it's https://....

    Attribution

    The content of this section incorporates some materials from “Host ASP.NET Core on Linux with Apache“ by Shayne Boyer licensed under CC BY 2.0.

    Back to top Generated by Appeon