Skip to content

Instantly share code, notes, and snippets.

@fuyuanli
Last active August 13, 2024 19:03
Show Gist options
  • Save fuyuanli/24e9726b2130e279a85a70d8c526edd5 to your computer and use it in GitHub Desktop.
Save fuyuanli/24e9726b2130e279a85a70d8c526edd5 to your computer and use it in GitHub Desktop.

Install LAMP environment on Amazon Linux 2023 with latest NextCloud.

This userdata is only for Amazon Linux 2023 on EC2

With this script, you can install a full LAMP environment with auto Let's Encrypt credential issuing on Amazon Linux 2023 without any 3rd party repository.

Requirements

  • Operation System: Amazon Linux 2023
  • Domain Name: Hosted your domain name on Route 53. How to use Amazon Route53 API
  • Instance Type: t3.small or above.
  • fill thes arguments:
    • DOMAIN: your domain name on route 53.
    • MAIL: your email for Let's encrypts issue progress.
    • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: the IAM user's AKSK which has the permission to update your domain for the domain owner confirmation.
    • ROOT_DB_PASSWORD: the root password of MariaDB.
    • NC_DB_NAME: the database name for nextcloud.
    • NC_DB_USER: the user who has the full permssion of the database above.
    • NC_DB_PASSWORD: the password of the user above.
    • NC_MAINTENANCE_WINDOW: the maintenance window for nextcloud (UTC+0).

How to use

  1. Click the Advanced details tab in the button of the Launch an instance page.
  2. Scrolling down to the button, copy & paste the user data contents. PLEASE REMEMBER TO UPDATE THE ARGUMENTS.
  3. Click Launch instance.
  4. Attache an Elastic IP to your instance to prevent which released after stop/start.
  5. Add an A record to your domain of the Elastic IP in Route53.
  6. SSH into your instance, run the commands below to check the status. If you see string like Cloud-init v. 22.2.2 finished at xxxx. Datasource DataSourceEc2. Up xxx seconds means the environment build successful.
$ tail -f /var/log/cloud-init-output.log
# OR
$ cat /var/log/cloud-init-output.log
  1. when done the script done, open your domain in browser to install nextcloud.
  2. click Storage & database and select MySQL&MariaDB. (You can change the data path to other destination.)
  3. Paste the DB info and click install.

Note

  • Amazon Linux 2023 is no providing php8.3-imagick package.
  • You can consider to connect with ElastiCache for the Redis/Memcached cache (More cost!!)
  • I will recommend you to enable External Storages in Nextcloud and mount S3 as storage to save cost (If you allocated a large EBS volume, no mater how many data you store in EBS it will charge for the full EBS volume size, but S3 only charge the object size you used, and you can access your file form the AWS S3 console even your nextcloud instance is terminated.)
