一次公司内网CICD搭建过程

账号密码


vSphere管理台前端开发账号 xxx.xxx.0.103/ [email protected] xxxxxx9


前端开发centos7 xxx.xxx.0.41 root xxxxxx9


gitlab xxx.xxx.0.41:30300/ root xxxxxx6


jenkins xxx.xxx.0.41:10240/ root xxxxxx6


Harbor xxx.xxx.0.41:30020/ admin xxxxxx5


verdaccio xxx.xxx.0.41:4873/ admin xxxxxx6 [email protected]


服务器需求

目前服务器上内存16G,硬盘500G

如果规划k8s最低两台服务器需求


机器A:192.168.1.200 8G内存 20G硬盘 规划安装 Docker、 Kuboard Spray 、Kuboard 、Gitlab 、Harbor 、Jenkins 机器B:192.168.1.201 6G内存 20G硬盘 不要装Docker,规划k8s的master和etcd节点、worker节点


VirtualBox 和 Centos 下载

VirtualBox

ruby 复制代码
https://www.oracle.com/virtualization/technologies/vm/downloads/virtualbox-downloads.html

CentOS 7

centos8 后面gitlab要报权限错误,还是用7就行了

ruby 复制代码
https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso

手动设置静态ip地址

ifcfg-enp0s3 根据每个机器名字不同,具体要查看 /etc/sysconfig/network-scripts/ 目录下

ini 复制代码
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens160
UUID=0897cf72-aab7-46e4-9c21-76af9adf9ef7
DEVICE=ens160
ONBOOT=yes
IPADDR=xxx.xxx.0.41
GATEWAY=xxx.xxx.0.126
NETMASK=255.255.255.0
DNS1=114.114.114.114
DNS2=8.8.8.8

shell连接服务器

推荐用 MobaXterm_Portable_v23.2.zip,在ftp上已经上传

arduino 复制代码
ftp://xxx.xxx.0.121 
 目录  /工具软件/运维软件   MobaXterm_Portable_v23.2.zip

内网加白地址

公司内网虚拟机需要加白下面这些地址: 国内docker镜像、国内jenkins插件镜像、国内npm仓库、国内yum源

lua 复制代码
mirrors.tuna.tsinghua.edu.cn
mirrors.aliyun.com
mirrors.fedoraproject.org
mirror-icn.yuki.net.uk
mirrors.fedoraproject.org
ung2thfc.mirror.aliyuncs.com
acs-cn-hangzhou-mirror.oss-cn-hangzhou.aliyuncs.com
docker.mirrors.ustc.edu.cn
auth.docker.io
registry-1.docker.io
production.cloudflare.docker.com
hub-mirror.c.163.com
updates.jenkins.io
get.jenkins.io
registry.npm.taobao.org
www.npmjs.com
registry.npmmirror.com
deb.debian.org

设置yum国内源

设置yum源

ini 复制代码
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
         -e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.tuna.tsinghua.edu.cn|g' \
         -i.bak \
         /etc/yum.repos.d/CentOS-*.repo

更新缓存

复制代码
yum makecache

Docker 环境安装

bash 复制代码
#关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
​
#安装基础软件包
yum install -y wget lsof net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack yum-utils
​
#配置 docker-ce 国内 yum 源(阿里云),如果失败还是用官网 https://download.docker.com/linux/centos/docker-ce.repo
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
​
#安装 docker 依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
​
#安装 docker-ce
yum install -y docker-ce docker-ce-cli containerd.io
​
#设置开机启动
systemctl enable docker
​
#启动Docker服务
systemctl start docker

Docker 语法

参考 yeasy.gitbook.io/docker_prac...

