1.前端部署
1.先打包前端项目为dist 文件
npm run build
!!!!!
重点 现在vscode 跑一下 看dist能不能跑起来
!!!!!
//1、打包项目文件npm run build //2、进入dist打包文件 !!!!!cd dist //3、全局安装http-servernpm install http-server -g //4、启动dist文件(-p:端口。9008具体端口号)http-server -p 9008
2.先安装nginx ,能成功跑起来
docker pull nginx
拉取nginx镜像
docker images
查看已有镜像
docker run --name nginx-test -p 9091:80 -d nginx
启动nginx
--name #给你启动的容器起个名字,以后可以使用这个名字启动或者停止容器-p #映射端口,将docker宿主机的9091端口和容器的80端口进行绑定,物理宿主机通过9091端口来访问容器的80端口-v #挂载文件用的-d #表示启动的是哪个镜像。
3. Nginx服务的配置和部署
`创建 conf文件目录 /home/docker/nginx/conf``
3.1从容器中拷贝出nginx.conf配置文件
docker cp 容器ID:/etc/nginx/nginx.conf /home/docker/nginx/conf
(刚刚运行一个nginx容器,就是为了拷贝出容器中的默认配置文件到宿主机系统目录里)
后边宿主机目录要提前创建好在home下创建一个docker文件夹,用来专门存docker容器的映射文件。在docker下创建一个nginx的文件夹,用于存nginx的映射文件。在nginx下创建三个关键的映射文件。html映射html目录,也就是网页目录。logs文件映射日志目录。conf文件映射配置目录
开始拷贝
[root@localhost nginx]# docker cp b56ec16a3be9:/etc/nginx/nginx.conf /home/docker/nginx/confSuccessfully copied 2.56kB to /home/docker/nginx/conf
nginx.conf 配置
user nginx;worker_processes auto;error_log /var/log/nginx/error.log notice;pid /var/run/nginx.pid;events { worker_connections 1024;}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 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 80; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }}
重点有两个 一个事 监听的端口号 可以自定义,不写默认80
还有一个 会去展示容器中index.html的 内容,容器中的是宿主机映射过来的
try那句是重定向的意思,刷新页面重定向
3.2 docker 容器与主机文件进行映射
为什么要进行映射?
我们的dockerfile,docker-compose 和nginx的dist等文件都是放在宿主机目录下的并不是某一个容器下。
我们在使用容器的过程中需,有时候需要对容器中的文件进行修改管理,如果不做文件映射的化,我们使用docker exec -it 容器ID/容器名 /bin/bash 才能进入nginx中的文件里面才能操作,无法通过改变宿主机目录的内容来改变容器中的内容。
那为什么不直接写在容器内呢?
因为容器是可变的,如果容器被删除了,那么容器里面的数据也将会被删除。这就提到了挂载,容器中的数据 挂载 到虚拟机的目录上,这样我们往容器里面写入东西,其实是写入到了Docker宿主(虚拟机)的路径下面,这样即使把容器删除掉了,数据还是会保存在Docker的宿主里面。除非docker宿主机的文件也被删除了,否则数据就会一直存在。
ok,下面操作
映射规则如下
宿主机 容器/home/docker/nginx/html /usr/share/nginx/html #网页文件/home/docker/nginx/conf/nginx.conf /etc/nginx/nginx.conf#配置文件/home/docker/nginx/logs /var/log/nginx#日志文件
复制完默认配置文件,前面那个容器就没用了,删了
docker stop 容器ID
docker rm 容器ID
再创建一个nginx容器,并进行文件挂载(宿主机目录和这个容器目录双向绑定)
docker run -d -p 9091:80 --name nginx-test -v /home/docker/nginx/html:/usr/share/nginx/html -v /home/docker/nginx/conf/nginx.conf :/etc/nginx/nginx.conf -v /home/docker/nginx/logs:/var/log/nginx nginx
这样宿主机目录里缺的,都会传过来,而文件更改,容器目录也会更改
成功,但后端没有接
2.后端部署
后端部署流程
在/home/docker 路径下,尽量用root用户
1.给项目打jar包
打好的包在target里
通过xftp传到虚拟机里
注意如果没有docker-compose文件,需要提前在application.yml里修改mysql的地址为ip地址而不是localhost
注意
jar 要测试
在jar包的目录下 打开cmd
运行 看是否成功运行
2.编写Dockerfile文件
FROM openjdk:8VOLUME /tmpADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar# 设置时区RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeRUN echo 'Asia/Shanghai' >/etc/timezone# 暴露17080端口EXPOSE 8081ENTRYPOINT [ "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar" ]
3.build jar包
docker build -t api .
## .是指当前目录,所以要cd到Dockerfile的目录下
4. 查看镜像
docker images
5.运行镜像
docker run -d -p 8081:8081 --name httpapi api
## -d:后台运行该容器 ,-p:容器内部端口随机映射到主机的端口
需要日志的 看下面日志问题
docker run -d -p 8081:8081 -v ./log:/log --name httpapi api
docker ps
查看运行容器命令
docker ps -a
查看全部容器
docker rm 容器ID
删除 容器
docker rmi 镜像ID
删除镜像
mkdir 文件名
新建文件
mv 原文件地址 现文件地址
移动/修改文件名
!!!重点!!!
删除所有容器
docker rm -f $(docker ps -aq)
删除所有镜像
docker rmi -f $(docker images -aq)
然后主机就可以访问swagger了
访问地址:
http://192.11.11(虚拟机ip地址):8081/swagger-ui.html#/
-------更新2023-6-23---------
docker-compose
①docker-compose 安装
①下载docker-compose命令
curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-'uname -s'-'uname -m' > /usr/local/bin/docker-compose
由于用命令下载docker-compose 会出现502错误
所以直接链接下载
https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-Linux-x86_64
②然后拷贝至/usr/local/bin/目录下,可以用xftp移动到/usr/local/bin/下
③授予权限
chmod +x /usr/local/bin/docker-compose
④验证是否安装成功
docker-compose -v
②docker-compose 使用
上面是安装,
会在/usr/local/bin/下有一个
但是使用是需要docker-compose.yml 文件的,而且路径是和之前你后端部署的Dockerfile在同一个文件夹下 我这都在/home/docker下
接下来就是编写docker-compose.yml 文件了
version: '3'services: swagger2-demo: image: swagger2-demo:0.0.3 container_name: swagger2-demo build: dockerfile: Dockerfile context: ./ args: JAR_RELEASE_PATH: swagger2-demo-0.0.1-SNAPSHOT.jar JAR_POSE: 8081 links: - redis ports: - 8081:8081 restart: always volumes: - ./log:/log environment: file.encodin: utf-8 server.port: 8081 spring.datasource.url: jdbc:mysql://数据库地址:3306/ludaTest?serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true spring.datasource.username: root spring.datasource.password: 数据库密码 spring.profiles.active: dev logging.file.max-history: 100 SPRING_REDIS_HOST: redis networks: mynet: aliases: - swagger2-demo redis: image: redis:latest container_name: redis-demo restart: always networks: mynet: aliases: - redis nginx: image: nginx container_name: nginx expose: - 80 ports: - "80:80" - "443:443" volumes: - /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf - /home/docker/nginx/html:/usr/share/nginx/html - /home/docker/nginx/logs:/var/log/nginx networks: mynet: aliases: - nginxmysql-test: image: mysql:5.7.37 restart: always container_name: mysql-test hostname: mysql-test environment: MYSQL_ROOT_PASSWORD: 密码 TZ: Asia/Shanghai ports: - 3306:3306 volumes: - /home/docker/mysql/conf/my.cnf:\/etc/mysql/my.cnf - /home/docker/mysql/data:\/var/lib/mysql command: --max_connections=1000 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --default-authentication-plugin=mysql_native_password networks: mynet: aliases: - mysql-testnetworks: mynet: external: true
我这里就是配了自定义镜像swagger2-demo ,和redis,nginx,还有主机的数据库地址(我的数据库在主机上,不在虚拟机上)
注意!!
yml文件特别 注意缩进 空格,可以给gpt,叫他给你改一改
然后就是一些命令
启动 docker-compose
docker-compose up
若是要后台运行
docker-compose up -d
成功启动之后可以通过docker-compose ps
查看
至此,docker-compose就成功了。
通过实践两种部署方式,第一种每一个容器都要手动启动,且要是jar包代码内有改动如数据库的改动,你要再打开idea重新打包一次,而docker-compose做到的就是覆盖,对原始代码的覆盖,这样修改只需要修改docker-compose文件就好。
注意一个问题 : 文件的位置问题
/log 是根目录下的log
./log 是当前目录下的log
要时刻知道 你当前是什么目录
另外 dockfile最好和docker-compose在一个目录下
标红是``
至此 前后端分别都能访问
-------------2023-6-25--------------------------------------------------------------
问题一:build出问题
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 668a7264-5d0b-45a6-b547-fa8fff014bda::g00ukurq2ipxuvrrz8rnpyskp: "/swagger2-demo-0.0.1-SNAPSHOT.jar": not found
[root@localhost /]# docker build -f ./home/docker/Dockerfile -t api .[+] Building 0.0s (6/8) => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 410B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/java:8 0.0s => [internal] load build context 0.0s => => transferring context: 2B 0.0s => [1/4] FROM docker.io/library/java:8 0.0s => ERROR [2/4] ADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar 0.0s------ > [2/4] ADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar:------Dockerfile:3-------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | >>> ADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar 4 | # 设置时区 5 | RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime--------------------ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 668a7264-5d0b-45a6-b547-fa8fff014bda::g00ukurq2ipxuvrrz8rnpyskp: "/swagger2-demo-0.0.1-SNAPSHOT.jar": not found
玄学,目前看,进入Dockerfile路径下,再build就可以,直接用-f 指定路径还是找不到
docker build 命令 :
docker build -t api .
终端
[root@localhost /]# cd /home[root@localhost home]# lsdocker redis website za[root@localhost home]# cd docker[root@localhost docker]# lsbk docker-compose.yml Dockerfile nginx swagger2-demo-0.0.1-SNAPSHOT.jar[root@localhost docker]# docker build -t api .[+] Building 0.0s (9/9) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 410B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/java:8 0.0s => [internal] load build context 0.0s => => transferring context: 115B 0.0s => [1/4] FROM docker.io/library/java:8 0.0s => CACHED [2/4] ADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar 0.0s => CACHED [3/4] RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 0.0s => CACHED [4/4] RUN echo 'Asia/Shanghai' >/etc/timezone 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:9d4269948f2d634446a5180c8b0d7fb5219f6246c5cf8a5aa437ce8354ca588e 0.0s => => naming to docker.io/library/api 0.0s[root@localhost docker]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEapi latest 9d4269948f2d 15 minutes ago 725MBswagger-demo latest 9d4269948f2d 15 minutes ago 725MBnginx latest 7d3c40f240e1 8 days ago 143MBredis latest 0ec8ab59a35f 4 weeks ago 117MBhello-world latest 9c7a54a9a43c 6 weeks ago 13.3kBopenjdk 17 5f94f53bbced 18 months ago 471MBmysql latest 3218b38490ce 18 months ago 516MBmysql 8.0.23 cbe8815cbea8 2 years ago 546MBjava 8 d23bdf5b1b1b 6 years ago 643MB
问题二:自定义镜像运行后就停止
这种一般是,build时候就有问题,Dockerfile 有问题。
Dockerfile文件 正确的
FROM java:8VOLUME /tmpADD swagger2-demo-0.0.1-SNAPSHOT.jar app.jar# 设置时区RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeRUN echo 'Asia/Shanghai' >/etc/timezone# 暴露17080端口EXPOSE 8081ENTRYPOINT [ "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar" ]
这里ADD 打包的jar包 build后的jar 包
一般还是因为路径问题找不到你打包的jar 包导致也找不到app.jar,
所以还有回去重新打包,看Dockerfile文件
我之前是没有明确jar包,改成
ARG JAR_RELEASE_PATH=swagger2-demo-0.0.1-SNAPSHOT.jar
== docker 运行命令 ==
docker run -d -p 8090:8090 --name music api
Dockerfile 错误的
FROM java:8ARG JAR_RELEASE_PATHARG JAR_POSE=8081RUN echo "ARGS is ${JAR_RELEASE_PATH}"COPY ${JAR_RELEASE_PATH} app.jarENTRYPOINT ["java","-jar","-Duser.timezone=GMT+8","/app.jar"]EXPOSE ${JAR_POSE}
启动成功示意
[root@localhost docker]# docker run -d -p 8081:8081 --name music apif57245ddf45b7709906dadc8d663244079f04154677eb2a1a02d9bafcc0e1a55[root@localhost docker]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf57245ddf45b api "java -Djava.securit…" 3 seconds ago Up 2 seconds 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp music4cc0e3a49eff redis "docker-entrypoint.s…" 8 days ago Up 40 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp myredis
补充 自定义网络(目前看没什么大用)
在我们通过docker run创建容器的时候默认就会去使用docker bridge的网络;
但是docker0,是无法容器之间互通的,需要--link设置,才能互相ping通
所以 在我们创建容器的时候指定容器使用的网络,并且我们也可以创建一个自定义的网络
两个容器之间使用的都是自定义的网络,那么他们之间就相当于添加了一个双向的link。即可以通过IP访问,也可以通过容器名访问
①修改docker-compose.yml
我是通过docker-compose 设置要创建的容器的网络为我自定义的网络mynet
services: api: image: api container_name: music build: dockerfile: Dockerfile context: ./ args: JAR_RELEASE_PATH: swagger2-demo-0.0.1-SNAPSHOT.jar JAR_POSE: 8081 links: - redis ports: - 8081:8081 restart: always volumes: - ./log:/log environment: file.encodin: utf-8 server.port: 8081 spring.datasource.url: jdbc:mysql://你的数据库ip:3306/ludaTest?serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true spring.datasource.username: root spring.datasource.password: 密码 spring.profiles.active: dev logging.file.max-history: 100 SPRING_REDIS_HOST: redis networks: 修改这里 - mynet redis: image: redis container_name: myredis restart: always # ports: # - 6379:6379 networks: 修改这里 - mynet nginx: #定义一个名为nginx-server的service image: nginx #容器镜像 container_name: nginx #容器名称 expose: #容器要暴露的端口 - 80 ports: #容器的端口映射, host_port:container_port - "80:80" - "443:443" volumes: - /home/docker/nginx/html:/usr/share/nginx/html - /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf - /home/docker/nginx/logs:/var/log/nginx networks: 修改这里 - mynet networks: 修改这里 mynet: external: true
设置好后,删除所有容器,所有镜像
docker rm -f $(docker ps -aq)
docker rmi -f $(docker images -aq)
再启动docker-compose
docker-compose up -d
成功
查看所有网络
docker network ls
查看某一网络详细信息
docker network inspect f9dc86662e23
现在我的前后端的容器都在我自定义的网络下,能互相ping通
互相ping通
中间有个小插曲 nginx ping不通music
[root@localhost docker]# docker exec -it nginx ping music
OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown
解决方法:
docker container exec -it nginx bash
apt-get update
apt-get install iputils-ping
ok
注意!一定进入bash 张这样root@01d54de815b2:/#
,
如果张下面这样,【root@01d54de815b2:/# 】
上面不行
下面这样才行
输入命令
docker container exec -it nginx bash
apt-get update
apt-get install iputils-ping
继续
问题三:docker exec -it 873619784f58 bash
命令进入容器,不是出现 [root@873619784f58 /]而是出现了bash-4.4#
产生原因:命令行显示-bash-4.4# 的原因是在当前用户的root目录缺少了两个文件
是但是不要退出bash,不要退回[root@localhost ~]处
我之前反复在[root@localhost ~]处执行下面命令,没效果
解决方法:
bash-4.4# cp /etc/skel/.bashrc /root/
bash-4.4# cp /etc/skel/.bash_profile /root/
bash-4.4# exit
然后(持久化 .bashrc文件和 .bash_profile这两个文件)
[root@6829a4eaef65 /]# source ~/.bashrc
[root@6829a4eaef65 /]# source ~/.bash_profile
重启容器,检查是否正确使用
[root@localhost ~]# docker restart 873619784f58
ok
问题四:但是前端只是个登录页面,调接口调不通显示 NETWORK ERROR
意思说 我的前端nginx容器无法访问后端api容器
如果前端页面调的接口地址应该是虚拟机的地址而不是物理主机的实际数据库地址,它是通过调后端接口转发到实际的物理主机数据库地址的
而不是10.53.16.11
这个物理主机实际数据库地址。如果错了,修正方法:dist的后端地址要是192.168.2.131:8081
虚拟机后端地址,然后删除nginx镜像,再跟着上面nginx run一个新的容器,挂载好,然后删容器,再执行docker-compose up -d
好了,
现在再访问前端页面也能调到接口数据了
问题五,修改nginx配置文件不起作用
问题分析:去看这个nginx容器,有没有和系统文件挂载上。
刚刚不是通过这个命令,挂载的吗
docker run -d -p 9091:80 --name nginx-test / -v /home/docker/nginx/html:/usr/share/nginx/html / -v /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf/ -v /home/docker/nginx/logs:/var/log/nginx nginx
挂载以后 ,查看容器详细,看mount会看到bind挂载
docker inspect 容器ID
重点!!!!
不要直接去找/var/log/nginx /usr/share/nginx/html
要进入容器后再看
进入容器后 用
whereis nginx
来看
容器加文件(建议挂载目录,而不是文件)
看到mount处挂载上了,再新增一个txt,试试效果。
最后
部署问题:
1 其他局域网下的物理机无法连上部署的虚拟机地址
2.Nginx部署的流程,为什么有时候会访问10.53.11.11:8080(我物理机的地址)
前端调后端接口地址没有改,要改成虚拟机后端地址
部署时的 9091:80 意思,能不能修改,为什么一个虚拟机部署两个nginx,容器都是默认80 端口,不会冲突
9091:80 容器端口80映射到宿主机端口9091,宿主机可以通过9091访问
可以改,如果你挂载的是nginx.conf,那么就改这个文件和docker-compose的中nginx的端口为81就好,如果出500502,可能dist文件映射有问题
3.Ping不ping通重要吗,除了直接改dist里的后端地址,其他文件可改吗,nginx.conf 里的 location 映射不起作用,
/etc/nginx 没有 有,但是要进入容器
可以不ping通,自定义网络和部署没太大关系。nginx.conf 里的 location 映射 / 前端的页面可以,但是后端代理不太行。
4.Nginx的挂载啥意思 相互绑定
5.部署到云服务器什么意思
暂定
问题六: 修改过的nginx.conf 后,docker容器就跑不起来了
解决办法:logs里看 error.log
一般两种问题
一种 格式问题
一种 root 位置不对
是系统的位置
问题七 对于 单页面一刷新会造成页面404的问题
参考上面的location /的代码
问题八 日志问题
前面提到的nginx 、mysql的日志都可以成功导到自己的文件夹中。但是后端这个api,找不到容器日志的默认地址。期间想过通过容器ID文件夹,到找到对应容器ID的json.log . 有点复杂 遂放弃。
新思路 :打包后端jar 包时,在yml中加入语句,导出log文件夹(这是容器文件夹),再挂载到 自定义文件夹
logging: file: name: log/dev.log
这样在左侧打包后 就会出现log文件夹,里面有dev.log
这是实时更新的。
执行 容器指令
docker run -d -p 8081:8081 -v ./log:/log --name httpapi api
重点是在 -v ./log:/log 把jar包中的log挂在到 当前文件夹的log中,./log 是因为我现在是在api文件下的
run起来后 ,看自己log文件夹有没有dev.log就可以了
其实平时看报错不建议这样 ,这是保留历史日志的
看最新日志是
docker logs -f 容器名
问题九 nginx改端口号
前端代码,vue.config.js ,加个port,默认是80
devServer: { publicPath: Setting.publicPath, port: 9091 },
docker-compose 里的nginx配置
nginx: image: nginx container_name: nginx expose: - 9091 ports: - "9091:9091" - "443:443" volumes: - /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf - /home/docker/nginx/html:/usr/share/nginx/html - /home/docker/nginx/logs:/var/log/nginx networks: mynet: aliases: - nginx
nginx.conf里
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 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 9091; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }
这几个里改9091 端口号