Linux/Ubuntu 24

우분투 24에 Docker로 워드프레스 설치하기 (운영 서버 보안 설정 적용)

Ryan's Tech Note 2025. 5. 11. 16:16

https://saju.choeum.com/pos/front/sjuF0101.do?ref=s_BwgZAV1CS2tVJUAFBwEHCjMAAAAAbUJXUg

 

처음 사주 - 인생 7포인트

2026년 성공하는 시기·성향·연애운·금전운·10년 운까지 한눈에

saju.choeum.com

 


우분투에 Docker로 워드프레스 설치하기 (운영 서버용 설정 및 보안 강화)

버전 정보

  • 우분투 버전: Ubuntu 24.04 LTS (Noble Numbat)
  • 워드프레스 버전: WordPress 6.5 LTS (최신 안정 버전)
  • 도커 버전: Docker 25.0 LTS
  • MariaDB 버전: MariaDB 10.11 LTS (설치 시점에 따라 최신 LTS 버전으로 선택하세요)
  • 컨테이너 이미지: wordpress:latest, mariadb:10.11

우분투 서버에 도커로 워드프레스 설치하는 방법을 정리했다. 도커 허브의 워드프레스 공식 이미지와 MariaDB 10.11 LTS 버전을 사용한다. 워드프레스는 MariaDB 10.5 이상을 권장하는데, 10.11은 2026년까지 장기 지원되는 LTS 버전이라 안정적이다. 설치 시점에 따라 MariaDB의 최신 LTS 버전을 선택하여 사용하는 것이 좋습니다.

도커를 사용하면 복잡한 LAMP 스택 설정 없이 워드프레스와 MariaDB를 간단하게 설치할 수 있다. 이것저것 알아볼 필요 없이 아래 순서대로만 따라하면 된다.

(1) 환경 확인

우분투 버전 확인:

lsb_release -a
# 출력:
# No LSB modules are available.
# Distributor ID: Ubuntu
# Description:    Ubuntu 24.04 LTS
# Release:        24.04
# Codename:       noble

(2) Docker 설치 및 root 권한 보안 설정

도커가 이미 설치되어 있으면 이 단계는 건너뛰면 된다.

# 필요한 패키지 설치
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# Docker의 공식 GPG 키 추가
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Docker 리포지토리 추가
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 패키지 인덱스 업데이트
sudo apt-get update

# Docker 설치
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Docker 서비스 활성화
sudo systemctl enable --now docker

도커 root 권한 보안 문제 해결:

# 일반 사용자를 docker 그룹에 추가하여 sudo 없이 도커 명령 실행
sudo usermod -aG docker $USER
newgrp docker  # 현재 세션에 그룹 변경 적용

# 도커 데몬 보안 설정 (root 권한 필요)
sudo nano /etc/docker/daemon.json

daemon.json 파일에 다음 내용 추가:

{
  "userns-remap": "default",
  "no-new-privileges": true
}

설정 적용 (root 권한 필요):

# root 권한으로 docker 서비스 재시작
sudo systemctl restart docker

(3) 프로젝트 디렉토리 생성

# 디렉토리 생성 및 권한 설정
sudo mkdir -p /srv/docker/wordpress
sudo chown $USER:docker /srv/docker/wordpress
sudo chmod 775 /srv/docker/wordpress

# 디렉토리로 이동
cd /srv/docker/wordpress

(4) Docker Compose 설정 파일 작성

nano docker-compose.yml

아래 내용 입력:

services:
  # MariaDB 10.11 LTS 컨테이너 (워드프레스 권장 버전)
  db:
    image: mariadb:10.11
    container_name: wp_mariadb
    restart: always
    volumes:
      - wp_database:/var/lib/mysql
      - wp_mariadb_logs:/var/log/mysql  # 로그 외부화
    environment:
      # 보안을 위해 아래 값들을 모두 변경하세요
      # 주의: MYSQL_DATABASE, MYSQL_USER 값을 변경할 경우
      # wordpress 컨테이너의 WORDPRESS_DB_NAME, WORDPRESS_DB_USER도 
      # 동일한 값으로 변경해야 합니다
      MYSQL_ROOT_PASSWORD: strong_root_password  # 강력한 비밀번호로 변경
      MYSQL_DATABASE: wp_database    # 기본값에서 변경 권장
      MYSQL_USER: wp_user            # 기본값에서 변경 권장
      MYSQL_PASSWORD: wp_password    # 강력한 비밀번호로 변경
    networks:
      - wordpress_net
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    user: mysql  # root가 아닌 mysql 사용자로 실행 (보안 강화)

  # 도커 허브 공식 WordPress 이미지
  wordpress:
    image: wordpress:latest
    container_name: wp_site
    depends_on:
      - db
    restart: always
    ports:
      - "8080:80"  # 8080 포트로 접속
    volumes:
      - wp_html:/var/www/html
      - wp_apache_logs:/var/log/apache2  # 아파치 로그 외부화
      - wp_php_logs:/var/log/php  # PHP 로그 외부화
    environment:
      # 아래 값들은 db 컨테이너의 환경 변수와 일치해야 합니다
      # db 컨테이너에서 MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD를 변경한 경우
      # 여기서도 WORDPRESS_DB_NAME, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD를
      # 정확히 동일한 값으로 설정해야 합니다
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wp_database    # MYSQL_DATABASE와 동일하게 설정
      WORDPRESS_DB_USER: wp_user        # MYSQL_USER와 동일하게 설정
      WORDPRESS_DB_PASSWORD: wp_password # MYSQL_PASSWORD와 동일하게 설정
    networks:
      - wordpress_net
    user: www-data  # root가 아닌 www-data 사용자로 실행 (보안 강화)

