这个文章的题目起的比较长,我想实现这样一个产品:

前端是微信小程序,后端是基于docker运行的asp.net core webapi。webapi通过nginx实现的反向代理接入,nginx同样基于docker来运行。开撸!

准备工作

1、微信小程序注册账号

微信小程序注册有一个限制,一个邮箱只能注册一个小程序。我用的qq邮箱,因为之前使用qq邮箱的默认账号注册过一个,但是qq邮箱可以针对同一个邮箱设置不同的账户(好像是三个),所以可以先设置一个额外的账号,然后通过这个账号来注册小程序

2、购买服务器

你要建立api必须得有一台服务器,我从腾讯云申请了一台免费的(3个月)2核心4G的服务器。

3、申请域名

申请域名是有一个原因的,你可以参考看看是不是否和你的条件,否则,你可以跳过这步。我的原因是首先小程序如果要接入api这个api必须是一个https的连接,https的连接涉及到ssl/tls证书,我采用let's encrypt来获取证书。但是let's encrypt不允许使用ip地址来获取证书,需要域名。所以,我又申请了一个域名。域名申请在腾讯云官网完成,花了45(原价55,10块的代金券)块钱申请了一个域名,有效期一年。但是需要注意你申请域名的时候必须得先有一台服务器。服务器用于一个公网ip。

4、申请ssl/tls证书

当你完成购买服务器和申请域名的步骤后,可以开始申请证书了。我的证书是通过let's encrypt来申请的,let's encrypt发布了一个certbot的工具,通过certbot来对证书进行获取和管理。certbot的网址是https://certbot.eff.org/

当然还有很多其他的工具,比如certbot-auto和acme.sh等,这里不做过多介绍,百度吧。

首先是安装certbot,我是用的是centos7,certbot是包含在epel(extra packges for enterprise linux)中的,所以需要安装epel包源,另外,需要python的运行环境。在centos7中,这些默认都有,所以,我直接运行

sudo yum install certbot 

就完成了安装。

关于epel的官网在这里:https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F 你可以对照你的操作系统来查看如何安装这个包源。

关于certbot的官网在这里:https://certbot.eff.org/lets-encrypt/centosrhel7-nginx 你可以查看相关文档。

安装好之后就是获取证书的环节了:

certbot certonly

键入上述命令后,根据提示操作,很快就会完成,然后在/etc/letsencrypt/live/you.domain.com下面会有你的证书和证书对应的key证书和key都是pem文件,证书的名字是fullchain.pen,key的名字是privkey.pem.

5、安装docker

docker:https://docs.docker.com/install/

windows开发机上的docker安装过程省略。下面是服务器(centos7.2)的安装步骤

centos安装docker的条件是系统在7以上,并且开通了centos-extras包源,它默认是开启的。从https://wiki.centos.org/AdditionalResources/Repositories上面可以查看centos关于这方面的一些信息。确认完上述信息后,按照一下步骤来完成安装:

  sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2

yum-utils提供了 yum-config-manager 这个工具,而device-mapper-persistent-data 和lvm2对于devicemapper存储驱动程序来说是必须的。然后配置包源:

sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

然后安装docker:

sudo yum install docker-ce docker-ce-cli containerd.io

安装文档在这里:https://docs.docker.com/install/linux/docker-ce/centos/ 不细说了。

6、安装nginx

我的nginx是通过docker来安装的。

docker pull nginx

上述命令会安装最新版的nginx docker镜像。

关于nginx的docker镜像可以参考我翻译的一篇文章。

nginx的主配置文件是/etc/nginx/nginx.conf,子配置文件在/etc/nginx/conf.d/default.conf主配置文件会使用include指令来调用子配置文件。

当使用nginx镜像时,我们在宿主系统上写好配置,然后通过将容器的目录挂载到宿主的相应目录上即可。

7、创建asp.net core api应用并制作镜像

我创建了一个asp.net core 的webapi,这个web服务监听了5000端口:

它的本地目录是这样的:

Source目录是这样:

列出目录的主要目的是要书写Dockerfile。Dockerfile里面有对路径的操作。Source目录里面放的就是api的工程文件了。Source目录的上一级放了Dockerfile文件,Dockerfile文件内容如下:

FROM microsoft/dotnet:2.2-sdk-alpine AS dotnetcore-sdk #以这个镜像为基础镜像
WORKDIR /source #定义工作路径,下面的命令都是以这个工作路径为基础
#复制工程文件
COPY Source/Widget.Application/Widget.Application.csproj ./Widget.Application/ #COPY命令有两个参数,第一个参数是宿主的目录,第二个参数是镜像上面的目录,如果是相对路径,那都是相对于WORKDIR的
COPY Source/Widgets.Core/Widgets.Core.csproj ./Widgets.Core/
COPY Source/Widgets.Domain/Widgets.Domain.csproj ./Widgets.Domain/
COPY Source/Widgets.Infrastructure/Widgets.Infrastructure.csproj ./Widgets.Infrastructure/
COPY Source/Widgets.UI/Widgets.UI.csproj ./Widgets.UI/
#执行命令
RUN dotnet restore ./Widgets.UI/Widgets.UI.csproj
#将Source目录复制到镜像中(WORKDIR指定的目录下)
COPY Source . #构建和发布
FROM dotnetcore-sdk as dotnetcore-publish #以上一个FROM子句制作好的镜像为基础镜像,并给了这个镜像一个新的命名
RUN dotnet publish ./Widgets.UI/Widgets.UI.csproj -c Release -o /publish #执行publish命令并将发布的内容放到容器内的/publish目录下 #ASP.NET CORE RUNTIME 用上一步发布好的dotnet core镜像作为基础镜像
FROM microsoft/dotnet:2.2-aspnetcore-runtime-alpine AS aspnetcore-runtime
WORKDIR /app #定义工作目录
COPY --from=dotnetcore-publish /publish . #--from=dotnetcore-publish这个参数说明COPY的第一个参数是从哪里复制的
EXPOSE 5000 #对外暴露5000端口
ENTRYPOINT [ "dotnet","Widgets.UI.dll" ] #镜像启动时执行的命令

上面就是这个dockerfile做的工作。里面有详细说明。我们从这个dockerfile构建一个镜像出来:

docker build -t widgets:1.0 .

上面的命令是在dockerfile这个目录下执行的,必须从这里执行,最后面有一个点,表示的就是执行路径。-t参数指明了镜像的名称和标签。

构建完镜像后,需要吧镜像上传到服务器,我没有构建私有仓库,我采用docker image save的方式将镜像保存成tar文件:

docker image save widgets:1.0 C:\\registry\widgets.tar

我将这个镜像保存成一个tar文件,然后上传到云服务器,然后在云服务器上面,使用下面命令将tar文件还原成镜像:

docker image load -i /path/to/widgets.tar

这样就从tar文件还原了一个镜像,然后之后后续的步骤。

8、启动应用和nginx

我是分别做了两个镜像,一个是nginx的,一个是asp.net core的,nginx作为asp.net core的反向代理来使用。这两个镜像运行后得到两个容器。因为nginx容器要和asp.net core容器进行交互,所以我需要一种方式来实现这个需求,我采用的是docker network命令来创建一个桥,然后吧这两个应用都运行在这个桥上。具体如下:

首先是nginx:

docker run -d -p : --name nginx \
--network=widgetsweb \
--network-alias=nginx \
-v /home/wallee/nginx/conf.d:/etc/nginx/conf.d \
-v /home/wallee/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /home/wallee/nginx/log:/var/log/nginx \
-v /etc/letsencrypt:/etc/letsencrypt \
nginx

解释一下这个命令的参数:

  • -d:后台运行
  • -p端口映射,从容器外部到容器内部的映射
  • --name指定容器名称
  • --network指定容器运行在那个桥,桥使用docker network create来创建的,这里桥的名称是widgetsweb
  • --network-alias指定容器运行的桥的别名,这个别名在nginx的配置中有用
  • 第一个-v 将宿主上的conf.d挂载到容器的conf.d上,包含了default.conf这个子配置文件
  • 第二个-v将宿主上的nginx.conf挂载到容器的的nginx.conf文件中,包含了nginx的主配置文件
  • 第三个-v将宿主上的log文件挂载到容器的log,包含了access.log和error.log
  • 第四个-v将宿主上的/etc/letsencrypt挂载到容器的/etc/letsencrypt上,包含了证书(ssl)的相关信息

然后启动asp.net core容器:

docker run -d -p :  --name widgetsweb \
--network=widgets \
--network-alias=widgetsweb \
widgets:1.0

我将容器内的5000端口映射到外部的5000端口,并将容器运行到widgets这个桥上,这样,asp.net core容器和nginx容器都在一个桥上,实现了互通信息的目的。然后,我给asp.net core 容器的桥起了一个别名,这个别名在nginx的配置中有用,下面来看看nginx的配置文件是怎杨的:

user  nginx;
worker_processes ; error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; events {
worker_connections ;
} http {
include /etc/nginx/mime.types;
default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on;
#tcp_nopush on; keepalive_timeout ; #gzip on; include /etc/nginx/conf.d/*.conf;
}

这个nginx的主配置文件分了几个模块:

events模块主要定义了工作者进程的连接数,https模块定义了一些在http模块上下文的全局参数如日志格式,长连接过期时间等,然后它里面有一个include指令,这个指令将conf.d文件夹下的defualt.conf文件包含了进来,default.conf文件的内容如下:

