← 목록으로

캠스터디 프로젝트 서버 배포 및 SSH 접속 불가 이슈 해결

YEJI · 2025. 04. 20. 16:24 · 2분
목차

서론

캠스터디 프로젝트를 진행하면서 초기에 빠른 개발을 위해 Supabase로 백엔드를 구축했으나, 실제 서비스 운영 하는 방식과 가장 가깝게 설정하고 싶어서 API를 따로 분리해서 만들기로 결정하였습니다. 백엔드 코드를 GPT의 도움으로 작성하였습니다.

본 게시물에서는 EC2와 Docker를 활용한 서버 배포 과정과 배포 후 지속적으로 발생한 SSH 접속 불가 문제를 해결한 과정을 기록했습니다.

사용한 기술 스택 및 환경

  • AWS EC2
  • Docker
  • Docker Compose
  • MySQL
  • Spring Boot

배포 과정

기존의 배포 방식과 달리 Docker를 이용한 컨테이너 기반의 배포를 진행했습니다. 아래 블로그 글을 참고하여 진행했습니다.

📘 참고 문서: [Docker] 도커로 EC2에 서버 배포하기

주요 Dockerfile 설정:

dockerfile
FROM openjdk:17-jdk-slim AS build
WORKDIR /app
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
 
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY src/main/resources/application.yml /app/application.yml
COPY --from=build /app/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dotel.resource.attributes=service.name=auth-server", "-jar", "app.jar"]

Docker Hub에 이미지 등록 후, EC2에서 아래의 Docker Compose 설정으로 배포했습니다:

yaml
version: "3.9"
 
services:
mysql:
image: mysql:8.0
platform: linux/amd64
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql-vl:/var/lib/mysql
command: >
--default-authentication-plugin=mysql_native_password
--innodb_buffer_pool_size=128M
--max_connections=50
--table_open_cache=200
--innodb_log_buffer_size=16M
restart: always
 
app:
image: yejiii1997/cmas:latest
platform: linux/amd64
container_name: camstudy-backend
depends_on:
- mysql
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: prod
DB_HOST: mysql
DB_PORT: 3306
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
restart: always
 
volumes:
mysql-vl:
driver: local

🔥 발생한 문제 및 원인 분석

배포 후 일정 시간이 지나면 서버가 정상적으로 동작하지 않았고, 심지어 SSH 접속조차 불가능했습니다. EC2의 상태 검사는 2개 중 1개만 통과하는 상태였습니다. 로그 확인 결과 다음의 에러가 나타났습니다:

bash
[18167.348589] Out of memory: Killed process 1971 (mysqld) total-vm:1294692kB, anon-rss:369024kB...

이는 MySQL 프로세스가 메모리 부족으로 인해 커널에서 강제 종료된(OOM Kill) 현상이었습니다.

당시 EC2 메모리 상태:

  • 총 메모리: 957.4 MiB
  • MySQL 사용: 370MB (%MEM 37.8)
  • Java 애플리케이션 사용: 207MB (%MEM 21.2)
  • 남은 여유 메모리: 69.6 MiB

해결 방안

Swap 메모리 설정

메모리 부족 문제를 해결하기 위해 Swap 메모리를 추가했습니다.

bash
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
 
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

MySQL 메모리 제한

MySQL 컨테이너의 메모리 사용량을 제한했습니다.

yaml
command: >
--default-authentication-plugin=mysql_native_password
--innodb_buffer_pool_size=128M
--max_connections=50
--table_open_cache=200
--innodb_log_buffer_size=16M
설정 항목설명
innodb_buffer_pool_size=128MInnoDB 캐시 메모리 크기
max_connections=50최대 동시 접속 수 제한
table_open_cache=200테이블 캐시 개수
innodb_log_buffer_size=16M로그 버퍼 크기

설정 변경 후에는 반드시 Docker 컨테이너를 재시작해야 합니다.

bash
docker-compose down
docker-compose up -d

개선된 결과

컨테이너변경 전변경 후차이
MySQL370MiB248.6MiB↓121MiB
Backend거의 동일거의 동일유지됨

현재 안정적으로 서버가 운영 중입니다. 다시는 이런 문제로 글을 쓰지 않기를 바랍니다... 제발~!