基于docker搭建大项目环境 | 青训营笔记

2023年 8月 15日 70.9k 0

基于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 即可访问项目

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论