bash 复制代码
docker pull [image] 拉取镜像
docker images 查看所有镜像
docker ps 查看正在运行的容器
docker ps -a 查看所有容器,包括停止的容器
docker logs [containerID] 查看容器日志 -f 参数就是持续输出日志  
docker containre rm  [containerID] 移除容器
docker container start [containerID] 启动容器
docker container stop [containerID] 停止容器
docker container restart [containerID] 重启容器
docker container update --restart=always [containerID] 更新容器增加restart
docker container exec -it [containerID] /bin/bash  进入容器且启动shell
docker exec -it --user root [containerID] bash  用root进入容器shell
docker container cp [containID]:[/path/to/file]  /path/to/file 从正在运行的 Docker 容器里面,将文件拷贝到本机,两路径可交换
docker run -d --restart always -p 10240:8080 -p 10241:50000 -v /var/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime --name myjenkins jenkins/jenkins 运行jenkins容器,如果没有回下载镜像再安装容器,-d 后台运行  -p 端口映射 -v 目录挂载 --name 设置容器名称
systemctl restart docker 重启docker
docker cp 本地路径 容器id或者容器名字:容器内路径   # 本地到服务器
docker cp 容器id或者容器名字:容器内路径 本地路径   # 服务器到本地
docker run -ti -p 8080:8080 --name node-1 -v $(pwd):/workspace node bash # 可能容器报错就退出了,这样直接进去查看错误
docker logs -fnt mynginx   # 容器启动退出了,可以-fnt查看日志
docker system df   # 查看docker存储情况
docker builder prune --filter  'until=240h' -f  # 保留10天内的docker缓存,清除以前的缓存
docker rmi $(docker images -f "dangling=true" -q) # 清理所有none的镜像
docker rmi -f $(docker images | grep "none" | awk '{print $3}') # 清理所有none的镜像
docker search centos # 查询centos所有版本
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3 # 保存镜像文件
docker load --input my_ubuntu_v3.tar  # 导入镜像文件

添加国内镜像和内网Harbor的http请求地址

创建或修改/etc/docker/daemon.json文件 默认没有daemon文件,先创建。

rust 复制代码
vi /etc/docker/daemon.json
​
{
  'registry-mirrors': [
    'https://ung2thfc.mirror.aliyuncs.com',
    'https://registry.docker-cn.com',
    'http://hub-mirror.c.163.com',
    'https://docker.mirrors.ustc.edu.cn'
  ],
  'insecure-registries':['xxx.xxx.0.41:30020']
}

加载重启docker,在终端输入以下命令

复制代码
systemctl daemon-reload
​
systemctl restart docker

测试

arduino 复制代码
docker run hello-world

Gitlab

Gitlab启动很慢,装好后,等待10分钟再看是否启动了,可查看网页是否能访问

bash 复制代码
docker run --detach \
  --publish 30300:80 --publish 30301:443 --publish 30302:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ce:latest

获取root初始密码,这里获取的密码如果不能登录gitlab,直接用第三步重置root密码 注意:The password file will be automatically deleted in the first reconfigure run after 24 hours.

bash 复制代码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

web界面首次修改root密码

复制代码
右上角 再点击  Edit profile 再点击  password

重置root密码 reset password

bash 复制代码
docker exec -it gitlab bash
gitlab-rake 'gitlab:password:reset[root]'

修改gitllab显示的clone地址,不然是一串数字乱码

bash 复制代码
docker exec -it -u root gitlab bash
vi /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
修改地址 host: xxx.xxx.0.41
        port: 30300
        
   
gitlab-ctl restart

注意:如果gitlab容器重新运行了,那下面host和port需要再次修改

补充 :这里的gitlab.yml并未挂到外部,所以如果docker或服务器重启那这个配置就还原了,需要重写进入来配置和restart,有个办法是运行起来后docker commit gitlab mynewgitlab,把container重新打包镜像,然后增加--volume $GITLAB_HOME/gitlab-rails:/opt/gitlab/embedded/service/gitlab-rails/config 挂载重新运行一个容器,然后把旧容器删掉。

Harbor

Harbor需要docker-compose安装,所以需要下载docker-compose和harbor,docker-compose是批量运行docker容器的工具

docker-compose

docker-compose和harbor安装文件需要从github或者国内镜像kgithub上下载,速度很慢,所以已经放到ftp服务器上

arduino 复制代码
ftp://xxx.xxx.0.121 
 目录  /工具软件/运维软件   docker-compose  harbor-online-installer-v2.8.3.tgz
bash 复制代码
#上传 docker-compose 到 /data/app 目录,这个可以随意
cp /data/app/docker-compose /usr/local/bin/docker-compose
#修改执行权限
chmod +x /usr/local/bin/docker-compose
#软连接映射到/usr/bin/
ln -sf  /usr/local/bin/docker-compose /usr/bin/docker-compose
#验证
which docker-compose
docker-compose version
#解压harbor安装包
tar xf /data/app/harbor-online-installer-v2.8.3.tgz -C /data/app/
#编辑harbor.yml文件
cd /data/app/harbor
cp harbor.yml.tmpl harbor.yml

手动修改harbor配置文件

yaml 复制代码
cd harbor
vi harbor.yml
hostname:   xxx.xxx.0.41   #第5行,主机IP/或者域名
port: 30020    # 第10行,端口可改为 30020
harbor_admin_password: xxxxxx5   #第34行,harbor UI界面admin登陆密码
data_volume: /data/app/harbor-data  #第47行,harbor 持久化数据

#关闭https(把以下的行都注释掉12-18行)
# https related config
#https:
# # https port for harbor, default is 443
# port: 443
# # The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/p

# 安装脚本
运行 ./install.sh

默认账号密码 admin xxxxxx5

设置开机启动

创建文件 /usr/local/bin/harbor/harborstartall.sh,放下面内容

bash 复制代码
#!/bin/bash
cd /usr/local/bin/harbor
docker-compose stop
docker-compose start
chmod 777 /var/run/docker.sock

设置开机启动

bash 复制代码
chmod +x  /usr/local/bin/harbor/harborstartall.sh
#3)把启动脚本加到系统启动之后最后一个执行的文件
echo '/bin/bash /usr/local/bin/harbor/harborstartall.sh'  >>  /etc/rc

jenkins安装

步骤:

  • 1、安装 jenkins docker,要给docker.sock和jennkins_home为777权限
  • 2、默认安装jenkins,默认安装推荐插件
  • 3、配置system三个凭据(gitlab账号密码:gitlabroot,部署服务器ssh密钥:sshserver,推送镜像仓库账号密码:harbor)
  • 4、增加jenkins插件 Git Parameter、SSH Agent
  • 5、web项目根目录建Dockerfile文件,用node镜像打包,用nginx镜像做web服务器
  • 6、jenkins中建项目,建流水线,选SCM并配置信息
  • 7、构建运行两遍

安装

如果docker服务重启后,需要每次执行sudo chmod 777 /var/run/docker.sock,因为jenkins里面不是root会报没权限

bash 复制代码
chmod 777 /var/run/docker.sock
​
mkdir -p /var/jenkins_home
​
chmod 777 /var/jenkins_home
​
docker run -d --restart always -p 10240:8080 -p 10241:50000 -u root -v /var/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker --name jenkins jenkins/jenkins

首次登录密码

bash 复制代码
cat /var/jenkins_home/secrets/initialAdminPassword

安装默认插件

不默认安装插件,因为国内会失败,直接选不安装插件,进入后修改插件地址,再手动安装

参考 zhuanlan.zhihu.com/p/378093468

修改jenkins插件更新地址

在 插件管理中 修改 http://xxx.xxx.0.41:10240/manage/pluginManager/advanced 修改升级站点地址

ruby 复制代码
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

安装额外插件

Git Parameter、SSH Agent 勾选安装后重启 注意:第一次运行会失败,因为是gitParameter依赖与后面checkout的仓库信息

在服务器上生成公私钥

bash 复制代码
ssh-keygen  一直回车就行
​
cd ~/.ssh
​
cat cat id_rsa
​
拷贝打印内容 

添加gitlab、harbor、ssh身份认证

http://xxx.xxx.0.41:10240/manage/credentials/store/system/domain/_/ 地址添加凭证

添加 ssh 凭据

类型选择 SSH Username with private key

id 写 sshserver

username 写 root

Private Key > Enter directly > Add ,将上面rsa私钥全部复制进来

参考:blog.csdn.net/nklinsirui/...

添加 gitlab 凭据

类型选择 Username with password

id 写 gitlabroot

username 和 password 分别写 gitlab创建的账号,我们这里直接用的 root 管理员账号密码

添加 harbor 凭据

类型选择 Username with password

id 写 harbor

username 和 password 分别写 harbor 创建的账号,我们这里直接用的 admin 管理员账号密码

新建流水线项目

选择Pipeline script from SCM或者直接贴下面pipeline内容

dart 复制代码
// 注意先建system凭据

pipeline {
  agent any
	
	environment {
        // 毫秒做镜像标签
        imageTag = sh returnStdout: true, script: "date +%Y%m%d%H%M%S"
        // harbor仓库
		    harborServer = 'xxx.xxx.0.41:30020'
        harborLibrary = 'web'  // 第一次需要在harbor仓库建这个目录
        // git项目
		    gitServer = 'xxx.xxx.0.41:30300'
        gitGroup = 'wms'
        gitProjectName = 'wms-353-web'
        // 后端接口,区分开测试环境和生产环境
        testApiServer = 'http://xxx.xxx.0.41:8088'
        proApiServer = 'https://222.111.113.4:8080'
        // 测试环境前端地址,生产环境只打包镜像不发布
        webHtmlServer = 'xxx.xxx.0.41'
        webHtmlPort = '50090'
    }
    
    parameters {
        gitParameter name:'MR_TO_BRANCH',
                     type:'PT_BRANCH_TAG',
                     branchFilter:'origin/(.*)',
                     defaultValue:'master',
                     selectedValue:'DEFAULT',
                     sortMode:'DESCENDING_SMART',
                     description:'选择分支'
        
        choice(
          choices: "test\npro", name:'buildType', description:'选择发布环境'
        )
    }
	
    stages {
        stage('拉取代码') {
            steps {
                script {
                  if(params.buildType == 'test'){
                    env.testApiServer = env.proApiServer
                  }
                }
                git branch: "${MR_TO_BRANCH}",credentialsId: 'gitlabroot', url: "http://${gitServer}/${gitGroup}/${gitProjectName}.git"
            }
        }
        stage('打包docker') {
            steps {
                script{
                    withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harbor_password', usernameVariable: 'harbor_username')]) {
                        sh '''
                            docker login -u ${harbor_username} -p ${harbor_password} ${harborServer}
                            docker build -t ${harborServer}/${harborLibrary}/${gitProjectName}_${buildType}:${imageTag} --build-arg API_SERVER=${testApiServer} .
                            docker push ${harborServer}/${harborLibrary}/${gitProjectName}_${buildType}:${imageTag}
    				            '''
                    }
                }
            }
        }
        stage('清理镜像') {
            steps {
                script{
                  catchError(buildResult:'SUCCESS', stageResult:'SUCCESS'){
                    // 1、清理当前镜像  2、清理10天前历史缓存中间镜像
                    sh '''
                      docker rmi -f ${harborServer}/${harborLibrary}/${gitProjectName}_${buildType}:${imageTag}
                      docker images -f "dangling=true" '--format={{.Tag}} {{.ID}} {{.CreatedAt}}' | awk '{CS=mktime(sprintf("%s %s %s 00 00 00",substr($3,0,4),substr($3,6,2),substr($3,9,2)));ID=$2;NS=systime();DT=NS-10*86400;if(DT > CS){print ID}}' | xargs -r docker rmi -f
                    '''
                    // 不移除空白的镜像,因为那些是docker分层缓存 2023.09.08
                    // docker rmi -f $(docker images | grep "none" | awk '{print $3}')
                    // docker自带清理缓存10天前
                    // docker builder prune --filter  'until=240h' -f
                  }
                }
            }
        }
        stage('部署') {
            steps {
                script{
                  // 测试环境要打包+发布;生成环境只打包
                  if(params.buildType == 'test'){
                      sshagent(credentials: ["sshserver"]) {
                          withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harbor_password', usernameVariable: 'harbor_username')]) {
                              // 到远程服务器上建立文件夹 mkdir -p /home/nginx/${gitProjectName}_${buildType}/log 
                              sh '''
                                  ssh -o StrictHostKeyChecking=no -l root ${webHtmlServer} uname -a
                                  docker login -u ${harbor_username} -p ${harbor_password} ${harborServer}
                                  docker ps -a --filter "name=${gitProjectName}_${buildType}" -aq | xargs -r docker rm -f 
                                  docker images | grep "${gitProjectName}_${buildType}" | awk '{print $3}'| xargs -r docker rmi -f
                                  rm -rf /home/nginx/${gitProjectName}_${buildType} && mkdir -p /home/nginx/${gitProjectName}_${buildType}/log
                                  docker run -d --restart always --name ${gitProjectName}_${buildType} -v /home/nginx/${gitProjectName}_${buildType}/log:/var/log/nginx -p ${webHtmlPort}:80 ${harborServer}/${harborLibrary}/${gitProjectName}_${buildType}:${imageTag}
                              '''
                          }
                      }
                  }
                }
            }
        }
        stage('打印结果') {
            steps {
              script {
                echo "本次构建 ${params.buildType} 完成:"
                echo "镜像名:${harborServer}/${harborLibrary}/${gitProjectName}_${params.buildType}:${imageTag}"
                if(params.buildType == 'test'){
                  echo "接口地址: ${testApiServer}"
                  echo "页面地址: http://${webHtmlServer}:${webHtmlPort}"
                }
              }
            }
        }
    }
}

项目根目录建Dockerfile

swift 复制代码
# compile
FROM node:16 as build-stage
WORKDIR /app
COPY package*.json yarn.lock ./
RUN yarn install --registry https://registry.npm.taobao.org
COPY . .
RUN npm run build
​
# production stage
FROM nginx as production-stage
ARG API_SERVER
ENV LANG en_US.UTF-8
ENV API_SERVER=${API_SERVER}
RUN echo "server {  \n\
              listen       80; \n\
              location   /jeecgboot/ { \n\
              proxy_pass              ${API_SERVER}/jeecg-boot/; \n\
              proxy_redirect          off; \n\
              proxy_set_header        Host jeecg-boot-system; \n\
              proxy_set_header        X-Real-IP $remote_addr; \n\
              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for; \n\
          } \n\
          #解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \n\
          location / { \n\
              root   /var/www/html/; \n\
              index  index.html index.htm; \n\
              if (!-e $request_filename) { \n\
                  rewrite ^(.*)$ /index.html?s=$1 last; \n\
                  break; \n\
              } \n\
          } \n\
          gzip on; \n\
          gzip_min_length 1k; \n\
          gzip_http_version 1.1; \n\
          gzip_comp_level 6; \n\
          gzip_types text/plain application/x-javascript text/css application/xml application/javascript; \n\
          gzip_vary on; \n\
          access_log  /var/log/nginx/access.log ; \n\
      } " > /etc/nginx/conf.d/default.conf \
    &&  mkdir  -p  /var/www \
    &&  mkdir -p /var/www/html
COPY --from=build-stage /app/dist /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
​

运行一遍后,勾选不允许并发构建,并设置参数化构建过程中高级的列表数量改为10

注意,为了满足多个项目同时打包,最好开起多个执行器

复制代码
1点击系统管理--》节点配置---》选择master配置从节点,将执行器数量增大即可,比如设置为10

增加 .dockerignore

Dockerfile一般是放到项目根目录,但是在执行docker build时,会讲Dockerfile所在目录所有文件放入daemon上下文中,会导致构建很慢,所以需要.dockerignore把那些不需要的文件夹/文件忽略掉,build和src等要有

csharp 复制代码
.git
node_modules
package-lock.json
pnpm-lock.yaml

运行jenkins

选择分支构建即可 注意运行前面几次可能只有master分支出现,要多等待,可能与 Git Parameter 依赖之前执行的git checkout 信息

Verdaccio搭建

搭建npm私服

新建挂载目录

bash 复制代码
mkdir -p /home/verdaccio/conf
mkdir -p /home/verdaccio/storage
chmod 777 /home/verdaccio

添加配置文件

如果不要权限,设置为$anonymous

yaml 复制代码
vi /home/verdaccio/conf/config.yaml
​
storage: /verdaccio/storage
auth:
  htpasswd:
    file: /verdaccio/conf/htpasswd
uplinks:
  npmjs:
    url: https://registry.npm.taobao.org/
