๐ผ๏ธ ์๋ก : ์ ๊ฐ์ธ ํ์ผ ์๋ฒ์ธ๊ฐ?
ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ณ , URL๋ก ์ ๊ทผํด์ ๋ณด์ฌ์ค์ผ ํ ์ผ์ด ๋ง์ต๋๋ค.
AWS S3 ๊ฐ์ ํด๋ผ์ฐ๋ ์คํ ๋ฆฌ์ง๋ ์ข์ง๋ง, ๊ฐ๋จํ ๋ด๋ถ ์๋น์ค๋ ํ
์คํธ์ฉ์ผ๋ก๋ ์ง์ ๊ตฌ์ถํ ํ์ผ ์๋ฒ๊ฐ ๋ ๊ฐํธํ๊ณ ๋น์ฉ๋ ๋ค์ง ์์ฃ .
๊ทธ๋์ ์ด๋ฒ์๋ Spring Boot + Docker + Nginx ์กฐํฉ์ผ๋ก ๊ฐ์ธ ์ด๋ฏธ์ง ํ์ผ ์๋ฒ๋ฅผ ๊ตฌ์ถํด๋ณด๊ฒ ์ต๋๋ค.
์ ์ฒด๊ตฌ์กฐ
[Client]
|
[Spring Boot] ← ํ์ผ ์
๋ก๋ + ๋๋ ํ ๋ฆฌ ์๋ ์์ฑ
|
[Docker Volume] (๊ณต์ )
|
[Nginx] → ์ ์ ํ์ผ ์๋ฒ (์ด๋ฏธ์ง ์๋น)
โ๏ธ 1. Spring Boot: ์ด๋ฏธ์ง ์ ๋ก๋ + ๋๋ ํ ๋ฆฌ ์์ฑ
Spring Boot๋ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ด๋ฏธ์ง๋ฅผ ๋ฐ์,
์ฌ์ฉ์ ID๋ณ ๋๋ ํ ๋ฆฌ์ ์ ์ฅํฉ๋๋ค.
๋๋ ํ ๋ฆฌ๊ฐ ์๋ค๋ฉด ์๋์ผ๋ก ์์ฑํฉ๋๋ค.
๐ FileUploadController.java
@RestController
@RequestMapping("/api/files")
public class FileUploadController {
private final FileUploadService fileUploadService;
public FileUploadController(FileUploadService fileUploadService) {
this.fileUploadService = fileUploadService;
}
@PostMapping("/upload/{userId}")
public ResponseEntity<String> uploadFile(
@PathVariable String userId,
@RequestParam("file") MultipartFile file) {
try {
String savedPath = fileUploadService.saveFile(userId, file);
return ResponseEntity.ok("File saved at: " + savedPath);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("File upload failed");
}
}
}
๐ FileUploadService.java
@Service
public class FileUploadService {
private final String uploadRoot = "/app/uploads/users";
public String saveFile(String userId, MultipartFile file) throws IOException {
Path userDir = Paths.get(uploadRoot, userId);
if (Files.notExists(userDir)) {
Files.createDirectories(userDir);
}
String originalFilename = file.getOriginalFilename();
Path targetPath = userDir.resolve(originalFilename);
file.transferTo(targetPath.toFile());
return targetPath.toString();
}
}
๐ application.yml
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
๐ณ 2. Docker + docker-compose ๊ตฌ์ฑ
Spring Boot ์ปจํ ์ด๋์ Nginx ์ปจํ ์ด๋๊ฐ **๊ฐ์ ๋ณผ๋ฅจ(/uploads)**์ ๊ณต์ ํ๋๋ก ์ค์ ํฉ๋๋ค.
version: '3'
services:
app:
build: .
volumes:
- ./uploads:/app/uploads
ports:
- "8080:8080"
nginx:
image: nginx
volumes:
- ./uploads:/usr/share/nginx/html:ro
ports:
- "80:80"
๐ 3. Nginx: ์ ์ ์ด๋ฏธ์ง ํ์ผ ์ ๊ณต
Nginx๋ uploads ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง์ดํธํด์
http://localhost/users/1234/profile.jpg์ฒ๋ผ ์ ์ ํ์ผ์ ์ง์ ์๋นํฉ๋๋ค.
๐งช 4. ํ ์คํธํ๊ธฐ
โ ํ์ผ ์ ๋ก๋
curl -F "file=@profile.jpg" http://localhost:8080/api/files/upload/1234
โ ์ด๋ฏธ์ง ์ ๊ทผ
http://localhost/users/1234/profile.jpg
โ ๋ง๋ฌด๋ฆฌ
์ด ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ ์ฅ์ ์ด ์์ต๋๋ค:
- ๊ฐ๋จํ๊ณ ๋ก์ปฌ ํ ์คํธ์ ์ ๋ฆฌ
- ๋น์ฉ์ด ๋ค์ง ์์
- Nginx๊ฐ ํ์ผ์ ๋น ๋ฅด๊ฒ ์๋น
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ์ ๋ ์ ์ํด์ผ ํฉ๋๋ค:
- ๋์ฉ๋ ํ์ผ ๋ฐฑ์ ๋ฐ ๋ด๊ตฌ์ฑ์ S3์ ๋นํด ๋จ์ด์ง
- ๋ณด์, ์ธ์ฆ ๋ก์ง์ ์ง์ ๊ตฌํํด์ผ ํจ
'Spring & SpringBoot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Spring Cloud Gateway์ MSA ํ๊ฒฝ์์ ๋ด๋ถ ์๋น์ค ๊ฐ ์ธ์ฆ ์ฒ๋ฆฌ ์ ๋ต (0) | 2025.07.18 |
|---|---|
| Spring Boot MSA ๊ตฌ์กฐ์์ Auth-Service ๊ฐ๋ฐํ๋ฉฐ ๊ฒช์ ์ค์ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ (1) | 2025.07.17 |
| Gateway๋? Front Desk? Entrance? (0) | 2025.04.15 |
| MSA ํ๊ฒฝ์์ Spring Clound์ Role (1) | 2025.04.15 |
| Spring @Transaction์ ๋ํด์ ๊น์ด์๊ฒ ์์๋ณด์ (0) | 2025.04.15 |