k8s部署gin-vue-admin框架、gitlab-ci、jenkins pipeline 、CICD

测试环境使用的jenkins
正式环境使用的gitlab-ci

测试环境

  1. 创建yaml文件
apiVersion: v1
kind: ConfigMap
metadata:name: dtk-go-tiktok-admin-configlabels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xd
data:config.yaml: |max-age: 0show-line: truelog-in-console: true---
apiVersion: v1
kind: ConfigMap
metadata:name: dtk-vue-tiktok-admin-configlabels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: frontapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xd
data:default.conf: |server{listen       80 default_server;server_name  _;access_log   /dev/stdout;error_log    /dev/stdout;root         /opt/app/dist/;location / {try_files $uri $uri/ /index.html;}location /api {proxy_set_header Host $http_host;proxy_set_header  X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;rewrite ^/api/(.*)$ /$1 break;  #重写add_header 'dtk-debug' 'api';#一个deployment2个pod是网络资源是共享的,所以可以直接代理proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址}location /api/swagger/index.html {proxy_pass http://127.0.0.1:8888/swagger/index.html;}location /health {access_log off;return 200;}}---
apiVersion: apps/v1
kind: Deployment
metadata:name: dtk-go-tiktok-adminlabels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xd
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xdtemplate:metadata:labels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xdspec:imagePullSecrets:- name: aliyun-regcredserviceAccountName: defaultsecurityContext:dnsPolicy: NonednsConfig:nameservers:- 172.31.74.196searches:- test1.svc.cluster.local- svc.cluster.local- cluster.localcontainers:- name: golangsecurityContext:runAsUser: 0image: "registry.buydance.com/dataoke-test/dtk-go-tiktok-admin-golang:latest"volumeMounts:- name: configmountPath: /opt/app/conf/ports:- name: httpcontainerPort: 8888protocol: TCPlivenessProbe:httpGet:path: /healthport: 8888initialDelaySeconds: 5periodSeconds: 20timeoutSeconds: 3readinessProbe:httpGet:path: /healthport: 8888initialDelaySeconds: 5periodSeconds: 10timeoutSeconds: 3resources:requests:cpu: 1mmemory: 20Mi- name: nginxsecurityContext:image: "registry.buydance.com/dataoke-test/dtk-go-tiktok-admin-nginx:latest"volumeMounts:- name: ng-configmountPath: /etc/nginx/conf.d/ports:- name: httpcontainerPort: 80protocol: TCPlivenessProbe:httpGet:path: /healthport: 80periodSeconds: 5readinessProbe:httpGet:path: /healthport: 80periodSeconds: 5resources:requests:cpu: 1mmemory: 64Milimits:cpu: 200mmemory: 256Mivolumes:- name: ng-configconfigMap:name: dtk-vue-tiktok-admin-config- name: configconfigMap:name: dtk-go-tiktok-admin-config
---
apiVersion: v1
kind: Service
metadata:name: dtk-go-tiktok-admin
spec:ports:- port: 80targetPort: 80protocol: TCPname: nginx- port: 8888targetPort: 8888protocol: TCPname: golangselector:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: testapp.kubernetes.io/managed-by: yong.xd
  1. 启动服务
kubectl apply -f ./ -n test1
  1. 配置jenkins
#!/usr/bin/env groovy
import groovy.json.JsonOutputString gitRepositryURL = 'https://test.com/dtk-go-tiktok-admin.git'
String dockerRegistry = 'test.com'
String dockerRegistryURL = 'https://test.com'
String dockerRegistryNameSpace = 'dataoke-test'
#dockerfile路径
String kubeManifestsRepo = '/home/jenkins/repo/dtk-kubernetes-test/app'
Map dockerFiles = ["nginx":"Dockerfile.test.nginx", "golang":"Dockerfile.test.golang"]
Map dockerImages = [:]
boolean notify = falseString jobBaseName = env.JOB_NAME[4..-1]
String jobK8sName = jobBaseName.replaceAll('_', "-") Map commitInfo = [:]
Map buildInfo = [:]commitInfo.projectName = gitRepositryURL.replaceFirst(/^.*\/([^\/]+?).git$/, '$1') 
commitInfo.gitRepositryURL = gitRepositryURL
buildInfo.buildId = currentBuild.id@NonCPS
def newSh(String cmd) {def script = '#!/bin/sh +x\n' << cmdresult = sh(returnStdout: true, script: script.toString())return result
}pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '10', numToKeepStr: '10')}parameters {choice( name: 'PENV',choices: ['dev1','dev2','test1','test2', 'test3', 'test4','test5','test6','test7','huise',
'huise4','huise3'], description: '选择发布环境,默认发布至dev1测试环境')gitParameter(name: 'GIT_BRANCH', type: 'PT_BRANCH_TAG',branchFilter: 'origin/(.*)',defaultValue: 'master',selectedValue: 'DEFAULT',sortMode: 'DESCENDING_SMART',quickFilterEnabled: true, description: 'Select your branch or tag.')booleanParam(name: 'force', defaultValue: false, description: '代码重复强制发版')}stages {stage('预处理') {steps {script {def now = new Date()buildInfo.buildDate = now.format("yy-MM-dd HH:mm", TimeZone.getTimeZone('UTC'))def causes = currentBuild.getBuildCauses()buildInfo.buildUser = causes[0]['userName']userList = readYaml(file:'/etc/jenkins/users.yaml')if (!(PENV in userList.env.dev ) && !(buildInfo.buildUser in userList.user.allow)) {error(message: "开发只能发布环境到${userList.env.dev.join(',')}")			}buildInfo.gitBranch = GIT_BRANCHbuildInfo.publishEnv = PENVcurrentBuild.description = "k8s环境: ${PENV} 构建人:${buildInfo.buildUser} 分支: ${GIT_BRANCH}"newSh("check.py -u ${buildInfo.buildUser} -e ${PENV}")}}}stage('同步代码仓库') {steps {script {def scmVars = checkout([$class: 'GitSCM', branches: [[name: "${GIT_BRANCH}"]], extensions: [[$class: 'CheckoutOption', timeout: 20], [$class: 'CloneOption', depth: 1]], userRemoteConfigs: [[credentialsId: "5411496d-3606-4855-ab9c-2e4453cd2880", url: "${gitRepositryURL}"]]])commitInfo.gitCommit = scmVars.GIT_COMMITcommitInfo.gitBranch = GIT_BRANCHcommitInfo.xiangmu_name = env.JOB_BASE_NAMEcommitInfo.commitDate = newSh('git log --pretty=format:"%ci" -1')commitInfo.cmmitMessage = newSh('git log --pretty=format:"%s" -1')String gitDiff = newSh('git diff HEAD^ HEAD')def committer = [:]committer.name = newSh('git log --pretty=format:"%cn" -1')committer.email =  newSh('git log --pretty=format:"%ce" -1')commitInfo.committer = committerString consoleStdout = "\n\n---------SYNCHRONIZE GIT REPOSITORY---------\nGit repo sync successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(commitInfo))println(consoleStdout)consoleStdout = "\n\n---------CHANGE LOGS---------\nGit diff:\n\n" + gitDiffprintln(consoleStdout)getDatabaseConnection(type: 'GLOBAL') {def sqlString="select commit_seccec from jenkins_commit.jenkins_jilu where xm_name = ? and env = ?"def params=[commitInfo.xiangmu_name,PENV]def rest_null = sql sql:sqlString,parameters:paramsif (rest_null.size() == 0){def sqlString2="insert  into  jenkins_commit.jenkins_jilu(xm_name,env,commit_seccec)   values(?,?,?)"def params2=[commitInfo.xiangmu_name,PENV,commitInfo.gitCommit]sql sql:sqlString2,parameters:params2println("mysql插入数据")}if (rest_null.size() >= 1) {def Map rest = rest_null.get(0)if (rest.get("commit_seccec") == commitInfo.gitCommit && force == "false"){currentBuild.description = "k8s环境: ${PENV} 构建人:${buildInfo.buildUser} 分支: ${GIT_BRANCH} 构建失败: 代码重复不发版"println("代码没有变化不做发版")error "上一个版本和现在正在发的版本一致,不做发版"}}}}}}stage('构建') {		agent {docker { image 'registry.buydance.com/dataoke-test/golang:1.19'args '--user root -v /data/jenkins_build_cache/.cache:/.cache'args '--user root -v /data/lib/go:/go'reuseNode true}	}steps {script {env.STAGE = "goujian"def now = new Date()String buildDate = now.format("yy-MM-dd HH:mm", TimeZone.getTimeZone('UTC'))sh (script: '#!/bin/sh +x\n' + '''cd ./servermkdir -p .cacheexport GO111MODULE=onexport GOPROXY=https://goproxy.cn,directexport GOPRIVATE="gitlab.buydance.com/*"export CGO_ENABLED=0go mod  tidygo build -o main''')def files = findFiles(glob: '**/main')String artifactPath = files[0].pathString sha1Checksum = sha1(file: artifactPath)String sha256Checksum = sha256(file: artifactPath)consoleStdout = "\n\n---------BUILD RESULTS---------\nBuild info generated successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(buildInfo))println(consoleStdout)}	}}stage('构建vue') {		agent {docker { image 'node:14.19.3-alpine3.15'args '--user root -v /data/jenkins_build_cache/.cache:${HOME}/.cache'args '--user root -v /data/lib/composer:/root/.composer'reuseNode true}	}steps {script {sh """cd ./webnpm config set puppeteer_download_host=https://npm.taobao.org/mirrorsnpm i --registry=https://registry.npm.taobao.orgnpm run build"""consoleStdout = "\n\n---------BUILD RESULTS---------\nBuild info generated successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(buildInfo))println(consoleStdout)}	}}stage('Docker') {steps {script {env.STAGE = "DOCKERFIEL"//	docker.withRegistry(dockerRegistryURL, '8f1a40fa-3258-4717-825c-a9f87299916d') {docker.withRegistry(dockerRegistryURL) {String dockerFile = kubeManifestsRepo + '/' + jobBaseName + '/' + 'Dockerfile.test.nginx'if (!fileExists(dockerFile)) {dockerFile = kubeManifestsRepo + '/' + jobK8sName + '/' + 'Dockerfile.test.nginx'}String dockerRepository = dockerRegistry + '/' + dockerRegistryNameSpace + '/' + jobK8sName + '-' + 'nginx'def customImage = docker.build(dockerRepository, "-f ${dockerFile} .")customImage.push(commitInfo.gitCommit)customImage.push('latest')dockerImages.nginx = dockerRepository + ':' + commitInfo.gitCommitdockerFile = kubeManifestsRepo + '/' + jobBaseName + '/' + 'Dockerfile.test.golang'if (!fileExists(dockerFile)) {dockerFile = kubeManifestsRepo + '/' + jobK8sName + '/' + 'Dockerfile.test.golang'}dockerRepository = dockerRegistry + '/' + dockerRegistryNameSpace + '/' + jobK8sName + '-' + 'golang'customImage = docker.build(dockerRepository, "-f ${dockerFile} .")customImage.push(commitInfo.gitCommit)customImage.push('latest')dockerImages."golang" = dockerRepository + ':' + commitInfo.gitCommit}}}}stage('部署') {steps {script {env.STAGE = "bushu"dockerImages.each { k, v -> newSh("kubectl -n ${PENV} set image deployment/${jobK8sName} ${k}=${v}")newSh("kubectl -n ${PENV} rollout status deployment/${jobK8sName} --timeout=2m")}String content = "![screenshot](https://comquent.de/wp-content/uploads/CQ-Pipeline-Kurs.png)\n\n### Jenkins Pipeline\n>**构建信息**:\n>- 构建项目: ${jobBaseName}\n>- 构建id: ${currentBuild.number}\n>- 构建人: ${buildInfo.buildUser}\n>- 构建分支: ${GIT_BRANCH}\n>- 发布环境: ${PENV}\n>**版本信息**:\n>- commit_hash: ${commitInfo.gitCommit}\n>- commit_date: ${commitInfo.commitDate}\n>- commit_message: ${commitInfo.cmmitMessage}\n>- committer: ${commitInfo.committer.name}"	def workflowMessage = ["msgtype": "actionCard","actionCard":["title":"构建信息","text":content,"btnOrientation": "0","btns": [["title": "详细信息","actionURL": "https://k8sjenkins.haojiequ.com/blue/organizations/jenkins/k8s_dtk_go_app_api/detail/k8s_dtk_go_app_api/${currentBuild.number}/pipeline"],["title": "日志监控","actionURL": "http://k8skibana.haou.com/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'18d51920-96c3-11eb-811f-1383c86a1d0',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"],]]]	String workflowMessageJSON = JsonOutput.toJson(workflowMessage)timeout(unit: 'SECONDS', time: 30) {newSh("curl 'https://oapi.dingtalk.com/robot/send?access_token=9e91f6860736ff69e7f6f986179e154e497b70e26fd749c' -s -H 'Content-Type: application/json' -d '${workflowMessageJSON}'")}}}}stage("commit入库"){steps {script{getDatabaseConnection(type: 'GLOBAL') {def sqlString3="update jenkins_commit.jenkins_jilu set commit_seccec=?    where xm_name=? and env=?;"def params3=[commitInfo.gitCommit,commitInfo.xiangmu_name,PENV]sql sql:sqlString3,parameters:params3}}}}}post {failure {script{if (STAGE == "goujian") {println("----> goujian失败")}if (STAGE == "bushu") {println("----> bushu失败")		   }if (STAGE == "DOCKERFIEL") {println("----> DOCKERFIEL失败")}}}}
}
  1. 配置nginx
upstream  dtk-vue-tiktok-admin  {server dtk-go-tiktok-admin  weight=1 max_fails=0 fail_timeout=0s;keepalive 20;
}server {
listen  80;
listen      443 ssl;
server_name test.com;
access_log  /var/log/nginx/dtest.com.access.log json;
error_log   /var/log/nginx/dtest.com.error.log;
ssl_certificate     conf.d/dtkcert/test.com.pem;
ssl_certificate_key conf.d/dtkcert/test.com.key;
more_set_headers 'Access-Control-Allow-Headers: Cookie,DNT,X-CSRF-Token,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Auth-token';
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT';
more_set_headers 'Access-Control-Allow-Credentials: true';
default_type     'text/html';
set $backend 'dtk-vue-tiktok-admin';include  public/deny.conf;
location / {proxy_pass http://$backend;
}location ~ /\.ht {deny  all;
}
}
  1. jenkins机器上的dockerfile
[root@k8s-jenkins dtk-go-tiktok-admin]# cat Dockerfile.test.golang
FROM test.com/dataoke-test/alpine:3.12-CST as test
WORKDIR /opt/app
COPY  $CI_PROJECT_DIR/server/main /opt/app/main
CMD ["/opt/app/main", "-c", "/opt/app/conf/config.yaml"][root@k8s-jenkins dtk-go-tiktok-admin]# cat Dockerfile.test.nginx
FROM test.com/dataoke-test/openresty:base
WORKDIR /opt/app/dist/
COPY --chown=nobody:nobody web/dist /opt/app/dist

线上环境配置

  1. yaml其它都一样除了svc,因为svc需要绑定slb地址
apiVersion: v1
kind: Service
metadata:name: dtk-go-tiktok-adminannotations:#开启slb使用service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"#slb地址service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: lb-2ze1hpcomc#    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "http:9090"service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler: "wrr"namespace: default
spec:type: LoadBalancerexternalTrafficPolicy: Localports:- port: 16107  #slb端口targetPort: 80 #pod服务端口protocol: TCPselector:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/runtime: golangapp.kubernetes.io/tier: backendapp.kubernetes.io/environment: prodapp.kubernetes.io/managed-by: yong.xd
  1. 启动
cat .gitlab-ci.ymlstages:- build- package- docker- deploy- notifybuild:stage: buildimage: test.com/dataoke-prod/golang:1.19-with-repo-certcache:key:files:- go.modpaths:- .cache/pkgartifacts:expire_in: 20 minsuntracked: falsepaths:- $CI_PROJECT_DIR/server/mainscript:- mkdir -p .cache- cd ./server - export GOPATH="$CI_PROJECT_DIR/.cache"- go env -w GO111MODULE=on - go env -w GOPROXY=https://goproxy.cn,direct - go env -w GOPRIVATE=gitlab.buydance.com - go env -w CGO_ENABLED=0- go build -o mainonly:- tagspackage:stage: packageimage: test.com/dataoke-prod/node:14.19.3-alpine3.15script:- cd ./web- npm config set puppeteer_download_host=https://npm.taobao.org/mirrors- npm i --registry=https://registry.npm.taobao.org- npm run buildcache:key:files:- package.jsonpaths:- node_modulesartifacts:name: "dist"untracked: falseexpire_in: 5 minspaths:- $CI_PROJECT_DIR/web/distonly:- tagsdocker:stage: dockerimage: test.com/dataoke-prod/kaniko-executor:debugscript:- mkdir -p /kaniko/.docker- echo "${DOCKER_AUTH_CONFIG}" > /kaniko/.docker/config.json- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile.prod.nginx --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:${CI_COMMIT_SHORT_SHA} --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:latest- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile.prod.golang --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:${CI_COMMIT_SHORT_SHA} --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:latestonly:- tagsdeploy:stage: deployimage: test.com/dataoke-prod/kubectl:1.18.1variables:GIT_STRATEGY: noneK8S_NAME_SPACE: defaultscript:- mkdir -p $HOME/.kube- echo "$KUBERNETES_SECRET" >> "$HOME/.kube/config"- kubectl version- kubectl get deployments.apps -n ${K8S_NAME_SPACE}- kubectl -n ${K8S_NAME_SPACE} set image deployment/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'` nginx=test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:${CI_COMMIT_SHORT_SHA} golang=test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:${CI_COMMIT_SHORT_SHA} --record- kubectl rollout status deployment/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`only:- tagsnotifyFailWeChat:stage: notifyimage: test.aliyuncs.com/dataoke-prod/curl-image:v1script:- curl 'https://oapi.dingtalk.com/robot/send?access_token=6147ec1eb7d8b9bd5cd1b15f1c' -H 'Content-Type:application/json' -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$CI_PROJECT_NAME项目构建失败\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"only:- tagswhen: on_failure# 构建成功时的通知消息
notifySuccessWeChat:stage: notifyimage: test.aliyuncs.com/dataoke-prod/curl-image:v1script:- curl 'https://oapi.dingtalk.com/robot/send?access_token=d6147ec1eb7d8b9bd5cd1b15f1c' -H 'Content-Type:application/json' -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$CI_PROJECT_NAME项目构建成功\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"only:- tagswhen: on_success
  1. 配置dockerfile
cat  Dockerfile.prod.golangFROM test.aliyuncs.com/dataoke-prod/alpine:3.12-CST as prod
WORKDIR /opt/app
COPY  $CI_PROJECT_DIR/server/main /opt/app/main
CMD ["/opt/app/main", "-c", "/opt/app/conf/config.yaml"]cat Dockerfile.prod.nginxFROM test.aliyuncs.com/dataoke-prod/openresty:base
WORKDIR /opt/app/dist/
COPY --chown=nobody:nobody web/dist /opt/app/dist
  1. 配置nginx
upstream  dtk-go-tiktok-admin {
#svc内网ip
server 192.168.10.123:16107  weight=1 max_fails=0 fail_timeout=0s;
keepalive 20;
}server {
listen  80;
listen      443 ssl;
server_name test.com;
access_log  /var/log/nginx/dtest.com.access.log json;
error_log   /var/log/nginx/dtest.com.error.log;
ssl_certificate     conf.d/dtkcert/test.com.pem;
ssl_certificate_key conf.d/dtkcert/test.com.key;more_set_headers 'Access-Control-Allow-Headers: Cookie,DNT,X-CSRF-Token,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Auth-token';
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT';
more_set_headers 'Access-Control-Allow-Credentials: true';
default_type     'text/html';
set $backend 'dtk-vue-tiktok-admin';include  public/deny.conf;
location / {
proxy_pass http://$backend;
}location ~ /\.ht {
deny  all;
}
}
  1. 结果图
    微信截图_20230928142620.png
    微信截图_20230928142639.png

微信截图_20230928142705.png
微信截图_20230928142657.png
微信截图_20230928142557.png
微信截图_20230928142535.png

原文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/90803.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国312个历史文化名镇及景区空间点位数据集

一部中华史&#xff0c;既是人类创造丰富物质财富的奋头史&#xff0c;又是与自然共生共存的和谐史不仅留存下悠久丰富的人文思想和情怀&#xff0c;还在各处镌刻下可流传的生活场景&#xff0c;历史文化名镇(以下简称:名镇)就是这样真实的历史画卷。“镇”是一方的政治文化中心…

Elasticsearch:使用 Elasticsearch 进行语义搜索

在数字时代&#xff0c;搜索引擎在通过浏览互联网上的大量可用信息来检索数据方面发挥着重要作用。 此方法涉及用户在搜索栏中输入特定术语或短语&#xff0c;期望搜索引擎返回与这些确切关键字匹配的结果。 虽然关键字搜索对于简化信息检索非常有价值&#xff0c;但它也有其局…

红黑树是如何实现的?

文章目录 一、红黑树的概念二、红黑树的性质三、红黑树和AVL树对比四、红黑树的插入1. 红黑树的结点定义2. 父亲的颜色3. 叔叔的颜色为红色4. 叔叔不存在5. 叔叔存在且为黑6. 插入的抽象图 五、红黑树的验证1. 检查平衡2. 计算高度与旋转次数3. 验证 六、 红黑树与AVL树的比较 …

【数据结构】——顺序表详解

大家好&#xff01;当我们学习了动态内存管理后&#xff0c;就可以写一个管理数据的顺序表了&#xff01;&#xff01;&#xff01; 顺序表的理解&#xff1a; 线性表是最基本、最简单、也是最常用的一种数据结构。线性表&#xff08;linear list&#xff09;是数据结构的一种…

青藏高原1-km分辨率生态环境质量变化数据集(2000-2020)

青藏高原平均海拔4000米以上&#xff0c;人口1300万&#xff0c;是亚洲九大河流的源头&#xff0c;为超过15亿人口提供淡水、食物和其他生态系统服务&#xff0c;被誉为地球第三极和亚洲水塔。然而&#xff0c;在该地区的人与自然的关系的研究是有限的&#xff0c;尤其是在精细…

高德地图根据两点的经纬度计算两点之间的距离(修正版)

SQL语句可以用来计算两个经纬度之间的距离。下面是一个示例的SQL语句&#xff1a; SELECT id, ( 6371 * ACOS( COS( RADIANS( lat1 ) ) * COS( RADIANS( lat2 ) ) * COS( RADIANS( lng2 ) - RADIANS( lng1 ) ) SIN( RADIANS( lat1 ) ) * SIN( RADIANS( lat2 ) ) ) ) AS dista…

PyTorch - 模型训练损失 (Loss) NaN 问题的解决方案

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/133378367 在模型训练中&#xff0c;如果出现 NaN 的问题&#xff0c;严重影响 Loss 的反传过程&#xff0c;因此&#xff0c;需要加入一些微小值…

【SQL Server】外键约束

外键约束 前序外键约束 前序 在很多场景里面&#xff0c;都会用到外键来关联两张表或两张以上的表之间主从关系&#xff0c;从而来快捷地通过外键字段来查询数据之间的联系。 其实外键在我的概念中还是比较模糊的&#xff0c;没有真正地使用过。大多数情况下&#xff0c;我都…

Pandas 2.1中的新改进和新功能

大家好&#xff0c;Pandas 2.1于2023年8月30日发布&#xff0c;跟随本文一起看看这个版本引入了哪些新内容&#xff0c;以及它如何帮助用户改进Pandas的工作负载&#xff0c;包含了一系列改进和一组新的弃用功能。 Pandas 2.1在Pandas 2.0中引入的PyArrow集成基础上进行了大量…

【RabbitMQ实战】07 3分钟部署一个RabbitMQ集群

一、集群的安装部署 我们还是利用docker来安装RabbitMQ集群。3分钟安装一个集群&#xff0c;开始。 前提条件&#xff0c;docker安装了docker-compose。如果没安装的话&#xff0c;参考这里 docker-compose文件参考bitnami官网&#xff1a;https://github.com/bitnami/contai…

巧用@Conditional注解根据配置文件注入不同的bean对象

项目中使用了mq&#xff0c;kafka两种消息队列进行发送数据&#xff0c;为了避免硬编码&#xff0c;在项目中通过不同的配置文件自动识别具体消息队列策略。这里整理两种实施方案&#xff0c;仅供参考&#xff01; 方案一&#xff1a;创建一个工具类&#xff0c;然后根据配置文…

Swift 周报 第三十八期

文章目录 前言新闻和社区苹果自研调制解调器芯片受挫&#xff1a;速度太慢容易过热&#xff0c;落后高通 3 年App Store 现已接受适用于最新版操作系统的 App 和游戏提交 提案通过的提案正在审查的提案驳回的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组…

弹性资源组件elastic-resource设计(一)-架构

简介 弹性资源组件提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。 本文介绍弹性资源组件的设计,包括架构设计和详细设计,指导开发人员代码开发 关键词 作业管理器/资源管理器/…

duilib 之 各种消息框

本文主要介绍,使用同一个布局文件,生成不同样式消息框是如何实现的。 目录 一、消息框 1、不同消息框展示 2、实现方式 1)、布局, 2)、扩展 MsgB

简易实现通讯录(2.0)

这篇文章是在上期实现的通讯录基础上&#xff0c;增加了自动增容的功能&#xff0c;也解决了一开始通讯录自动开辟一个空间&#xff0c;可能会浪费空间&#xff0c;或者是信息过多无法增容的痛点&#xff0c;由于我们使用的是malloc这类函数来开辟空间&#xff0c;我们也需要来…

vue 实现弹出菜单,解决鼠标点击其他区域的检测问题

弹出菜单应该具有的功能&#xff0c;当鼠标点击其他区域时&#xff0c;则关闭该菜单。 问题来了&#xff0c;怎么检测鼠标点击了其他区域而不是当前菜单&#xff1f; 百度“JS检测区域外的点击事件”&#xff0c;会发现有很多方法&#xff0c;有递归检测父元素&#xff0c;有遍…

大语言模型LLM知多少?

你知道哪些流行的大语言模型?你都体验过哪写? GPT-4,Llamma2, T5, BERT 还是 BART? 1.GPT-4 1.1.GPT-4 模型介绍 GPT-4(Generative Pre-trained Transformer 4)是由OpenAI开发的一种大型语言模型。GPT-4是前作GPT系列模型的进一步改进,旨在提高语言理解和生成的能力,…

Centos 7安装pm2 , 操作等常用命令

Centos 7安装pm2 1、首先需要安装node&#xff0c;node安装教程前一篇已经说了&#xff0c;是安装pm2 [rootlocalhost ~]# npm install -g pm2 2、pm2 命令参考 复制代码 2.1 启动进程/应用 pm2 start bin/www 或 pm2 start app.js 2.2 重命名进程/应用 pm2 start app.js -…

Blender导出FBX给UE5

最近在学习UE5的资源导入&#xff0c;总结如下&#xff1a; 建模使用Blender&#xff0c;UE5版本是5.3 1.纯静态模型导入UE5 Blender FBX导出设置保持默认即可&#xff0c; UE5把导入设置里Miscellaneous下Force Front XAxis和Convert Scene Unit勾选即可 2.带骨骼动画的模型…

ios项目安装hermes-engine太慢问题

问题说明 ios工程&#xff0c;在使用"pod install"安装依赖的时候&#xff0c;由于超时总是报错 $ pod install ... Installing hermes-engine (0.71.11)[!] Error installing hermes-engine [!] /usr/bin/curl -f -L -o /var/folders/4c/slcchpy55s53ysmz_1_q_gzw…