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.xdnf.cn/news/144417.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

定时任务管理平台青龙 QingLong

一、关于 QingLong 1.1 QingLong 介绍 青龙面板是支持 Python3、JavaScript、Shell、Typescript 多语言的定时任务管理平台&#xff0c;支持在线管理脚本和日志等。其功能丰富&#xff0c;能够满足大部分需求场景&#xff0c;值得一试。 主要功能 支持多种脚本语言&#xf…

Python接口自动化之unittest单元测试

以下主要介绍unittest特性、运行流程及实际案例。 一、单元测试三连问 1、什么是单元测试&#xff1f; 按照阶段来分&#xff0c;一般就是单元测试&#xff0c;集成测试&#xff0c;系统测试&#xff0c;验收测试。单元测试是对单个模块、单个类或者单个函数进行测试。 将访…

【网络协议】TCP

TCP协议全称为传输控制协议(Transmission Control Protocol).要理解TCP就要从他的特性开始说&#xff0c;这些特性各自之间或多或少各有联结&#xff0c;需要以宏观视角来看待。 目录&#xff1a; 1.TCP报文格式 因为报文解释过于繁琐&#xff0c;具体内容请看这篇文章TCP报文…

大模型lora微调-chatglm2

通义千问大模型微调源码&#xff08;chatglm2 微调失败&#xff0c;训练通义千问成功&#xff09;&#xff1a;GitHub - hiyouga/LLaMA-Efficient-Tuning: Easy-to-use LLM fine-tuning framework (LLaMA-2, BLOOM, Falcon, Baichuan, Qwen, ChatGLM2)Easy-to-use LLM fine-tun…

pytorch的pixel_shuffle转tflite文件

torch.pixel_shuffle()是pytorch里面上采样比较常用的方法&#xff0c;但是和tensoflow的depth_to_space不是完全一样的&#xff0c;虽然看起来功能很像&#xff0c;但是细微是有差异的 def tf_pixelshuffle(input, upscale_factor):temp []depth upscale_factor *upscale_f…

项目集成七牛云存储sdk

以PHP为例 第一步&#xff1a;下载sdk PHP SDK_SDK 下载_对象存储 - 七牛开发者中心 sdk下载成功之后&#xff0c;将sdk放入项目中&#xff0c;目录选择以自己项目实际情况而定。 注意&#xff1a;在examples目录中有各种上传文件的参考示例&#xff0c;这里我们主要参考的是…

朴素贝叶斯深度解码:从原理到深度学习应用

目录 一、简介贝叶斯定理的历史和重要性定义例子 朴素贝叶斯分类器的应用场景定义例子常见应用场景 二、贝叶斯定理基础条件概率定义例子 贝叶斯公式定义例子 三、朴素贝叶斯算法原理基本构成定义例子 分类过程定义例子 不同变体定义例子 四、朴素贝叶斯的种类高斯朴素贝叶斯&a…

[Framework] Android Binder 工作原理

Binder 是 Android 系统中主要的 IPC 通信方式&#xff0c;其性能非常优异。但是包括我在内的很多开发者都对它望而却步&#xff0c;确实比较难&#xff0c;每次都是看了忘&#xff0c;忘了看&#xff0c;但是随着工作的时间约来越长&#xff0c;每次看也都对 Binder 有新的认识…

Machine Learning(study notes)

There is no studying without going crazy Studying alwats drives us crazy 文章目录 DefineMachine LearningSupervised Learning&#xff08;监督学习&#xff09;Regression problemClassidication Unspervised LearningClustering StudyModel representation&#xff08…

IntelliJ IDEA 左侧Commit栏不见了

1.点击File->Settings->Version Control->Commit 2.勾选Use non-modal commit interface

Git 学习(2)

Git 学习&#xff08;2&#xff09; 版本号 Git 中文件的版本号是 40 位十六进制的数字字符串&#xff0c;采用 SHA-1 加密算法计算获得 这样一方面可避免在合并时的冲突问题 另一方面可以用于文件定位&#xff0c;其中前两位表示文件夹&#xff0c;后 38 位表示文件 指令介…

阿里云网络、数据中心和服务器技术创新优势说明

阿里云服务器技术创新、网络技术创新、数据中心技术创新和智能运维&#xff1a;云服务器方升架构、自研硬件、自研存储硬件AliFlash和异构计算加速平台&#xff0c;以及全自研网络系统技术创新和数据中心巴拿马电源、液冷技术等技术创新说明&#xff0c;阿里云百科aliyunbaike.…

游戏设计模式专栏(一):工厂方法模式

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》&#xff0c;让糟糕的代码在潜移默化中升华&#xff0c;欢迎大家关注分享收藏订阅。 在游戏开发中&#xff0c;代码的组织和结构对于项目的可…

maven找不到jar包

配置settings.xml文件之后出现报错找不到jar包 先改maven设置: 然后在重新清理构建项目: 可以通过执行以下命令清理本地 Maven 仓库 mvn dependency:purge-local-repository

Java 实现前端数据的导出操作

前端 <el-button class"export" type"primary" icon"el-icon-download" click"exportData()">导出</el-button>exportData() {//data 操作data 变成后端需要的格式let data {capacityVos: resultVo}this.$confirm("…

服务器补丁管理软件

随着漏洞的不断上升&#xff0c;服务器修补是增强企业网络安全的典型特征。作为业务关键型机器&#xff0c;计划服务器维护的停机时间无疑是一件麻烦事。但是&#xff0c;借助高效的服务器补丁管理软件&#xff08;如 Patch Manager Plus&#xff09;&#xff0c;管理员可以利用…

FileManager/本地文件增删改查, Cache/图像缓存处理 的操作

1. FileManager 本地文件管理器&#xff0c;增删改查文件 1.1 实现 // 本地文件管理器 class LocalFileManager{// 单例模式static let instance LocalFileManager()let folderName "MyApp_Images"init() {createFolderIfNeeded()}// 创建特定应用的文件夹func cr…

JavaScript Web APIs第一天笔记

复习&#xff1a; splice() 方法用于添加或删除数组中的元素。 **注意&#xff1a;**这种方法会改变原始数组。 删除数组&#xff1a; splice(起始位置&#xff0c; 删除的个数) 比如&#xff1a;1 let arr [red, green, blue] arr.splice(1,1) // 删除green元素 consol…

数字乡村包括哪些方面?数字乡村应用介绍

数字乡村是指利用物联网、数字化和智能化技术&#xff0c;借助现代数字智能产品、高效信息服务和物联网基础设施&#xff0c;以提高农村居民生活质量&#xff0c;助力拓展经济发展前景。 创建数字村庄有助于缩小城乡社区之间的差距&#xff0c;保障每个人都能平等地享受科技发展…

flask_apscheduler实现定时推送飞书消息

需求场景&#xff1a; 实现一个flask服务&#xff0c;通过接口控制一个定时任务任务&#xff08;对酒店订房情况进行检查&#xff09;的开启和停止。要求定时任务完成后&#xff0c;可以通过飞书机器人推送任务完成的消息。 展现效果&#xff1a; 启动定时任务 关闭定时任务…