packages:
  '@cy/*':
    access: $all
    publish: $authenticated
    proxy: npmjs
  '@*/*':
    access: $all
    publish: $authenticated
    proxy: npmjs
  '**':
    access: $anonymous
    proxy: npmjs
logs:
  - {type: stdout, format: pretty, level: http}

新建空密码文件,空内容就行

arduino 复制代码
/home/verdaccio/conf/htpasswd

设置权限

bash 复制代码
chown 10001:65533 /home/verdaccio/conf/htpasswd
chown 10001:65533 /home/verdaccio/storage

启动容器

bash 复制代码
docker run -d --restart always --name verdaccio -p 4873:4873 -v /home/verdaccio/storage:/verdaccio/storage -v /home/verdaccio/conf:/verdaccio/conf -v /home/verdaccio/plugins:/verdaccio/plugins verdaccio/verdaccio

即可网页访问 4873端口了

添加用户

arduino 复制代码
npm adduser --registry http://xxx.xxx.0.41:4873/

输入用户名、密码和邮箱。自己设定就行。已经设置了一个账号 admin xxxxxx6 [email protected]

登录

arduino 复制代码
npm login --registry http://xxx.xxx.0.41:4873/

publish

当需要把某个项目发布到私有库时,直接 publish。

arduino 复制代码
npm publish --registry http://xxx.xxx.0.41:4873/

发布成功后,刷新页面,就能看到最新发布的包。

主项目使用私服包

1、包项目packages.json中name设置为@cy/xxxx 注意固定前缀为@cy

arduino 复制代码
{
  'name': '@cy/vue2-workflow-designer',
}

2、主项目设置.npmrc

ini 复制代码
registry=https://registry.npmmirror.com
@cy:registry=http://xxx.xxx.0.41:4873/

防火墙端口开起/关闭

css 复制代码
firewall-cmd --zone=public --add-port=5672/tcp --permanent && firewall-cmd --reload  # 开放5672端口
​
firewall-cmd --zone=public --remove-port=5672/tcp --permanent && firewall-cmd --reload #关闭5672端口
​
firewall-cmd --zone=public --list-ports       # 查看防火墙所有开放的端口
​
systemctl start firewalld.service  # 防火墙打开  stop是关闭

nginx

注意需要两次启动nginx,否则报配置文件不存在错误

bash 复制代码
docker run -p 30600:80 --name mynginx -d nginx:latest
​
docker cp mynginx:/etc/nginx /home/nginx
​
docker cp mynginx:/usr/share/nginx/html /home/nginx/html
​
docker rm -f mynginx
​
docker run -p 9001:80 --restart always \
--name mynginx \
-v /home/nginx:/etc/nginx \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-d nginx:latest

前端容器优化策略

Docker 如何缓存前端依赖

参考

juejin.cn/post/715766...

juejin.cn/post/721596...

docker build context 太大问题

css 复制代码
Sending build context to Docker daemon 2G

这个问题需要增加 .gitignore文件,因为 docker build时会根据Dockerfile文件所在位置加载所有同级目录和文件,所以需要排除不拷贝到上下文的文件比如 .git,node_modules

相关推荐
专注VB编程开发20年1 分钟前
VB.NET关于接口实现与简化设计的分析,封装其他类
java·前端·数据库
小妖66610 分钟前
css 中 content: “\e6d0“ 怎么变成图标的?
前端·css
L耀早睡1 小时前
mapreduce打包运行
大数据·前端·spark·mapreduce
HouGISer1 小时前
副业小程序YUERGS,从开发到变现
前端·小程序
outstanding木槿1 小时前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
霸王蟹2 小时前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹2 小时前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
专注VB编程开发20年2 小时前
asp.net IHttpHandler 对分块传输编码的支持,IIs web服务器后端技术
服务器·前端·asp.net
爱分享的程序员3 小时前
全栈项目搭建指南:Nuxt.js + Node.js + MongoDB
前端
隐含3 小时前
webpack打包,把png,jpg等文件按照在src目录结构下的存储方式打包出来。解决同一命名的图片资源在打包之后,重复命名的图片就剩下一个图片了。
前端·webpack·node.js