EC2 인스턴스에 웹 서버 설치 - Amazon Aurora

EC2 인스턴스에 웹 서버 설치

EC2 인스턴스를 시작하여 DB 클러스터에 연결에서 생성한 EC2 인스턴스에 웹 서버를 설치합니다. 웹 서버는 Amazon Aurora DB 클러스터 생성에서 생성한 Amazon Aurora DB 클러스터에 연결됩니다.

PHP 및 MariaDB와 함께 Apache 웹 서버 설치

EC2 인스턴스에 연결하고 서버를 설치합니다.

EC2 인스턴스에 연결하고 PHP가 포함된 Apache 웹 서버를 설치하는 방법
  1. Amazon EC2 사용 설명서에 있는 Linux 인스턴스에 연결의 단계를 따라 앞에서 만든 EC2 인스턴스에 연결합니다.

    SSH를 사용하여 EC2 인스턴스에 연결하는 것이 좋습니다. Windows, Linux 또는 Mac에 SSH 클라이언트 유틸리티가 설치된 경우 다음 명령 형식을 사용하여 인스턴스에 연결할 수 있습니다.

    ssh -i location_of_pem_file ec2-user@ec2-instance-public-dns-name

    예를 들어 ec2-database-connect-key-pair.pem이 Linux의 /dir1에 저장되어 있고, EC2 인스턴스의 퍼블릭 IPv4 DNS가 ec2-12-345-678-90.compute-1.amazonaws.com이라고 가정해 보겠습니다. SSH 명령은 다음과 같이 표시됩니다.

    ssh -i /dir1/ec2-database-connect-key-pair.pem ec2-user@ec2-12-345-678-90.compute-1.amazonaws.com
  2. EC2 인스턴스에서 소프트웨어를 업데이트하여 최신 버그 수정 및 보안 업데이트를 받습니다. 이렇게 하려면 다음 명령을 사용하십시오.

    참고

    -y 옵션을 사용하면 확인 여부를 묻지 않고 업데이트를 설치합니다. 설치 전에 업데이트 정보를 확인하려면 이 옵션을 생략합니다.

    sudo dnf update -y
  3. 업데이트가 완료되면 다음 명령을 사용하여 Apache 웹 서버, PHP, MariaDB 또는 PostgreSQL 소프트웨어를 설치합니다. 이 명령은 여러 소프트웨어 패키지와 관련 종속 프로그램을 동시에 설치합니다.

    MariaDB & MySQL
    sudo dnf install -y httpd php php-mysqli mariadb105
    PostgreSQL
    sudo dnf install -y httpd php php-pgsql postgresql15

    오류가 발생하면 인스턴스가 Amazon Linux 2023 AMI로 실행되지 않은 것입니다. Amazon Linux 2 AMI를 사용하고 있는 것일 수 있습니다. 다음 명령을 사용하여 Amazon Linux 버전을 볼 수 있습니다.

    cat /etc/system-release

    자세한 내용은 인스턴스 소프트웨어 업데이트 단원을 참조하십시오.

  4. 다음 명령을 사용하여 웹 서버를 시작합니다.

    sudo systemctl start httpd

    웹 서버가 제대로 설치되고 시작되었는지 테스트할 수 있습니다. 이렇게 하려면 웹 브라우저의 주소 표시줄에 EC2 인스턴스의 퍼블릭 Domain Name System(DNS) 이름을 입력합니다(예: http://ec2-42-8-168-21.us-west-1.compute.amazonaws.com). 웹 서버가 실행되고 있으면 Apache 테스트 페이지가 표시됩니다.

    Apache 테스트 페이지가 표시되지 않으면 자습서: DB 클러스터에 사용할 Amazon VPC 생성(IPv4 전용)에서 생성한 VPC 보안 그룹에 대한 인바운드 규칙을 확인합니다. 인바운드 규칙에 웹 서버에 연결할 IP 주소에 대한 HTTP(포트 80) 액세스를 허용하는 규칙이 포함되어 있는지 확인합니다.

    참고

    Apache 테스트 페이지는 문서의 루트 디렉터리 /var/www/html에 콘텐츠가 없는 경우에만 표시됩니다. 문서의 루트 디렉터리에 콘텐츠를 추가한 후에는 콘텐츠가 EC2 인스턴스의 퍼블릭 DNS 주소에 나타납니다. 이 시점 이전에는 Apache 테스트 페이지에 나타납니다.

  5. systemctl 명령을 사용하여 웹 서버가 시스템 부팅 때마다 시작되도록 구성합니다.

    sudo systemctl enable httpd

ec2-user가 Apache 웹 서버의 기본 루트 디렉터리에 있는 파일을 관리할 수 있도록 하려면 /var/www 디렉터리의 소유권 및 권한을 변경합니다. 이 작업을 수행하는 방법에는 여러 가지가 있습니다. 본 자습서에서는 ec2-userapache 그룹에 추가하여 apache 그룹에 /var/www 디렉터리의 소유권을 부여하고 쓰기 권한을 할당합니다.

Apache 웹 서버에 대한 파일 권한 설정 방법
  1. ec2-user 사용자를 apache 그룹에 추가합니다.

    sudo usermod -a -G apache ec2-user
  2. 권한을 새로 고치고 새 apache 그룹을 포함하려면 로그아웃합니다.

    exit
  3. 다시 로그인한 다음, apache 명령을 사용하여 groups 그룹이 있는지 확인합니다.

    groups

    출력 결과는 다음과 비슷합니다.

    ec2-user adm wheel apache systemd-journal
  4. /var/www 디렉터리 및 해당 콘텐츠의 그룹 소유권을 apache 그룹으로 변경합니다.

    sudo chown -R ec2-user:apache /var/www
  5. /var/www 및 그 하위 디렉터리의 디렉터리 권한을 변경해서 그룹 쓰기 권한을 추가하고 나중에 생성될 하위 디렉터리에서 그룹 ID를 설정합니다.

    sudo chmod 2775 /var/www find /var/www -type d -exec sudo chmod 2775 {} \;
  6. /var/www 디렉터리 및 하위 디렉터리의 파일 권한을 계속 변경해서 그룹 쓰기 권한을 추가합니다.

    find /var/www -type f -exec sudo chmod 0664 {} \;

이제 ec2-user(및 apache 그룹의 향후 멤버)는 Apache 문서 루트에서 파일을 추가, 삭제, 편집할 수 있습니다. 따라서 정적 웹 사이트 또는 PHP 애플리케이션과 같은 콘텐츠를 추가할 수 있습니다.

참고

HTTP 프로토콜을 실행하는 웹 서버는 송신하거나 수신하는 데이터에 대해 아무런 전송 보안 기능도 제공하지 않습니다. 웹 브라우저를 사용하여 HTTP 서버에 연결하면 네트워크 경로를 따라 어디서든 엿보려는 사람들이 많은 정보를 볼 수 있습니다. 이 정보에는 방문하는 URL, 수신하는 웹 페이지의 내용, HTML 양식의 내용(암호 포함)이 포함됩니다.

웹 서버를 안전하게 보호하기 위한 최선의 방법은 HTTPS(HTTP Secure) 지원 기능을 설치하는 것입니다. 이 프로토콜은 SSL/TLS 암호화로 데이터를 보호합니다. 자세한 내용은 Amazon EC2 사용 설명서에서 자습서: Amazon Linux AMI를 사용하여 SSL/TLS 구성을 참조하세요.

DB 클러스터에 Apache 웹 서버 연결

이제 Amazon Aurora DB 클러스터에 연결되는 Apache 웹 서버에 콘텐츠를 추가합니다.

DB 클러스터에 연결되는 Apache 웹 서버에 콘텐츠를 추가하는 방법
  1. EC2 인스턴스에 계속 연결되어 있을 때 디렉터리를 /var/www로 변경하고 inc라는 새로운 하위 디렉터리를 생성합니다.

    cd /var/www mkdir inc cd inc
  2. inc라는 dbinfo.inc 디렉터리에서 새 파일을 생성한 다음 nano 또는 선택한 편집기를 호출하여 파일을 편집합니다.

    >dbinfo.inc nano dbinfo.inc
  3. 다음 내용을 dbinfo.inc 파일에 추가합니다. 여기서 db_instance_endpoint는 DB 클러스터에 대해 포트가 없는 DB 클러스터 라이터 엔드포인트입니다.

    참고

    웹 서버의 문서 루트에 속하지 않은 폴더에 사용자 이름과 암호 정보를 두는 것이 좋습니다. 이렇게 하면 보안 정보가 노출될 가능성이 줄어듭니다.

    애플리케이션에서 적절한 암호로 master password를 변경해야 합니다.

    <?php define('DB_SERVER', 'db_cluster_writer_endpoint'); define('DB_USERNAME', 'tutorial_user'); define('DB_PASSWORD', 'master password'); define('DB_DATABASE', 'sample'); ?>
  4. dbinfo.inc 파일을 저장하고 닫습니다. nano를 사용하는 경우 Ctrl+S 및 Ctrl+X를 사용하여 파일을 저장하고 닫습니다.

  5. 디렉터리를 /var/www/html로 변경합니다.

    cd /var/www/html
  6. html라는 SamplePage.php 디렉터리에서 새 파일을 생성한 다음 nano 또는 선택한 편집기를 호출하여 파일을 편집합니다.

    >SamplePage.php nano SamplePage.php
  7. 다음 콘텐츠를 SamplePage.php 파일에 추가합니다.

    MariaDB & MySQL
    <?php include "../inc/dbinfo.inc"; ?> <html> <body> <h1>Sample page</h1> <?php /* Connect to MySQL and select the database. */ $connection = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD); if (mysqli_connect_errno()) echo "Failed to connect to MySQL: " . mysqli_connect_error(); $database = mysqli_select_db($connection, DB_DATABASE); /* Ensure that the EMPLOYEES table exists. */ VerifyEmployeesTable($connection, DB_DATABASE); /* If input fields are populated, add a row to the EMPLOYEES table. */ $employee_name = htmlentities($_POST['NAME']); $employee_address = htmlentities($_POST['ADDRESS']); if (strlen($employee_name) || strlen($employee_address)) { AddEmployee($connection, $employee_name, $employee_address); } ?> <!-- Input form --> <form action="<?PHP echo $_SERVER['SCRIPT_NAME'] ?>" method="POST"> <table border="0"> <tr> <td>NAME</td> <td>ADDRESS</td> </tr> <tr> <td> <input type="text" name="NAME" maxlength="45" size="30" /> </td> <td> <input type="text" name="ADDRESS" maxlength="90" size="60" /> </td> <td> <input type="submit" value="Add Data" /> </td> </tr> </table> </form> <!-- Display table data. --> <table border="1" cellpadding="2" cellspacing="2"> <tr> <td>ID</td> <td>NAME</td> <td>ADDRESS</td> </tr> <?php $result = mysqli_query($connection, "SELECT * FROM EMPLOYEES"); while($query_data = mysqli_fetch_row($result)) { echo "<tr>"; echo "<td>",$query_data[0], "</td>", "<td>",$query_data[1], "</td>", "<td>",$query_data[2], "</td>"; echo "</tr>"; } ?> </table> <!-- Clean up. --> <?php mysqli_free_result($result); mysqli_close($connection); ?> </body> </html> <?php /* Add an employee to the table. */ function AddEmployee($connection, $name, $address) { $n = mysqli_real_escape_string($connection, $name); $a = mysqli_real_escape_string($connection, $address); $query = "INSERT INTO EMPLOYEES (NAME, ADDRESS) VALUES ('$n', '$a');"; if(!mysqli_query($connection, $query)) echo("<p>Error adding employee data.</p>"); } /* Check whether the table exists and, if not, create it. */ function VerifyEmployeesTable($connection, $dbName) { if(!TableExists("EMPLOYEES", $connection, $dbName)) { $query = "CREATE TABLE EMPLOYEES ( ID int(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(45), ADDRESS VARCHAR(90) )"; if(!mysqli_query($connection, $query)) echo("<p>Error creating table.</p>"); } } /* Check for the existence of a table. */ function TableExists($tableName, $connection, $dbName) { $t = mysqli_real_escape_string($connection, $tableName); $d = mysqli_real_escape_string($connection, $dbName); $checktable = mysqli_query($connection, "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = '$t' AND TABLE_SCHEMA = '$d'"); if(mysqli_num_rows($checktable) > 0) return true; return false; } ?>
    PostgreSQL
    <?php include "../inc/dbinfo.inc"; ?> <html> <body> <h1>Sample page</h1> <?php /* Connect to PostgreSQL and select the database. */ $constring = "host=" . DB_SERVER . " dbname=" . DB_DATABASE . " user=" . DB_USERNAME . " password=" . DB_PASSWORD ; $connection = pg_connect($constring); if (!$connection){ echo "Failed to connect to PostgreSQL"; exit; } /* Ensure that the EMPLOYEES table exists. */ VerifyEmployeesTable($connection, DB_DATABASE); /* If input fields are populated, add a row to the EMPLOYEES table. */ $employee_name = htmlentities($_POST['NAME']); $employee_address = htmlentities($_POST['ADDRESS']); if (strlen($employee_name) || strlen($employee_address)) { AddEmployee($connection, $employee_name, $employee_address); } ?> <!-- Input form --> <form action="<?PHP echo $_SERVER['SCRIPT_NAME'] ?>" method="POST"> <table border="0"> <tr> <td>NAME</td> <td>ADDRESS</td> </tr> <tr> <td> <input type="text" name="NAME" maxlength="45" size="30" /> </td> <td> <input type="text" name="ADDRESS" maxlength="90" size="60" /> </td> <td> <input type="submit" value="Add Data" /> </td> </tr> </table> </form> <!-- Display table data. --> <table border="1" cellpadding="2" cellspacing="2"> <tr> <td>ID</td> <td>NAME</td> <td>ADDRESS</td> </tr> <?php $result = pg_query($connection, "SELECT * FROM EMPLOYEES"); while($query_data = pg_fetch_row($result)) { echo "<tr>"; echo "<td>",$query_data[0], "</td>", "<td>",$query_data[1], "</td>", "<td>",$query_data[2], "</td>"; echo "</tr>"; } ?> </table> <!-- Clean up. --> <?php pg_free_result($result); pg_close($connection); ?> </body> </html> <?php /* Add an employee to the table. */ function AddEmployee($connection, $name, $address) { $n = pg_escape_string($name); $a = pg_escape_string($address); echo "Forming Query"; $query = "INSERT INTO EMPLOYEES (NAME, ADDRESS) VALUES ('$n', '$a');"; if(!pg_query($connection, $query)) echo("<p>Error adding employee data.</p>"); } /* Check whether the table exists and, if not, create it. */ function VerifyEmployeesTable($connection, $dbName) { if(!TableExists("EMPLOYEES", $connection, $dbName)) { $query = "CREATE TABLE EMPLOYEES ( ID serial PRIMARY KEY, NAME VARCHAR(45), ADDRESS VARCHAR(90) )"; if(!pg_query($connection, $query)) echo("<p>Error creating table.</p>"); } } /* Check for the existence of a table. */ function TableExists($tableName, $connection, $dbName) { $t = strtolower(pg_escape_string($tableName)); //table name is case sensitive $d = pg_escape_string($dbName); //schema is 'public' instead of 'sample' db name so not using that $query = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = '$t';"; $checktable = pg_query($connection, $query); if (pg_num_rows($checktable) >0) return true; return false; } ?>
  8. SamplePage.php 파일을 저장하고 닫습니다.

  9. 웹 브라우저를 열고 http://EC2 instance endpoint/SamplePage.php(예: http://ec2-12-345-67-890.us-west-2.compute.amazonaws.com/SamplePage.php)를 검색하여 웹 서버에서 DB 클러스터에 제대로 연결되는지 확인합니다.

SamplePage.php를 사용하여 DB 클러스터에 데이터를 추가할 수 있습니다. 그러면 추가한 데이터가 페이지에 표시됩니다. 데이터가 테이블에 삽입되었는지 확인하려면 Amazon EC2 인스턴스에 MySQL을 설치합니다. 그런 다음 DB 클러스터에 연결하여 테이블을 쿼리합니다.

DB 클러스터 연결에 대한 자세한 내용은 Amazon Aurora DB 클러스터에 연결 섹션을 참조하세요.

DB 클러스터를 최대한 보호하려면 VPC 외부의 소스가 DB 클러스터에 연결할 수 없는지 확인합니다.

웹 서버 및 데이터베이스 테스트를 완료한 후에는 DB 클러스터와 Amazon EC2 인스턴스를 삭제해야 합니다.