Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

ssuperjun 님의 블로그

[과제 4-2] MySQL 자동 설치 스크립트 생성 - 압축파일 이용 본문

인턴

[과제 4-2] MySQL 자동 설치 스크립트 생성 - 압축파일 이용

ssuperjun 2026. 1. 8. 16:46

요구사항

  • 앞선 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