volumes:
  wp_database:
  wp_html:
  wp_mariadb_logs:
  wp_apache_logs:
  wp_php_logs:

networks:
  wordpress_net:

(5) 컨테이너 실행

docker compose up -d

이미지 다운로드 때문에 처음에는 좀 시간이 걸린다.

(6) 워드프레스 접속

브라우저에서 http://서버IP:8080 또는 http://localhost:8080으로 접속하면 워드프레스 설치 화면이 나온다. 언어 선택하고 계정 정보 입력하면 끝.

(7) 포트 충돌 문제 해결

만약 이런 오류가 발생한다면:

Error response from daemon: driver failed programming external connectivity on endpoint wp_site: Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use

이미 80번 포트를 사용 중인 서비스(Apache나 Nginx)가 있다는 뜻이다. docker-compose.yml 파일의 포트 설정을 다른 번호로 바꿔주면 된다:

ports:
  - "8080:80"  # 8080 포트로 변경

변경 후 다시 실행:

docker compose up -d

(8) 로그 관리 및 정리 설정

Named Volume에 저장된 로그 파일을 효과적으로 관리하기 위한 스크립트를 생성합니다:

cd /srv/docker/wordpress
nano cleanup-logs.sh

다음 내용 입력:

#!/bin/bash
# 로그 볼륨 내부 로그 파일 정리 스크립트

LOG_FILE="/srv/docker/wordpress/logs-cleanup.log"
echo "로그 정리 시작: $(date)" >> $LOG_FILE

# 각 로그 볼륨의 오래된 로그 파일 정리 (7일 이상)
for volume in wp_apache_logs wp_php_logs wp_mariadb_logs; do
  docker run --rm -v $volume:/logs alpine sh -c '
    find /logs -type f -mtime +7 -delete
    echo "'$volume' 정리 완료"
  '
done

# 일반적인 도커 리소스 정리 (미사용 컨테이너, 이미지 등)
docker system prune -f

echo "로그 정리 완료: $(date)" >> $LOG_FILE

실행 권한 설정:

chmod +x cleanup-logs.sh

로그 확인 방법

# 컨테이너 로그 확인 (가장 일반적인 방법)
docker logs wp_site     # 워드프레스 컨테이너 로그
docker logs wp_mariadb  # MariaDB 컨테이너 로그
docker logs -f wp_site  # 실시간 로그 확인 (Ctrl+C로 종료)

# Named Volume 내 로그 파일 직접 확인
docker run --rm -v wp_apache_logs:/logs alpine sh -c "ls -la /logs && tail -n 50 /logs/access.log"

(9) 보안 취약점 자동 업데이트 설정

보안 취약점이 있을 때만 도커 이미지를 자동으로 업데이트하는 스크립트를 만든다:

cd /srv/docker/wordpress
nano update-security.sh

스크립트 내용:

#!/bin/bash
# 보안 취약점이 있을 때만 이미지 업데이트

# Trivy 설치 (없는 경우)
if ! command -v trivy &> /dev/null; then
    sudo apt-get install -y wget apt-transport-https gnupg lsb-release jq
    wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
    echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
    sudo apt-get update
    sudo apt-get install -y trivy
fi

# 로그 파일 설정
LOG_FILE="/srv/docker/wordpress/security-updates.log"
touch $LOG_FILE
chmod 666 $LOG_FILE

# 보안 취약점 스캔
echo "현재 이미지의 보안 취약점을 스캔합니다..."
WP_VULNS_OUTPUT=$(trivy image --severity HIGH,CRITICAL wordpress:latest 2>/dev/null)
MARIADB_VULNS_OUTPUT=$(trivy image --severity HIGH,CRITICAL mariadb:10.11 2>/dev/null)

# 취약점 포함 여부 확인
WP_HAS_VULNS=0
MARIADB_HAS_VULNS=0

if echo "$WP_VULNS_OUTPUT" | grep -q "CRITICAL\|HIGH"; then
    WP_HAS_VULNS=1
fi

if echo "$MARIADB_VULNS_OUTPUT" | grep -q "CRITICAL\|HIGH"; then
    MARIADB_HAS_VULNS=1
fi

