ssuperjun 님의 블로그
[과제 4-2] MySQL 자동 설치 스크립트 생성 - 압축파일 이용 본문
요구사항
- 앞선 mysql 설치 과제의 절차대로 자동으로 MySQL을 설치할 수 있는 쉘 스크립트 작성
- 스크립트를 실행하면 mysql -u root 를 입력하여 비밀번호 없이 접속할 수 있도록 작성
sh install_mysql 8.0.44
1. MySQL 설치 버전: 8.0.44
2. 설치 버전을 변수로 받기
- NHN Cloud에서 인스턴스 생성 시 사용자 스크립트 기능을 사용하여 작성한 스크립트 테스트
과제 1-3 이후 추가로 고려한 부분
은빈님 블로그를 보고 아이디어를 반영해, 기존에 mysql이 이미 설치돼 있다면 제거하는 코드를 추가
data 디렉토리 경로와 mysql 디렉토리 경로는 /home/ubuntu 대신, /usr/local을 사용하는 경우가 일반적이라고 하여, 디렉토리 경로 수정
*참고
MYSQL_VERSION을 사용자로부터 입력받아야 하므로, MYSQL_VERSION이 미리 정의되어 있지 않으면 스크립트를 종료하도록 설정함
MYSQL_VERSION="8.0.44" 처럼 고정 값을 넣어둬야, 스크립트 전체가 인스턴스 생성 시 자동 실행됨
사용자 스크립트
#!/bin/bash
set -e
# ======================================================
# MySQL 설치 스크립트 생성 (실행은 나중에 수동으로)
# ======================================================
cat <<'EOF' >/usr/local/bin/install_mysql.sh
#!/bin/bash
set -e
### =========================
### 0. 인자 체크
### =========================
MYSQL_VERSION="$1"
if [ -z "$MYSQL_VERSION" ]; then
echo "Usage: $0 <mysql_version>"
echo "Example: $0 8.0.44"
exit 1
fi
MYSQL_BASE="/usr/local/mysql"
MYSQL_DATA="/usr/local/data"
MYSQL_TARBALL="mysql-${MYSQL_VERSION}-linux-glibc2.17-x86_64-minimal.tar.xz"
MYSQL_URL="https://dev.mysql.com/get/Downloads/MySQL-8.0/${MYSQL_TARBALL}"
echo "[INFO] Installing MySQL version: ${MYSQL_VERSION}"
### =========================
### 1. 기존 MySQL 제거
### =========================
echo "[INFO] Removing existing MySQL (if any)..."
systemctl stop mysql 2>/dev/null || true
systemctl disable mysql 2>/dev/null || true
apt remove --purge -y mysql-server mysql-client mysql-common mariadb-server mariadb-client 2>/dev/null || true
apt autoremove -y || true
rm -rf /etc/mysql
rm -rf /var/lib/mysql
rm -rf /var/log/mysql
rm -rf /etc/systemd/system/mysql.service
rm -rf ${MYSQL_BASE}
rm -rf ${MYSQL_DATA}
### =========================
### 2. 필수 라이브러리 설치
### =========================
echo "[INFO] Installing dependencies..."
apt update -y
apt install -y wget libncurses5
### =========================
### 3. MySQL 바이너리 설치
### =========================
cd /usr/local
echo "[INFO] Downloading MySQL..."
wget -q ${MYSQL_URL}
echo "[INFO] Extracting MySQL..."
tar -xvf ${MYSQL_TARBALL}
mv mysql-${MYSQL_VERSION}-linux-glibc2.17-x86_64-minimal mysql
rm -f ${MYSQL_TARBALL}
### =========================
### 4. mysql 전용 사용자 생성
### =========================
echo "[INFO] Creating mysql system user..."
if ! id mysql >/dev/null 2>&1; then
useradd -r -s /bin/false mysql
fi
chown -R mysql:mysql ${MYSQL_BASE}
### =========================
### 5. MySQL 설정 파일 작성
### =========================
echo "[INFO] Writing MySQL config..."
mkdir -p /etc/mysql
cat <<CONF >/etc/mysql/mysqld.cnf
[mysqld]
user=mysql
basedir=${MYSQL_BASE}
datadir=${MYSQL_DATA}
socket=${MYSQL_DATA}/mysql.sock
pid-file=${MYSQL_DATA}/mysqld.pid
log-error=${MYSQL_DATA}/mysql.err
port=3306
bind-address=0.0.0.0
skip-name-resolve
# 초기 접속용 (비밀번호 없이 root 접속)
skip-grant-tables
CONF
### =========================
### 6. 데이터베이스 초기화
### =========================
echo "[INFO] Initializing MySQL data directory..."
${MYSQL_BASE}/bin/mysqld \
--defaults-file=/etc/mysql/mysqld.cnf \
--initialize-insecure \
--user=mysql
chown -R mysql:mysql ${MYSQL_DATA}
### =========================
### 7. systemd 서비스 등록
### =========================
echo "[INFO] Creating systemd service..."
cat <<SERVICE >/etc/systemd/system/mysql.service
[Unit]
Description=MySQL Server
After=network.target
[Service]
Type=simple
User=mysql
Group=mysql
ExecStart=${MYSQL_BASE}/bin/mysqld --defaults-file=/etc/mysql/mysqld.cnf
LimitNOFILE=65535
Restart=on-failure
[Install]
WantedBy=multi-user.target
SERVICE
systemctl daemon-reload
systemctl enable mysql
systemctl start mysql
### =========================
### 8. 클라이언트 소켓 설정
### =========================
echo "[INFO] Configuring client socket..."
cat <<CLIENT >/etc/mysql/my.cnf
[client]
socket=${MYSQL_DATA}/mysql.sock
CLIENT
### =========================
### 9. 일반 사용자 mysql 그룹 추가
### =========================
if [ -n "$SUDO_USER" ]; then
usermod -aG mysql "$SUDO_USER"
fi
### =========================
### 10. PATH 설정
### =========================
echo "[INFO] Setting PATH..."
cat <<PATHCONF >/etc/profile.d/mysql.sh
export PATH=${MYSQL_BASE}/bin:\$PATH
PATHCONF
echo "========================================"
echo "[SUCCESS] MySQL ${MYSQL_VERSION} installed"
echo "Re-login is required for group changes"
echo "After login:"
echo " mysql -u root"
echo "========================================"
EOF
# 실행 권한 부여
chmod +x /usr/local/bin/install_mysql.sh
echo "========================================"
echo "[READY] install_mysql.sh created"
echo "SSH into the instance and run:"
echo " sudo /usr/local/bin/install_mysql.sh <mysql_version>"
echo "Example:"
echo " sudo /usr/local/bin/install_mysql.sh 8.0.44"
echo "========================================"
실행
ssh ubuntu@<instance-ip>
sudo /usr/local/bin/install_mysql.sh 8.0.44
// 재로그인(그룹 반영)
exit
ssh ubuntu@<instance-ip>
// 비밀번호 없이 접속 성공
mysql -u root
실행 화면



