Skip to content

Instantly share code, notes, and snippets.

@Potherca
Last active April 27, 2023 21:31
Show Gist options
  • Save Potherca/556b7a2bdff6318bb5932bcf7ef60379 to your computer and use it in GitHub Desktop.
Save Potherca/556b7a2bdff6318bb5932bcf7ef60379 to your computer and use it in GitHub Desktop.
Scripts to setup/install Potherca projects on OVH VPS.
📝️ This document is part of several gists related to installing things on OVH VPS:
All steps to a clean OVH VPS install
Script to make a VPS more secure
Scripts to install Potherca projects on OVH VPS(This Gist)

Scripts to setup/install Potherca projects on OVH VPS

Recently I moved various web-apps I have created to an OVH VPS.

I strongly believe in automating things and making virtual setups easy to throw away/start again.

This project contains various scripts that, when used together, completely populate an empty OVH VPS to a working apps.peachey-schoorl.com instance.

This includes a cloud9.peachey-schoorl.com Cloud IDE.

Contents of the VPS

Besides installing Apache and PHP, the following is also part of the stack:

Installation

  1. Setup an SSH key
  2. Log in to the VPS
  3. Clone this repository
  4. Run the installer script

1. Setup an SSH key

The SSH private key (that is used to unlock any secrets committed to this repo) needs to be manually uploaded to the VPS first.

2. Log in to the VPS

Use your favorite SSH client to log in to the VPS.

3. Clone this repository

git clone https://gist.github.com/556b7a2bdff6318bb5932bcf7ef60379.git ovh-install-scripts

4. Run the installer script

bash./ovh-install-scripts/install-vps.sh

Usage

@TODO

@TODO and @FIXME

There are still some shortcuts in the code that need to be addressed before I can consider this effort successful.

Most notably, the PHP Modules (and other steps) should not be installed the way they currently are.

There should be a script that installs whatever is needed based on information from the project it is installing.

Also, instead of certain actions being run in the VPS, they should be run by a separate (external) build process. The created assets should then be pushed to the VPS.

Finally, the file-system for Cloud9 (in /home/potherca/workspace) should not be local but loaded from a cloud service (through rclone).

Only then will the VPS truely be throw-away.