# 취약점이 있는 경우만 업데이트
if [ $WP_HAS_VULNS -eq 1 ] || [ $MARIADB_HAS_VULNS -eq 1 ]; then
    echo "보안 취약점이 발견되어 이미지를 업데이트합니다."
    
    # 이미지 업데이트
    [ $WP_HAS_VULNS -eq 1 ] && docker pull wordpress:latest
    [ $MARIADB_HAS_VULNS -eq 1 ] && docker pull mariadb:10.11
    
    # 컨테이너 재시작
    docker compose down
    docker compose up -d
    
    echo "업데이트 완료: $(date)" >> $LOG_FILE
else
    echo "보안 취약점이 없습니다. 업데이트가 필요하지 않습니다."
    echo "검사 완료 (취약점 없음): $(date)" >> $LOG_FILE
fi

실행 권한 설정:

chmod +x update-security.sh

(10) 자동화 스크립트 실행 설정

로그 정리와 보안 업데이트를 자동으로 실행하도록 crontab에 등록합니다:

sudo crontab -e

다음 내용 추가:

# 매주 월요일 새벽 2시에 로그 정리 실행
0 2 * * 1 /srv/docker/wordpress/cleanup-logs.sh > /dev/null 2>&1

# 매주 일요일 새벽 3시에 보안 업데이트 검사
0 3 * * 0 /srv/docker/wordpress/update-security.sh > /dev/null 2>&1

(11) 유용한 명령어

# 컨테이너 상태 확인
docker ps

# 컨테이너 중지/시작
docker compose stop
docker compose start

# 컨테이너와 네트워크 제거 (볼륨 데이터는 유지)
docker compose down

# 볼륨 정보 확인
docker volume ls

(12) 도커 컨테이너 재시작 방법

서버 재부팅이나 설정 변경 후 컨테이너를 재시작하는 방법:

# 모든 컨테이너 재시작
docker compose restart

# 개별 컨테이너 재시작
docker compose restart wordpress  # 워드프레스만 재시작
docker compose restart db         # MariaDB만 재시작

# 설정 변경 후 완전히 다시 시작
docker compose down     # 컨테이너 중지 및 제거 (볼륨은 유지)
docker compose up -d    # 컨테이너 다시 생성 및 시작

(13) 볼륨 백업 및 복원

데이터를 안전하게 백업하려면:

# 모든 볼륨 백업
docker run --rm -v $(pwd):/backup -v wp_database:/data alpine tar czf /backup/wp_database_backup.tar.gz -C /data .
docker run --rm -v $(pwd):/backup -v wp_html:/data alpine tar czf /backup/wp_html_backup.tar.gz -C /data .

# 볼륨 복원 (필요한 경우)
docker run --rm -v $(pwd):/backup -v wp_database:/data alpine sh -c "cd /data && tar xzf /backup/wp_database_backup.tar.gz"
docker run --rm -v $(pwd):/backup -v wp_html:/data alpine sh -c "cd /data && tar xzf /backup/wp_html_backup.tar.gz"

(14) Named Volume 완전 삭제 방법

데이터베이스 오류나 설정 문제 발생 시 모든 볼륨을 초기화하고 싶다면:

# 1. 먼저 컨테이너 중지
docker compose down

# 2. 현재 볼륨 목록 확인
docker volume ls

# 3. 워드프레스 관련 볼륨 모두 삭제 (기본 볼륨명 사용 시)
docker volume rm wp_database wp_html wp_mariadb_logs wp_apache_logs wp_php_logs

# 또는 프로젝트명이 접두사로 추가된 경우
# 예: 'wordpress_wp_database'와 같은 형식으로 볼륨이 생성된 경우
docker volume rm wordpress_wp_database wordpress_wp_html wordpress_wp_mariadb_logs wordpress_wp_apache_logs wordpress_wp_php_logs

# 또는 패턴으로 일치하는 모든 볼륨 한 번에 삭제
docker volume rm $(docker volume ls -q --filter name=wp_)
# 또는
docker volume rm $(docker volume ls -q --filter name=wordpress_wp_)

# 4. 컨테이너 다시 시작 (볼륨은 자동으로 새로 생성됨)
docker compose up -d

주의: 볼륨을 삭제하면 해당 볼륨에 저장된 모든 데이터(데이터베이스, 워드프레스 파일 등)가 영구적으로 삭제됩니다. 중요한 데이터가 있다면 먼저 백업하세요.

이렇게 설치한 워드프레스는 데이터와 로그가 도커 볼륨에 저장되어 컨테이너가 삭제되어도 데이터가 안전하게 보존된다. 도커 컨테이너는 root 권한 없이 전용 사용자로 실행되어 보안이 강화되었다. 또한 보안 취약점이 있을 때만 자동으로 이미지가 업데이트되므로 안정성과 보안을 모두 확보할 수 있다.

 


 

https://saju.choeum.com/pos/front/sjuF0101.do?ref=s_BwgZAV1CS2tVJUAFBwEHCjMAAAAAbUJXUg

 

처음 사주 - 인생 7포인트

2026년 성공하는 시기·성향·연애운·금전운·10년 운까지 한눈에

saju.choeum.com