本文搭建的docker==镜像==和前后端==源码==可私信我哦^^
1.概述
本文基于 《图床共享云存储》进行部署上的改进,如需了解项目请先阅读本站的《图床单机搭建》与《图床项目详解》文章^^
之前的图床采用单机架构,本文带来用docker容器+微服务的方式部署该项目,为项目增加亮点
拓展:
docker
k8s
优势: 为什么要用docker+微服务?
解耦合,方便调整与拓展开发单个模块
避免了一个模块崩溃而整个项目崩溃,例如文件系统崩溃了导致整个图床项目不可访问
方便拓展与管理(例如添加storage增加容灾备份节点)
2.项目架构
本文将项目解耦为三个微服务,分别是:
fastdfs+nginx
http-server + redis
mysql
3.部署步骤
3.1镜像构建方式
一般docker镜像的构建有三种方式可选:
Dockerfile 通过编写dockerfile文件的方式,一键启动构建后等待构建完成即可 优势:中间过程省事,不需要处理 缺点:在项目环境搭建复杂的情况下不好编写dockerfile文件,复杂
commit方式 通过搭建一个基础容器,在容器中搭建好环境后再commit成一个新镜像 优势:过程完全可见 劣势:需要自己搭建,过程较繁琐
原生搭建+copy方式 当搭建基础容器时(比如ubuntu容器),可能出现项目编译需要内核支持的情况,但是拉取构建的ubuntu镜像是精简版的内核,没法支持编译(笔者在之前搭建dpdk环境的时候无法通过基础ubuntu容器编译dpdk,采用的是宿主机编译好后采用docker cp的方式,具体参见本站博客《docker 基础命令详解》)
3.2容器搭建流程
docker-compose docker-compose是xxxxx。
version: '3.8'
services:
tc_mysql:
image: tc_mysql:v1.0
container_name: tc_mysql
# networks:
# my_net:
# ipv4_address: 172.17.0.2
restart: unless-stopped
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 5
fastdfs_nginx:
image: tc_fastdfs_nginx:v2
container_name: tc_fastdfs_nginx
# networks:
# my_net:
# ipv4_address: 172.17.0.3
restart: unless-stopped
ports:
- "8080:80"
- "443:443"
command: /usr/local/bin/init_fastdfs.sh # 关键修改:直接调用脚本
volumes:
# 挂载脚本(如果镜像中没有内置)
- ./init_fastdfs.sh:/usr/local/bin/init_fastdfs.sh:ro
- ./tmp:/root
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 10s
timeout: 3s
retries: 3
tc_server:
image: tc_server:v1.1
container_name: tc_server
restart: unless-stopped
ports:
- "8081:8080"
command: /usr/local/bin/init_server.sh # 修改启动命令
volumes:
- ./init_server.sh:/usr/local/bin/init_server.sh:ro
- ./tmp:/root
depends_on:
tc_mysql:
condition: service_healthy
fastdfs_nginx:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/"]
interval: 10s
timeout: 3s
retries: 3
# networks:
# my_net:
# driver: bridge
# ipam:
# config:
# - subnet: 172.17.0.0/24
# # 将配置文件挂载到容器外
# volumes:
# - ./configs/tc_http_server.conf:/tc/tc-src/buile_new/tc_http_server.conf:ro
# # 增强健康检查
# tc_mysql:
# healthcheck:
# test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
# interval: 5s
# timeout: 3s
# retries: 5
# fastdfs_nginx:
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost/health"]
# interval: 10s
# timeout: 3s
# retries: 3
# tc_server:
# depends_on:
# tc_mysql:
# condition: service_healthy
# fastdfs_nginx:
# condition: service_healthy
#!/bin/bash
# 自动替换 FastDFS 配置文件中 tracker_server 的 IP
# 获取本容器在 Docker 网络中的 IP(推荐两种方式任选其一)
# 方式1:通过 hostname 获取(适用于大多数情况)
CONTAINER_IP=$(hostname -i | awk '{print $1}')
# 方式2:通过 eth0 接口获取(更精确)
# CONTAINER_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
# ---------- 获取 tc_server 容器的实际IP ----------
# 通过 Docker DNS 解析服务名(关键改动)
TC_SERVER_IP=$(getent hosts tc_server | awk '{print $1}')
# 配置文件路径
CONF_FILE="/etc/fdfs/mod_fastdfs.conf"
# 配置文件storage.conf路径
STORAGE_CONF_FILE="/etc/fdfs/storage.conf"
# 配置文件nginx.conf路径
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
# 执行替换操作(保留原端口号)
sed -i "s/^tracker_server=.*:\([0-9]\+\)$/tracker_server=${CONTAINER_IP}:\1/" "${CONF_FILE}"
# 执行替换操作(保留原端口号)
sed -i "s/^tracker_server =.*:\([0-9]\+\)$/tracker_server=${CONTAINER_IP}:\1/" "${STORAGE_CONF_FILE}"
# ---------- Nginx 配置替换(关键新增部分)----------
# 替换所有 proxy_pass 中的 tc_server 为实际IP(保留端口号)
sed -i "s/\btc_server\b/${TC_SERVER_IP}/g" "${NGINX_CONF_FILE}"
# 验证修改结果
echo "修改后的 tracker_server 配置:"
grep "^tracker_server" "${CONF_FILE}"
echo -e "\n==== Nginx 代理后端IP ===="
grep "proxy_pass" "${NGINX_CONF_FILE}"
# 启动Tracker服务
/etc/init.d/fdfs_trackerd start
# 启动Storage服务
/etc/init.d/fdfs_storaged start
# 启动Nginx(必须前台运行)
/usr/local/nginx/sbin/nginx -g "daemon off;"
# 保持容器运行(备用命令)
# tail -f /dev/null
#!/bin/bash
# 自动替换配置文件中的动态IP
# 获取本容器IP
CONTAINER_IP=$(hostname -i | awk '{print $1}')
# 获取其他服务的IP(Docker DNS解析)
MYSQL_IP=$(getent hosts tc_mysql | awk '{print $1}')
FASTDFS_IP=$(getent hosts fastdfs_nginx | awk '{print $1}')
# 配置文件路径
CONFIG_FILE="/tc/tc-src/buile_new/tc_http_server.conf"
#build文件夹路径
BUILD_PATH="/tc/tc-src/buile_new"
# 执行替换操作
sed -i \
-e "s/^web_server_ip=.*/web_server_ip=${CONTAINER_IP}/" \
-e "s/^storage_web_server_ip=.*/storage_web_server_ip=${FASTDFS_IP}/" \
-e "s/^tuchuang_master_host=.*/tuchuang_master_host=${MYSQL_IP}/" \
-e "s/^tuchuang_slave_host=.*/tuchuang_slave_host=${MYSQL_IP}/" \
"${CONFIG_FILE}"
# 启动redis服务
redis-server &
cd /tc/tc-src/buile_new/
# 启动tc_http_server
./tc_http_server -g "daemon off;"
# 验证修改
echo "==== 修改后的关键配置 ===="
grep -E "web_server_ip|storage_web_server_ip|tuchuang_.*_host" "${CONFIG_FILE}"
fastdfs 本项目fastdfs构建复杂,涉及多个conf文件,nginx搭建,nginx重编译,过程复杂,笔者希望过程可见,采用commit方式,在一个基础ubuntu镜像中搭建。
fastdfs+nginx容器构建命令
mkdir -p /tmp
docker run -it -p 8080:80 -v /tmp:/root --name myfastdfs_nginx <镜像id> /bin/bash
#注意:一定要修改端口映射,否则将会导致nginx与宿主机80端口冲突!
#注意:一定要挂载volume,因为分布式场景下源码有bug,需要fastdfs与http_server挂载共同的/root/tmp目录
进入容器后,修改mod_fastdfs.conf中的tracker_server ip, storage.conf 中的tracker_server ip,
ifconfig #查看容器ip
docker inspect <容器id> | grep IPAddress #宿主机查看容器ip
修改storage.conf中的tracker_ip
修改mod_fastdfs.conf中的tracker_ip
修改nginx.conf中的路由的主机地址
/etc/init.d/fdfs_trackerd start
/etc/init.d/fdfs_storaged start
./usr/local/nginx/sbin/nginx
redis redis模块单一,在本项目中没有改动,直接dockerfile处理即可,或者拉取对应版本的镜像 redis可以直接放在back-end container中也可以
redis-server & #后台运行redis-server
mysql
FROM mysql:8.0
# 设置 root 用户的密码
ENV MYSQL_ROOT_PASSWORD=123456
ENV MYSQL_DATABASE=0voice_tuchuang
ENV MYSQL_USER=qhr
ENV MYSQL_PASSWORD=123456
# 复制数据库初始化 SQL 文件
COPY 0voice_tuchuang.sql /docker-entrypoint-initdb.d/
EXPOSE 3306
#启动容器
docker run -d --name tc-mysql -e MYSQL_ROOT_PASSWORD=yourpasswd -p 3306:3306 mysql:v1.0
#连接测试
mysql -h 127.0.0.1 -P 3306 -u root -p
http_server 采用docker cp的方式,在编译好项目后导入基础镜像中
docker run -it -v tmp:/root --name tc-server <镜像id> /bin/bash
cd /tc/tc-src/build/
vim tc_http_conf #修改内容如下
web_server_ip
mysql_ip
storage_web_ip
client_path
安装fastdfs及相关依赖
安装mysql相关依赖
编译
修改tc_http_conf
web_server_ip
mysql_ip
storage_web_ip
client_path
修改/etc/fdfs/client.conf(貌似不需要了)
后续: 后续将优化为==k3s==编排多种容器