概述
前端打包成docker镜像
概述
dist
文件夹有几个步骤,首先是安装依赖:执行npm install
命令,会将package.json
文件中的依赖安装下来。然后使用npm run build
指令编译打包,这个过程通常会使用webpack
打包工具,完成后会生成dist
静态文件,里面包含了生产环境的代码包括JS、CSS、HTML文件以及其他静态资源。最后将dist
部署到服务器上,使用Nginx
或Apache
来托管这个目录。Node.js
是一个JavaScript运行环境,它可以让Javascript在服务端运行。npm
是Node.js
的包管理器,用来安装、更新或卸载js包。安装Node.js
时会自动安装一个与Nodejs
兼容的npm
版本。如果node
和npm
版本不兼容,那么安装或运行某个包会失败。思路
package.json
文件,执行npm install
下载安装依赖,执行npm run build
输出dist
静态文件。项目打包首先需要编写Dockerfile
文件,我们在多阶段构建的Dockerfile
中定义第一阶段先将前端项目打包成静态文件,第二阶段再将静态文件复制到容器中部署运行。node
作为基础镜像,但可能会使打包的镜像文件较大;我们可以选择node-alpine
或alpine
作为基础镜像。node-alpine
镜像已经包含了nodejs运行时的相关工具,如npm和yarn,在打包时可以直接使用npm
指令。或是以alpine
作为基础镜像,在小操作系统中通过apk add
方式安装node
和npm
。如果需要指定node
版本需要在指令后追加版本号,如apk add nodejs=14.16.0
。步骤
以nodejs-alpine
作为基础镜像
# 第一阶段: 以node:14.16.0-alpine作为基础镜像,打包dist文件
FROM node:14.16.0-alpine AS builder
# 更换npm国内源
RUN npm config set registry https://registry.npm.taobao.org
WORKDIR /app
# 复制pakcge*.json 配置文件
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 第二阶段: 以nginx作为基础镜像,复制dist文件到nginx中
FROM nginx:stable-alpine3.17
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
以alpine作为基础镜像
# 使用apline作为基础镜像,下载nodejs和npm
FROM alpine:3.17 AS builder
# 换国内源,加快下载速度
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache --update nodejs npm
WORKDIR /app
# 复制package*.json配置文件
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 第二阶段: 以nginx作为基础镜像,复制dist文件到nginx中
FROM nginx:stable-alpine3.17
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
Makefile文件添加指令
.PHONY: docker
docker:
@rm -rf ./dist || true
@docker rmi basic_project_frontend:v1 || true
@docker build -t basic_project_frontend:v1 .
make docker
就开始打包了修改Docker compose文件
version: '3.7'
services:
db:
image: 'mysql:8.0'
container_name: 'basic-project-mysql'
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: 12345678
MYSQL_DATABASE: testdb
# 要确保要挂载的目录存在且有正确的读取权限
volumes:
- /var/lib/mysql
ports:
- '13306:3306'
redis:
image: 'redis:7.2.3'
container_name: 'basic_project_redis'
ports:
- '16379:6379'
backend:
depends_on:
- redis
- db
image: 'basic_project:v1'
container_name: 'basic-project'
ports:
- '8085:8000'
restart: always
# - - - - - 新增部分- - - -
frontend:
depends_on:
- backend
image: 'basic_project_frontend_compose:v1'
container_name: 'basic_project_frontend_compose'
environment:
# 配置 VUE_APP_BASE_API 访问后端服务的地址和端口
- VUE_APP_BASE_API='http://your_ip:port'
ports:
- '8080:80'
使用Docker compose方式运行
❯ docker-compose up -d
[+] Running 5/5
✔ Network frontend_default Created 0.1s
✔ Container basic-project-mysql Started 0.1s
✔ Container basic_project_redis Started 0.1s
✔ Container basic-project Started 0.0s
✔ Container basic_project_frontend_compose Started
登录功能
配置k8s的Ingress路由规则
概述
思路
helm
下载安装Ingress-Nginx
控制器。helm
是k8s的包管理器,可以管理k8s的应用程序。在helm
中仓库(repo)是存储Helm Chart的地方。Helm Chart是一种打包k8s应用程序的格式,它包含了一组定义k8s资源的YAML文件。Helm Chart仓库是一个Web服务器,该服务器保存了一系列的Chart应用以供用户下载,并且提供了一个该Respository的Chart包的清单文件以供查询。所以我们需要先安装helm
,使用helm
安装Ingress-Nginx
控制器,编写Ingress配置文件,创建Ingress资源、测试Ingress是否生效。步骤
安装helm
helm
的脚本,下载下来执行。完成后执行helm version
验证是否安装成功。如果确实网络不通畅可以讲下面的脚本复制到.sh
文件后执行;Mac用户可以直接使用brew
安装helm
。# Mac
brew install helm
# 其他设备 先将脚本下载,保存名字为 get-helm-3.sh,然后执行脚本。
url => https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
./get-helm-3.sh
# 验证helm是否安装成功。
❯ helm version
version.BuildInfo{Version:"v3.13.1", GitCommit:"3547a4b5bf5edb5478ce352e18858d8a552a4110", GitTreeState:"clean", GoVersion:"go1.20.8"}
#!/usr/bin/env bash
# Copyright The Helm Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The install script is based off of the MIT-licensed script from glide,
# the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get
: ${BINARY_NAME:="helm"}
: ${USE_SUDO:="true"}
: ${DEBUG:="false"}
: ${VERIFY_CHECKSUM:="true"}
: ${VERIFY_SIGNATURES:="false"}
: ${HELM_INSTALL_DIR:="/usr/local/bin"}
: ${GPG_PUBRING:="pubring.kbx"}
HAS_CURL="$(type "curl" &> /dev/null && echo true || echo false)"
HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)"
HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)"
HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)"
HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)"
# initArch discovers the architecture for this system.
initArch() {
ARCH=$(uname -m)
case $ARCH in
armv5*) ARCH="armv5";;
armv6*) ARCH="armv6";;
armv7*) ARCH="arm";;
aarch64) ARCH="arm64";;
x86) ARCH="386";;
x86_64) ARCH="amd64";;
i686) ARCH="386";;
i386) ARCH="386";;
esac
}
# initOS discovers the operating system for this system.
initOS() {
OS=$(echo `uname`|tr '[:upper:]' '[:lower:]')
case "$OS" in
# Minimalist GNU for Windows
mingw*|cygwin*) OS='windows';;
esac
}
# runs the given command as root (detects if we are root already)
runAsRoot() {
if [ $EUID -ne 0 -a "$USE_SUDO" = "true" ]; then
sudo "${@}"
else
"${@}"
fi
}
# verifySupported checks that the os/arch combination is supported for
# binary builds, as well whether or not necessary tools are present.
verifySupported() {
local supported="darwin-amd64ndarwin-arm64nlinux-386nlinux-amd64nlinux-armnlinux-arm64nlinux-ppc64lenlinux-s390xnwindows-amd64"
if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then
echo "No prebuilt binary for ${OS}-${ARCH}."
echo "To build from source, go to https://github.com/helm/helm"
exit 1
fi
if [ "${HAS_CURL}" != "true" ] && [ "${HAS_WGET}" != "true" ]; then
echo "Either curl or wget is required"
exit 1
fi
if [ "${VERIFY_CHECKSUM}" == "true" ] && [ "${HAS_OPENSSL}" != "true" ]; then
echo "In order to verify checksum, openssl must first be installed."
echo "Please install openssl or set VERIFY_CHECKSUM=false in your environment."
exit 1
fi
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
if [ "${HAS_GPG}" != "true" ]; then
echo "In order to verify signatures, gpg must first be installed."
echo "Please install gpg or set VERIFY_SIGNATURES=false in your environment."
exit 1
fi
if [ "${OS}" != "linux" ]; then
echo "Signature verification is currently only supported on Linux."
echo "Please set VERIFY_SIGNATURES=false or verify the signatures manually."
exit 1
fi
fi
if [ "${HAS_GIT}" != "true" ]; then
echo "[WARNING] Could not find git. It is required for plugin installation."
fi
}
# checkDesiredVersion checks if the desired version is available.
checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL
local latest_release_url="https://get.helm.sh/helm-latest-version"
local latest_release_response=""
if [ "${HAS_CURL}" == "true" ]; then
latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true )
elif [ "${HAS_WGET}" == "true" ]; then
latest_release_response=$( wget "$latest_release_url" -q -O - 2>&1 || true )
fi
TAG=$( echo "$latest_release_response" | grep '^v[0-9]' )
if [ "x$TAG" == "x" ]; then
printf "Could not retrieve the latest release tag information from %s: %sn" "${latest_release_url}" "${latest_release_response}"
exit 1
fi
else
TAG=$DESIRED_VERSION
fi
}
# checkHelmInstalledVersion checks which version of helm is installed and
# if it needs to be changed.
checkHelmInstalledVersion() {
if [[ -f "${HELM_INSTALL_DIR}/${BINARY_NAME}" ]]; then
local version=$("${HELM_INSTALL_DIR}/${BINARY_NAME}" version --template="{{ .Version }}")
if [[ "$version" == "$TAG" ]]; then
echo "Helm ${version} is already ${DESIRED_VERSION:-latest}"
return 0
else
echo "Helm ${TAG} is available. Changing from version ${version}."
return 1
fi
else
return 1
fi
}
# downloadFile downloads the latest binary package and also the checksum
# for that binary.
downloadFile() {
HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz"
DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST"
CHECKSUM_URL="$DOWNLOAD_URL.sha256"
HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)"
HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST"
HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256"
echo "Downloading $DOWNLOAD_URL"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE"
curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL"
wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL"
fi
}
# verifyFile verifies the SHA256 checksum of the binary package
# and the GPG signatures for both the package and checksum file
# (depending on settings in environment).
verifyFile() {
if [ "${VERIFY_CHECKSUM}" == "true" ]; then
verifyChecksum
fi
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
verifySignatures
fi
}
# installFile installs the Helm binary.
installFile() {
HELM_TMP="$HELM_TMP_ROOT/$BINARY_NAME"
mkdir -p "$HELM_TMP"
tar xf "$HELM_TMP_FILE" -C "$HELM_TMP"
HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/helm"
echo "Preparing to install $BINARY_NAME into ${HELM_INSTALL_DIR}"
runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR/$BINARY_NAME"
echo "$BINARY_NAME installed into $HELM_INSTALL_DIR/$BINARY_NAME"
}
# verifyChecksum verifies the SHA256 checksum of the binary package.
verifyChecksum() {
printf "Verifying checksum... "
local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}')
local expected_sum=$(cat ${HELM_SUM_FILE})
if [ "$sum" != "$expected_sum" ]; then
echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting."
exit 1
fi
echo "Done."
}
# verifySignatures obtains the latest KEYS file from GitHub main branch
# as well as the signature .asc files from the specific GitHub release,
# then verifies that the release artifacts were signed by a maintainer's key.
verifySignatures() {
printf "Verifying signatures... "
local keys_filename="KEYS"
local github_keys_url="https://raw.githubusercontent.com/helm/helm/main/${keys_filename}"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "${github_keys_url}" -o "${HELM_TMP_ROOT}/${keys_filename}"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "${HELM_TMP_ROOT}/${keys_filename}" "${github_keys_url}"
fi
local gpg_keyring="${HELM_TMP_ROOT}/keyring.gpg"
local gpg_homedir="${HELM_TMP_ROOT}/gnupg"
mkdir -p -m 0700 "${gpg_homedir}"
local gpg_stderr_device="/dev/null"
if [ "${DEBUG}" == "true" ]; then
gpg_stderr_device="/dev/stderr"
fi
gpg --batch --quiet --homedir="${gpg_homedir}" --import "${HELM_TMP_ROOT}/${keys_filename}" 2> "${gpg_stderr_device}"
gpg --batch --no-default-keyring --keyring "${gpg_homedir}/${GPG_PUBRING}" --export > "${gpg_keyring}"
local github_release_url="https://github.com/helm/helm/releases/download/${TAG}"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
fi
local error_text="If you think this might be a potential security issue,"
error_text="${error_text}nplease see here: https://github.com/helm/community/blob/master/SECURITY.md"
local num_goodlines_sha=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" 2> "${gpg_stderr_device}" | grep -c -E '^[GNUPG:] (GOODSIG|VALIDSIG)')
if [[ ${num_goodlines_sha} -lt 2 ]]; then
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256!"
echo -e "${error_text}"
exit 1
fi
local num_goodlines_tar=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" 2> "${gpg_stderr_device}" | grep -c -E '^[GNUPG:] (GOODSIG|VALIDSIG)')
if [[ ${num_goodlines_tar} -lt 2 ]]; then
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz!"
echo -e "${error_text}"
exit 1
fi
echo "Done."
}
# fail_trap is executed if an error occurs.
fail_trap() {
result=$?
if [ "$result" != "0" ]; then
if [[ -n "$INPUT_ARGUMENTS" ]]; then
echo "Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS"
help
else
echo "Failed to install $BINARY_NAME"
fi
echo -e "tFor support, go to https://github.com/helm/helm."
fi
cleanup
exit $result
}
# testVersion tests the installed client to make sure it is working.
testVersion() {
set +e
HELM="$(command -v $BINARY_NAME)"
if [ "$?" = "1" ]; then
echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?'
exit 1
fi
set -e
}
# help provides possible cli installation arguments
help () {
echo "Accepted cli arguments are:"
echo -e "t[--help|-h ] ->> prints this help"
echo -e "t[--version|-v <desired_version>] . When not defined it fetches the latest release from GitHub"
echo -e "te.g. --version v3.0.0 or -v canary"
echo -e "t[--no-sudo] ->> install without sudo"
}
# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977
cleanup() {
if [[ -d "${HELM_TMP_ROOT:-}" ]]; then
rm -rf "$HELM_TMP_ROOT"
fi
}
# Execution
#Stop execution on any error
trap "fail_trap" EXIT
set -e
# Set debug if desired
if [ "${DEBUG}" == "true" ]; then
set -x
fi
# Parsing input arguments (if any)
export INPUT_ARGUMENTS="${@}"
set -u
while [[ $# -gt 0 ]]; do
case $1 in
'--version'|-v)
shift
if [[ $# -ne 0 ]]; then
export DESIRED_VERSION="${1}"
if [[ "$1" != "v"* ]]; then
echo "Expected version arg ('${DESIRED_VERSION}') to begin with 'v', fixing..."
export DESIRED_VERSION="v${1}"
fi
else
echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary"
exit 0
fi
;;
'--no-sudo')
USE_SUDO="false"
;;
'--help'|-h)
help
exit 0
;;
*) exit 1
;;
esac
shift
done
set +u
initArch
initOS
verifySupported
checkDesiredVersion
if ! checkHelmInstalledVersion; then
downloadFile
verifyFile
installFile
fi
testVersion
cleanup
helm安装Ingress-nginx
ingress-nginx
的压缩包下载下来再安装。# 自动安装
# 添加Ingress-nginx的仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 更新仓库索引
helm repo update
# 安装Ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx
#手动安装
#如何网络不好下载不了ingress-nginx,可以先在电脑上手动下载
# https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.8.4/ingress-nginx-4.8.4.tgz
# 创建namespace
kubectl create namespace ingress-nginx
# 安装ingress-nginx
helm install ingress-nginx ingress-nginx-4.8.4.tgz --namespace ingress-nginx
编写Ingress配置文件
apiVersion
是networking.k8s.io/v1
,kind
属于Ingress
,还有spec -> ingressClassName
是nginx
,这三个配置对于INgress-nginx
是固定的。此外还需要告诉Ingress
从哪里来的路由发送到哪里去,下面这个配置文件意思是从basicproject.me.com
这个域名来的流量,前缀匹配/
这个路径,就转发到名为basic
的服务(与k8s-basicproject-backend
中Service的保持一致)和端口。# 指定k8s API版本
apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型
metadata:
name: ingress-demo # 起个名
spec:
ingressClassName: nginx # 这个只能写nginx
rules: # Ingress规则
- host: basicproject.me.com # 域名 ,该host要跟这个一致
http:
paths:
- backend:
service:
name: basic # 跟k8s-basicproject-backend.yaml文件 Service metadata的name对应
port:
number: 8085 #跟Service spec -> ports -> port对应
pathType: Prefix #路径类型:前缀
path: / # 匹配路径
更新Ingress规则&检查Ingress-Nginx状态
Ingress
的配置文件就更新一下配置,看看ingree-nginx的运行状态。# 更新ingress路由规则
kubectl apply -f k8s-basicproject-ingress.yaml
# 获取ingress-nginx-controller 资源的状态,指定ingress-nginx的命名空间
❯ kubectl get svc ingress-nginx-controller -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.102.48.106 localhost 80:30597/TCP,443:31086/TCP 122m
# huoqu 获取资源的详细信息, ingress-demo与配置文件中metadata -> name 对应
❯ kubectl describe ingress ingress-demo
Name: ingress-demo
Labels: <none>
Namespace: default
Address: localhost
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
basicproject.me.com
/ basic:8085 (10.1.0.55:8000)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 69m (x6 over 124m) nginx-ingress-controller Scheduled for sync
Normal Sync 15m (x3 over 51m) nginx-ingress-controller Scheduled for sync
修改本机Host
测试访问
写在最后
https://github.com/FengZeHe/LearnGolang/tree/main/project/BasicProject
原文始发于微信公众号(ProgrammerHe):前端项目打包部署与k8s配置Ingress
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207885.html