返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Asp-Net-Core开发笔记

Asp-Net-Core Development Notes: Framework-Dependent Deployment Paired with Docker

Previously, I wrote an article about deploying AspNetCore applications using Docker. This approach is very convenient when combined with CICD. After the build, you push the image to a private DockerHub, and on the production server, you can pull the image and run it directly. However, sometimes a more traditional deployment method is needed, such as packaging the executable locally and then placing it directly on the server to run. Once this method is configured, each update only requires re-publishing locally and then uploading the executable.

曦远 (DealiAxy)约 13 分钟
目录7 个章节

Preface

Previously, I wrote an article about deploying an AspNetCore application using Docker. This method, combined with CICD, is very convenient—after building, you push to a private DockerHub, and on the production server, you simply pull the image and run it directly.

However, sometimes a more traditional deployment method is needed, such as packaging an executable locally and then placing it directly on the server to execute.

There are two ways to package an executable in .NetCore:

  • Self-contained executable - Does not depend on any runtime environment; it can be started directly upon execution.
  • Framework-dependent - Requires the corresponding version of the dotnet-runtime to be installed first to run.

While the former is convenient, the packaged file size is relatively large. It is said that there will be optimizations in .NET 8, but we’ll deal with that later. This article records the second method, framework-dependent, combined with Docker deployment, so there is no need to install the runtime on the server.

(PS: It feels a bit like Java deployment)

After configuring this method, each update only requires re-publishing locally, uploading the executable, and overwriting the version on the server. It’s very convenient~

Do Not Generate PDB

Each build generates a bunch of PDB debug files, but we don't need these files during deployment. You can disable them by configuring the .csproj file.

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
  <DebugType>none</DebugType>
  <DebugSymbols>false</DebugSymbols>
</PropertyGroup>

A better approach is to create a common.props file in the solution directory, place the above configuration in this file, and then have each .csproj file reference it. The specific path may vary depending on your actual situation.

<Import Project="../../common.props" />

Packaging

Use the following command to package

dotnet publish -f net7.0 -c Release -p:PublishSingleFile=true

After packaging, it generates an executable file that needs to depend on a runtime to run. Next, prepare the Docker configuration.

dockerfile

The official Dockerfile includes the entire workflow from source code building to deployment. Here we only need base and final, which means placing the executable into Microsoft's base image to run.

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM base AS final
WORKDIR /app
COPY . .
ENTRYPOINT ["./AIHub.Blazor"]

docker-compose

If you don't want to type a bunch of docker commands every time, or prefer not to write bash scripts, docker-compose is the best choice. It also makes it very convenient to use with other container orchestration tools.

version: '3.6'

services:
  web:
    image: ${DOCKER_REGISTRY-}web
    container_name: aihub
    restart: always
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://+:80
    build:
      context: .
    volumes:
      - .:/app
    ports:
      - "12001:80"
    networks:
      - default
      - swag

networks:
  swag:
    name: swag
    external: true
  default:
    name: aihub

Additional notes:

  • The ports section maps port 80 inside the container.
  • I am using swag to provide the web service, so technically, there's no need to use ports for port mapping.
  • I will later try using candy / traefik to replace nginx (this project does not use nginx; it uses kestrel directly).

Start!

Start using the command line!

docker compose up

If ports are not mapped, you will also need to configure a reverse proxy.

Swag Configuration

Here's the configuration

/path/to/swag/config/nginx/proxy-confs/aihub.subdomain.conf

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name aihub.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for ldap auth, fill in ldap details in ldap.conf
    #include /config/nginx/ldap.conf;

    # enable for Authelia
    #include /config/nginx/authelia-server.conf;

    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable the next two lines for ldap auth
        #auth_request /auth;
        #error_page 401 =200 /ldaplogin;

        # enable for Authelia
        #include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;

        set $upstream_app aihub;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

        proxy_hide_header X-Frame-Options; # Possibly not needed after Portainer 1.20.0
    }
}

_EOF_

Asp-Net-Core Development Notes: Framework-Dependent Deployment Paired with Docker

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…

Asp-Net-Core Development Notes: Framework-Dependent Deployment Paired with Docker · StarBlog