Технологии веб-разработки
Web Server
Nginx
Установка
apt install nginxОсновные команды управления
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl status nginxСтруктура конфигурации
Основные файлы/директории:
/etc/nginx/nginx.conf– главный конфигурационный файл/etc/nginx/sites-available/– доступные конфиги сайтов/etc/nginx/sites-enabled/– активные конфиги сайтов (обычно симлинки)/var/log/nginx/– логи ошибок и доступа
Добавление сайта
nano /etc/nginx/sites-available/siteВставляем:
server {
listen 80;
server_name example.com;
server_tokens off;
access_log off;
error_log off;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
server_tokens off;
access_log off;
error_log off;
ssl_certificate /etc/nginx/ssl/site.pem;
ssl_certificate_key /etc/nginx/ssl/site-key.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/site;
index index.php index.html;
# Обработка PHP через FastCGI
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
}Не забываем поменять значения на свои, и включить логи
Активируем наш сайт
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/Проверяем конфиг на ошибки и перезагружаем
nginx -tsystemctl reload nginxСайт по умолчанию
Для безопасности нашего сервера настроим сайт по умолчанию в Nginx. В большинстве дистрибутивов Nginx уже содержит файл сайта по умолчанию, открываем его:
nano /etc/nginx/sites-available/defaultи приводим к следующему виду:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_tokens off;
default_type "text/html";
return 200 'Server ON';
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate default.crt;
ssl_certificate_key default.key;
server_tokens off;
default_type "text/html";
return 200 'Server ON';
}Генерируем SSL сертификат для нашего сайта по умолчанию:
cd /etc/nginx &&
openssl req -x509 -out default.crt -keyout default.key \
-newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <(printf "
[dn]
CN=localhost
[req]
distinguished_name = dn
[EXT]
subjectAltName=DNS:localhost
keyUsage=digitalSignature
extendedKeyUsage=serverAuth")Включаем сайт по умолчанию если вдруг Вы его отключили, если нет, пропускаем этот шаг:
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/defaultПроверяем конфигурацию Nginx и если все хорошо, перезагружаем:
nginx -t
systemctl reload nginxВсе! Теперь при доступе к нашему серверу по IP или неизвестному домену, будет открывается заглушка с минимум информации о нашем сервере.
Обратный прокси (для Node.js, Python и др.)
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}Базовая аутентификация
- Создать файл с паролями:
sudo sh -c "echo -n 'user:' >> /etc/nginx/.htpasswd" sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd" - Добавить в конфиг:
location /admin { auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; }
Ограничение доступа
- По IP:
location /secret { allow 192.168.1.1; deny all; } - Запрет горячих ссылок:
location ~ .(jpg|png|gif)$ { valid_referers none blocked example.com; if ($invalid_referer) { return 403; } } - Запрет доступа к скрытым файлам:
location ~ /\. { deny all; }
Оптимизация
# Gzip сжатие
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Кэширование статики
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}Ошибка 405 Not Allowed
Nginx выдает ошибку 405 Not Allowed, если для доступа к файлам используется запрещенный или не поддерживаемый метод. В большинстве случаев это POST, который в Nginx запрещен для доступа к статическим файлам. Для решения проблемы можно использовать один из двух подходов.
Обход ограничения
В простейшем случае можно заставить веб-сервер думать, что все хорошо, просто перенаправляя ошибку дальше:
server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 404 /404.html; error_page 403 /403.html; error_page 405 =200 $uri; # ... }А если Nginx работает как прокси, скажем, для Apache, то можно сделать так:
error_page 405 =200 @405; location @405 { root /htdocs; proxy_pass http://localhost:8080; }Когда используется FastCGI
Если в Nginx используется модуль FastCGI, то в некоторых случаях веб-сервер может некорректно воспринимать скрипты, которые вызываются методом POST. Для этого запрашиваемый URL разбивается на адрес самого скрипта и запрашиваемых параметров:
location ~\.php(.*) { fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include /etc/nginx/fastcgi_params; }
Apache
Основные команды управления
# Проверить конфигурацию
sudo apachectl configtest
# Запустить сервер
sudo systemctl start apache2 # Debian/Ubuntu
sudo systemctl start httpd # CentOS/RHEL
# Остановить сервер
sudo systemctl stop apache2
sudo systemctl stop httpd
# Перезагрузить конфигурацию
sudo systemctl reload apache2
sudo systemctl reload httpd
# Полный перезапуск
sudo systemctl restart apache2
sudo systemctl restart httpd
# Проверить статус
sudo systemctl status apache2
sudo systemctl status httpdСтруктура конфигурации
Основные файлы/директории:
Debian/Ubuntu:
/etc/apache2/apache2.conf– главный конфиг/etc/apache2/sites-available/– конфиги виртуальных хостов/etc/apache2/sites-enabled/– активные виртуальные хосты/etc/apache2/mods-available/– доступные модули/var/log/apache2/– логи ошибок и доступа
CentOS/RHEL:
/etc/httpd/conf/httpd.conf– главный конфиг/etc/httpd/conf.d/– дополнительные конфиги/var/log/httpd/– логи
Базовый Virtual Host
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>Активация сайта (Debian/Ubuntu):
sudo a2ensite example.com.conf
sudo systemctl reload apache2Перенаправления
- HTTP → HTTPS:
<VirtualHost *:80> ServerName example.com Redirect permanent / https://example.com/ </VirtualHost> - WWW → без WWW:
<VirtualHost *:80> ServerName www.example.com Redirect permanent / https://example.com/ </VirtualHost>
SSL/TLS конфигурация
- Сначала активируйте модуль SSL:
sudo a2enmod ssl - Пример конфига:
<VirtualHost *:443> ServerName example.com DocumentRoot /var/www/example.com/public_html SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem # Modern SSL configuration SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 SSLHonorCipherOrder on </VirtualHost>
Обратный прокси (для Node.js, Python и др.)
<VirtualHost *:80>
ServerName api.example.com
ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# Для WebSockets
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://localhost:3000/$1" [P,L]
</VirtualHost>Активируйте модули:
sudo a2enmod proxy proxy_http proxy_wstunnel rewriteБазовая аутентификация
- Создать файл с паролями:
sudo htpasswd -c /etc/apache2/.htpasswd username - Добавить в конфиг:
<Directory "/var/www/protected"> AuthType Basic AuthName "Restricted Area" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Directory>
Ограничение доступа
- По IP:
<Directory "/var/www/private"> Require ip 192.168.1.0/24 # Или для нескольких IP: # Require ip 192.168.1.1 192.168.1.2 </Directory> - Запрет доступа к файлам:
<FilesMatch "\.(env|log|htaccess)$"> Require all denied </FilesMatch>
Оптимизация
# Включение gzip сжатия
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
</IfModule>
# Кэширование статики
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
</IfModule>Полезные модули
Активация модулей (Debian/Ubuntu):
sudo a2enmod модульВажные модули:
rewrite– для ЧПУ и перенаправленийheaders– управление HTTP-заголовкамиcache– кэшированиеsecurity– security-related модули
Полезные команды для анализа
# Показать активные соединения
sudo netstat -tnpa | grep apache
# Проверить занятые порты
sudo lsof -i :80
# Мониторинг трафика
sudo apt install apachetop
sudo apachetop -f /var/log/apache2/access.logPHP
Установка PHP 8.4 на Debian 12
Загрузим новый PGP-ключ
wget https://mirror.yandex.ru/mirrors/packages.sury.org/php/apt.gpgЗапустим:
mv apt.gpg /etc/apt/trusted.gpg.d/php.gpgКлюч установлен!
Добавим репозиторий
echo "deb https://mirror.yandex.ru/mirrors/packages.sury.org/php/ bookworm main" |tee /etc/apt/sources.list.d/php.listОбновим:
apt updateУстановка PHP 8.4
apt install php8.4 php8.4-common php8.4-cli php8.4-gd php8.4-sqlite3 php8.4-mysql php8.4-pgsql php8.4-curl php8.4-intl php8.4-mbstring php8.4-bcmath php8.4-xml php8.4-zip php8.4-bz2 php8.4-intl php8.4-ldap php8.4-imap php8.4-gmp php8.4-imagick php8.4-fpmНенужные модули убрать
Проверка установлен ли модуль PHP
php -m | grep mysqlmysql - имя искомого модуля
БД
PostgreSQL
Установка
apt install postgresql postgresql-contrib1. Подключение к серверу
psql -U пользователь -d база_данных -h хост -p порт(затем ввести пароль)
2. Основные команды
- Показать базы данных:
\l - Создать базу данных:
CREATE DATABASE имя_базы; - Удалить базу данных:
DROP DATABASE имя_базы; - Подключиться к базе:
\c имя_базы - Показать таблицы:
\dt
3. Работа с таблицами
- Создание таблицы:Пример:
CREATE TABLE имя_таблицы ( id SERIAL PRIMARY KEY, имя_столбца1 ТИП_ДАННЫХ [ограничения], имя_столбца2 ТИП_ДАННЫХ [ограничения], ... );CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE, age INT DEFAULT 18 ); - Удаление таблицы:
DROP TABLE имя_таблицы; - Очистка таблицы (без удаления):
TRUNCATE TABLE имя_таблицы; - Изменение таблицы (ALTER TABLE):
-- Добавить столбец ALTER TABLE имя_таблицы ADD COLUMN новый_столбец ТИП_ДАННЫХ; -- Удалить столбец ALTER TABLE имя_таблицы DROP COLUMN столбец; -- Изменить тип столбца ALTER TABLE имя_таблицы ALTER COLUMN столбец TYPE НОВЫЙ_ТИП; -- Переименовать столбец ALTER TABLE имя_таблицы RENAME COLUMN старое_имя TO новое_имя;
4. Вставка данных (INSERT)
INSERT INTO имя_таблицы (столбец1, столбец2, ...)
VALUES (значение1, значение2, ...)
RETURNING *; -- вернуть вставленные данные (опционально)Пример:
INSERT INTO users (name, email, age)
VALUES ('Иван', 'ivan@example.com', 25)
RETURNING id;5. Выборка данных (SELECT)
- Простой SELECT:
SELECT * FROM имя_таблицы; - Выборка с условием (WHERE):
SELECT * FROM users WHERE age > 20; - Сортировка (ORDER BY):
SELECT * FROM users ORDER BY name ASC; -- по возрастанию (DESC — по убыванию) - Лимит выборки (LIMIT):
SELECT * FROM users LIMIT 10; -- первые 10 записей - Группировка (GROUP BY):
SELECT age, COUNT(*) FROM users GROUP BY age;
6. Обновление данных (UPDATE)
UPDATE имя_таблицы
SET столбец1 = новое_значение1, столбец2 = новое_значение2
WHERE условие
RETURNING *; -- вернуть обновленные данные (опционально)Пример:
UPDATE users SET age = 30 WHERE name = 'Иван' RETURNING *;7. Удаление данных (DELETE)
DELETE FROM имя_таблицы WHERE условие
RETURNING *; -- вернуть удаленные данные (опционально)Пример:
DELETE FROM users WHERE age < 18 RETURNING *;8. Индексы
- Создание индекса:
CREATE INDEX индекс_имя ON имя_таблицы (столбец); - Уникальный индекс:
CREATE UNIQUE INDEX индекс_имя ON имя_таблицы (столбец); - Удаление индекса:
DROP INDEX индекс_имя;
9. Связи между таблицами (JOIN)
- INNER JOIN:
SELECT * FROM таблица1 INNER JOIN таблица2 ON таблица1.столбец = таблица2.столбец; - LEFT JOIN:
SELECT * FROM таблица1 LEFT JOIN таблица2 ON таблица1.столбец = таблица2.столбец; - RIGHT JOIN:
SELECT * FROM таблица1 RIGHT JOIN таблица2 ON таблица1.столбец = таблица2.столбец;
10. Агрегатные функции
SELECT
COUNT(*) AS количество,
AVG(age) AS средний_возраст,
SUM(age) AS сумма_возрастов,
MAX(age) AS максимальный_возраст,
MIN(age) AS минимальный_возраст
FROM users;11. Транзакции
BEGIN; -- начало транзакции
-- SQL-запросы
COMMIT; -- подтвердить изменения
-- или
ROLLBACK; -- отменить изменения12. Работа с JSON
- Вставка JSON:
INSERT INTO таблица (json_data) VALUES ('{"key": "value"}'); - Выборка JSON:
SELECT json_data->>'key' FROM таблица;
13. Экспорт и импорт
- Экспорт базы (в командной строке):
pg_dump -U пользователь -d имя_базы > backup.sql - Импорт базы:
psql -U пользователь -d имя_базы < backup.sql
MySQL
Смена пароля root
mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');Еще можно вот так:
mysqladmin -u root password "newpass"1. Подключение к серверу
mysql -u пользователь -p(затем ввести пароль)
2. Основные команды
- Показать базы данных:
SHOW DATABASES; - Создать базу данных:
CREATE DATABASE имя_базы; - Удалить базу данных:
DROP DATABASE имя_базы; - Выбрать базу данных:
USE имя_базы; - Показать таблицы:
SHOW TABLES; - Создать пользователя user с паролем pass:
CREATE USER 'user'@'localhost' IDENTIFIED BY 'pass'; - Выдать привилегии пользователю на базу данных:
GRANT ALL PRIVILEGES ON `db`.* TO 'user'@'localhost'; - Обновить таблицу привилегий:
FLUSH PRIVILEGES; - Удаление пользователя user:
DROP USER 'user'@'localhost';
3. Работа с таблицами
- Создание таблицы:Пример:
CREATE TABLE имя_таблицы ( id INT AUTO_INCREMENT PRIMARY KEY, имя_столбца1 ТИП_ДАННЫХ [ограничения], имя_столбца2 ТИП_ДАННЫХ [ограничения], ... );CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE, age INT DEFAULT 18 ); - Удаление таблицы:
DROP TABLE имя_таблицы; - Очистка таблицы (без удаления):
TRUNCATE TABLE имя_таблицы; - Изменение таблицы (ALTER TABLE):
-- Добавить столбец ALTER TABLE имя_таблицы ADD COLUMN новый_столбец ТИП_ДАННЫХ; -- Удалить столбец ALTER TABLE имя_таблицы DROP COLUMN столбец; -- Изменить тип столбца ALTER TABLE имя_таблицы MODIFY COLUMN столбец НОВЫЙ_ТИП; -- Переименовать столбец ALTER TABLE имя_таблицы RENAME COLUMN старое_имя TO новое_имя;
4. Вставка данных (INSERT)
INSERT INTO имя_таблицы (столбец1, столбец2, ...)
VALUES (значение1, значение2, ...);Пример:
INSERT INTO users (name, email, age)
VALUES ('Иван', 'ivan@example.com', 25);5. Выборка данных (SELECT)
- Простой SELECT:
SELECT * FROM имя_таблицы; - Выборка с условием (WHERE):
SELECT * FROM users WHERE age > 20; - Сортировка (ORDER BY):
SELECT * FROM users ORDER BY name ASC; -- по возрастанию (DESC — по убыванию) - Лимит выборки (LIMIT):
SELECT * FROM users LIMIT 10; -- первые 10 записей - Группировка (GROUP BY):
SELECT age, COUNT(*) FROM users GROUP BY age;
6. Обновление данных (UPDATE)
UPDATE имя_таблицы
SET столбец1 = новое_значение1, столбец2 = новое_значение2
WHERE условие;Пример:
UPDATE users SET age = 30 WHERE name = 'Иван';7. Удаление данных (DELETE)
DELETE FROM имя_таблицы WHERE условие;Пример:
DELETE FROM users WHERE age < 18;8. Индексы
- Создание индекса:
CREATE INDEX индекс_имя ON имя_таблицы (столбец); - Удаление индекса:
DROP INDEX индекс_имя ON имя_таблицы;
9. Связи между таблицами (JOIN)
- INNER JOIN:
SELECT * FROM таблица1 INNER JOIN таблица2 ON таблица1.столбец = таблица2.столбец; - LEFT JOIN:
SELECT * FROM таблица1 LEFT JOIN таблица2 ON таблица1.столбец = таблица2.столбец; - RIGHT JOIN:
SELECT * FROM таблица1 RIGHT JOIN таблица2 ON таблица1.столбец = таблица2.столбец;
10. Агрегатные функции
SELECT
COUNT(*) AS количество,
AVG(age) AS средний_возраст,
SUM(age) AS сумма_возрастов,
MAX(age) AS максимальный_возраст,
MIN(age) AS минимальный_возраст
FROM users;11. Транзакции
START TRANSACTION;
-- SQL-запросы
COMMIT; -- подтвердить изменения
-- или
ROLLBACK; -- отменить изменения12. Экспорт и импорт
- Экспорт базы (в командной строке):
mysqldump -u пользователь -p имя_базы > backup.sql - Импорт базы:
mysql -u пользователь -p имя_базы < backup.sql