Creating a Server Image
Provision the Server
Here's the script we used to provision the server:
1#!/usr/bin/env bash 2 3set -e 4 5### 6# Note: This script is assumed to be run as user root 7## 8 9 10 11## Add PHP repository 12add-apt-repository -y ppa:ondrej/php 13apt-get update 14 15 16 17## Install utilities and PHP 18## Configure PHP-FPM to run as user "ubuntu" 19apt-get install -y ca-certificates curl wget jq zip unzip ripgrep pv \ 20 nginx supervisor \ 21 php8.1-fpm php8.1-cli \ 22 php8.1-pgsql php8.1-sqlite3 php8.1-gd \ 23 php8.1-curl php8.1-memcached \ 24 php8.1-imap php8.1-mysql php8.1-mbstring \ 25 php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \ 26 php8.1-intl php8.1-readline \ 27 php8.1-msgpack php8.1-igbinary php8.1-ldap \ 28 php8.1-redis \ 29 && php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \ 30 && sed -i "s/user = .*/user = ubuntu/" /etc/php/8.1/fpm/pool.d/www.conf \ 31 && service php8.1-fpm restart \ 32 && curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh \ 33 && bash nodesource_setup.sh \ 34 && apt-get install -y nodejs \ 35 && rm nodesource_setup.sh 36 37 38 39## Configure Nginx to host site at location /home/ubuntu/onboarding-aws 40tee /etc/nginx/sites-available/default > /dev/null <<EOT 41server { 42 listen 80 default_server; 43 44 root /home/ubuntu/onboarding-aws/public; 45 46 index index.html index.htm index.php; 47 48 server_name _; 49 50 charset utf-8; 51 52 location = /favicon.ico { log_not_found off; access_log off; } 53 location = /robots.txt { log_not_found off; access_log off; } 54 55 client_max_body_size 100M; 56 57 location / { 58 try_files $uri $uri/ /index.php$is_args$args; 59 } 60 61 location ~ \.php$ { 62 include snippets/fastcgi-php.conf; 63 fastcgi_pass unix:/run/php/php8.1-fpm.sock; 64 } 65 66 error_page 404 =200 /index.php; 67 68 location ~ /\.ht { 69 deny all; 70 } 71} 72EOT 73 74service nginx reload 75 76 77 78## CloudWatch Agent 79cd /tmp 80wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb 81dpkg -i -E ./amazon-cloudwatch-agent.deb 82rm amazon-cloudwatch-agent.deb 83 84# To check if it's running: 85# service amazon-cloudwatch-agent status 86 87# Configure CloudWatch Agent for our application + Nginx logs 88tee /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/config.json > /dev/null <<EOT 89{ 90 "agent": { 91 "metrics_collection_interval": 60, 92 "region": "us-east-2", 93 "logfile": "/var/log/amazon-cloudwatch-agent.log", 94 "debug": false 95 }, 96 "logs": { 97 "logs_collected": { 98 "files": { 99 "collect_list": [100 {101 "file_path": "/home/ubuntu/onboarding-aws/storage/logs/laravel.log",102 "log_group_name": "onboarding-aws-production-app",103 "log_stream_name": "app-log-{hostname}",104 "timestamp_format": "[%Y-%m-%d %H:%M:%S]",105 "multi_line_start_pattern": "{timestamp_format}"106 },107 {108 "file_path": "/var/log/nginx/access.log",109 "log_group_name": "onboarding-aws-production-access",110 "log_stream_name": "web-access-{hostname}",111 "timestamp_format" :"[%d/%b/%Y:%H:%M:%S %z]"112 },113 {114 "file_path": "/var/log/nginx/error.log",115 "log_group_name": "onboarding-aws-production-error",116 "log_stream_name": "web-error-{hostname}",117 "timestamp_format" :"[%d/%b/%Y:%H:%M:%S %z]"118 }119 ]120 }121 }122 }123}124EOT
Create an AMI
We create an image from a snapshot of the EBS disk, but you can also create an image directly from the server. However it's recommended the server is off when doing so (so data isn't actively being written to the disk drive).