Docker 部署 前端+后端+数据库 3个服务整合进一个容器中

前言

工作中我们总会遇到许多抽象的需求,前段时间组长让我写了个验证码组件,前端后端数据库都让我整,写完打包给他,耗时1周整完。

正当我准备继续摸鱼时,组长又给我提个需求,把前端后端数据库所有服务用docker整合进一个镜像中,到时候直接运行。。。。我听完懵逼了两秒,不是哪有这种操作啊?这不违反了Docker的单一职责原则吗,用Docker Compose多香啊。。。。

吐槽归吐槽,该干还得干,去网上搜了一下,牛魔的根本没人会这么干啊,只能自己摸着石头过河了。

前端,后端,数据库,三个服务,一个容器


基础镜像的选择

首先是基础镜像的选择,我一开始想的是用 mysql:8.0、openjdk:8-alpine 或者 nginx 为基础镜像,在这个基础镜像上安装其他服务所需要的环境,但是后来发现,这三个镜像没有包管理器,不能使用 apt 或者 yum 安装其他服务,所以这条路走不通。

既然那三个镜像没有包管理器,那我们就找一个自带包管理器的基础镜像就行了,这里我选的是Ubuntu,包管理器为 apt

然后是版本的选择,下面这个表格是不同Ubuntu版本和它们通常默认安装的MySQL版本

Ubuntu版本默认MySQL版本
Ubuntu 22.04 LTSMySQL 8.0
Ubuntu 20.04 LTSMySQL 8.0
Ubuntu 18.04 LTSMySQL 5.7
Ubuntu 16.04 LTSMySQL 5.7
Ubuntu 14.04 LTSMySQL 5.5
Ubuntu 12.04 LTSMySQL 5.5

我使用的数据库是 MySQL 8,所以应该选 22 或者 20 的版本,关于 22 和 20 两个版本的选择,我给出的答案是选择 22,理由如下

在 Ubuntu 20.04 版本中,使用 apt install -y mysql-server安装 mysql 时,会在提示我们选择时区,此时系统会阻塞并等待我们输入,但是我们在写 Dockerfile 构建镜像时应该尽可能避免这种要交互的操作

FROM ubuntu:20.04

# 安装MYSQL
RUN apt update \
 && apt install -y mysql-server

提示选择时区

而 Ubuntu 22.04 则不需要选择时区,直接就能安装成功,所以这里我选择的是 Ubuntu 22.04 版本


MySQL 的安装和配置

选择完基础镜像后就是安装 MySQL,使用 apt install -y mysql-server安装完 mysql 后,默认是没有密码的,输入mysql -u rooot直接就能登录成功,接下来需要设置密码,这一步不能少,否则后端会连接不上!!!

设置密码的常规操作是先登录进 mysql,然后设置密码

mysql -u root
ALTER user 'root'@'localhost' identified with mysql_native_password by 'root';

我这里设置的密码是 root,大家可以自行设置,改最后的引号里的内容

然而,我们要在 Dockerfile 里面完成设置密码这件事,需要把登录mysql设置密码 合成一句话,变成这样

mysql -u root -e "ALTER user 'root'@'localhost' identified with mysql_native_password by 'root';"

写在 Dockerfile 中是这样

FROM ubuntu:22.04

# 安装MYSQL
RUN apt update \
 && apt install -y mysql-server

# 改密码
RUN service mysql restart \
 && mysql -u root -e "ALTER user 'root'@'localhost' identified with mysql_native_password by 'root';" 

其中这句 service mysql restart不能少,安装完 mysql 后要重启一次才能正常登录,否则会报下面这个错误

在这里插入图片描述

然后我们再把执行 sql 文件的部分加进去,记得先将 sql 文件和 Dockerfile 放在一个目录下

在这里插入图片描述

复制 sql 文件到容器中,执行sql,同理,也是登录和执行写成一句话

mysql -u root < /verify-code.sql

Dockerfile

FROM ubuntu:22.04

# 复制sql文件
COPY ./verify-code.sql /

# 安装MYSQL
RUN apt update \
 && apt install -y mysql-server

# 执行sql && 设置密码
RUN service mysql restart \
 && mysql -u root < /verify-code.sql \
 && mysql -u root -e "ALTER user 'root'@'localhost' identified with mysql_native_password by 'root';"

这里我把执行 sql 放在设置密码前面,这样就可以少写一个-p root

至此,MySQL 的安装算是告一段落了


JDK的安装

apt install -y openjdk-8-jdk

准备好后端 jar 包(这里默认大家都会了哈),和 Dockerfile 放一起

在这里插入图片描述

Dockerfile

FROM ubuntu:22.04

# 复制sql文件
........
# 复制后端jar包
COPY ./verify-code-server-0.0.1-SNAPSHOT.jar /tmp/verify-code-server-0.0.1-SNAPSHOT.jar

# 安装MYSQL && jdk8
RUN apt update \
 && apt install -y mysql-server \
 && apt install -y openjdk-8-jdk

# 执行sql && 设置密码
........

运行 jar 包的操作我们后续会放到 entrypoint 中


Nginx的安装和配置

安装 nginx

apt install -y nginx

Dockerfile

FROM ubuntu:22.04

# 复制sql文件
# 复制后端jar包
........

# 安装MYSQL && jdk8 && nginx
RUN apt update \
 && apt install -y mysql-server \
 && apt install -y openjdk-8-jdk \
 && apt-get install -y nginx

# 执行sql && 设置密码
........



