意义:避免部署对服务器环境的依赖,减少复杂的部署流程
学习资料。黑马2024年springcloud
https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec
ubuntu如何安装docker
安装https://www.runoob.com/docker
思考:我的服务器原本有mysql,如果我使用docker,又创建一个mysql,我的程序怎么区分使用哪个mysql
在同一台服务器上同时运行本地安装的MySQL和Docker中的MySQL实例时,需要通过不同的连接方式来区分它们。可以通过配置不同的端口、使用不同的网络、或者通过指定容器名来连接相应的MySQL实例。以下是一些方法和步骤:
- 通过不同端口区分
假设本地的MySQL服务运行在默认的3306端口上,可以在创建Docker容器时为其分配一个不同的端口,例如3307。
步骤:
-
启动Docker中的MySQL容器并指定端口:
docker run --name docker-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -p 3307:3306 -d mysql:latest
-
在应用程序中连接本地MySQL和Docker MySQL:
-
本地MySQL:
// 配置文件或代码中 String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "your-local-password";
-
Docker MySQL:
// 配置文件或代码中 String url = "jdbc:mysql://localhost:3307/mydatabase"; String username = "root"; String password = "my-secret-pw";
-
-
使用不同的网络配置
也可以通过Docker的网络配置来区分不同的MySQL实例。例如,可以创建一个自定义网络,并将Docker中的MySQL实例连接到该网络。
步骤:
-
创建一个Docker网络:
docker network create my-network
-
启动Docker中的MySQL容器并连接到自定义网络:
docker run --name docker-mysql --network my-network -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
-
在应用程序中通过网络别名连接Docker MySQL:
// 配置文件或代码中 String url = "jdbc:mysql://docker-mysql:3306/mydatabase"; String username = "root"; String password = "my-secret-pw";
-
使用容器名或IP地址区分
如果你知道容器的IP地址或使用容器名来连接Docker中的MySQL实例,也可以通过这种方式进行区分。
步骤:
-
获取Docker容器的IP地址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-mysql
-
在应用程序中使用容器IP地址连接Docker MySQL:
// 假设获取到的IP地址是172.17.0.2 String url = "jdbc:mysql://172.17.0.2:3306/mydatabase"; String username = "root"; String password = "my-secret-pw";
示例总结
假设你的本地MySQL运行在默认端口3306,Docker中的MySQL运行在端口3307。你的应用程序可以通过不同的连接字符串来区分它们:
本地MySQL连接字符串:
String localMysqlUrl = "jdbc:mysql://localhost:3306/mydatabase";
String localUsername = "root";
String localPassword = "your-local-password";
Docker MySQL连接字符串:
String dockerMysqlUrl = "jdbc:mysql://localhost:3307/mydatabase";
String dockerUsername = "root";
String dockerPassword = "my-secret-pw";
通过这些方法,你的程序可以明确区分和连接到不同的MySQL实例,确保数据和服务的正确性。
常用命令
docker pull | 拉取镜像 | docker pull |
---|---|---|
docker push | 推送镜像到DockerRegistry | docker push |
docker images | 查看本地镜像 | docker images |
docker rmi | 删除本地镜像 | docker rmi |
docker run | 创建并运行容器(不能重复创建) | docker run |
docker stop | 停止指定容器 | docker stop |
docker start | 启动指定容器 | docker start |
docker restart | 重新启动容器 | docker restart |
docker rm | 删除指定容器 | docs.docker.com |
docker ps | 查看容器 | docker ps |
docker logs | 查看容器运行日志 | docker logs |
docker exec | 进入容器 | docker exec |
docker save | 保存镜像到本地压缩文件 | docker save |
docker load | 加载本地压缩文件到镜像 | docker load |
docker inspect | 查看容器详细信息 | docker inspect |
修改别名
坑点,如果用户没有权限的话 使用sudo source /root/.bashrc 命令报错sudo: source: command not found
在Unix/Linux系统中,source
命令是一个Shell内置命令,不能直接通过sudo
来运行。sudo
只会寻找可执行文件,而source
不是一个可执行文件,而是一个Shell内置命令。因此,当你试图使用sudo source
时,会出现command not found
的错误。
为了以root用户的身份执行/root/.bashrc
文件中的内容,你可以以root用户的身份运行一个Shell,然后在该Shell中执行source
命令。解决问题:
sudo su
source /root/.bashrc
因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦。
引入 数据卷
数据卷
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。
目录关联叫挂载
docker volume create | 创建数据卷 |
---|---|
docker volume ls | 查看所有数据卷 |
docker volume rm | 删除指定数据卷 |
docker volume inspect | 查看某个数据卷的详情 |
docker volume prune | 清除数据卷 |
容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。
这里有点绕,前面提到的是不要直接指向本地,我们这里是挂载到本地
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
思考
我创建了一个docker,docker run 一个mysql数据库,怎么把sql文件传进去docker
将SQL文件传入运行中的Docker容器可以通过多种方式实现。以下是几种常见的方法:
方法 1:使用 docker cp
命令
docker cp
命令可以将本地文件复制到容器中。
-
复制SQL文件到容器:
docker cp /path/to/yourfile.sql <container_name>:/path/in/container
例如,将
mydatabase.sql
文件复制到容器名为my-mysql
的容器中的/tmp
目录:docker cp mydatabase.sql my-mysql:/tmp/mydatabase.sql
-
进入容器执行SQL文件:
docker exec -it <container_name> /bin/bash
例如:
docker exec -it my-mysql /bin/bash
-
在容器内执行SQL文件:
mysql -u root -p < /tmp/mydatabase.sql
你需要输入MySQL root用户的密码。
方法 2**:直接在启动时执行SQL文件**
你可以在启动容器时通过挂载卷和使用 docker exec
命令来执行SQL文件。
-
启动容器时挂载SQL文件所在的目录:
docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -v /path/to/sql/files:/docker-entrypoint-initdb.d -d mysql:latest
这里
/path/to/sql/files
是你的SQL文件所在的目录。MySQL官方镜像会自动执行挂载在
/docker-entrypoint-initdb.d
目录中的所有*.sql
文件来初始化数据库。
方法 3:使用 docker exec
命令直接执行SQL文件
-
将SQL文件放在宿主机的一个目录中,然后通过
docker exec
命令执行:docker exec -i <container_name> mysql -u root -p < /path/to/yourfile.sql
例如:
docker exec -i my-mysql mysql -u root -pmy-secret-pw < mydatabase.sql
方法 4:通过Volume挂载实现
-
启动容器时挂载SQL文件所在目录:
docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -v /path/to/sql/files:/docker-entrypoint-initdb.d -d mysql:latest
MySQL容器会自动执行
/docker-entrypoint-initdb.d
目录中的所有SQL脚本来初始化数据库。
总结
根据你的需求选择合适的方法:
- 如果你已经有一个正在运行的容器,可以使用
docker cp
和docker exec
。 - 如果你刚刚启动容器并希望自动初始化数据库,可以使用Volume挂载并将SQL文件放在挂载的目录中。
以上方法都可以有效地将SQL文件传入Docker容器并执行。
镜像
镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。
镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。
Docker就提供了自动打包镜像的功能Dockerfile
FROM | 指定基础镜像 |
---|---|
ENV | 设置环境变量,可在后面指令使用 |
COPY | 拷贝本地文件到镜像的指定目录 |
RUN | 执行Linux的shell命令,一般是安装过程的命令 |
EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 |
有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
当Dockerfile文件写好以后,就可以利用命令来构建镜像了。
# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
docker build
: 就是构建一个docker镜像-t docker-demo:1.0
:-t
参数是指定镜像的名称(repository
和tag
).
: 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.
代表当前目录,也可以直接指定Dockerfile目录
网络
容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。
命令 | 说明 |
---|---|
docker network create | 创建一个网络 |
docker network ls | 查看所有网络 |
docker network rm | 删除指定网络 |
docker network prune | 清除未使用的网络 |
docker network connect | 使指定容器连接加入某网络 |
docker network disconnect | 使指定容器连接离开某网络 |
docker network inspect | 查看网络详细信息 |
在Docker网络中,每个容器都会被分配一个名称和一个IP地址。Docker的内部DNS服务器会记录这些信息,从而使得容器可以通过名称相互访问。例如,假设有两个容器,一个名为app
,另一个名为mysql
,它们在同一个自定义网络中。容器app
可以通过mysql
这个名称访问MySQL数据库。
DockerCompose
避免麻烦
docker run 参数 | docker compose 指令 |
---|---|
–name | container_name |
-p | ports |
-e | environment |
-v | volumes |
–network | networks |
举例
version: "3.8"
services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
- "./mysql/init:/docker-entrypoint-initdb.d"
networks:
- hm-net
hmall:
build:
context: .
dockerfile: Dockerfile
container_name: hmall
ports:
- "8080:8080"
networks:
- hm-net
depends_on:
- mysql
nginx:
image: nginx
container_name: nginx
ports:
- "18080:18080"
- "18081:18081"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/html:/usr/share/nginx/html"
depends_on:
- hmall
networks:
- hm-net
networks:
hm-net:
name: hmall