Compare commits

..

20 Commits

Author SHA1 Message Date
Valentin
9ddc7df6c4 fichiers séparés 2024-05-03 17:19:46 +02:00
Valentin
41378a31c6 start modularisation 2024-05-02 23:54:06 +02:00
Valentin
9607769086 ajout de build-essential pour installer node 2024-04-18 15:13:23 +02:00
Valentin
22d5bbdde2 nuxt generate 4 node limit 2024-04-18 14:49:53 +02:00
Valentin
74ef2ae486 nuxt generate 3 2024-04-18 13:27:53 +02:00
Valentin
78a7b65475 nuxt generate 2 2024-04-18 13:03:20 +02:00
Valentin
c8fb3d5ce9 nuxt generate 1 2024-04-18 12:47:12 +02:00
Valentin
b98459e839 import directus db 13 2024-04-17 18:55:54 +02:00
Valentin
f69856792d import directus db 12 2024-04-17 18:24:40 +02:00
Valentin
5c88a81e5d import directus db 11 2024-04-17 18:18:56 +02:00
Valentin
e4717d6433 import directus db 10 2024-04-17 18:14:28 +02:00
Valentin
535fbd0da9 import directus db 9 2024-04-17 18:02:20 +02:00
Valentin
2828dd5dcb import directus db 8 2024-04-17 17:59:57 +02:00
Valentin
11d78e9bb9 import directus db 7 2024-04-17 17:51:05 +02:00
Valentin
7a4e392f6c import directus db 6 2024-04-17 17:45:40 +02:00
Valentin
89c834703a import directus db 5 2024-04-17 17:44:10 +02:00
Valentin
7b664fe444 import directus db 4 pas possible de supprimer l'user debian sans être kick 2024-04-17 17:35:05 +02:00
Valentin
3d76ae8811 import directus db 3 modif ufw port ssh and ip 2024-04-17 17:16:02 +02:00
Valentin
244742a8a1 import directus db 2 2024-04-17 17:08:53 +02:00
Valentin
0adaa20e8d import directus db 1 2024-04-17 16:48:16 +02:00
21 changed files with 581 additions and 386 deletions

View File

@@ -4,7 +4,11 @@ Deployment [**D**ebian](https://www.debian.org/) (os) + [**C**addy](https://cadd
## Installation
On a fresh install as root user
On a fresh install as root user using
`sudo passwd root`
`su - root`
1. Upgrade
@@ -42,6 +46,10 @@ On a fresh install as root user
## Post-install
0. Delete unix Debian account
`userdel --remove-home debian`
1. Configure DNS Zone
```
Domain : <domain_name> | Type : A | Target : <ip>

View File

@@ -1,5 +1,5 @@
<?php
# https://docs.gitea.com/usage/webhooks
// https://docs.gitea.com/usage/webhooks
// check for POST request
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
@@ -33,7 +33,38 @@ if (json_last_error() !== JSON_ERROR_NONE) {
}
// success, do something
$repo_name = $decoded['repository']['name'];
echo "launching hook script ";
echo shell_exec('bash ../webhook/webhook.sh ' . $repo_name . ' >> ../webhook/webhook.log 2>&1');
?>
$current_date = date('d-m-y_H-i-s', time());
$log_directory = '../webhook/logs';
// create the log folder if needed
if (!file_exists($log_directory)) {
mkdir($log_directory, 0777, true);
}
// clean the log folder if needed
if (count(scandir($log_directory)) > 10) {
$files = scandir($log_directory);
$log_files = array_diff($files, array('.', '..'));
usort($files, function($a, $b) use ($log_directory) {
return filemtime("$log_directory/$a") - filemtime("$log_directory/$b");
});
for ($i = 0; $i < 5; $i++) {
unlink("$log_directory/{$files[$i]}");
}
}
if (isset($decoded['repository'])) {
// git hook
echo shell_exec('bash ../webhook/webhook.sh ' . 'git' . ' >> ' . $log_directory . '/webhook_' . $current_date . '.log 2>&1');
} else {
// directus hook
$debounce_delay = 1 * 60;
file_put_contents("debounce_hook", time());
sleep($debounce_delay);
if (time() >= intval(file_get_contents('debounce_hook')) + $debounce_delay) {
echo shell_exec('bash ../webhook/webhook.sh ' . 'directus' . ' >> ' . $log_directory . '/webhook_' . $current_date . '.log 2>&1');
}
}
?>

View File

@@ -1,17 +1,19 @@
#!/bin/bash
repo_name=$1
cms_dir=$(ls -d /var/www/repositories/cms*/)
tmux send-keys -t directus C-c
tmux send-keys -t front C-c
hook_origin=$1
repo_name=$(ls /var/www/repositories/ | grep -v '^cms')
cd /var/www/repositories/$repo_name
git pull origin prod
echo "Trigger : ${hook_origin}"
if [[ "$hook_origin" == "git" ]]; then
git pull origin prod
fi
jq '.scripts |= with_entries(.value |= gsub("\\bnuxt \\b"; "./node_modules/nuxt/bin/nuxt.mjs "))' package.json > temp.json && mv temp.json package.json
NUXT_TELEMETRY_DISABLED=1 ; npm install -y
npm run build
node --max-old-space-size=250 `which npm` install -y
node --max-old-space-size=250 `which npm` run generate --prerender
tmux send-keys -t front "cd /var/www/repositories/${repo_name} && node .output/server/index.mjs" C-m
tmux send-keys -t directus "cd ${cms_dir} && npx directus start" C-m
rm -r /var/www/html/public
cp -r "/var/www/repositories/${repo_name}/.output/public" /var/www/html

23
bin/create_user.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
. bin/variables.sh
echo -e "${PURPLE}${BOLD}Create user${RESET}"
read -p "Enter username: " username
if id "$username" &>/dev/null; then
echo "User '$username' already exists."
exit 1
fi
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
read -s -p "Enter password: " password
echo
useradd -m "$username"
chsh -s /bin/bash $username
echo "$username:$password" | chpasswd
usermod -aG sudo $username
echo -e "${PURPLE}${BOLD}User '$username' created with password successfully.${RESET}"

27
bin/functions.sh Normal file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
install_pkg() {
pkg="$1"
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
apt update && apt install -y "$pkg"
echo -e "${PURPLE}${BOLD}${pkg} installed${RESET}"
fi
}
get_username() {
if [[ -z "$username" ]]; then
username=$(getent passwd 1001 | cut -d: -f1)
fi
}
get_ip() {
if [[ -z "$ip" ]]; then
ip=$(hostname -I | cut -d' ' -f1)
fi
}
get_ssh_port() {
if [[ -z "$ssh_port" ]]; then
ssh_port=$(cat /etc/ssh/sshd_config.d/custom.conf | grep "Port " | sed 's/^Port //')
fi
}

38
bin/import_directus_db.sh Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
get_ssh_port
get_username
get_ip
echo -e "${PURPLE}${BOLD}Import the .tar.gz archive from your local storage${RESET}"
echo -e "${PURPLE}The archive should contain the sql dump, the upload directory and the .env file${RESET}"
echo -e "${BLUE}scp -P ${ssh_port} /local/path/to/archive.tar.gz ${username}@${ip}:/home/${username}/${RESET}"
echo -e "${PURPLE}${BOLD}Press any key when done${RESET}"
read
directus_archive=$(ls /home/${username}/*.tar.gz);
tar -xzf "${directus_archive}" -C "${CMS_DIRECTORY}" --strip-components=2
rm "${directus_archive}"
sed -i "s/^\(DB_PASSWORD=\)'.*'$/\1'$DB_DIRECTUS_PASSWORD'/" "${CMS_DIRECTORY}/.env"
port=$(cat ${CMS_DIRECTORY}/.env | grep "^PORT=" | sed 's/^PORT=//')
sql_dump=$(ls ${CMS_DIRECTORY}/*.sql)
install_pkg expect
mariadb -u directus -p"$DB_DIRECTUS_PASSWORD" directus < "$sql_dump"
rm $sql_dump
chown -R www-data:www-data $CMS_DIRECTORY
su -s /bin/bash -c "cd ${CMS_DIRECTORY} &&\
npm init -y &&\
npx directus bootstrap --skipAdminInit &&\
npx directus database migrate:latest
tmux new-session -d -s directus &&\
tmux send-keys -t directus \"cd ${CMS_DIRECTORY} && npx directus start\" C-m" www-data
echo -e "${PURPLE}Directus launched with imported database${RESET}"

View File

@@ -0,0 +1,17 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
get_username
get_ip
get_ssh_port
echo -e "${PURPLE}${BOLD}Import local Directus data model${RESET}"
echo -e "${BLUE}npx directus schema snapshot ./snapshot.yaml${RESET}"
echo -e "${BLUE}scp -P ${ssh_port} /local/path/to/snapshot.yaml ${username}@${ip}:/home/${username}/snapshot.yaml${RESET}"
echo -e "${PURPLE}${BOLD}Press any key when done${RESET}"
read
su -s /bin/bash -c "cd ${CMS_DIRECTORY} &&\
npx directus schema apply --yes /home/${username}/snapshot.yaml" www-data

19
bin/install_caddy.sh Normal file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
if systemctl is-enabled apache2 >/dev/null 2>&1; then
systemctl disable --now apache2
fi
install_pkg debian-keyring
install_pkg debian-archive-keyring
install_pkg apt-transport-https
install_pkg curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
install_pkg caddy
> /etc/caddy/Caddyfile
echo -e "${PURPLE}${BOLD}Caddy Webserver installed${RESET}"

46
bin/install_directus.sh Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
install_pkg tmux
if [[ -z "$DB_DIRECTUS_PASSWORD" ]]; then
echo -e "${PURPLE}${BOLD}Enter the MariaDB Directus password : ${RESET}"
read -s DB_DIRECTUS_PASSWORD
echo
fi
if [[ -z "$CMS_DIRECTORY" ]]; then
. bin/set_url.sh
fi
echo "set -g default-shell /bin/sh" >> /etc/tmux.conf
su -s /bin/bash -c "mkdir ${CMS_DIRECTORY}" www-data
echo -e "${PURPLE}${BOLD}Import the Directus database ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
. bin/import_directus_db.sh
else
. bin/setup_directus.sh
echo -e "${PURPLE}${BOLD}Import Directus data model ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
. bin/import_directus_schema.sh
fi
echo -e "${PURPLE}${BOLD}You can now add some content${RESET}"
echo -e "${ORANGE}${BOLD}Do not forget to set the permissions${RESET}"
echo -e "${ORANGE}${BOLD}Website role ${RESET}${ORANGE}Read content collections and directus_files${RESET}"
echo -e "${ORANGE}${BOLD}User role ${RESET}${ORANGE}All permissions on content collections, directus_files and directus_folders${RESET}"
fi
echo "cms.${DOMAIN_NAME} {" >> $CADDYFILE
echo "reverse_proxy ${ip}:${port}" >> $CADDYFILE
echo "}" >> $CADDYFILE
caddy fmt $CADDYFILE -w
caddy reload -c $CADDYFILE
echo -e "${PURPLE}${BOLD}Access Directus ${RESET}${PURPLE}https://cms.${DOMAIN_NAME}${RESET}"

40
bin/install_mariadb.sh Normal file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Automate mysql secure installation for debian-based systems
# https://gist.github.com/coderua/5592d95970038944d099
. bin/variables.sh
. bin/functions.sh
install_pkg mariadb-server
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the MariaDB root password : ${RESET}"
read -s DB_ROOT_PASSWORD
echo
install_pkg expect
secure_mysql=$(expect -c "
set timeout 3
spawn mysql_secure_installation
expect \"Enter current password for root (enter for none):\"
send \"\r\"
expect \"Switch to unix_socket authentication \\[Y/n\\]\"
send \"n\r\"
expect \"Change the root password? \\[Y/n\\]\"
send \"y\r\"
expect \"New password:\"
send \"$DB_ROOT_PASSWORD\r\"
expect \"Re-enter new password:\"
send \"$DB_ROOT_PASSWORD\r\"
expect \"Remove anonymous users?\"
send \"y\r\"
expect \"Disallow root login remotely?\"
send \"y\r\"
expect \"Remove test database and access to it?\"
send \"y\r\"
expect \"Reload privilege tables now?\"
send \"y\r\"
expect eof
")
echo "${secure_mysql}"
echo -e "${PURPLE}MariaDB is installed and secure${RESET}"

22
bin/install_node.sh Normal file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
touch /var/www/.bashrc
mkdir /var/www/.nvm
mkdir /var/www/.npm
chown -R www-data:www-data /var/www
install_pkg build-essential
su -s /bin/bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash &&\
export NVM_DIR="$HOME/.nvm" &&\
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" &&\
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" &&\
nvm install v18' www-data
ln -sf /var/www/.nvm/versions/node/v18.*/bin/node /usr/bin/node
ln -sf /var/www/.nvm/versions/node/v18.*/bin/npm /usr/bin/npm
ln -sf /var/www/.nvm/versions/node/v18.*/bin/npx /usr/bin/npx
echo -e "${PURPLE}Node installed${RESET}";

50
bin/install_nuxt_front.sh Normal file
View File

@@ -0,0 +1,50 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
get_ip
echo -e "${PURPLE}${BOLD}Create and push a prod branch on the repo${RESET}"
echo -e "${BLUE}git fetch . main:prod${RESET}"
echo -e "${BLUE}git push origin prod${RESET}"
echo -e "${PURPLE}${BOLD}Enter the .git url of the repo${RESET}"
read repo_url
front_repo_name=$(echo "$repo_url" | sed 's#.*/\([^/]*\)\.git#\1#')
front_directory="${REPO_DIRECTORY}/${front_repo_name}"
if [[ -z "$WEBSITE_TOKEN" ]]; then
echo -e "${PURPLE}${BOLD}Enter the Directus Website user static token${RESET}"
read -s WEBSITE_TOKEN
fi
touch /var/www/.nuxtrc
echo "telemetry.consent=0" > /var/www/.nuxtrc
echo "telemetry.enabled=false" >> /var/www/.nuxtrc
chown -R www-data:www-data /var/www/.nuxtrc
rm /var/www/html/*
chown www-data:www-data /var/www/html
su -s /bin/bash -c "cd ${REPO_DIRECTORY} &&\
git clone ${repo_url} &&\
cd ${front_directory} &&\
git checkout prod &&\
echo \"DIRECTUS_API_TOKEN=${WEBSITE_TOKEN}\" > .env &&\
echo \"URL=https://${DOMAIN_NAME}\" >> .env &&\
echo \"DIRECTUS_URL=https://cms.${DOMAIN_NAME}\" >> .env &&\
node --max-old-space-size=250 `which npm` install -y &&\
node --max-old-space-size=250 `which npm` run generate --prerender" www-data
cp -r "${front_directory}/.output/public" /var/www/html
chown -R www-data:www-data /var/www/html/public
echo "www.${DOMAIN_NAME} {" >> $CADDYFILE
echo "redir ${DOMAIN_NAME}{uri} permanent" >> $CADDYFILE
echo "}" >> $CADDYFILE
echo "${DOMAIN_NAME} {" >> $CADDYFILE
echo "root * /var/www/html/public" >> $CADDYFILE
echo "file_server" >> $CADDYFILE
echo "}" >> $CADDYFILE
caddy fmt $CADDYFILE -w
caddy reload -c $CADDYFILE

20
bin/set_url.sh Normal file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
echo -e "${PURPLE}${BOLD}Enter the domain name of the website${RESET}"
read DOMAIN_NAME
get_ip
echo -e "${PURPLE}${BOLD}Configure the ${DOMAIN_NAME} DNS ZONE as the following${RESET}"
echo -e "${BLUE}Domain : ${DOMAIN_NAME} | Type : A | Target : ${ip}${RESET}"
echo -e "${BLUE}Domain : cms.${DOMAIN_NAME} | Type : A | Target : ${ip}${RESET}"
echo -e "${BLUE}Domain : www.${DOMAIN_NAME} | Type : A | Target : ${ip}${RESET}"
echo -e "${PURPLE}${BOLD}Press any key when done${RESET}"
read
REPO_DIRECTORY="/var/www/repositories"
mkdir $repo_directory
chown www-data:www-data $repo_directory
CMS_DIRECTORY="${repo_directory}/cms_${DOMAIN_NAME}"

60
bin/setup_directus.sh Normal file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
echo -e "${ORANGE}${BOLD}Generate and store the credentials somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the Directus admin email : ${RESET}"
read directus_admin_email
echo -e "${PURPLE}${BOLD}Enter the Directus admin password : ${RESET}"
read -s directus_admin_password
env_file="${CMS_DIRECTORY}/.env"
port=8055
key=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
secret=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
su -s /bin/bash -c "mkdir ${CMS_DIRECTORY} &&\
mkdir ${CMS_DIRECTORY}/uploads &&\
echo \"HOST='${ip}'\" >> ${env_file} &&\
echo \"PORT=${port}\" >> ${env_file} &&\
echo \"PUBLIC_URL='https://cms.${DOMAIN_NAME}'\" >> ${env_file} &&\
echo \"DB_CLIENT='mysql'\" >> ${env_file} &&\
echo \"DB_HOST='127.0.0.1'\" >> ${env_file} &&\
echo \"DB_PORT='3306'\" >> ${env_file} &&\
echo \"DB_DATABASE='directus'\" >> ${env_file} &&\
echo \"DB_USER='directus'\" >> ${env_file} &&\
echo \"DB_PASSWORD='${DB_DIRECTUS_PASSWORD}'\" >> ${env_file} &&\
echo \"SECRET='${secret}'\" >> ${env_file} &&\
echo \"KEY='${key}'\" >> ${env_file} &&\
echo \"CORS_ENABLED='true'\" >> ${env_file} &&\
echo \"CORS_ORIGIN='true'\" >> ${env_file} &&\
echo \"IMPORT_IP_DENY_LIST=\" >> ${env_file} &&\
cd ${CMS_DIRECTORY} &&\
npm init -y &&\
npx directus bootstrap --skipAdminInit &&\
tmux new-session -d -s directus &&\
tmux send-keys -t directus \"cd ${CMS_DIRECTORY} && npx directus start\" C-m &&\
npx directus roles create --role Administrator --admin true &&\
npx directus roles create --role Website &&\
npx directus roles create --role User" www-data
admin_role_uuid=$(echo $(mariadb -u directus -p${DB_DIRECTUS_PASSWORD} \
-e "SELECT id FROM directus.directus_roles WHERE name='Administrator'") | awk '{print $2}')
website_role_uuid=$(echo $(mariadb -u directus -p${DB_DIRECTUS_PASSWORD} \
-e "SELECT id FROM directus.directus_roles WHERE name='Website'") | awk '{print $2}')
user_role_uuid=$(echo $(mariadb -u directus -p${DB_DIRECTUS_PASSWORD} \
-e "SELECT id FROM directus.directus_roles WHERE name='User'") | awk '{print $2}')
website_password=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
su -s /bin/bash -c "cd ${CMS_DIRECTORY} &&\
npx directus users create --email \"${directus_admin_email}\" \
--password \"${directus_admin_password}\" --role \"${admin_role_uuid}\" &&\
npx directus users create --email \"website@${DOMAIN_NAME}\" --password \"${website_password}\" --role \"${website_role_uuid}\"" www-data
WEBSITE_TOKEN=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
mariadb -u directus -p${DB_DIRECTUS_PASSWORD} -e "UPDATE directus.directus_roles SET icon='robot' WHERE name='Website'";
mariadb -u directus -p${DB_DIRECTUS_PASSWORD} -e "UPDATE directus.directus_roles SET app_access='0' WHERE name='Website'";
mariadb -u directus -p${DB_DIRECTUS_PASSWORD} -e "UPDATE directus.directus_users SET token=\"${WEBSITE_TOKEN}\" WHERE email=\"website@${DOMAIN_NAME}\"";

35
bin/setup_directus_db.sh Normal file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
if ! dpkg -s mariadb-server >/dev/null 2>&1; then
. bin/install_mariadb.sh
fi
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the MariaDB Directus password : ${RESET}"
read -s DB_DIRECTUS_PASSWORD
echo
if [[ -z "$DB_ROOT_PASSWORD" ]]; then
echo -e "${PURPLE}${BOLD}Enter the MariaDB root password : ${RESET}"
read -s DB_ROOT_PASSWORD
echo
fi
install_pkg expect
create_directus_db=$(expect -c "
spawn mariadb -u root -p
expect \"Enter password:\"
send \"$DB_ROOT_PASSWORD\r\"
expect \"mysql>\"
send \"CREATE USER 'directus'@'localhost' IDENTIFIED BY '${DB_DIRECTUS_PASSWORD}';\r\"
send \"CREATE DATABASE directus;\r\"
send \"GRANT ALL PRIVILEGES ON directus.* TO 'directus'@'localhost' IDENTIFIED BY '${DB_DIRECTUS_PASSWORD}';\r\"
send \"FLUSH PRIVILEGES;\r\"
expect \"mysql>\"
send \"quit;\r\"
expect eof
")
echo "${create_directus_db}" >& /dev/null
echo -e "${PURPLE}Directus database created${RESET}"

View File

@@ -0,0 +1,15 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
echo -e "${PURPLE}${BOLD}Setup Firewall and Fail2ban${RESET}"
install_pkg ufw
install_pkg fail2ban
systemctl enable fail2ban
get_ssh_port
ufw allow $ssh_port
ufw allow http
ufw allow https
echo -e "${PURPLE}Firewall and Fail2ban are setup${RESET}"

15
bin/setup_ssh.sh Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
. bin/variables.sh
echo -e "${PURPLE}${BOLD}Setup SSH${RESET}"
ssh_port=$((RANDOM % (65536 - 1024 + 1) + 1024))
touch /etc/ssh/sshd_config.d/custom.conf
echo "PermitRootLogin no" >> /etc/ssh/sshd_config.d/custom.conf
echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config.d/custom.conf
echo "Port ${ssh_port}" >> /etc/ssh/sshd_config.d/custom.conf
systemctl reload ssh
echo -e "${ORANGE}${BOLD}Store the ssh port ${ssh_port} somewhere safe${RESET}"

42
bin/setup_webhook.sh Normal file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
. bin/variables.sh
. bin/functions.sh
echo -e "${PURPLE}${BOLD}If it does not already exists, create a webhook at the following url${RESET}"
echo -e "${PURPLE}${BOLD}${repo_url}/settings/hooks/gitea/new${RESET}"
echo -e "${BLUE}${BOLD}Target URL ${RESET}${BLUE}https://${domain_name}/webhook.php${RESET}"
echo -e "${BLUE}${BOLD}Branch filter ${RESET}${BLUE}prod${RESET}"
echo -e "${BLUE}${BOLD}Authorization Header ${RESET}${ORANGE}Generate a safe string using \`openssl rand -base64 32\`${RESET}"
echo -e "${PURPLE}${BOLD}Enter the Authorization Header${RESET}"
read -s auth_header
install_pkg php
install_pkg php-fpm
install_pkg jq
rm /var/www/html/index.html
cp ./assets/webhook.php /var/www/html/
mkdir /var/www/webhook
cp ./assets/webhook.sh /var/www/webhook
chown www-data:www-data /var/www/webhook/webhook.sh
chmod u+x /var/www/webhook/webhook.sh
mkdir /var/www/webhook/logs
chown www-data:www-data /var/www/webhook/logs
get_ip
head -n $(($(wc -l < $CADDYFILE) - 2)) $CADDYFILE > temp_Caddyfile && mv temp_Caddyfile $CADDYFILE
echo "handle /webhook.php {" >> $CADDYFILE
echo "@unauthorized not header Authorization \"${auth_header}\"" >> $CADDYFILE
echo "respond @unauthorized \"Unauthorized access\"" >> $CADDYFILE
echo "root * /var/www/html" >> $CADDYFILE
echo "php_fastcgi unix//run/php/php8.2-fpm.sock" >> $CADDYFILE
echo "file_server" >> $CADDYFILE
echo "}" >> $CADDYFILE
echo "handle {" >> $CADDYFILE
echo "reverse_proxy ${ip}:3000" >> $CADDYFILE
echo "}" >> $CADDYFILE
echo "}" >> $CADDYFILE
caddy fmt $CADDYFILE -w
caddy reload -c $CADDYFILE

19
bin/variables.sh Normal file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
# Texts layout
PURPLE='\033[35m'
ORANGE='\033[33m'
BLUE='\033[34m'
BOLD='\033[1m'
RESET='\033[0m'
DB_ROOT_PASSWORD=""
DB_DIRECTUS_PASSWORD=""
DOMAIN_NAME=""
CMS_DIRECTORY=""
REPO_DIRECTORY=""
WEBSITE_TOKEN=""
CADDYFILE="/etc/caddy/Caddyfile"

View File

@@ -1,33 +1,18 @@
#!/bin/bash
PURPLE='\033[35m'
ORANGE='\033[33m'
BLUE='\033[34m'
BOLD='\033[1m'
RESET='\033[0m'
install_pkg() {
pkg="$1"
if ! command -v "$pkg" &> /dev/null; then
apt install -y "$pkg"
echo -e "${PURPLE}${BOLD}${pkg} installed${RESET}"
fi
}
# TODO
## DIRECTUS EMAIL
## DIRECTUS REDIS
## LOGING DE TOUT
## CADDYFILE EN JSON
## MÀJ
## reboot a running system
## MATOMO
## NODE EXPORTER
get_username() {
if [[ -z "$username" ]]; then
username=$(getent passwd 1000 | cut -d: -f1)
fi
}
get_ip() {
if [[ -z "$ip" ]]; then
ip=$(hostname -I)
if [[ "${ip: -1}" == " " ]]; then
ip="${ip%?}"
fi
fi
}
. bin/functions.sh
. bin/variables.sh
echo -e "${PURPLE}${BOLD}Deployment Debian + Caddy + Directus + Nuxt${RESET}"
@@ -36,402 +21,83 @@ if [ "$EUID" -ne 0 ]; then
exit
fi
apt install -y php php-fpm
systemctl disable --now apache2
if [ "$(dirname "$0")" != "$(pwd)" ]; then
echo "Please run this script from its directory."
exit
fi
#
# USER
#
echo -e "${PURPLE}${BOLD}Create a user ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${PURPLE}${BOLD}Create user${RESET}"
read -p "Enter username: " username
if id "$username" &>/dev/null; then
echo "User '$username' already exists."
exit 1
fi
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
read -s -p "Enter password: " password
echo
useradd -m "$username"
chsh -s /bin/bash $username
echo "$username:$password" | chpasswd
usermod -aG sudo $username
echo -e "${PURPLE}${BOLD}User '$username' created with password successfully.${RESET}"
. bin/create_user.sh
fi
#
# SSH
#
echo -e "${PURPLE}${BOLD}Setup SSH ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${PURPLE}${BOLD}Setup SSH${RESET}"
touch /etc/ssh/sshd_config.d/custom.conf
echo "PermitRootLogin no" >> /etc/ssh/sshd_config.d/custom.conf
echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config.d/custom.conf
systemctl reload ssh
. bin/setup_ssh.sh
fi
#
# FIREWALL AND FAIL2BAN
#
echo -e "${PURPLE}${BOLD}Setup Firewall and Fail2ban ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${PURPLE}${BOLD}Setup Firewall and Fail2ban${RESET}"
apt install -y ufw fail2ban
systemctl enable fail2ban
ufw allow ssh
ufw allow http
ufw allow https
. bin/setup_firewall_fail2ban.sh
fi
#
# CADDY
#
echo -e "${PURPLE}${BOLD}Install Caddy webserver ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${PURPLE}${BOLD}Install Caddy Webserver${RESET}"
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install -y caddy
> /etc/caddy/Caddyfile
. bin/install_caddy.sh
fi
#
# MARIADB
#
echo -e "${PURPLE}${BOLD}Install MariaDB ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
apt install -y mariadb-server
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the MariaDB root password : ${RESET}"
read -s db_root_password
echo
install_pkg expect
SECURE_MYSQL=$(expect -c "
set timeout 3
spawn mysql_secure_installation
expect \"Enter current password for root (enter for none):\"
send \"\r\"
expect \"Switch to unix_socket authentication \\[Y/n\\]\"
send \"n\r\"
expect \"Change the root password? \\[Y/n\\]\"
send \"y\r\"
expect \"New password:\"
send \"$db_root_password\r\"
expect \"Re-enter new password:\"
send \"$db_root_password\r\"
expect \"Remove anonymous users?\"
send \"y\r\"
expect \"Disallow root login remotely?\"
send \"y\r\"
expect \"Remove test database and access to it?\"
send \"y\r\"
expect \"Reload privilege tables now?\"
send \"y\r\"
expect eof
")
echo "${SECURE_MYSQL}"
# https://gist.github.com/coderua/5592d95970038944d099
. bin/install_mariadb.sh
fi
#
# DIRECTUS DB
#
echo -e "${PURPLE}${BOLD}Setup Directus database ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${ORANGE}${BOLD}Generate and store the password somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the MariaDB Directus password : ${RESET}"
read -s db_directus_password
echo
if [[ -z "$db_root_password" ]]; then
echo -e "${PURPLE}${BOLD}Enter the MariaDB root password : ${RESET}"
read -s db_root_password
echo
fi
install_pkg expect
CREATE_DIRECTUS_DB=$(expect -c "
spawn mariadb -u root -p
expect \"Enter password:\"
send \"$db_root_password\r\"
expect \"mysql>\"
send \"CREATE USER 'directus'@'localhost' IDENTIFIED BY '${db_directus_password}';\r\"
send \"CREATE DATABASE directus;\r\"
send \"GRANT ALL PRIVILEGES ON directus.* TO 'directus'@'localhost' IDENTIFIED BY '${db_directus_password}';\r\"
send \"FLUSH PRIVILEGES;\r\"
expect \"mysql>\"
send \"quit;\r\"
expect eof
")
echo "${CREATE_DIRECTUS_DB}" >& /dev/null
echo -e "${PURPLE}${BOLD}Directus database created${RESET}"
. bin/setup_directus_db.sh
fi
#
# NODE
#
echo -e "${PURPLE}${BOLD}Install Node ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
touch /var/www/.bashrc
chown www-data:www-data /var/www/.bashrc
mkdir /var/www/.nvm
chown www-data:www-data /var/www/.nvm
mkdir /var/www/.npm
chown www-data:www-data /var/www/.npm
su -s /bin/bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash &&\
export NVM_DIR="$HOME/.nvm" &&\
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" &&\
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" &&\
nvm install v18' www-data
ln -sf /var/www/.nvm/versions/node/v18.19.1/bin/node /usr/bin/node
ln -sf /var/www/.nvm/versions/node/v18.19.1/bin/npm /usr/bin/npm
ln -sf /var/www/.nvm/versions/node/v18.19.1/bin/npx /usr/bin/npx
echo -e "${PURPLE}${BOLD}Node installed${RESET}";
. bin/install_node.sh
fi
#
# SET THE URL
#
echo -e "${PURPLE}${BOLD}Enter the domain name of the website${RESET}"
read domain_name
get_ip
echo -e "${PURPLE}${BOLD}Configure the ${domain_name} DNS ZONE as the following${RESET}"
echo -e "${BLUE}Domain : ${domain_name} | Type : A | Target : ${ip}${RESET}"
echo -e "${BLUE}Domain : cms.${domain_name} | Type : A | Target : ${ip}${RESET}"
echo -e "${BLUE}Domain : www.${domain_name} | Type : A | Target : ${ip}${RESET}"
echo -e "${PURPLE}${BOLD}Press any key when done${RESET}"
read
repo_directory="/var/www/repositories"
mkdir $repo_directory
chown www-data:www-data $repo_directory
cms_directory="${repo_directory}/cms_${domain_name}"
#
# DIRECTUS
#
# SET URL
echo -e "${PURPLE}${BOLD}Set url ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
. bin/set_url.sh
fi
# INSTALL DIRECTUS
echo -e "${PURPLE}${BOLD}Install Directus ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
install_pkg tmux
if [[ -z "$db_directus_password" ]]; then
echo -e "${PURPLE}${BOLD}Enter the MariaDB Directus password : ${RESET}"
read -s db_directus_password
echo
fi
echo -e "${ORANGE}${BOLD}Generate and store the credentials somewhere safe${RESET}"
echo -e "${PURPLE}${BOLD}Enter the Directus admin email : ${RESET}"
read directus_admin_email
echo -e "${PURPLE}${BOLD}Enter the Directus admin password : ${RESET}"
read -s directus_admin_password
env_file="${cms_directory}/.env"
port=8055
key=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
secret=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
echo "set -g default-shell /bin/sh" >> /etc/tmux.conf
su -s /bin/bash -c "mkdir ${cms_directory} &&\
mkdir ${cms_directory}/uploads &&\
echo \"HOST='${ip}'\" >> ${env_file} &&\
echo \"PORT=${port}\" >> ${env_file} &&\
echo \"PUBLIC_URL='https://cms.${domain_name}'\" >> ${env_file} &&\
echo \"DB_CLIENT='mysql'\" >> ${env_file} &&\
echo \"DB_HOST='127.0.0.1'\" >> ${env_file} &&\
echo \"DB_PORT='3306'\" >> ${env_file} &&\
echo \"DB_DATABASE='directus'\" >> ${env_file} &&\
echo \"DB_USER='directus'\" >> ${env_file} &&\
echo \"DB_PASSWORD='${db_directus_password}'\" >> ${env_file} &&\
echo \"SECRET='${secret}'\" >> ${env_file} &&\
echo \"KEY='${key}'\" >> ${env_file} &&\
echo \"CORS_ENABLED='true'\" >> ${env_file} &&\
echo \"CORS_ORIGIN='true'\" >> ${env_file} &&\
cd ${cms_directory} &&\
npm init -y &&\
npx directus bootstrap --skipAdminInit &&\
tmux new-session -d -s directus &&\
tmux send-keys -t directus \"cd ${cms_directory} && npx directus start\" C-m &&\
npx directus roles create --role Administrator --admin true &&\
npx directus roles create --role Website &&\
npx directus roles create --role User" www-data
admin_role_uuid=$(echo $(mariadb -u directus -p${db_directus_password} \
-e "SELECT id FROM directus.directus_roles WHERE name='Administrator'") | awk '{print $2}')
website_role_uuid=$(echo $(mariadb -u directus -p${db_directus_password} \
-e "SELECT id FROM directus.directus_roles WHERE name='Website'") | awk '{print $2}')
user_role_uuid=$(echo $(mariadb -u directus -p${db_directus_password} \
-e "SELECT id FROM directus.directus_roles WHERE name='User'") | awk '{print $2}')
website_password=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
su -s /bin/bash -c "cd ${cms_directory} &&\
npx directus users create --email \"${directus_admin_email}\" \
--password \"${directus_admin_password}\" --role \"${admin_role_uuid}\" &&\
npx directus users create --email \"website@${domain_name}\" --password \"${website_password}\" --role \"${website_role_uuid}\"" www-data
website_token=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
mariadb -u directus -p${db_directus_password} -e "UPDATE directus.directus_roles SET icon='robot' WHERE name='Website'";
mariadb -u directus -p${db_directus_password} -e "UPDATE directus.directus_roles SET app_access='0' WHERE name='Website'";
mariadb -u directus -p${db_directus_password} -e "UPDATE directus.directus_users SET token=\"${website_token}\" WHERE email=\"website@${domain_name}\"";
caddyfile="/etc/caddy/Caddyfile"
echo "cms.${domain_name} {" >> $caddyfile
echo "reverse_proxy ${ip}:${port}" >> $caddyfile
echo "}" >> $caddyfile
caddy fmt $caddyfile -w
caddy reload -c $caddyfile
echo -e "${PURPLE}${BOLD}Import Directus data model ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
get_username
echo -e "${PURPLE}${BOLD}Import local Directus data model${RESET}"
echo -e "${BLUE}npx directus schema snapshot ./snapshot.yaml${RESET}"
echo -e "${BLUE}scp /local/path/to/snapshot.yaml ${username}@${ip}:/home/${username}/snapshot.yaml${RESET}"
echo -e "${PURPLE}${BOLD}Press any key when done${RESET}"
read
su -s /bin/bash -c "cd ${cms_directory} &&\
npx directus schema apply --yes /home/${username}/snapshot.yaml" www-data
fi
echo -e "${PURPLE}${BOLD}You can now add some content${RESET}"
echo -e "${ORANGE}${BOLD}Do not forget to set the permissions${RESET}"
echo -e "${ORANGE}${BOLD}Website role ${RESET}${ORANGE}Read content collections and directus_files${RESET}"
echo -e "${ORANGE}${BOLD}User role ${RESET}${ORANGE}All permissions on content collections, directus_files and directus_folders${RESET}"
echo -e "${PURPLE}${BOLD}Access Directus ${RESET}${PURPLE}https://cms.${domain_name}${RESET}"
. bin/install_directus.sh
fi
#
# NUXT
#
# NUXT STATIC
echo -e "${PURPLE}${BOLD}Install the front-end ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
get_ip
echo -e "${PURPLE}${BOLD}Create and push a prod branch on the repo${RESET}"
echo -e "${BLUE}git checkout -b prod${RESET}"
echo -e "${BLUE}git add . && git commit -m "first commit to prod"${RESET}"
echo -e "${BLUE}git push origin prod${RESET}"
echo -e "${PURPLE}${BOLD}Enter the .git url of the repo${RESET}"
read repo_url
front_repo_name=$(echo "$repo_url" | sed 's#.*/\([^/]*\)\.git#\1#')
front_directory="${repo_directory}/${front_repo_name}"
if [[ -z "$website_token" ]]; then
echo -e "${PURPLE}${BOLD}Enter the Directus Website user static token${RESET}"
read -s website_token
fi
touch /var/www/.nuxtrc
echo "telemetry.consent=0" > /var/www/.nuxtrc
echo "telemetry.enabled=false" >> /var/www/.nuxtrc
chown -R www-data:www-data /var/www/.nuxtrc
su -s /bin/bash -c "cd ${repo_directory} &&\
git clone ${repo_url} &&\
cd ${front_directory} &&\
git checkout prod &&\
echo \"DIRECTUS_API_TOKEN=${website_token}\" > .env &&\
echo \"URL=https://${domain_name}\" >> .env &&\
echo \"DIRECTUS_URL=https://cms.${domain_name}\" >> .env &&\
tmux send-keys -t directus C-c &&\
npm install -y &&\
NUXT_TELEMETRY_DISABLED=1 bash -c \"npm run build\" &&\
tmux new-session -d -s front &&\
tmux send-keys -t front \"cd ${front_directory} && node .output/server/index.mjs\" C-m &&\
tmux send-keys -t directus \"npx directus start\" C-m" www-data
caddyfile="/etc/caddy/Caddyfile"
echo "www.${domain_name} {" >> $caddyfile
echo "redir ${domain_name}{uri} permanent" >> $caddyfile
echo "}" >> $caddyfile
echo "${domain_name} {" >> $caddyfile
echo "reverse_proxy ${ip}:3000" >> $caddyfile
echo "}" >> $caddyfile
caddy fmt $caddyfile -w
caddy reload -c $caddyfile
. bin/install_nuxt_front.sh
echo -e "${PURPLE}${BOLD}Setup a webhook ? (y/N) ${RESET}"
read answer
if [[ "$answer" == "y" ]]; then
echo -e "${PURPLE}${BOLD}If it does not already exists, create a webhook at the following url${RESET}"
echo -e "${PURPLE}${BOLD}${repo_url}/settings/hooks/gitea/new${RESET}"
echo -e "${BLUE}${BOLD}Target URL ${RESET}${BLUE}https://${domain_name}/webhook.php${RESET}"
echo -e "${BLUE}${BOLD}Branch filter ${RESET}${BLUE}prod${RESET}"
echo -e "${BLUE}${BOLD}Authorization Header ${RESET}${ORANGE}Generate a safe string using \`openssl rand -base64 32\`${RESET}"
echo -e "${PURPLE}${BOLD}Enter the Authorization Header${RESET}"
read -s auth_header
apt install -y jq
rm /var/www/html/index.html
cp ./assets/webhook.php /var/www/html/
mkdir /var/www/webhook
cp ./assets/webhook.sh /var/www/webhook
chown www-data:www-data /var/www/webhook/webhook.sh
chmod u+x /var/www/webhook/webhook.sh
touch /var/www/webhook/webhook.log
chown www-data:www-data /var/www/webhook/webhook.log
head -n $(($(wc -l < $caddyfile) - 2)) $caddyfile > temp_Caddyfile && mv temp_Caddyfile $caddyfile
echo "handle /webhook.php {" >> $caddyfile
echo "@unauthorized not header Authorization \"${auth_header}\"" >> $caddyfile
echo "respond @unauthorized \"Unauthorized access\"" >> $caddyfile
echo "root * /var/www/html" >> $caddyfile
echo "php_fastcgi unix//run/php/php8.2-fpm.sock" >> $caddyfile
echo "file_server" >> $caddyfile
echo "}" >> $caddyfile
echo "handle {" >> $caddyfile
echo "reverse_proxy ${ip}:3000" >> $caddyfile
echo "}" >> $caddyfile
echo "}" >> $caddyfile
caddy fmt $caddyfile -w
caddy reload -c $caddyfile
. bin/setup_webhook.sh
fi
fi
apt purge expect
# TODO
#
# ZABBIX
# URBACKUP
# DIRECTUS EMAIL
# DIRECTUS REDIS
# LOGING DE TOUT
# IMPORT DIRECTUS FULL DB
# CADDYFILE EN JSON
# MÀJ
# reboot a running system
fi

View File

@@ -6,7 +6,6 @@ if [ "$EUID" -ne 0 ]; then
fi
PURPLE='\033[35m'
ORANGE='\033[33m'
BLUE='\033[34m'
BOLD='\033[1m'
RESET='\033[0m'
@@ -21,6 +20,7 @@ if [[ "$answer" == "y" ]]; then
current_date=$(date +'%d-%m-%y_%H-%M')
export_base_folder="/home/${user}/content_exports"
export_folder="${export_base_folder}/${site_name}_export_${current_date}"
mkdir -p "${export_folder}"
mysqldump -u directus -p"${db_password}" directus > "${export_folder}/db_${site_name}_${current_date}.sql"
cp -r /var/www/repositories/cms*/uploads "${export_folder}"
@@ -29,7 +29,7 @@ if [[ "$answer" == "y" ]]; then
rm -r "${export_folder}"
chown -R "${user}:${user}" "${export_base_folder}"
ssh_port=$(cat /etc/ssh/sshd_config | grep "Port " | sed 's/^Port //')
ssh_port=$(cat /etc/ssh/sshd_config.d/custom.conf | grep "Port " | sed 's/^Port //')
ip=$(hostname -I)
if [[ "${ip: -1}" == " " ]]; then
ip="${ip%?}"