一、CentOS7 安装 FTP 服务
以前,如果要完成譬如上传头像功能,需要访问后端接口,将头像信息上传到前端项目中(也就是我们自己的服务器上),这是不合理的,需要有一个专门的 文件服务器 来存储。就需要用 FTP 来搭建一个 文件服务器。
1:安装 vsftpd
yum -y install vsftpd
2:关闭匿名访问
可以不关,但是关了以后就必须得输入用户名和密码才能访问
vim /etc/vsftpd/vsftpd.conf
将anonymous_enable的值改为NO
3:启动服务
systemctl start vsftpd.service
4:查看服务状态
systemctl status vsftpd.service
如果结果中包含 active(running) 则表示启动成功。
启动成功后,需要通过外部去访问 FTP 服务器,需要开放端口。
5:开放端口访问
firewall-cmd --zone=public --add-port=21/tcp --permanent
firewall-cmd --zone=public --add-port=1025-65535/tcp --permanent
systemctl restart firewalld
firewall-cmd --list-ports
Add:直接在 Windows 上访问 Linux
需要新建用户,来操作 FTP。
ROOT 用户不能用于 FTP 服务器登录
6:新建一个用户,测试操作 FTP
adduser user-file
passwd user-file
上传的文件,会保存在访问用户的工作空间下:/home/user-file
登录,如果提示错误:
chmod -R 777 /home/user-file/
二、SpringBoot上传文件到Linux的FTP文件服务器
1:pom 依赖
<!-- FTP上传文件组件 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
2:编写一个用于 FTP 操作的工具类
package com.du.ftptest.utils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import java.io.IOException;
import java.io.InputStream;
public class FtpUtil {
// FTP服务器IP地址
// @Value("${ftp.service.address}")
private static final String FTP_SERVICE_ADDRESS = "106.225.xxx.xxx";
// 端口号
// @Value("${ftp.service.port}")
private static final int FTP_SERVICE_PORT = 21;
// 用户名
// @Value("${ftp.service.username}")
private static final String FTP_SERVICE_USERNAME = "duruikun-file";
// 密码
// @Value("${ftp.service.password}")
private static final String FTP_SERVICE_PASSWORD = "duruikun.123";
// 附件路径
// @Value("${ftp.service.basepath}")
private static final String FTP_SERVICE_BASEPATH = "/home/duruikun-file/files";
public static boolean uploadFile(String fileName, InputStream input) {
boolean success = false;
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(FTP_SERVICE_ADDRESS, FTP_SERVICE_PORT);
ftp.login(FTP_SERVICE_USERNAME, FTP_SERVICE_PASSWORD);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return false;
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.makeDirectory(FTP_SERVICE_BASEPATH);
ftp.changeWorkingDirectory(FTP_SERVICE_BASEPATH);
ftp.enterLocalPassiveMode();
ftp.storeFile(fileName, input);
input.close();
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return success;
}
}
3:上传文件接口
@RestController
public class UserController {
@Resource
private UserService userService;
@PostMapping("addUser")
public String addUser(User user, @RequestParam("headPic") MultipartFile file) {
try {
InputStream inputStream = file.getInputStream();
String filename = file.getOriginalFilename();
String suffix = filename.substring(filename.lastIndexOf("."));
String finalName = UUID.randomUUID() + suffix;
boolean flag = FtpUtil.uploadFile(finalName, inputStream);
} catch (IOException e) {
e.printStackTrace();
}
return "成功";
}
}
4:postman 测试文件上传
三、Docker 部署 FTP
1:docker search
docker search vsftpd
2:docker pull
docker pull fauria/vsftpd
3: docker run
docker run -d -p 20:20 -p 21:21 -p 8800-8899:8800-8899 -v /home/dockerData/ftpData:/home/vsftpd -e FTP_USER=duruikun -e FTP_PASS=123456 -e PASV_ADDRESS=127.0.0.1 -e PASV_MIN_PORT=8800 -e PASV_MAX_PORT=8899 --name vsftpd --restart=always fauria/vsftpd
如果8848与nacos冲突:
docker run -d -p 20:20 -p 21:21 -p 8800-8847:8800-8847 -p 8849-8899:8849-8899 -v /home/dockerData/ftpData:/home/vsftpd -e FTP_USER=duruikun -e FTP_PASS=123456 -e PASV_ADDRESS=127.0.0.1 -e PASV_MIN_PORT=8800 -e PASV_MAX_PORT=8899 --name vsftpd --restart=always fauria/vsftpd
-d 指定容器运行于前台还是后台,默认为false
-p 端口映射 容器暴露的端口:内部真实端口
-v 容器挂载存储卷(暴露给外部的存储卷):挂载到容器的某个目录(内部真实目录)
-e 指定环境变量,容器中可以使用该环境变量
FTP_USER ftp账户
FTP_PASS ftp秘钥
PASV_ADDRESS 宿主机ip
PASV_MIN_PORT ftp被动模式下的最小端口
PASV_MAX_PORT ftp被动模式下的最大端口
–name 指定容器的名字
–restart 指定容器停止后的重启策略:no:容器退出时不重启 on-failure:容器故障退出(返回值非零)时重启 always:容器退出时总是重启
fauria/vsftpd 要部署到容器中得镜像
最后需要在服务器端开启 20-21 8800-8899 端口