upstream widgets{
server widgetsweb:;
}
server{
listen ssl;
server_name www.bankskit.com;
ssl_certificate /etc/letsencrypt/live/www.bankskit.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.bankskit.com/privkey.pem;
location / {
proxy_pass http://widgets;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} }

upstream模块定义了上游服务器的一些信息,upstream主要用来做负载均衡,这里面只定义了一台服务器,这个服务器就是asp.net core容器运行的服务。注意看这句:

server widgetsweb:5000

widgetsweb这个就是运行asp.net core容器时给这个容器的桥器的别名。这里配置成这样是生效的。

在server模块中定义了监听的地址(https的标准端口)和ssl证书以及证书的密钥。location模块中定义了代理的地址,proxy_pass http://widgets这句话中的widgets是upstream后面定义的名称。

到此主要的配置已经完成。

然后在浏览器上访问你的网站已经成功。

然后就需要在微信小程序中将你申请好的域名配置到里面,然后你的小程序就能访问你建立好的api了

微信小程序和asp.net core基于docker和nginx的交互的更多相关文章

  1. [微信小程序直播平台开发]___(二)Nginx+rtmp在Windows中的搭建

    1.一个可以忽略的前言 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramble ...

  2. 微信小程序踩坑集合

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

  3. 微信小程序内训笔记

    2016年9月22日凌晨微信官方正式宣布“小程序”开始内测,有“微信之父”之称.腾讯集团高级执行副总裁张小龙在2016年末对外宣布“小程序“应用将于2017年1月9日正式推出 这一次微信还是按照惯例, ...

  4. 原创:WeZRender:微信小程序Canvas增强组件

    WeZRender是一个微信小程序Canvas增强组件,基于HTML5 Canvas类库ZRender. 使用 WXML: <canvas style="width: 375px; h ...

  5. 微信小程序开发带来的思考

    若无小程序开发经验,可先阅读 玩转微信小程序 一文. 微信小程序正式上线已有几周时间,相信它的开发模式你已烂熟于胸,可能你也有所疑问,我竟能用 web 语言开发出如此流畅的几乎原生体验的应用.可能你又 ...

  6. 微信小程序之生成图片分享

    通过社交软件分享的方式来进行营销小程序,是一个常用的运营途径.小程序本身支持直接将一个小程序的链接卡片分享至微信好友或微信群,然后别人就可以通过点击该卡片进入该小程序页面.但是小程序目前不支持直接分享 ...

  7. 微信小程序开发之formId使用(模板消息)

    基于微信小程序的模板消息:基于微信的通知渠道,我们为开发者提供了可以高效触达用户的模板消息能力,以便实现服务的闭环并提供更佳的体验.模板推送位置:服务通知模板下发条件:用户本人在微信体系内与页面有交互 ...

  8. WordPress版微信小程序安装使用说明

    昨天在群里,有刚刚使用WordPress版微信小程序朋友,在问安装过程中的问题,这些问题是经常被问到,这至少说明两个问题: 1.我开发的程序安装和使用不够简易,无法通过简单的配置就可以使用,特别是如果 ...

  9. 微信小程序 - debug(调试)

    微信小程序调试的方式是基于Chrome. 1. 常见console.log调试(可以具体参考console.log这个函数使用,它可不止这一个作用!) 2.使用NETWORK(我们可以查询到访问了那些 ...

随机推荐

  1. mysql5.6采集数据插入出现MySQL server has gone away解决办法

    当做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到My ...

  2. 13-C#笔记-数组

    # 1 初始化 double[] balance = new double[10]; // 隐式初始化为0 double[] balance = { 2340.0, 4523.69, 3421.0}; ...

  3. Git 游离态的一次问题解决

    jie@mozq MINGW64 /d/0xcEdu/xcEduService01 ((20ce6a5...)) $ git branch -v * (HEAD detached at 20ce6a5 ...

  4. python语言(八)多线程、多进程、虚拟环境、unittest、生成测试报告

    一.多线程 进程与线程 进程:进程是资源(CPU.内存等)分配的最小单位,进程有独立的地址空间与系统资源,一个进程可以包含一个或多个线程 线程:线程是CPU调度的最小单位,是进程的一个执行流,线程依赖 ...

  5. struts2学习2

    拦截器 //拦截器:第一种创建方式 //拦截器生命周期:随项目的启动而创建,随项目关闭而销毁 public class MyInterceptor implements Interceptor { @ ...

  6. 8个SpringBoot精品项目

    8个SpringBoot精品项目 https://gitee.com/52itstyle/spring-boot-seckill 秒杀 https://gitee.com/52itstyle/spri ...

  7. 操作excel文件爬取nvd.nist数据

    #!/usr/bin/env python # encoding: utf-8 #@author: jack import random from time import sleep import p ...

  8. vue 实现模块上移下移 实现排序

    效果图 上移 下移 首先想到的是 数组的相互替换嘛 <template> <div> <div class="box" v-for="(it ...

  9. Java 并发系列之一:java 并发体系

    1.  java 并发机制的底层原理实现 1.1 volatile 1.2 synchronized 1.3 原子操作 2. java 内存模型(JMM) 3. java并发基础线程 4. java ...

  10. ipv6转ipv4 NAT64与DNS64基本原理概述

    原文: https://blog.csdn.net/zhangjie1989/article/details/51464251 1.NAT64与 DNS64背景 在 IPv6网络的发展过程中,面临最大 ...