Skip to content

Instantly share code, notes, and snippets.

@phoenixweiss
Last active January 27, 2024 13:27
Show Gist options
  • Save phoenixweiss/458593c3e921aeef782053d0d8473602 to your computer and use it in GitHub Desktop.
Save phoenixweiss/458593c3e921aeef782053d0d8473602 to your computer and use it in GitHub Desktop.
Настраиваем площадку под Ruby on Rails 7 / Sinatra / Nodejs на базе Ubuntu 22.04 + MySQL 8
# !!!Все что ниже делаем от имени пользователя root!!!
# Проверяем что раскомментировано в файле /etc/locale.gen
# Раскомментируем или добавляем локаль ru_RU.UTF-8 UTF-8
# Либо можем сразу внести только основные командой:
printf "en_US.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8" > /etc/locale.gen
# После чего генерируем локаль
locale-gen
# Открываем ручками /etc/hosts и добавляем туда имя нашего сервера, его же дублируем в /etc/hostname
# Выполняем для очистки кэша пакетов, апдейтим источники, обновляем все что можно, чистим мусор
apt-get clean
apt-get update
apt-get -y upgrade
apt-get -y dist-upgrade
apt-get -y autoremove
# Узнать что у нас с памятью можно командой
free -m
# Узнать подключенные файлы подкачки можно так
cat /proc/swaps
# Если в системе уже есть swapfile, перед тем как его переразмечать, нужно его отключить командой 'swapoff -a'
# Создадим руками файл подкачки из блоков по 1Мб в количестве равном размеру физической памяти в Мб, пример для 512Мб
dd if=/dev/zero of=/swapfile bs=1M count=512
# Зададим права и подключим файл подкачки
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# !ВАЖНО! если при создании виртуальной машины swapfile был создан, он может быть уже прописан здесь
# Автоматизируем поднятие файла подкачки при каждой загрузке системы
echo "/swapfile none swap defaults 0 0" >> /etc/fstab
# Укажем при какой загруженности физической памяти будет подхватываться запись в файл подкачки
echo "vm.swappiness=15" >> /etc/sysctl.conf
# Для проверки работоспособности файла подкачки лучше всего перезагрузить контейнер и проверить работу файла
reboot
cat /proc/swaps
# Опционально устанаваливаем ssh, sudo и curl
apt-get -y install ssh sudo curl
# Проверяем есть ли пользователь deploy
id -u deploy
# И если его нет то добавляем его, но для начала добавляем группу, затем самого пользователя с его окружением и даем ему права sudo
groupadd -f deploy
useradd -m -g deploy -s /bin/bash deploy
chmod +w /etc/sudoers
echo "deploy ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chmod -w /etc/sudoers
# Если папки .ssh нет то создаем ее, присвоив соответствующие права
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chown deploy /home/deploy/.ssh
chgrp deploy /home/deploy/.ssh
# Генерируем деплой-ключ для сервера, причем лучше вместо yourservername указать реальное имя сервера или домен
ssh-keygen -b 521 -t ecdsa -C "deploy@yourservername" -f /home/deploy/.ssh/id_ecdsa -q -N ""
# Ужесточаем права
chmod -R 600 /home/deploy/.ssh/*
chown -R deploy /home/deploy/.ssh/*
chgrp -R deploy /home/deploy/.ssh/*
# Дублируем файл authorized_keys от рута для пользователя deploy с соответствующими правами
cp /root/.ssh/authorized_keys /home/deploy/.ssh/
chmod 600 /home/deploy/.ssh/authorized_keys
chown deploy /home/deploy/.ssh/authorized_keys
chgrp deploy /home/deploy/.ssh/authorized_keys
# !!!ОПАСНО!!!
# Отключаем авторизацию по паролю для сервера и рестартим демона ssh
# Делайте это только в том случае если УВЕРЕНЫ что на сервер можно попасть как минимум по двум SSH-ключам.
sed -i "s/.*PasswordAuthentication yes.*/PasswordAuthentication no/g" "/etc/ssh/sshd_config"
service ssh restart
# Волшебный набор пакетов на все случаи жизни
# Утилиты и системные пакеты
apt-get install -y --fix-missing \
tree dirmngr gpg curl gawk debconf unzip lsb-core sudo
# Разработка и сборка
apt-get install -y --fix-missing \
git gcc make autoconf bison build-essential
# Графика и изображения
apt-get install -y --fix-missing \
imagemagick libmagickwand-dev libpoppler-glib8 libheif-dev libvips-dev libvips
# Сеть и безопасность
apt-get install -y --fix-missing \
libcurl4-openssl-dev libssl-dev libyaml-dev
# XML и HTML
apt-get install -y --fix-missing \
libxml2-dev libxslt1-dev
# Другие зависимости
apt-get install -y --fix-missing \
libreadline-dev zlib1g zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libglib2.0-0 libglib2.0-dev
# Готовимся к установке MySQL
# Пароль задаем в переменной $MYSQL_ROOT_PASS
debconf-set-selections <<< "mysql-server mysql-server/root_password password $MYSQL_ROOT_PASS"
debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASS"
# Логичнее указать конкретные версии из `apt list | grep mysql`
apt-get -y install libmysqlclient-dev mysql-client-8.0 mysql-server-8.0
### Не забыть если нужен доступ извне, открыть его добавив строчки в файл: /etc/mysql/mysql.conf.d/mysqld.cnf или /etc/mysql/my.cnf
#
# [mysqld]
# #bind-address = 127.0.0.1
# bind-address = 0.0.0.0
#
###
# !!!Уточните $SERVER_NAME!!!
# Конфигурируем и устанавливаем postfix, указываем вместо $SERVER_NAME то что писали в /etc/hostname
echo $SERVER_NAME > "/etc/mailname"
debconf-set-selections <<< "postfix postfix/mailname string $SERVER_NAME"
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
apt-get install -y postfix
# Для отправки почты из командной строки не забываем о mailutils
apt-get install -y mailutils
# Не забываем настроить postfix здесь: /etc/postfix/main.cf
# Например оставить там только inet_protocols = ipv4 и mydestination = localhost
# А после этого не забыть service postfix restart
# Для проверки мыла можно отправить например
echo "Hello from your new server" | mail -s "Hello from server" yourmail@yourserver.ru
##########################################################
# !!!Все что ниже делаем от имени пользователя deploy!!! #
##########################################################
##########################################################
# Для начала выберем чем ставить node: asdf / fnm / nvm #
##########################################################
###
# ВАРИАНТ 1 -- asdf [https://asdf-vm.com/]
###
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0
printf '
. "$HOME/.asdf/asdf.sh"
. "$HOME/.asdf/completions/asdf.bash"
' >> /home/deploy/.profile
# Чтобы реинициализировать окружение, можно в терминале выполнить
source /home/deploy/.profile
# Убедиться в том что все установилось можно командой
asdf --version
# Ставим нужный плагин
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
# Ставим последнюю стабильную версию nodejs с раширенной поддержкой, либо указываем нужную в формате asdf install nodejs 12.34.56
asdf install nodejs "20.11.0"
# Указываем глобальную версию по-умолчанию как lts или через asdf global nodejs 12.34.56
asdf global nodejs "20.11.0"
# Проверяем при помощи
node -v
###
# ВАРИАНТ 2 -- fnm [https://github.com/Schniz/fnm]
###
curl -fsSL https://fnm.vercel.app/install | bash
printf '
export PATH=/home/deploy/.fnm:$PATH
eval "`fnm env`"
' >> /home/deploy/.profile
# Чтобы реинициализировать окружение, можно в терминале выполнить
source /home/deploy/.profile
# Убедиться в том что все установилось можно командой
fnm --version
# Ставим последнюю стабильную версию nodejs с раширенной поддержкой, либо указываем нужную в формате fnm install 12.34.56
fnm install --lts
# Проверяем при помощи
node -v
###
# ВАРИАНТ 3 -- nvm [https://github.com/nvm-sh/nvm]
###
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
printf '
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
' >> /home/deploy/.profile
# Чтобы реинициализировать окружение, можно в терминале выполнить
source /home/deploy/.profile
# Убедиться в том что все установилось можно командой
nvm --version
# Ставим последнюю стабильную версию nodejs с раширенной поддержкой, либо указываем нужную в формате nvm install 12.34.56
nvm install --lts
# Проверяем при помощи
node -v
#####################################################################################################################
# От лица пользователя deploy из его корневой папки по-умолчанию ставим rbenv при помощи rbenv-installer'а (БЕЗ sudo)
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
# Добавляем rbenv в пути пользователя
echo 'export RBENV_ROOT="/home/deploy/.rbenv"' >> /home/deploy/.profile
# Если в переменной окружение у нас не определился RBENV_ROOT, то скриптом по-умолчанию при инициализации профиля пользователя, мы его пробрасыааем
printf '
if [ -d "${RBENV_ROOT}" ]; then
export PATH="${RBENV_ROOT}/bin:${PATH}"
eval "$(rbenv init -)"
fi
' >> /home/deploy/.profile
# Чтобы реинициализировать окружение, можно в терминале выполнить
source /home/deploy/.profile
# Проверить что все нормально можно скриптом
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor | bash
# Чтобы не ставился лишний мусор типа документации вместе с руби и гемами, не забудем добавить исключения
echo "gem: --no-ri --no-rdoc --no-document --suggestions" >> ~/.gemrc
# Устанавливаем на сервер нужную нам версию руби, например 3.1.2 (если нужен полный вывод то указываем флаг verbose через два дефиса)
rbenv install 3.1.2
# Указываем установленную версию руби в качестве глобальной
rbenv global 3.1.2
# Проверяем при помощи
ruby -v
# Ставим NGINX со всеми возможными модулями
sudo apt-get install -y nginx-full
# Обновляем что можно
sudo apt-get update --fix-missing
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get -y autoremove
# Конфигурируем NGINX
sudo sed -i "s|www-data;|deploy;|g" /etc/nginx/nginx.conf
sudo sed -i "s|# server_tokens off.*|client_max_body_size 20M;|" /etc/nginx/nginx.conf
# Ставим пассажира, в зависимости от ОС, варианты могут отличаться
# смотреть тут: https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/nginx/install/
# Ставим ключи и соответствующие модули поддержки для APT
sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates
##
# Добавляем соответствующий репозиторий
##
# Для 20.04 (если вдруг потребуется)
# sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main > /etc/apt/sources.list.d/passenger.list'
# Для 22.04
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main > /etc/apt/sources.list.d/passenger.list'
# Чтобы при обновлении списка репозиториев не ругалось на отсутствие i386, укажем точно [arch=amd64] здесь: /etc/apt/sources.list.d/passenger.list
# deb [arch=amd64] https://oss-binaries.phusionpassenger.com/apt/passenger jammy main
# обновляемся
sudo apt-get update
# Устанавливаем модуль расширения пассажира который подтянет все остальное
sudo apt-get install -y libnginx-mod-http-passenger
# Убедимся что файл конфигурации на месте
if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
sudo ls /etc/nginx/conf.d/mod-http-passenger.conf
# Конфигурируем пассажира в файле /etc/nginx/conf.d/mod-http-passenger.conf
sudo sed -i "s|passenger_ruby.*|passenger_ruby /home/deploy/\.rbenv/shims/ruby;|" /etc/nginx/conf.d/mod-http-passenger.conf
sudo su - root -c "echo 'passenger_max_pool_size 2;' >> /etc/nginx/conf.d/mod-http-passenger.conf"
# Проверяем работает ли конфиг nginx
sudo nginx -t
# Рестартим NGINX
sudo service nginx restart
# Проверить установку пассажира после этого можно командами ниже, причем процессы NGINX и Passenger должны быть запущены параллельно
sudo /usr/bin/passenger-config validate-install
sudo /usr/sbin/passenger-memory-stats
# В очередной раз обновляемся
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get update --fix-missing
# Может потребоваться установить Yarn
## Если нужна версия посовеременнее (node -v >= 16.10):
corepack enable
yarn set version berry
## Если достаточно классической, то просто:
npm install -g yarn
# Проверяем версию
yarn --version
# Готовим папку для проетков от лица пользователя deploy
mkdir -p /home/deploy/projects/
### ДАЛЕЕ ИДЕТ ПОДГОТОВКА ПЛОЩАДКИ ПОД ПРОЕКТ ###
# Пусть у нас будет проект на домене my.domain.name
PROJECTNAME="my.domain.name"
# Создадим
mkdir -p "/home/deploy/projects/$PROJECTNAME/shared/config/"
# Создаем БД, нового пользователя и передаем ему права
mysql_username="projectname_user"
mysql_dbname="projectname_db"
mysql_dbpass="PaSsWoRd"
Q1="CREATE DATABASE IF NOT EXISTS $mysql_dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
Q2="CREATE USER '$mysql_username'@'localhost' IDENTIFIED WITH mysql_native_password BY '$mysql_dbpass';"
Q3="GRANT ALL PRIVILEGES ON $mysql_dbname.* TO '$mysql_username'@'localhost';"
Q4="FLUSH PRIVILEGES;"
Q5="SELECT User,Host FROM mysql.user;"
Q6="SHOW DATABASES;"
SQL="${Q1}${Q2}${Q3}${Q4}${Q5}${Q6}"
# Не забываем что здесь потребуется ввести пароль root для MySQL
mysql -uroot -p -e "$SQL"
# Не забываем для Rails-проекта создать файлы конфига БД, для нашего примера они могут быть примерно такими
DB_CONFIG="
production:
adapter: mysql2
encoding: utf8mb4
collation: utf8mb4_unicode_ci
host: localhost
reconnect: true
database: $mysql_dbname
pool: 5
username: $mysql_username
password: $mysql_dbpass
"
printf "$DB_CONFIG" > "/home/deploy/projects/$PROJECTNAME/shared/config/database.yml"
# Настраиваем бесплатные SSL-сертификаты
# https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx
# Подготавливаем основные пакеты
sudo apt-get update
sudo apt-get install software-properties-common
# Устанавливаем менеджер паетов snap
sudo apt install snapd
# Проверяем его работоспособность
sudo snap install hello-world
# И запускаем
hello-world
# ЕСЛИ он уже установлен, то обновляем до последней версии
sudo snap install core; sudo snap refresh core
# ЕСЛИ ранее были установлены более старые пакеты certbot то удаляем
sudo apt-get remove certbot
# Устанавливаем сам certbot
sudo snap install --classic certbot
# Прокидываем certbot чтобы был доступен для запуска из терминала
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Запускаем сертбота и генерируем сертификаты
sudo certbot --nginx
# ЛИБО если нужен только сертификат
sudo certbot certonly --nginx
#####
# Для проверки доступности отдельных портов можно использовать nmap, это может быть полехно например для MySQL
nmap -p 3306 localhost
nmap -p 3306 192.168.1.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment