https://saju.choeum.com/pos/front/sjuF0101.do?ref=s_BwgZAV1CS2tVJUAFBwEHCjMAAAAAbUJXUg
처음 사주 - 인생 7포인트
2026년 성공하는 시기·성향·연애운·금전운·10년 운까지 한눈에
saju.choeum.com
우분투에 Docker로 워드프레스 설치하기 (OpenSSL 암호화 및 보안 강화)
버전 정보
- 우분투 버전: 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
- 암호화 알고리즘: AES-256-CBC (OpenSSL)
우분투 서버에 도커로 워드프레스를 설치하는 방법을 정리했습니다. 이 가이드에서는 OpenSSL을 사용하여 데이터베이스 비밀번호를 암호화하여 보안을 강화합니다. 도커를 사용하면 복잡한 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
# OpenSSL 암호화를 위한 키 생성
openssl rand -base64 32 > .key
chmod 600 .key
(4) 암호화 스크립트 생성
워드프레스와 MariaDB의 비밀번호를 안전하게 암호화하고 복호화하는 스크립트를 생성합니다:
# 암호화/복호화 스크립트 생성
cat > encrypt.sh << 'EOF'
#!/bin/bash
KEYFILE="/srv/docker/wordpress/.key"
encrypt() {
echo -n "$1" | openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass file:$KEYFILE
}
decrypt() {
echo "$1" | openssl enc -d -aes-256-cbc -a -pbkdf2 -pass file:$KEYFILE
}
# 사용법 출력
if [ "$1" == "--help" ] || [ "$1" == "-h" ] || [ -z "$1" ]; then
echo "사용법: $0 [encrypt|decrypt] \"텍스트\""
exit 1
fi
# 암호화 또는 복호화 실행
if [ "$1" == "encrypt" ]; then
encrypt "$2"
elif [ "$1" == "decrypt" ]; then
decrypt "$2"
else
echo "알 수 없는 명령: $1"
echo "사용법: $0 [encrypt|decrypt] \"텍스트\""
exit 1
fi
EOF
chmod +x encrypt.sh
# 비밀번호 설정 스크립트 생성 (비밀번호 확인 기능 추가)
cat > setup-passwords.sh << 'EOF'
#!/bin/bash
set -e
SECRETS_FILE="/srv/docker/wordpress/.secrets"
KEYFILE="/srv/docker/wordpress/.key"
# 키 파일 존재 확인
if [ ! -f "$KEYFILE" ]; then
echo "암호화 키를 생성합니다..."
openssl rand -base64 32 > $KEYFILE
chmod 600 $KEYFILE
fi
# 비밀번호 암호화 함수
encrypt() {
echo -n "$1" | openssl enc -aes-256-cbc -a -salt -pbkdf2 -pass file:$KEYFILE
}
# 기본값 설정
DEFAULT_DB_NAME="wp_database"
DEFAULT_DB_USER="wp_user"
# 데이터베이스 이름 및 사용자 입력 받기
read -p "MariaDB 데이터베이스 이름 [기본값: $DEFAULT_DB_NAME]: " DB_NAME
DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
read -p "MariaDB 사용자 이름 [기본값: $DEFAULT_DB_USER]: " DB_USER
DB_USER=${DB_USER:-$DEFAULT_DB_USER}
# 루트 비밀번호 입력 및 확인
while true; do
read -sp "MariaDB 루트 비밀번호: " ROOT_PASSWORD
echo
read -sp "MariaDB 루트 비밀번호 확인: " ROOT_PASSWORD_CONFIRM
echo
if [ "$ROOT_PASSWORD" == "$ROOT_PASSWORD_CONFIRM" ]; then
break
else
echo "비밀번호가 일치하지 않습니다. 다시 입력해주세요."
fi
done
# 사용자 비밀번호 입력 및 확인
while true; do
read -sp "MariaDB 사용자 비밀번호: " USER_PASSWORD
echo
read -sp "MariaDB 사용자 비밀번호 확인: " USER_PASSWORD_CONFIRM
echo
if [ "$USER_PASSWORD" == "$USER_PASSWORD_CONFIRM" ]; then
break
else
echo "비밀번호가 일치하지 않습니다. 다시 입력해주세요."
fi
done
# 비밀번호 암호화
ROOT_PASSWORD_ENC=$(encrypt "$ROOT_PASSWORD")
USER_PASSWORD_ENC=$(encrypt "$USER_PASSWORD")
# 암호화된 비밀번호 저장
cat > $SECRETS_FILE << EOL
DB_NAME=$DB_NAME
DB_USER=$DB_USER
ROOT_PASSWORD_ENC=$ROOT_PASSWORD_ENC
USER_PASSWORD_ENC=$USER_PASSWORD_ENC
EOL
chmod 600 $SECRETS_FILE
echo "데이터베이스 설정 및 비밀번호가 암호화되어 저장되었습니다."
EOF
chmod +x setup-passwords.sh
(5) 비밀번호 설정
이제 암호화된 비밀번호를 생성합니다:
./setup-passwords.sh
이 스크립트는 데이터베이스 이름, 사용자 이름 및 비밀번호를 입력받아 암호화하여 .secrets 파일에 저장합니다. 비밀번호는 두 번 입력받아 일치하는지 확인합니다.
(6) Docker Compose 템플릿 작성
cat > docker-compose.template.yml << 'EOF'
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_ROOT_PASSWORD: "{{ROOT_PASSWORD}}"
MYSQL_DATABASE: "{{DB_NAME}}"
MYSQL_USER: "{{DB_USER}}"
MYSQL_PASSWORD: "{{USER_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:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: "{{DB_NAME}}"
WORDPRESS_DB_USER: "{{DB_USER}}"
WORDPRESS_DB_PASSWORD: "{{USER_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:
EOF
이미지가 업데이트 되어도 데이터가 날라가지 않도록 내부 저장공간과는 또 다른 개념인 named volume 을 사용한다. 외부에 데이터가 저장되도록 설정하려고 했는데 폴더 권한 문제가 계속 발생해서 설정이 너무 복잡하여 심플하게 이 방법으로 해결했다.
(7) 보안 시작 스크립트 생성
워드프레스를 안전하게 시작할 수 있는 스크립트를 작성합니다:
cat > start-secure.sh << 'EOF'
#!/bin/bash
set -e
SECRETS_FILE="/srv/docker/wordpress/.secrets"
TEMPLATE_FILE="/srv/docker/wordpress/docker-compose.template.yml"
OUTPUT_FILE="/srv/docker/wordpress/docker-compose.yml"
KEYFILE="/srv/docker/wordpress/.key"
# 비밀번호 복호화 함수
decrypt() {
echo "$1" | openssl enc -d -aes-256-cbc -a -pbkdf2 -pass file:$KEYFILE
}
# 설정 파일 불러오기
source $SECRETS_FILE
# 비밀번호 복호화
ROOT_PASSWORD=$(decrypt "$ROOT_PASSWORD_ENC")
USER_PASSWORD=$(decrypt "$USER_PASSWORD_ENC")
# 템플릿에 비밀번호 및 DB 설정 적용
cat $TEMPLATE_FILE | \
sed "s|{{ROOT_PASSWORD}}|$ROOT_PASSWORD|g" | \
sed "s|{{USER_PASSWORD}}|$USER_PASSWORD|g" | \
sed "s|{{DB_NAME}}|$DB_NAME|g" | \
sed "s|{{DB_USER}}|$DB_USER|g" > $OUTPUT_FILE
# Docker Compose 실행
docker compose -f $OUTPUT_FILE up -d
# 보안을 위해 비밀번호가 포함된 docker-compose.yml 파일 삭제
sleep 10
rm $OUTPUT_FILE
echo "워드프레스가 성공적으로 시작되었습니다. 보안을 위해 민감한 정보가 포함된 파일을 삭제했습니다."
EOF
chmod +x start-secure.sh
(8) 컨테이너 실행
./start-secure.sh
(9) 워드프레스 접속
브라우저에서 http://서버IP:8080 또는 http://localhost:8080으로 접속하면 워드프레스 설치 화면이 나옵니다. 언어 선택하고 계정 정보 입력하면 완료됩니다.
(10) 포트 충돌 문제 해결
만약 이런 오류가 발생한다면:
Error response from daemon: driver failed programming external connectivity on endpoint wp_site: Error starting userland proxy: listen tcp4 0.0.0.0:8080: bind: address already in use
이미 8080번 포트를 사용 중인 서비스가 있다는 뜻입니다. docker-compose.template.yml 파일의 포트 설정을 다른 번호로 바꿔주면 됩니다:
ports:
- "8081:80" # 8081 포트로 변경
그리고 start-secure.sh를 다시 실행하세요.
(11) 로그 관리 및 정리 설정
Named Volume에 저장된 로그 파일을 효과적으로 관리하기 위한 스크립트를 생성합니다:
cat > cleanup-logs.sh << 'EOF'
#!/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
EOF
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"
(12) 보안 취약점 자동 업데이트 설정
보안 취약점이 있을 때만 도커 이미지를 자동으로 업데이트하는 스크립트를 만듭니다:
cat > update-security.sh << 'EOF'
#!/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.yml 백업
if [ -f "/srv/docker/wordpress/docker-compose.yml" ]; then
cp /srv/docker/wordpress/docker-compose.yml /srv/docker/wordpress/docker-compose.yml.bak
fi
# 컨테이너 재시작 (start-secure.sh 사용)
/srv/docker/wordpress/start-secure.sh
echo "업데이트 완료: $(date)" >> $LOG_FILE
else
echo "보안 취약점이 없습니다. 업데이트가 필요하지 않습니다."
echo "검사 완료 (취약점 없음): $(date)" >> $LOG_FILE
fi
EOF
chmod +x update-security.sh
(13) 자동화 스크립트 실행 설정
로그 정리와 보안 업데이트를 자동으로 실행하도록 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
(14) 유용한 명령어
# 컨테이너 상태 확인
docker ps
# 컨테이너 중지/시작
docker compose stop
docker compose start
# 컨테이너와 네트워크 제거 (볼륨 데이터는 유지)
docker compose down
# 볼륨 정보 확인
docker volume ls
(15) 도커 컨테이너 재시작 방법
서버 재부팅이나 설정 변경 후 컨테이너를 재시작하는 방법:
# 안전한 방법으로 재시작 (비밀번호 복호화하여 적용)
./start-secure.sh
# 개별 컨테이너 재시작 (이미 실행 중일 때)
docker compose restart wordpress # 워드프레스만 재시작
docker compose restart db # MariaDB만 재시작
(16) 볼륨 백업 및 복원
데이터를 안전하게 백업하려면:
# 모든 볼륨 백업
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"
(17) 암호화 키 및 비밀번호 백업
보안 키와 암호화된 비밀번호도 안전하게 백업하세요(시스템 복구 시 필요):
# 보안 백업 디렉토리 생성
mkdir -p ~/.wordpress_secure_backup
chmod 700 ~/.wordpress_secure_backup
# 키와 비밀번호 파일 백업
cp /srv/docker/wordpress/.key ~/.wordpress_secure_backup/
cp /srv/docker/wordpress/.secrets ~/.wordpress_secure_backup/
(18) 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. 컨테이너 다시 시작 (볼륨은 자동으로 새로 생성됨)
./start-secure.sh
주의: 볼륨을 삭제하면 해당 볼륨에 저장된 모든 데이터(데이터베이스, 워드프레스 파일 등)가 영구적으로 삭제됩니다. 중요한 데이터가 있다면 먼저 백업하세요.
이렇게 설치한 워드프레스는 데이터와 로그가 도커 볼륨에 저장되어 컨테이너가 삭제되어도 데이터가 안전하게 보존됩니다. 비밀번호는 AES-256-CBC 알고리즘으로 암호화되어 저장되며, 도커 컨테이너는 root 권한 없이 전용 사용자로 실행되어 보안이 강화되었습니다. 또한 보안 취약점이 있을 때만 자동으로 이미지가 업데이트되므로 안정성과 보안을 모두 확보할 수 있습니다.
ps) 1부 - 기본 설치 및 보안, 2부 - HTTPS 설정
https://saju.choeum.com/pos/front/sjuF0101.do?ref=s_BwgZAV1CS2tVJUAFBwEHCjMAAAAAbUJXUg
처음 사주 - 인생 7포인트
2026년 성공하는 시기·성향·연애운·금전운·10년 운까지 한눈에
saju.choeum.com
'Linux > Ubuntu 24' 카테고리의 다른 글
| 우분투 24에 Docker로 워드프레스 설치하기 (운영 서버 보안 설정 적용) (0) | 2025.05.11 |
|---|