프롬프트
지금까지의 명령어들을 정리해봤어. 이 명령어들을 바탕으로 자동화 스크립트를 만들건데, 만들기 전에 불필요한 부분이 있는지, 순서가 올바른지만 알려줘.
이제 클라우드 인스턴스 생성 시 자동으로 실행될 사용자 스크립트를 작성해줘.
기존 조건
1. 기본 datadir 변경
2. mysql -u root 를 입력하여 비밀번호 없이 접속 가능
추가 조건
1. MySQL 설치 버전은 변수로 받아야 하고, sh install_mysql 8.0.44과 비슷한 명령어로 스크립트를 실행하면 mysql -u root 를 입력하여 비밀번호 없이 접속 가능해야 한다.
2. 기존에 mysql이 이미 설치돼 있다면 제거하는 코드도 추가해줘.
추가 요구사항
26.1.13(화) 추가
1. datadir 경로 변경(/home/ubuntu로)
2. skip-grant-tables 없애기
#!/bin/bash
set -e
cd /home/ubuntu
cat <<'EOF' > install_mysql.sh
#!/bin/bash
set -e
############################
# Argument Check
############################
if [ -z "$1" ]; then
echo "Usage: sh install_mysql.sh <MYSQL_VERSION>"
exit 1
fi
MYSQL_VERSION="$1"
MYSQL_BASE="mysql-${MYSQL_VERSION}-linux-glibc2.17-x86_64-minimal"
MYSQL_TAR="${MYSQL_BASE}.tar.xz"
MYSQL_URL="https://dev.mysql.com/get/Downloads/MySQL-8.0/${MYSQL_TAR}"
MYSQL_HOME="/home/ubuntu/mysql"
MYSQL_DATA="/home/ubuntu/data"
############################
# Existing MySQL Remove
############################
echo "[INFO] Removing existing MySQL if exists..."
sudo systemctl stop mysql 2>/dev/null || true
sudo systemctl disable mysql 2>/dev/null || true
sudo rm -f /etc/systemd/system/mysql.service
sudo rm -rf /etc/mysql
sudo rm -rf ${MYSQL_HOME}
sudo rm -rf ${MYSQL_DATA}
sudo userdel mysql 2>/dev/null || true
############################
# Required Packages
############################
echo "[INFO] Installing required libraries..."
sudo apt update -y
sudo apt install -y libncurses5 wget xz-utils
############################
# Download & Extract MySQL
############################
cd /home/ubuntu
wget -q ${MYSQL_URL}
tar -xvf ${MYSQL_TAR}
sudo mv ${MYSQL_BASE} ${MYSQL_HOME}
############################
# MySQL User & Permission
############################
sudo useradd -r -s /bin/false mysql
sudo chown -R mysql:mysql ${MYSQL_HOME}
sudo mkdir -p ${MYSQL_DATA}
sudo chown mysql:mysql ${MYSQL_DATA}
sudo chmod 750 ${MYSQL_DATA}
sudo chmod o+x /home/ubuntu
############################
# mysqld.cnf
############################
sudo mkdir -p /etc/mysql
sudo tee /etc/mysql/mysqld.cnf > /dev/null <<CONF
[mysqld]
user=mysql
basedir=${MYSQL_HOME}
datadir=${MYSQL_DATA}
socket=${MYSQL_DATA}/mysql.sock
pid-file=${MYSQL_DATA}/mysqld.pid
skip-name-resolve
port=3306
bind-address=0.0.0.0
CONF
############################
# Initialize Database (No Password)
############################
sudo ${MYSQL_HOME}/bin/mysqld \
--defaults-file=/etc/mysql/mysqld.cnf \
--initialize-insecure \
--user=mysql
sudo chown -R mysql:mysql ${MYSQL_DATA}
############################
# systemd Service
############################
sudo tee /etc/systemd/system/mysql.service > /dev/null <<SERVICE
[Unit]
Description=MySQL Server
After=network.target
[Service]
Type=simple
User=mysql
Group=mysql
ExecStart=${MYSQL_HOME}/bin/mysqld --defaults-file=/etc/mysql/mysqld.cnf
LimitNOFILE=65535
Restart=on-failure
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable mysql
sudo systemctl start mysql
############################
# Client Socket Config
############################
sudo tee /etc/mysql/my.cnf > /dev/null <<CLIENT
[client]
socket=${MYSQL_DATA}/mysql.sock
CLIENT
############################
# Ubuntu User Permission
############################
sudo usermod -aG mysql ubuntu
############################
# PATH Setup
############################
echo "export PATH=${MYSQL_HOME}/bin:\$PATH" | sudo tee /etc/profile.d/mysql.sh
echo "[SUCCESS] MySQL ${MYSQL_VERSION} installation completed"
echo "Please reconnect and run: mysql -u root"
EOF
chmod +x install_mysql.sh
# usermod 적용을 위한 재로그인 안내
echo "================================================="
echo "MySQL installation finished."
echo "Please reconnect to the instance, then run:"
echo " mysql -u root"
echo "================================================="
실행
ssh ubuntu@<instance-ip>
sh install_mysql.sh 8.0.44
// 재로그인(그룹 반영)
exit
ssh ubuntu@<instance-ip>
// 비밀번호 없이 접속 성공
mysql -u root
Deprecated
사용자 스크립트
#!/bin/bash
set -e
echo "[USER-DATA] Creating install_mysql.sh script..."
# 설치 스크립트 내용 저장(EOF 블록)
cat <<'EOF' > /usr/local/bin/install_mysql.sh
#!/bin/bash
set -e
export DEBIAN_FRONTEND=noninteractive
echo "===== MySQL Automated Installation Script Start ====="
############################
# 1. 인자 체크
############################
if [ -z "$1" ]; then
echo "[ERROR] MySQL version is required."
echo "Usage: $0 <MYSQL_VERSION>"
exit 1
fi
MYSQL_VERSION="$1"
UBUNTU_VERSION="ubuntu22.04"
MYSQL_WORK_DIR="/usr/local/mysql"
MYSQL_DATA_DIR="/usr/local/data"
CONF_FILE="/etc/mysql/mysql.conf.d/mysqld.cnf"
APPARMOR_FILE="/etc/apparmor.d/usr.sbin.mysqld"
MYSQL_TAR="mysql-server_${MYSQL_VERSION}-1${UBUNTU_VERSION}_amd64.deb-bundle.tar"
MYSQL_URL="https://dev.mysql.com/get/Downloads/MySQL-8.0/${MYSQL_TAR}"
############################
# 2. root 권한 확인
############################
if [ "$(id -u)" -ne 0 ]; then
echo "[ERROR] Run as root."
exit 1
fi
############################
# 3. 기존 MySQL 제거
############################
echo "[STEP 1/10] Removing existing MySQL..."
systemctl stop mysql 2>/dev/null || true
apt-get purge -y \
mysql-server mysql-client mysql-common \
mysql-community-server mysql-community-client || true
apt-get autoremove -y || true
apt-get autoclean || true
rm -rf /var/lib/mysql /var/log/mysql
############################
# 4. 작업 디렉토리
############################
echo "[STEP 2/10] Preparing working directory..."
mkdir -p "${MYSQL_WORK_DIR}"
cd "${MYSQL_WORK_DIR}"
############################
# 5. 다운로드
############################
echo "[STEP 3/10] Downloading MySQL ${MYSQL_VERSION}..."
wget -q "${MYSQL_URL}" || {
echo "[ERROR] Download failed: ${MYSQL_URL}"
exit 1
}
tar -xvf "${MYSQL_TAR}"
############################
# 6. 필수 라이브러리
############################
echo "[STEP 4/10] Installing system libraries..."
apt-get update -y
apt-get install -y libaio1 libnuma1
############################
# 7. MySQL 설치
############################
echo "[STEP 5/10] Installing MySQL packages..."
# 1차: 전부 풀어놓기 (dependency 무시하고 unpack)
dpkg -i *.deb
# 2차: 의존성 구성은 apt에게 맡김
apt-get --fix-broken install -y
############################
# 8. datadir 변경
############################
echo "[STEP 6/10] Updating datadir..."
systemctl stop mysql 2>/dev/null || true
# 기존 datadir에 데이터가 있을 경우만 이전
if [ -d /var/lib/mysql ] && [ "$(ls -A /var/lib/mysql 2>/dev/null)" ]; then
rsync -av /var/lib/mysql/ "${MYSQL_DATA_DIR}/"
chown -R mysql:mysql "${MYSQL_DATA_DIR}"
fi
# 기존 datadir 백업 (되돌릴 수 있게)
if [ -d /var/lib/mysql ]; then
mv /var/lib/mysql /var/lib/mysql.bak
fi
if [ ! -f "${CONF_FILE}" ]; then
echo "[ERROR] MySQL config not found"
exit 1
fi
sed -i \
's|^[[:space:]]*datadir[[:space:]]*=.*|datadir = '"${MYSQL_DATA_DIR}"'|' \
"${CONF_FILE}"
############################
# 9. AppArmor
############################
echo "[STEP 7/10] Updating AppArmor..."
if ! grep -q "${MYSQL_DATA_DIR}" "${APPARMOR_FILE}"; then
sed -i "/# Site-specific additions and overrides/i \
# Allow custom MySQL datadir\n\
/usr/ r,\n\
/usr/local/ r,\n\
${MYSQL_DATA_DIR}/ r,\n\
${MYSQL_DATA_DIR}/** rwk,\n" \
"${APPARMOR_FILE}"
fi
apparmor_parser -r "${APPARMOR_FILE}"
############################
# 10. datadir 권한
############################
echo "[STEP 8/10] Preparing datadir..."
mkdir -p "${MYSQL_DATA_DIR}"
chown mysql:mysql "${MYSQL_DATA_DIR}"
chmod 750 "${MYSQL_DATA_DIR}"
echo "[PATCH] Overriding systemd mysql.service datadir..."
mkdir -p /etc/systemd/system/mysql.service.d
cat <<EOL > /etc/systemd/system/mysql.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld
EOL
systemctl daemon-reload
############################
# 11. MySQL 기동 & root 설정
############################
echo "[STEP 9/10] Starting MySQL..."
systemctl start mysql
mysql --protocol=socket <<EOL
ALTER USER 'root'@'localhost'
IDENTIFIED WITH mysql_native_password BY '';
FLUSH PRIVILEGES;
EOL
############################
# 12. 상태 확인
############################
echo "[STEP 10/10] Status check..."
systemctl status mysql --no-pager | sed -n '1,8p'
mysql -u root -e "SELECT VERSION();"
mysql -u root -e "SHOW VARIABLES LIKE 'datadir';"
echo "===== MySQL installation completed successfully ====="
EOF
# 실행 권한 부여
chmod +x /usr/local/bin/install_mysql.sh
echo "[USER-DATA] install_mysql.sh created at /usr/local/bin/install_mysql.sh"
echo "[USER-DATA] Run it with: sudo /usr/local/bin/install_mysql.sh <version>"
실행
sudo /usr/local/bin/install_mysql.sh 8.0.44
mysql -u root'인턴' 카테고리의 다른 글
| [교육1] NHN Cloud Essentials(CES) 교육 메모 (1) | 2026.01.12 |
|---|---|
| AWS 교육(노션 백업) (0) | 2026.01.11 |
| [과제 3-2] NHN Cloud 인스턴스에서 MySQL 설치 - 압축파일 이용 (0) | 2026.01.08 |
| [과제 4-1] MySQL 자동 설치 스크립트 생성 - apt 레포지터리 이용 (0) | 2026.01.07 |
| [과제 3-1] NHN Cloud 인스턴스에서 MySQL 설치 - apt 레포지터리 이용 (0) | 2026.01.06 |