基于docker搭建大项目环境
基于docker搭建大项目本地开发环境
包括环境准备、中间件配置,打包部署
流程
- 前置准备
- 编写项目配置文件
- 配置文件解析工具类
- 部署 Sql 型数据库
- 部署 NoSql 型数据库
- 部署 OSS 对象存储
- 运行测试
- 编写 Dockerfile
- 打包成 Docker 镜像并运行
前置准备
简介
Docker是一种开源的容器化平台,它可以将应用程序及其所有的依赖打包到一个可移植的容器中。Docker容器可以在任何运行Docker的系统上运行,无论是在开发环境中的笔记本电脑上,还是在云服务器上。
使用Docker可以实现应用程序的快速部署、跨平台运行、环境隔离和资源管理等优势。通过创建一个Docker镜像,你可以定义一个应用程序运行所需的所有环境和设置,然后使用这个镜像在任何地方运行你的应用程序,而不必担心环境的差异或依赖的安装。
在Docker中,使用Dockerfile来定义镜像的构建过程,包括基础镜像选择、安装依赖、配置环境等。然后,使用Docker命令可以方便地构建镜像、创建容器、启动、停止和管理容器。
系统要求
- 一台 linux 系统的计算机(WSL, Vmware 虚拟机,云服务器等),下面以 ubuntu 22.04 系统举例
- 建议配置 内存 >= 1G, 硬盘 >= 20G
下载 docker
- 网上的相关资源很多,这里给出一个示例
# 更新软件包索引 sudo apt update # 安装必要的软件包 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # 添加Docker官方的GPG密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加Docker的稳定存储库 echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 更新软件包索引 sudo apt update # 安装Docker Engine sudo apt install -y docker-ce docker-ce-cli containerd.io # 验证Docker是否成功安装并正在运行 sudo docker run hello-world
- 配置 docker 镜像加速
单机环境 docker 的基本命令
- 显示信息
docker info docker version systemctl status docker
- 显示镜像
docker images
- 搜索镜像
docker search xx
- 拉取镜像
docker pull xx:version
- 删除镜像
docker rmi 镜像名
操作容器
- 查看所有容器
docker ps -a
- 运行容器
# 创建容器 docker run -id --name==容器名 镜像名 # 进入容器 docker exec -it 容器名 /bin/bash #常用参数说明 --name="Name" # 容器名字 例如:tomcat01 tomcat02 用来区分容器 -i # 保持运行 -d # 后台方式运行 -t # 分配一个命令行,使用交互方式运行 -p(小写p) # 指定容器的端口 -P(大写P) # 随机指定端口 -v [宿主机绝对路径]:[容器中路径] # 挂载数据卷 # 退出 exit #退出容器并停止
- 修改容器
docker start 容器ID # 启动容器 docker restart 容器ID # 重启容器 docker stop 容器ID # 停止当前正在运行的容器 docker kill 容器ID # 强制停止当前的容器 # 删除容器 docker rm c1 # 查看容器信息 docker inspect c1
编写项目的配置文件
- 以技术栈 gin+gorm+mysql+redis+mongoDB+minio 为例
- 将 config.yml 放在根目录下,与 main.go, go.mod 并列
- config.yml 配置内容示例,根据需要替换ip(docker 宿主机的ipv4地址), 端口,数据库密码等信息
gin: port: 8080 database: host: ip port: 3306 username: root password: 123456 name: douyin redis: address: ip:6379 db: 0 mongodb: uri: mongodb://ip:27017 username: root password: 123456 database: admin minio: server: ip:9000 accessKey: xxx secretKey: xxx
配置文件读取工具类
- 根目录/util/config_reader.go 示例
package util import ( "github.com/spf13/viper" ) // Config 配置结构体 type Config struct { Gin GinConfig `mapstructure:"gin"` Database DatabaseConfig `mapstructure:"database"` MinIO MinIOConfig `mapstructure:"minio"` Mongo MongoDBConfig `mapstructure:"mongodb"` Redis RedisConfig `mapstructure:"redis"` } // GinConfig Gin配置结构体 type GinConfig struct { Port int `mapstructure:"port"` } // DatabaseConfig 数据库配置结构体 type DatabaseConfig struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` Name string `mapstructure:"name"` } // MinIOConfig MinIO配置结构体 type MinIOConfig struct { Server string `mapstructure:"server"` AccessKey string `mapstructure:"accessKey"` SecretKey string `mapstructure:"secretKey"` } // MongoDBConfig MongoDB配置结构体 type MongoDBConfig struct { URI string `mapstructure:"uri"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` Database string `mapstructure:"database"` } // RedisConfig Redis配置结构体 type RedisConfig struct { Address string `mapstructure:"address"` DB int `mapstructure:"db"` } // LoadConfig 加载配置文件 func LoadConfig() (*Config, error) { var config Config viper.SetConfigName("config") // 配置文件名称(不带后缀) viper.AddConfigPath(".") // 配置文件所在路径 viper.SetConfigType("yml") // 配置文件类型(yaml、json、toml等) if err := viper.ReadInConfig(); err != nil { return nil, err } if err := viper.Unmarshal(&config); err != nil { return nil, err } return &config, nil }
- 使用 config
func main() { config, err := util.LoadConfig() if err != nil { log.Fatal(err) } // 使用配置进行连接 }
docker 部署 Sql 数据库
- 停止本机原有的服务(若与本机端口冲突), 下同
sudo service mysql stop sudo systemctl stop mysql
- 拉取镜像
docker pull mysql
- 启动容器, 自行配置容器名和 root 密码和挂载目录, 下同
docker run --name mysql-server \ -e MYSQL_ROOT_PASSWORD=123456 \ -p 3306:3306 \ -v mysql/conf/my.conf:/etc/mysql/conf.d/my.conf \ -v mysql/data:/var/lib/mysql \ -d \ mysql
docker 部署 NoSql
部署 redis
- 拉取镜像
docker pull redis
- 启动容器, 自行配置容器名和挂载目录
docker run -d --name redis -p 6379:6379 \ --privileged=true \ -v /redis/data:/data --restart always redis \ --appendonly yes
部署 mongoDB
- 拉取镜像
docker pull mongo:4.4
- 启动容器, 自行配置容器名和挂载目录
docker run -itd --name mongo -v mongodb/data:/data/db -p 27017:27017 mongo:4.4 --auth
- 创建用户
docker exec -it mongo mongo admin # 默认无用户,创建一个。详细的命令含义参考 mongoDB 官方文档 db.createUser({ user:'root',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},'readWriteAnyDatabase']}); db.auth('root', '123456');
参考链接:blog.csdn.net/packge/arti…
部署 OSS 对象存储
MinIO是一个开源的对象存储服务器,它实现了Amazon S3(Simple Storage Service)云存储服务的API。它致力于提供高性能、高可用性和可扩展性的存储解决方案,可以用于构建私有云存储、备份和归档、大规模数据分析等应用。
兼容性:MinIO提供了与Amazon S3兼容的API,意味着您可以使用已经支持Amazon S3的工具和应用来访问和管理MinIO服务器。
开源:MinIO完全开源,使用Apache License 2.0许可证。这意味着您可以自由地查看、修改和分发代码。
分布式存储:MinIO可以在多个节点上部署,创建一个分布式存储系统。它支持数据的分片,将数据均匀地分布在不同的节点上,以实现高可用性和可扩展性。
高性能:MinIO使用Go语言编写,具有出色的性能和低延迟。它能够利用现代硬件的多核处理能力和高速网络连接,提供快速的数据传输和处理。
- 拉取镜像
docker pull minio/minio
- 运行容器
docker run -p 9090:9000 -p 9001:9001 --name minio \ -v /minio/data:/data \ -e MINIO_ROOT_USER=minio \ -e MINIO_ROOT_PASSWORD=123456 \ -d minio/minio server /data --console-address ":9001"
- 访问 http://{docker宿主机IP}:9000 进入 UI 控制台继续完成下面操作
- 创建 access-key 和 secret-key 用于客户端认证
- 创建 bucket 等
部署其他中间件
如有需要参考上面的步骤配置 MQ, API gateway 等,此处略
运行测试
- 检查 docker 容器启动
root@ubuntu-22.04:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 279da23cac51 minio/minio "/usr/bin/docker-ent…" 2 hours ago Up 2 hours 0.0.0.0:9000-9001->9000-9001/tcp, :::9000-9001->9000-9001/tcp minio e28f9e51b7ca redis "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis-server 7714aee4745c mysql "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-server 9c6cbb18801c mongo:4.4 "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp mongodb
go 项目中根据配置文件连接到部署的docker容器,在本地进行代码开发,依赖的中间件全部由另一台计算机的 docker 进行管理。
同时可以使用 Datagrip 等数据库UI连接到 docker 容器。实现分离开发
为项目编写 Dockerfile
-
Dockerfile 是一种文本配置文件,用于定制镜像。详细的参数含义参考 docker 官方文档
-
在项目根目录中创建文件 Dockerfile
-
Go web项目的示例Dockerfile 如下:
# 设置基础镜像 FROM golang:1.20.0-alpine as build # 指定go的环境变量 ENV GOPROXY=https://goproxy.cn \ GO111MODULE=on \ CGO_ENABLED=0 \ GOOS=linux \ GOARCH=amd64 # 可以自定义其他环境变量 # 指定工作空间目录,会自动cd到这个目录 WORKDIR /build # 把项目的依赖配置文件拷贝到容器中,并下载依赖 COPY go.mod . COPY go.sum . RUN go mod download # 把项目的其他所有文件拷贝到容器中 COPY . . # 编译成可执行二进制文件 RUN go build -o app . # 指定新的运行环境,最终的运行会基于这个坏境,使得最终的镜像非常小 FROM scratch as deploy # 把编译环境中打包好的可执行文件和配置文件拷贝到当前镜像 COPY --from=build /build/app / COPY --from=build /build/config.yml ./config.yml CMD ["/app"]
打包发布镜像
- 将项目根目录压缩为 zip 文件
- 使用 scp 等指令将 zip 文件上传到 linux 设备中并解压
- 继续 cd到项目根目录,创建镜像
docker build . -t douyin-server
- 创建容器
docker run -itd --name douyin -p 8080:8080 douyin-server
- 查看结果
root@VM-8-11-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89fc75ba6a22 douyin-server "/app" 2 hours ago Up 2 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp douyin
- app 输入baseURL http://{docker宿主机IP}:8080 即可访问项目