#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
install-graphviz() {
local -r sPath="${HOME}/repos"
sudo apt update
sudo apt install -y \
autoconf \
automake \
bison \
expat \
flex \
fontconfig \
gcc \
ghostscript \
libfreetype6-dev \
libgd-dev \
libglib2.0-0 \
libpng-dev \
librsvg2-dev \
libtool-bin \
libwebp6 \
libxrender-dev \
pkg-config \
swig \
zlib1g-dev
if [[ ! -d "${sPath}" ]];then
mkdir "${sPath}"
fi
git clone https://gitlab.com/graphviz/graphviz.git "${sPath}/graphviz"
cd "$_"
./autogen.sh
./configure
make
make install
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-graphviz
else
install-graphviz # "${@}"
exit $?
fi
#EOF
<VirtualHost *:443>
ServerName cloud9.peachey-schoorl.com
SSLProxyEngine on
SSLProxyCheckPeerCN off
# Avoid "Invalid SSL" handshake when LetsEncrypt expires
SSLProxyCheckPeerExpire off
ProxyPass / https://0.0.0.0:8181/
ProxyPassReverse / https://0.0.0.0:8181/
# ProxyPassReverseCookieDomain 0.0.0.0 cloud9.peachey-schoorl.com
# ProxyPreserveHost On
# SSLProxyCheckPeerName off
# SSLProxyVerify none
</VirtualHost>
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
create-encrypted-password-file(){
openssl rsautl \
-encrypt
-oaep
-pubin
-inkey <(ssh-keygen -e -f "${HOME}/.ssh/id_rsa.pub" -m PKCS8)
-in <(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)
-out ~/.password
# To use, decrypt the password file. We do that once so the user has a chance to see the generated password.
openssl rsautl -decrypt -oaep -inkey ~/.ssh/id_rsa -in ~/.password
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f create-encrypted-password-file
else
create-encrypted-password-file # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
install-apache-php() {
local -r sWebRoot='/var/www/html/'
sudo apt-get update
# Install packages
sudo apt-get install -y \
apache2 \
graphviz \
libapache2-mod-php \
unzip \
php \
php-curl \
php-gd \
php-dom \
php-mbstring \
php-zip
# Enable Modules
sudo phpenmod \
dom \
mbstring
sudo a2enmod proxy
# Restart web server
sudo systemctl restart apache2
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-apache-php
else
install-apache-php # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
# @TODO: This script should be split up into separate responsibilities.
install-cloud9(){
local -r sPath="${HOME}/repos"
local -r iNodeVersion=10
# Install NodeJS
curl -sL "https://deb.nodesource.com/setup_${iNodeVersion}.x" -o nodejs-setup.sh
sudo bash nodejs-setup.sh
rm nodejs-setup.sh
sudo apt update
sudo apt install -y \
build-essential \
gcc \
g++ \
make \
nodejs
# Install Cloud9
git clone https://github.com/c9/core.git "${sPath}/cloud9-sdk"
cd "$_"
scripts/install-sdk.sh
mkdir "${HOME}/workspace"
# @TODO: Install codeintel, see https://github.com/c9/c9.ide.language.codeintel/blob/master/README.md
# Setup Production Process Manager for Node.js
sudo npm install --global pm2@latest
sudo pm2 startup systemd
# Setup Production Process Manager
local -r sPassword="$(openssl rsautl -decrypt -oaep -inkey "${HOME}/.ssh/id_rsa" -in ~/.password)"
local -r sName='cloud9'
local -r -i iPort=8181
pm2 start server.js \
--name "${sName}" \
-- \
-a "${USER}:${sPassword}" \
--listen 0.0.0.0 \
--port "${iPort}" \
--secure "${HOME}/combined_key.pem" \
-w "${HOME}/workspace"
pm2 save
# Create reverse proxy with Apache
cat << EOF | sudo tee "/etc/apache2/sites-available/${sName}.conf"
<VirtualHost *:443>
ServerName ${sName}.peachey-schoorl.com
SSLProxyEngine on
SSLProxyCheckPeerCN off
ProxyPass / https://0.0.0.0:${iPort}/
ProxyPassReverse / https://0.0.0.0:${iPort}/
</VirtualHost>
EOF
sudo a2ensite "${sName}"
sudo systemctl restart apache2
sudo certbot --apache -m "[email protected]" --agree-tos --webroot-path /var/www/html -d "${sName}.peachey-schoorl.com" -n
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-cloud9
else
install-cloud9 # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
declare -r sPath="$HOME/repos"
declare -r sWebRoot='/var/www/html/'
install-projects(){
if [[ ! -d "${sPath}" ]];then
mkdir "${sPath}"
fi
git clone https://gist.github.com/Potherca/100-Best-Novels-of-the-20th-Century.git "${sPath}/100-Best-Novels-of-the-20th-Century"
git clone https://gist.github.com/Potherca/GraphvizWebEditor.git "${sPath}/GraphvizWebEditor"
sudo chown www-data "${sPath}/GraphvizWebEditor/local_file_storage/"
git clone https://gist.github.com/Potherca/Parrots.git "${sPath}/Parrots"
git clone https://gist.github.com/potherca-blog/count-article-words-per-language-on-wikipedia.git "${sPath}/count-article-words-per-language-on-wikipedia"
git clone https://gist.github.com/potherca-blog/github-find-typos.git "${sPath}/github-find-typos"
git clone https://gist.github.com/potherca-blog/hello-world-cross-reference.git "${sPath}/hello-world-cross-reference"
mkdir "${sPath}/hello-world-cross-reference/.cache"
sudo chown www-data "${sPath}/hello-world-cross-reference/.cache/"
echo 'GITHUB_TOKEN=1234567890123456789012345678901234567890' > hello-world-cross-reference/.env
git clone https://gist.github.com/potherca-blog/package-dependency-popularity-per-searchterm.git "${sPath}/package-dependency-popularity-per-searchterm"
git clone https://gist.github.com/potherca-blog/XmlDiff.git "${sPath}/XmlDiff"
}
run-composer(){
# Download composer
if [[ ! -f "${sPath}/composer.phar" ]];then
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar "${sPath}/composer.phar"
fi
# Run composer for all projects
for sDir in "${sPath}/"*;do
"${sPath}/composer.phar" install --no-dev --optimize-autoloader --working-dir="${sDir}"
cd -
done
}
link-projects(){
# Symlink projects to web root
for sDir in "${sPath}/"*;do
sudo ln -s "${sPath}/web" "${sWebRoot}/$(basename "${sPath}")"
done
}
install-potherca-projects(){
# @TODO: These two steps should be replaced by an external build step
install-projects
run-composer
link-projects
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-potherca-projects
else
install-potherca-projects # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
install-rclone() {
sudo apt update
sudo apt install -y rclone
rclone config
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f rclone
else
rclone # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
install-ssl-certificate() {
local -r sDomain='apps.peachey-schoorl.com'
local -r sEmail='[email protected]'
local -r sLetsencryptPath='/etc/letsencrypt/live'
local -r sWebRoot='/var/www/html/'
# Add certbot PPA
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:certbot/certbot/
sudo apt-get update
# Install packages
sudo apt-get install -y \
certbot \
python-certbot-apache
# Setup SSL
sudo certbot --apache -m "${sEmail}" --agree-tos --webroot-path "${sWebRoot}" -d "${sDomain}" -n
# Create PEM for Node.js apps
sudo openssl rsa \
-in "${sLetsencryptPath}/${sDomain}/privkey.pem" \
-out "${sLetsencryptPath}/${sDomain}/privkey_rsa.pem"
sudo cat \
"${sLetsencryptPath}/${sDomain}/privkey_rsa.pem" \
"${sLetsencryptPath}/${sDomain}/fullchain.pem" \
>> "${HOME}/combined_key.pem"
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-ssl-certificate
else
install-ssl-certificate # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
# source install-rclone.sh
source install-apache-php.sh
source install-ssl-certificate.sh
# source install-potherca-projects.sh
source install-cloud9.sh
install-vps() {
# install-rclone
install-apache-php
install-ssl-certificate
# install-potherca-projects
install-cloud9
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-vps
else
install-vps # "${@}"
exit $?
fi
#EOF
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
install-yarn() {
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn
yarn --version
}
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
export -f install-yarn
else
install-yarn # "${@}"
exit $?
fi
#EOF
@Potherca
Copy link
Author

@TODO: Install PlantUML?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment