写给Java开发看的 Docker 干货(零基础部署Nginx MySQL SpringBoot)

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: Docker是当下使用最多的一种容器技术,想精通Docker并不容易,在公司生产中会有专门的运维人员负责。但是身为开发人员 ,适当的学习Docker是必要的。Docker的好处这里就不介绍了,网上一搜一大堆。本篇将用最简短的篇幅介绍开发人员需要学习的Docker干货,你将学习到

前言

Docker是当下使用最多的一种容器技术,想精通Docker并不容易,在公司生产中会有专门的运维人员负责。但是身为开发人员 ,适当的学习Docker是必要的。Docker的好处这里就不介绍了,网上一搜一大堆。

本篇将用最简短的篇幅介绍开发人员需要学习的Docker干货,你将学习到

  • Docker的安装
  • 第一个HelloWorld镜像
  • 运行nginx并访问静态页面
  • 运行mysql数据库
  • 制作自己的镜像

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

概念

Docker最重要的3个概念:仓库、镜像、容器,以springboot项目为例:

  • **镜像(Image): ** 将jdk + 项目jar包等文件以Docker的形式打包在一起就是镜像。这个概念跟重装系统时用的镜像是很相似的
  • 容器(Container): 将镜像实例化启动起来就是容器。容器是一个轻量级的linux系统,root用户权限、进程空间、用户空间和网络空间容器都有。假设现在想要部署一个redis,你得解压、安装、配置环境变量吧,但是docker不一样,只要有人把redis的镜像做好,运行起来成为一个小linux(也就是容器),这些环境跟做镜像的人的环境就会是一毛一样的,用户只需要run就行了
  • 仓库(Repository): 这里的仓库用于存放镜像,github就是代码的仓库,而这里的docker hub也就是存放镜像的仓库,供用户pull

docker跟git是十分相识的,通常我们会进行一下操作

  • 通过pull命令到docker hub上拉取需要的镜像,比如mysql、redis等等
  • 镜像已经拉取到本地了,通过run命令将镜像运行起来成为容器
  • 以上两步是使用他人的镜像,而当自己要构建一个例如springboot的镜像时,使用build命令构建镜像

微信图片_20220908120918.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

一、连接linux

本篇使用的服务器是ubuntu,没有服务器的同学也可以使用虚拟机,效果是一样的

# ssh 用户名@ip地址
chaitous-Mac-mini:~ chaitou$ ssh ubuntu@148.70.139.121
ubuntu@148.70.139.121's password: 
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-157-generic x86_64)
# 如果连接不上的,可能是你本机之前有其他服务的缓存和公钥信息
# 使用`ssh-keygen -R 148.70.139.121`清一下

如果是学生或者还没有接触过服务器的同学,笔者还是建议去买一个,现在面向新用户一年就几十块钱。能接触到公网,买个域名也能让项目真实的接触一下生产环境。

二、安装docker

# 先切换到root用户下
sudo su
# 更新apt-get,保证apt-get最新版本
apt-get update
# 安装docker
apt-get install -y docker.io
# 查看docker版本
docker version
# 启动docker服务(有可能不需要这一步,多执行一遍也不会有错)
service docker start
# 再执行一次version,看到Client、Service说明启动成功了
docker version
Client:
 Version:           18.09.7
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        2d0083d
 Built:             Fri Aug 16 14:19:38 2019
 OS/Arch:           linux/amd64
 Experimental:      false
Server:
 Engine:
  Version:          18.09.7
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       2d0083d
  Built:            Thu Aug 15 15:12:41 2019
  OS/Arch:          linux/amd64
  Experimental:     false

三、第一个Docker镜像hello world

步骤:

  • 先用pull命令从远端拉镜像到本地
  • 用images命令查看所有镜像
  • run命令运行镜像
# pull: 从仓库拉取镜像
# docker pull [options] name[:tag]
# docker pull [可选参数] 镜像名[:版本号](如果不填默认为最新版本)
docker pull hello-world
# 默认从docker官方获取镜像,很可能因为网络原因需要多拉取几次
# 查看本机上的所有镜像
# docker images [可选参数]
docker images
# 看到hello-world说明拉取成功了
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        15 months ago       1.84kB
# 运行镜像
# docker run [options] image[:tag] [command] [args]
# docker run [可选参数] 镜像名[:版本号] [镜像运行时要执行的命令] [命令参数]
docker run hello-world
Hello from Docker!
# 当你看到这条消息说明安装成功了
This message shows that your installation appears to be working correctly.
# 生成这条信息,docker做了以下几个步骤
To generate this message, Docker took the following steps:
 # client端(也就是终端,命令行)连接到daemon端(指的是我们本地docker)
 1. The Docker client contacted the Docker daemon.
 # daemon端(本地docker)到Docker hub仓库中拉取了hello-world镜像
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 # daemon端(本地docker)从镜像中创建了一个容器,这个镜像运行了当前看到输出的代码
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 # daemon端(本地docker)将输出流给client端(命令行),显示到终端
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

配置加速器

docker hub毕竟是境外网站,可能会网络超时,因此配置一下阿里镜像加速器

打开阿里云https://cr.console.aliyun.com/,登录一下aliyun,按着下面的提示配置一遍

微信图片_20220908120955.png

四、运行nginx

# 拉取nginx镜像
docker pull nginx
# 查看镜像
docker images
# REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              ed21b7a8aee9        12 days ago         127MB
hello-world         latest              fce289e99eb9        15 months ago       1.84kB

运行方式

刚刚run命令运行了hello world,这里详细将一下,运行方式有2种,前台运行和后台运行,前台运行则会占用终端,一般都会选择让容器在后台运行

前台运行,这种方式终端将不能进行其他操作,使用Ctrl+C停止

docker run nginx

后台运行,更常用的方式应该是这种

# 可以用docker run --help查看一下帮助文档,其中有这么一条
docker run --help
...
-d, --detach                         Run container in background and print container ID
...
# 使用-d后台运行nginx
docker run -d nginx
# 返回的是容器Id
7f7468b0d50ddea5bd258e78339d8c8a3681a7d601c82000bde1c6653e273c13
# docker ps 查看当前运行的容器
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
7f7468b0d50d        nginx               "nginx -g 'daemon of…"   46 seconds ago      Up 45 seconds       80/tcp              dazzli
# 终止容器运行
docker stop 7f
7f

网络

刚刚提到docker容器就是一个小linux,也就是一个虚拟机。而容器行跟外界交互,只能先通过ubuntu主机的网卡,才能跟外界交互。主机与docker容器网络通讯的方式有为3种:

  • 桥接(Bridge): 也是最常用的方式,该模式下会将ubuntu主机上的端口映射到docker容器的端口上,例如8080:8081则会- 将主机上的8080端口映射到docker容器的8081端口
  • 共享(Host): ubuntu主机与docker共享同一端口
  • 无网络(None): docker没有网络,外界无法访问

我们重点讲解一下最常用的桥接模式

桥接 Bridge

桥接模式需要使用-p参数或者-P参数,-p 主机端口:容器端口,-P则使用随机的主机端口映射到docker容器

  1. -p 指定端口模式
# docker run -d -p 主机端口:容器端口 image[:tag]
docker run -d -p 8080:80 nginx
5e0cc45d89288faf9ba04b5e8b30548b8c14409a6d93e1abdd297676a7b7769a
docker stop 5e

此时我们就可以通过:8080访问nginx了

微信图片_20220908121535.png

-P 随机端口

可以看到docker自动将0.0.0.0:32768->80/tcp随机端口32768映射到80上

# 随机开启一个端口映射到容器
# docker run -d -P image[:tag]
docker run -d -P nginx
docker ps
# 可以看到是32768端口映射到80端口
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
be30acaeb546        nginx               "nginx -g 'daemon of…"   10 seconds ago      Up 9 seconds        0.0.0.0:32768->80/tcp   trusting_keller
docker stop be

五、运行mysql

使用docker进行mysql的部署比起在ubuntu上部署简直不要太方便!打开阿里云https://cr.console.aliyun.com/

微信图片_20220908121813.png

跳转到mysql的镜像地址查看mysql在docker下的使用。

链接地址:https://hub.docker.com/_/mysql

微信图片_20220908121845.png

使用步骤:

  • 从远端仓库拉取mysql
  • 通过docker run运行
  • -d进行后台运行
  • -p指定端口映射
  • -e后面跟着的是mysql的参数,通过上方连接可以查询到通过MYSQL_ROOT_PASSWORD设置数据库密码、MYSQL_DATABASE设置数据库名
docker pull mysql
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=leilema -e MYSQL_DATABASE=leilema mysql:latest

通过数据库连接工具,例如Navicat等等进行数据连接,验证

微信图片_20220908121904.png

是不是很简单,傻瓜式部署啊。特别是停止mysql容器跟删除mysql镜像,以前都是执行一大堆脚本还删不干净,现在就暴力多了,直接容器一停,镜像已删除,相当于整个虚拟linux全部删掉,要多干净有多干净,关键还快!

# 停止容器
docker stop 容器ID
# 删除镜像
docker rmi image[:tag]

错误(*进入容器内部)

2059错误: Authentication plugin 'caching_sha2_password' cannot be loaded

这个错误不难,装mysql时也遇到过,通过google 2059错误,知道解决方案是要给进入到mysql,设置一下ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'leilema';才能连接。

难面也是会有错误的发生,既然docker容器就是一个虚拟linux,我们偶尔也是要进入到docker容器中查查日志啊,改改配置文件什么的。真好顺着这个错误,学习一下如何进入容器内部,也顺便看看容器内部是什么样子的:

  • 通过docker ps查询容器id
  • 通过docker exec -it 容器ID(可以只输入前缀) bash进入容器,此时你会发现终端前方的用户从root@VM-0-12-ubuntu改变成了root@9d71ee58f07c,@后方跟着的正式我们的容器id
  • 进入容器后的操作就跟linux的操作是一样的,最后通过exit退出mysql和容器
root@VM-0-12-ubuntu:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
9d71ee58f07c        mysql:latest        "docker-entrypoint.s…"   8 minutes ago       Up 8 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   hardcore_nash
root@VM-0-12-ubuntu:~# docker  exec  -it  9d  bash
# 进入容器内部,ls可以看到这货就是一个linux
root@9d71ee58f07c:/# ls
bin   docker-entrypoint-initdb.d  home  media proc  sbin  tmp
boot  entrypoint.sh    lib  mnt root  srv   usr
dev   etc     lib64  opt run   sys   var
# 进入mysql
root@9d71ee58f07c:/# mysql  --user=root  --password
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
...
# 执行一下命令,修改下mysql密码
mysql>  ALTER  USER  'root'  IDENTIFIED  WITH  mysql_native_password  BY  'leilema';
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
root@9d71ee58f07c:/# exit
exit

六、制作自己的镜像

想要制作自己的镜像需要有2步操作:

  • 编写Dockerfile,说明镜像要如何进行创建,跟makefile有点像
  • 通过docker build命令构建镜像

编写Dockerfile

这里以springboot项目为例,手头有springboot项目的同学可以直接使用手头的。我这里提供一个sringboot构建helloworld的jar包,已经传到git上,因此

  • 使用git拉取项目(或者自己通过rz命令将jar包传到服务器上)
  • cd到jar包目录下,在同级目录开始编写Dockerfile文件
get clone https://gitee.com/chaitou/hello-springboot
cd hello-springboot
vim Dockerfile

dockerfile文件如下:

# 依赖的基础镜像
from java:8
# 创建者
MAINTAINER bugpool xxx@163.com
# 将当前目录下的jar复制到容器/目录下
COPY hello-springboot.jar /hello-springboot.jar
# 指定启动时运行java -jar 命令
ENTRYPOINT ["java", "-jar","/hello-springboot.jar"]

构建镜像

springboot项目肯定是需要需要jdk才能运行,dockerfile上也写了from java:8,因此

  • 需要从仓库先pull一下java镜像
  • 使用docker build构建镜像,-t指定镜像名:版本号,最后一个.表示当前目录
  • 启动镜像,如果使用的是上面我提供的jar包,我特意将其运行端口改为8081来练习一下-p桥接网络的使用。
# 拉取java8
docker pull java:8
# 构建镜像
docker build -t hello-springboot:1.0 .
# 启动镜像
docker run -p 80:8081 hello-springboot:1.0

我们将主机80端口映射成为了docker容器的8081端口,因此我们需要访问ip:80/hello,80端口可以省略,因此就是ip/hello,如果看到一下界面,说明已经build成功,并且成功部署了

微信图片_20220908121940.png

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
应用服务中间件 网络安全 nginx
手把手教你使用 Docker 部署 Nginx 教程
本文详解Nginx核心功能与Docker部署优势,涵盖镜像拉取、容器化部署(快速、挂载、Compose)、HTTPS配置及常见问题处理,助力高效搭建稳定Web服务。
1459 4
|
3月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
3月前
|
应用服务中间件 Linux nginx
在虚拟机Docker环境下部署Nginx的步骤。
以上就是在Docker环境下部署Nginx的步骤。需要注意,Docker和Nginix都有很多高级用法和细节需要掌握,以上只是一个基础入门级别的教程。如果你想要更深入地学习和使用它们,请参考官方文档或者其他专业书籍。
186 5
|
4月前
|
存储 Docker Python
docker 部署 sftp
本文介绍SFTP服务的部署与配置,包括users.conf用户配置规则、Docker容器运行命令及上传目录权限说明,重点解析atmoz/sftp镜像的chroot机制与子目录映射,确保用户登录后正确访问/upload目录,并提供Python脚本实现文件上传示例。
398 12
docker 部署 sftp
|
4月前
|
运维 Linux 数据库
基于 Docker 部署 n8n 指南,新手一看就会
本教程详解如何通过 Docker 快速部署开源自动化工具 n8n,适合新手快速上手。内容涵盖官方部署步骤、常见难点及第三方一键部署方案,助你高效搭建自动化工作流平台。
1698 6
|
3月前
|
存储 NoSQL Redis
手把手教你用 Docker 部署 Redis
Redis是高性能内存数据库,支持多种数据结构,适用于缓存、消息队列等场景。本文介绍如何通过Docker快速拉取轩辕镜像并部署Redis,涵盖快速启动、持久化存储及docker-compose配置,助力开发者高效搭建稳定服务。
1087 7
|
3月前
|
存储 搜索推荐 数据库
🚀 RAGFlow Docker 部署全流程教程
RAGFlow是开源的下一代RAG系统,融合向量数据库与大模型,支持全文检索、插件化引擎切换,适用于企业知识库、智能客服等场景。支持Docker一键部署,提供轻量与完整版本,助力高效搭建私有化AI问答平台。
2595 8
|
3月前
|
存储 关系型数据库 MySQL
MySQL Docker 容器化部署全指南
MySQL是一款开源关系型数据库,广泛用于Web及企业应用。Docker容器化部署可解决环境不一致、依赖冲突问题,实现高效、隔离、轻量的MySQL服务运行,支持数据持久化与快速迁移,适用于开发、测试及生产环境。
676 4
|
4月前
|
前端开发 JavaScript 应用服务中间件
在Docker部署的前端应用中使用动态环境变量
以上步骤展示了如何在 Docker 配置过程中处理并注入环墨遁形成可执行操作流程,并确保最终用户能够无缝地与之交互而无须关心背后复杂性。
240 13