#!/bin/sh
set -x
export DOMAIN=""
export MAIL=""
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
export ROOT_DB_PASSWORD=""
export NC_DB_NAME="nextcloud"
export NC_DB_USER="nc_user"
export NC_DB_PASSWORD=""
export NC_MAINTENANCE_WINDOW=16
########
export HOME=/root
max_attempts=5
attempt_num=1
success=false
while [ $success = false ] && [ $attempt_num -le $max_attempts ]; do
echo "Trying dnf install"
dnf install cronie httpd mod_ssl socat mariadb105-server unzip php8.3-fpm php8.3-pdo php8.3-mysqlnd php8.3-xml php8.3-mbstring php8.3-gd php8.3-zip php8.3-opcache php8.3-modphp php8.3-process php8.3-bcmath php8.3-gmp php8.3-intl php8.3-sodium -y
if [ $? -eq 0 ]; then
echo "dnf install succeeded"
success=true
else
echo "Attempt $attempt_num failed. Sleeping for 3 seconds and trying again..."
sleep 3
((attempt_num++))
fi
done
systemctl start httpd
systemctl enable httpd
systemctl start mariadb
systemctl enable mariadb
curl https://get.acme.sh | sh -s email=$MAIL
/root/.acme.sh/acme.sh --issue --force\
--dns dns_aws \
-d $DOMAIN \
--cert-file /etc/pki/tls/certs/$DOMAIN.cert.pem \
--key-file /etc/pki/tls/private/$DOMAIN.key.pem \
--fullchain-file /etc/pki/tls/certs/$DOMAIN.fullchain.pem \
--reloadcmd "systemctl reload httpd" --apache
# Replace the default SSL credential files.
sed -i 's/SSLCertificateFile\ \/etc\/pki\/tls\/certs\/localhost.crt/SSLCertificateFile\ \/etc\/pki\/tls\/certs\/'$DOMAIN'.cert.pem/g' /etc/httpd/conf.d/ssl.conf
sed -i 's/SSLCertificateKeyFile\ \/etc\/pki\/tls\/private\/localhost.key/SSLCertificateKeyFile\ \/etc\/pki\/tls\/private\/'$DOMAIN'.key.pem/g' /etc/httpd/conf.d/ssl.conf
sed -i 's/#SSLCertificateChainFile\ \/etc\/pki\/tls\/certs\/server-chain.crt/SSLCertificateChainFile\ \/etc\/pki\/tls\/certs\/'$DOMAIN'.fullchain.pem/g' /etc/httpd/conf.d/ssl.conf
sed -i 's/Options\ Indexes\ FollowSymLinks/Options\ -Indexes\ +FollowSymLinks/g' /etc/httpd/conf/httpd.conf
sed -i 's/AllowOverride\ None/AllowOverride\ All/g' /etc/httpd/conf/httpd.conf
# Update the php limits.
echo "php_value[memory_limit] = 1G" >> /etc/php-fpm.d/www.conf
echo "php_value[post_max_size] = 10G" >> /etc/php-fpm.d/www.conf
echo "php_value[upload_max_filesize] = 10G" >> /etc/php-fpm.d/www.conf
# Set Strict-Transport-Security header
sed -i 's/<\/VirtualHost>/\ \ \ \ \<IfModule\ mod_headers.c\>\n\ \ \ \ \ \ \ \ Header\ always\ set\ Strict-Transport-Security\ \"max-age\=15552000\;\ includeSubDomains\"\n\ \ \ \ \<\/IfModule\>\n<\/VirtualHost>/g' /etc/httpd/conf.d/ssl.conf
# Update the opcache configuation.
sed -i "s/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=64/g" /etc/php.d/10-opcache.ini
systemctl reload httpd
systemctl restart php-fpm
curl -O --output-dir /var/www/ https://download.nextcloud.com/server/releases/latest.zip
unzip /var/www/latest.zip -d /var/www/
rm -rf /var/www/html/
mv /var/www/nextcloud /var/www/html
chown -R apache:apache /var/www/html
### mysql_secure_installation
mysql -e "UPDATE mysql.user SET Password=PASSWORD('$ROOT_DB_PASSWORD') WHERE User='root';"
mysql -e "DELETE FROM mysql.user WHERE User='';"
mysql -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
mysql -e "DROP DATABASE IF EXISTS test;"
mysql -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';"
mysql -e "FLUSH PRIVILEGES;"
### Create a database for NextCloud
mysql -e "CREATE USER '$NC_DB_USER'@'localhost' IDENTIFIED BY '$NC_DB_PASSWORD';"
mysql -e "CREATE DATABASE IF NOT EXISTS $NC_DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
mysql -e "GRANT ALL PRIVILEGES on $NC_DB_NAME.* to '$NC_DB_USER'@'localhost';"
### Set root password form empty.
mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$ROOT_DB_PASSWORD';"
### First access to generate config.php from config.sample.php
curl localhost >> /dev/null
sed -i "s/);/ 'maintenance_window_start' => $NC_MAINTENANCE_WINDOW,\n);/g" /var/www/html/config/config.php
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment