创建Docker镜像
springboot-docker模块
这个应用可以随便找一个即可,这里不做详细描述了。
pom.xml
依赖版本可参考 springbootSeries 模块中pom.xml文件中的版本定义
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
application.properties配置
spring.profiles.active = dev
spring.application.name=SpringbootDocker
server.port=19508
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.fail-fast=true
spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos
SpringbootApplication启动类
@Slf4j
@SpringBootApplication(scanBasePackages = {"com.korgs", "cn.hutool.extra.spring"})
@Configuration
@EnableConfigurationProperties
@ServletComponentScan
@RestController
@EnableDiscoveryClient
public class AlibabaSpringbootDockerServerApplication {
@Value("${server.port}")
private String serverPort;
public static void main(String[] args) {
SpringApplication.run(AlibabaSpringbootDockerServerApplication.class, args);
}
@GetMapping("/helloworld/{uuid}")
public BaseResponse<String> helloWorld(@PathVariable String uuid){
String str = LogGenerator.trackLog()
+ " uuid=" + uuid + " I am busy to handle this request."
+ " serverPort=" + serverPort;
log.info( str );
return BaseResponse.success(str);
}
}
创建Dockerfile文件
内容如下,详细解释可参考文章最后:
#FROM openjdk:8
#需要先通过本地maven打包具体jar包,account版本与pom中version保持一致
#该文件为部署本地docker中的配置
#使用openjdk8, 基于哪个镜像
FROM openjdk
#将target中打包的文件映射到docker中,# 拷贝文件到容器,也可以直接写成ADD microservice-discovery-eureka-0.0 .1-SNAPSHOT.jar /app.jar
ADD target/springboot-docker-*.jar /springbootDocker.jar
#查看是否存在springbootDocker.jar文件
RUN bash -c 'touch ../springbootDocker.jar'
#容器启动后执行的命令,执行java -jar运行jar包,设置环境变量,时区,jvm
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Duser.timezone=GMT+08","-Xmx256m","-Xms256m","/springbootDocker.jar"]
Build Docker镜像
执行以下命令打包
mvn -clear package
docker build -t springbootapp:lecture .
docker run -it -d -p 19508:19508 springbootapp:lecture /bin/bash
docker logs containerId
使用shell脚本部署Docker镜像(可选)
新增localDeployment.sh文件,负责部署build出docker镜像并启动服务(下面这个文件需要修改一些源码)
#!/bin/bash
#部署前本地先maven package打包
#本地部署到本机docker
echo ========开始执行本地Docker部署========
#version是从pom.xml中的<version>0.0.1-SNAPSHOT</version>中取出来的,所以应该是0.0.1
CURRENT_V=$(echo $line | grep 'SNAPSHOT' pom.xml | awk '{split($0,a,"-"); print a[1]}'| awk '{split($0,a,">"); print a[2]}')
echo ========当前版本$CURRENT_V========
#如果docker中已经存在该版本或者运行着的版本,停止,删除服务,删除镜像
echo ========停止以及删除旧版本========
#停止在运行的版本服务
docker stop springboot-docker-$CURRENT_V
#删除刚刚停止的服务
docker rm springboot-docker-$CURRENT_V
#删除image镜像
docker rmi springboot-docker/$CURRENT_V
echo ========开始build新版本$NEW_V========
#build出新的镜像
docker build -t springboot-docker/$CURRENT_V .
echo ========开始部署新版本$NEW_V========
#启动服务
docker run -it -d springbootapp:lecture /bin/bash
echo ========本地Docker部署完成========
源码下载
涉及模块:
- springboot-docker:19508
源码下载:
- 基础框架源码下载
- 使用Dockerfile配置Springboot应用服务发布Docker镜像
源码运行方法:
- 模块详细功能说明和运行测试方法
Dockerfile详细说明
一个简单的示例如下:
FROM openjdk:laster
#将target中打包的文件映射到docker中
ADD target/springboot-docker-*.jar /springbootDocker.jar
#查看是否存在springbootDocker.jar文件
RUN bash -c 'touch ../springbootDocker.jar'
#容器启动后执行的命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Duser.timezone=GMT+08","-Xmx256m","-Xms256m","/springbootDocker.jar"]
参考文档
- 安装:https://hub.docker.com/editions/community/docker-ce-desktop-mac
- 帮助:https://www.runoob.com/docker/docker-tutorial.html
- 配置:https://docs.docker.com/reference/cli/dockerd/
指令说明
设置基础镜像(必选)
- FROM:指定基于哪个基础镜像构建,FROM必须为第一个命令,比如
FROM openjdk:laster
设置镜像作者(必选)
- MAINTAINER: 维护者信息,比如
MAINTAINER yongboy "yongboy@gmail.com"
复制文件到镜像(必选)
- ADD:将本地文件添加到容器中,tar类型文件会自动解压,可以访问网络资源,类似wget
- COPY:功能类似ADD,但是不会自动解压文件,也不能访问网络资源
设置镜像环境变量
- ENV:设置环境变量,在后续指令中使用,比如在RUN指令中使用,比如
ENV java_home /usr/etc/java
- ARG:与ENV作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
设置运行指令的工作目录
切换工作目录,类似于cd命令,对RUN, CMD, ENTRYPOINT指令有效,比如WORKDIR /user/etc/bin
,需要注意的是 WORKDIR 指定的工作目录,必须是提前创建好的。
运行指令(必选)
- RUN : 在 docker build 时运行,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令,通常用于安装软件使用;
RUN <command> (the command is run in a shell - `/bin/sh -c`)
RUN ["executable", "param1", "param2" ... ] (exec form)
- CMD : 在docker run 时运行,设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
,比如CMD ["flask", "run"]
CMD ["executable","param1","param2"] (like an exec, this is the preferred form)
CMD command param1 param2 (as a shell)
- ENTRYPOINT:在docker run 后运行,当指定多个时只有最后一个起效,格式
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)
ENTRYPOINT command param1 param2 (as a shell)
设置镜像端口(必选)
EXPOSE <端口1> [<端口2>...]
,用于docker run -p 命令中的 -p
参数指定
启动挂载目录
- VOLUME:用于指定持久化目录,即使
容器
中的某个目录具有存储持久化数据的能力,比如VOLUME ["<路径1>", "<路径2>"...]
。
可以避免重要的数据,因容器重启而丢失,或是避免容器不断变大。
其它指令
- LABEL:用于为镜像添加元数据,比如
LABEL version=1.0
,LABEL desc= this is my first docker
- USER:指定运行容器时的用户名
- ONBUILD:用于设置镜像触发器,即当所创建的镜像做为其它镜像的基础时,所执行的命令
另一个示例
RUN mkdir -p /var/run/sshd
# 添加orache java7源,一次性安装vim,wget,curl,java7,tomcat7等必备软件
RUN apt-get install -y vim wget curl oracle-java7-installer tomcat7
# 设置JAVA_HOME环境变量
RUN echo "JAVA_HOME=/usr/lib/jvm/java-7-oracle">> /etc/environment
# 设置Tomcat7初始化运行,SSH终端服务器作为后台运行
ENTRYPOINT service tomcat7 start && /usr/sbin/sshd -D
# Pull base image
FROM ubuntu:13.10
MAINTAINER zing wang "zing.jian.wang@gmail.com"
# update source
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"> /etc/apt/sources.list
RUN apt-get update
# Install curl
RUN apt-get -y install curl
# Install JDK 7
RUN cd /tmp && curl -L 'http://download.oracle.com/otn-pub/java/jdk/7u65-b17/jdk-7u65-linux-x64.tar.gz' -H 'Cookie: oraclelicense=accept-securebackup-cookie; gpw_e24=Dockerfile' | tar -xz
RUN mkdir -p /usr/lib/jvm
RUN mv /tmp/jdk1.7.0_65/ /usr/lib/jvm/java-7-oracle/
# Set Oracle JDK 7 as default Java
RUN update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-7-oracle/bin/java 300
RUN update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-7-oracle/bin/javac 300
ENV JAVA_HOME /usr/lib/jvm/java-7-oracle/
# Install tomcat7
RUN cd /tmp && curl -L 'http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.8/bin/apache-tomcat-7.0.8.tar.gz' | tar -xz
RUN mv /tmp/apache-tomcat-7.0.8/ /opt/tomcat7/
ENV CATALINA_HOME /opt/tomcat7
ENV PATH $PATH:$CATALINA_HOME/bin
ADD tomcat7.sh /etc/init.d/tomcat7
RUN chmod 755 /etc/init.d/tomcat7
# Expose ports.
EXPOSE 8080
# Define default command.
ENTRYPOINT service tomcat7 start && tail -f /opt/tomcat7/logs/catalina.out
Docker简介
Docker是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖项打包到一个可移植的容器中,并发布到任何流行的Linux或Windows操作系统的机器上。以下是关于Docker的详细介绍:
- 定义:Docker是一个开源的应用容器引擎,它使用沙箱机制来确保容器之间是完全隔离的,每个容器都有自己的文件系统、进程空间和网络接口,这使得Docker容器具有很高的安全性和隔离性。
- 组成部分:Docker由DockerClient客户端、Docker Daemon守护进程、Docker Image镜像和Docker Container容器等部分组成。Docker客户端和守护进程之间的通信可以通过UNIX套接字或网络接口实现。
- 特点:
- 轻量级:Docker容器利用操作系统的资源更加高效,相比于虚拟机,容器更轻量,启动更快。
- 可移植性:Docker容器可以在任何支持Docker的环境中运行,无论是本地开发环境、云服务器还是物联网设备。
- 隔离性:Docker容器提供了隔离的运行环境,每个容器都有自己的文件系统、进程空间和网络接口,相互之间不会互相干扰,提供了更安全的环境。
- 简化部署:Docker容器可以通过Docker镜像进行快速部署,减少了配置和依赖的问题,提高了应用的部署效率。
- 起源:Docker起源于PaaS提供商dotCloud开源的一个基于LXC的高级容器引擎,其源代码托管在Github上,基于Go语言并遵从Apache2.0协议开源。Docker的设计初衷是为了解决环境管理复杂、中间件相关问题以及虚拟化手段的变化等问题,提供了一种更高效、灵活和快速的解决方案。
- 使用方式:使用Docker时,开发者只需要将项目打包成镜像放到Docker中,然后通过Docker镜像进行快速部署。Docker还提供了Docker Compose等客户端工具,允许用户使用由一组容器组成的应用程序。
总的来说,Docker是一个功能强大的应用容器引擎,它提供了一种高效、灵活和快速的解决方案来管理和部署应用程序。
Docker常用命令
创建和修改镜像
创建镜像
docker build -t <imageName>:<tag> <-f Dockerfile的相对位置>
docker build -t springbootDemo:v1 . #表示用当前目录下的Dockerfile创建镜像,tag:省略则默认为`latest`
其中 -t和-f是常使用的参数,-t为指定构建镜像的名字和版本,格式为’name:tag’,-f为指定其他目录下的DockerFIle文件。
修改镜像
用docker commit
的前提一般是进入容器,然后在容器中修改了一些内容,然后退出后,把容器保存为一个新镜像。
docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
# -m: 提交的描述信息;
# -a: 指定镜像作者;
# e218edb10161:容器ID;
# runoob/ubuntu:v2: 指定要创建的目标镜像名
镜像打标
# 设置860cc279d2fec的标签,这相当于复制一个,不是直接修改
docker tag 860c279d2fec runoob/centos:dev
发布镜像
docker push localhost:5000/namespace/dockerName:tag
dokcer push localhost:5000/lecture/springbootDemo:0.0.1
导入和导出
- 针对Image的操作。
- 导出:docker save 把镜像保存成一个文件供下载
- 导入:docker load 把镜像文件加载为一个镜像
# 将镜像 runoob/ubuntu:v3 打包为 my_ubuntu_v3.tar
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
# 导入使用 docker save 命令导出的镜像
docker load < my_ubuntu_v3.tar
- 针对Container的操作。
- docker export containerId > fileName
- docker import - fileName imageName:tag
# 导出容器 1e560fca3906 快照到本地文件 ubuntu.tar,文件路径默认为本地用户根目录
docker export 1e560fca3906 > ubuntu.tar
# 导入本地文件到test/ubuntu:v1镜像
docker import ubuntu.tar test/ubuntu:v1
import和export是快照操作,而镜像docker save将保存完整记录。export 和 import 导出的是一个容器的快照, 不是镜像本身, 也就是说没有 layer。dockerfile 里的 workdir, entrypoint 之类的所有东西都会丢失,commit 过的话也会丢失。所以一般会用save和load;
全局服务命令
docker info #查看docker基本信息
docker network ls #查询本机镜像网络
docker container ls -a #查看所有容器
docker images #查看所有镜像
docker ps # 查看容器启动情况
docker login -u 用户名 -p 密码 #登陆仓库
Image 操作命令
查询远程镜像
docker search is-official=true openjdk #查询远程镜像,is-official=true表示只查询官方镜像
拉取远程镜像到本地
docker pull redis:v2 #这里的v2其实是tag,类似版本的概念
删除本地镜像
docker rmi redis
Container 操作命令
启动新容器
docker run -it -d imageName /bin/bash
- -d: 后台运行容器,并返回容器ID;
- -i: 以交互模式运行容器,通常与 -t 同时使用;
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
- -P: 随机端口映射,容器内部端口随机映射到主机的端口
- -v: 绑定一个卷
- –name name:指定一个自定义的容器名字
- –env-file=[]: 从指定文件读入环境变量;
# 在容器里执行 bin/echo "Hello world",然后输出结果
docker run ubuntu:15.10 /bin/echo "Hello world" Hello world
# 主机的目录 /data 映射到容器的 /data。
docker run -p 80:80 -v /data:/data nginx:latest
# 指定IP和端口
docker run -p 127.0.0.1:80:80 -v /data:/data nginx:latest
查看容器运行情况
# 查看容器内输出
docker logs -f containerid
# -f : 跟踪日志输出
# --since :显示某个开始时间的所有日志
# -t : 显示时间戳
# --tail :仅列出最新N条容器日志
# 查看指定端口映射
docker port containerid
# 查看容器内部运行的进程
docker top containerid
# 查看 Docker 的底层信息
docker inspect containerid
# 显示容器启动后更改了哪些原镜像的文件
docker diff containerid
重启/暂停
docker stop containerid #停止已启动的容器
docker start containerid #启动已停止的容器
docker restart containerid #重启已启动的容器
docker pause containerid #暂停已启动的容器
docker unpause containerid #恢复已启动的容器
删除容器
docker rm -f 1e560fca3906
# -f :通过 SIGKILL 信号强制删除一个运行中的容器。
# -l :移除容器间的网络连接,而非容器本身。
# -v :删除与容器关联的卷。
# 删除所有处于终止状态容器
docker container prune
进入容器
# 进入容器
docker exec -it 243c32535da7 /bin/bash
Docker使用技巧
阿里云镜像加速
配置:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
- 上面地址是需要申请的,每个人都不一样。
容器和主机间复制文件
# 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下
docker cp /www/runoob 96f7f14e99ab:/www/
# 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中
docker cp 96f7f14e99ab:/www /tmp/
网络设置
镜像共享使用宿主主机的网络
使用固定参数--network=host
,有时大多数 Docker 引擎安装时会将主机表示为默认 docker0 桥接网络上的 172.17.0.1。比如可以在容器里通过172.0.17.1:3306访问到宿主机的mysql服务器。
docker run -d --network=host my-container:latest
设置镜像中的localhost指向宿主主机
把镜像程序中的localhost
替换成 host.docker.internal
, host.docker.internal
只适用于从容器内部访问宿主机。如果想要在容器之间进行通信,可以使用容器名称或 IP 地址。
使用 link 参数实现容器互通
- 运行第一个容器:
docker run -it --name centos-1 docker.io/centos:latest
- 运行第二个容器:
[root@CentOS ~]# docker run -it --name centos-2 --link centos-1:centos-1 docker.io/centos:latest
# --link:参数中第一个centos-1是容器名,第二个centos-1是定义的容器别名(使用别名访问容器)
使用桥接设置Docker独享网络
- 运行
docker network create lcgnet
创建一个新的bridge网络,并通过 docker network ls查看是否创建成功。 - 通过指定网络的方式创建容器lcg。
docker run -it --name lcg --network lcgnet --network-alias lcgsky mycentos:1.3
--network lcgnet :表示使用lcgnet网络
--network-alias lcgsky: 表示网络别名为lcgsky
- 使用相同方式创建容器lcg1
docker run -it --name lcg1 --network lcgnet --network-alias lcgsky1 mycentos:1.3
- 可以使用网络别名加端口号这用方式访问容器中服务。
docker run -it --name <容器名> ---network <bridge> --network-alias <网络别名> <镜像名>
推荐使用这种方法,自定义网络,因为使用的是网络别名,可以不用顾虑ip是否变动,只要连接到docker内部bright网络即可互访。bridge也可以建立多个,隔离不同的网段。
连接宿主主机的mysql
- 设置Mysql访问权限
grant all privileges on . to 'root'@'%' identified by 'root' with grant option;
# 上面的 on . 也可换成 on *.*
安装私有Docker仓库(本机)
-软件地址 : https://github.com/distribution/distribution
docker run -d -p 15000:15000 --restart=always --name registry2 registry:2