Nginx 配置文件
nginx 配置文件分两种情况,自己提前写好了有完整的 nginx.conf没有 nginx.conf

1.先说有 nginx.conf 的情况,直接把自己的 nginx.conf 文件复制到容器的 /etc/nginx/目录下,覆盖掉原来的 nginx.conf

将 nginx.conf 文件和 Dockerfile 放在同级目录
在这里插入图片描述
Dockerfile

COPY ./nginx.conf /etc/nginx/
FROM ubuntu:22.04

# 复制sql文件
# 复制后端jar包
........

# 安装MYSQL && jdk8 && nginx
........

# 执行sql && 设置密码
........

# 复制nginx.conf配置文件
COPY ./nginx.conf /etc/nginx/

2.第二种是没有 nginx.conf 文件,可以写一个精简版的
先在 Dockerfile 的目录下新建一个 my.conf文件

touch my.conf

在这里插入图片描述

使用 vim 编辑 my.conf

vim my.conf

内容

server {
    listen       5173;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

然后将这个 my.conf 复制到容器的 /etc/nginx/conf.d目录下

COPY ./my.conf /etc/nginx/conf.d/
FROM ubuntu:22.04

# 复制sql文件 && 复制后端jar包
........

# 安装MYSQL && jdk8 && nginx
.........

# 执行sql && 设置密码
.........

# 复制自定义Nginx配置文件
COPY ./my.conf /etc/nginx/conf.d/




前端的打包

在这里插入图片描述

记得先将请求路径改成服务器的url
在这里插入图片描述

将 dist 文件夹和 Dockerfile 放到同一目录

在这里插入图片描述

将 dist 目录重命名为 html

mv dist html

在这里插入图片描述

打包成后缀 .tar.gz 格式,文件名 html.tar.gz

tar -czvf html.tar.gz html

在这里插入图片描述

将打包文件复制到/usr/share/nginx/html目录下(先删除html目录,然后直接解压)

rm -rf /usr/share/nginx/html
tar -xzvf /usr/share/nginx/html.tar.gz -C /usr/share/nginx
FROM ubuntu:22.04

# 复制sql文件 && 复制后端jar包
........

# 安装MYSQL && jdk8 && nginx
.........

# 执行sql && 设置密码
.........

# 复制自定义Nginx配置文件
........

# 复制前端打包文件
COPY ./html.tar.gz /usr/share/nginx/
# 解压覆盖
RUN rm -rf /usr/share/nginx/html
RUN tar -xzvf /usr/share/nginx/html.tar.gz -C /usr/share/nginx

启动 nginx 的命令我们也是后面放到 entrypoint 中


暴露端口

这里我后端的端口是 8080,前端是5173

FROM ubuntu:22.04

# 中间省略
........

# 暴露端口
EXPOSE 8080 5173

ENTRYPOINT

在 Dockerfile 同级目录下新建一个 entrypoint.sh

touch entrypoint.sh

在这里插入图片描述

使用 vim 编辑

vim entrypoint.sh

内容

#!/bin/bash

# 重启MySQL服务
service mysql restart

# 启动后端
java -jar /tmp/verify-code-server-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &

# 启动前端
/usr/sbin/nginx

# 保持容器运行
exec tail -f /dev/null

最后在 Dockerfile 中加上执行 entrypoint 脚本的语句

FROM ubuntu:22.04

# 中间省略
........

# 复制自定义的entrypoint脚本到镜像中
COPY entrypoint.sh /usr/local/bin/

# 赋予脚本执行权限
RUN chmod +x /usr/local/bin/entrypoint.sh

# 设置ENTRYPOINT为自定义脚本
ENTRYPOINT ["bash", "/usr/local/bin/entrypoint.sh"]



接下来就可以进行构建了

docker build -t verify-code:1.0 .

运行

docker run --name verify-code -p 8080:8080 -p 5173:5173 -itd verify-code:1.0

导出镜像

docker save -o verify-code.tar verify-code:1.0

最后附上完整的 Dockerfile 供大家参考

FROM ubuntu:22.04

# 复制sql文件
COPY ./verify-code.sql /

# 复制后端jar包
COPY ./verify-code-server-0.0.1-SNAPSHOT.jar /tmp/verify-code-server-0.0.1-SNAPSHOT.jar

# 安装MYSQL && jdk8 && nginx
RUN apt update \
 && apt install -y mysql-server \
 && apt install -y openjdk-8-jdk \
 && apt-get install -y nginx
 
# 执行sql && 设置密码
RUN service mysql restart \
 && mysql -u root < /verify-code.sql \
 && mysql -u root -e "ALTER user 'root'@'localhost' identified with mysql_native_password by 'root';"

# 复制自定义Nginx配置文件
COPY ./my.conf /etc/nginx/conf.d/

# 复制前端打包文件
COPY ./html.tar.gz /usr/share/nginx/
# 解压覆盖
RUN rm -rf /usr/share/nginx/html
RUN tar -xzvf /usr/share/nginx/html.tar.gz -C /usr/share/nginx

# 暴露端口
EXPOSE 8080 5173

# 复制自定义的entrypoint脚本到镜像中
COPY entrypoint.sh /usr/local/bin/

# 赋予脚本执行权限
RUN chmod +x /usr/local/bin/entrypoint.sh

# 设置ENTRYPOINT为自定义脚本
ENTRYPOINT ["bash", "/usr/local/bin/entrypoint.sh"]

OK,大功告成,又可以愉快的摸鱼了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值