Простыми словами о веб-разработке.

Эгея | Основы веба | Как стать веб-разработчиком
Docker | Веб-сервер | PHP | Базы данных

Позднее Ctrl + ↑

Как работает веб, или что происходит, когда вы сёрфите в интернете

Каждый раз, когда вы открываете на компьютере или телефоне google.com, ваш браузер незаметно для вас отправляет множество запросов в интернет. Что это за запросы? Кто на них отвечает? Где хранятся страницы социальных сетей и статьи медиа-проектов?

Браузер и веб-сервер

Для базового понимания работы веба можно провести аналогию с телевидением.

Браузеры — Google Chrome, Firefox, Safari, Internet Explorer / Edge — это всего лишь экраны телевизоров, которые показывают программу, записанную и транслируемую откуда-то из далёких телестудий. В вебе такие студии называются веб-серверами.

Вбивая новый адрес в браузере, вы переключаете канал. Только в отличие от телевидения в интернете этих каналов огромное количество, вы даже можете создать свой, настроив собственный веб-сервер.

У каждого веб-сервера подобно телеканалу есть свой номер, который называется IP. Чаще всего он выглядит как четыре группы трёхзначных чисел, разделённых точкой — XXX.XXX.XXX.XXX, но может выглядеть иначе — см. IPv6.

Например, Вконтакте имеет IP 87.240.137.158, Facebook — 31.13.72.36, данный блог — 5.63.155.79.

Чтобы нам не пришлось запоминать адреса в виде 87.240.137.158 для посещения контакта, были придуманы доменные имена — это как раз тот понятный и лёгкий для запоминания адрес, что мы вбиваем в браузере: vk.com, facebook.com, maxkuznetsov.ru.

Поскольку таких пар «IP — домен» по всему интернету огромное количество, то браузер не может все их знать и поэтому он обращается за помощью к DNS-серверу, который работает как адресная книга — по домену выдаёт IP, на который нужно слать запросы, и перенаправляет запрос на нужный веб-сервер в интернете.

Получив запрос от браузера, веб-сервер отправляет в ответ запрошенную веб-страницу или ошибку, если что-то пошло не так.

Если такой страницы не существует, браузер покажет ошибку.

Из чего состоит веб-страница

Веб-страница — это то, что вы видите в браузере. Она представляет собой HTML — обычный текст, но помещённый в специальные символы — «теги», подсказывающие браузеру, где заголовки и списки, а где картинки, формы для пользовательского ввода и, конечно же, ссылки на другие страницы. Ссылки — они же гипертекс — в своё время и сделали веб таким удобным и популярным.

Вы можете посмотреть из чего состоит любая веб-страница, кликнув по ней в браузере правой кнопкой мыши и выбрав пункт View Page Source / Посмотреть исходную страницу или что-то аналогичное в зависимости от браузера и языка интерфейса. Скорее всего вы ничего не поймёте, так как помимо HTML-разметки современные веб-страницы включают в себя кучу CSS и Javascript. Первая технология позволяет создавать красивый вид страниц (дизайн), а вторая — анимировать их и расширять функционал: всплывающие окна, проигрыватели аудио и видео, слайдеры, счётчики, метрики, обработка картинок, анимированная галерея фотографий и много чего ещё.

Кратко:
HTML — это разметка статического контента, задание его структуры
CSS — наведение красоты, включая простую анимацию
Javascript — более сложная анимация и дополнительный функционал поверх контента

Вы можете создавать свои веб-страницы прямо у себя на компьютере. Но чтобы другие люди их увидели, вам нужен веб-сервер, доступный через интернет. Попробуйте создать на своём компьютере файл index.html (скачать готовый пример), внутри которого написать

<h1>Hello world!</h1>
<ol>
  <li>Это мой первый</li>
  <li>Сайт</li>
</ol>
<button>Супер!</button>

Сохраните и перетащите файл прямо в браузер — вы увидите ваш первый, хоть и не публичный, сайт.

Статические и динамические страницы

Все веб-страницы можно условно разделить на два вида — статичные и динамичные.

  • Статичные — это уже готовый HTML, CSS, Javascript, который веб-сервер сразу же отдаёт по запросу браузера. Пример с index.html выше является статичной страницей. Её контент зафиксирован и будет отображаться одинаково для всех браузеров.
  • Динамичные (и их сейчас большинство) страницы можно представить себе как шаблоны итоговых страниц, но с вкраплениями серверного кода. Такой код при выполнении может проверять авторизован пользователь или нет, обращаться к базе данных или сторонним сервисам (например, за курсом валют) и даже полностью менять содержимое страницы, но в конечном итоге он всё равно превращается в HTML, CSS и Javascript, которые веб-сервер отдаёт браузеру.

Так, разные пользователи видят страницу https://youtube.com по-разному. Красным выделены те блоки, что «вставляются» серверным кодом, остальная часть страницы имеет одинаковый вид для всех пользователей.
Серверный код определяет вас по логину и выстраивает контент из ваших предпочтений. При этом шаблон страницы один для всех, что очень удобно, например, при редизайне — можно менять представление сайта без изменения самого контента. Это довольно важный принцип в программировании — разделять логику, данные и их визуальное представление.

Браузеру вся эта кухня не видна, он лишь делает запрос и получает в ответ HTML, CSS и Javascript. Каждый клик по ссылке или отправка формы делает новый запрос на веб-сервер, который начинает весь процесс заново.

Чтобы посмотреть на запросы, которые отправляет ваш браузер и что он получает в ответ, можно воспользоваться инструментом инспекции кода в браузере. Правый клик в любом месте страницы, выберите пункт «Inspect / Инспектировать элемент» или подобный, а потом перейдите в таб «Netword / Сеть». Перезагрузите страницу и вы увидите, как браузер общается с веб-сервером (или даже несколькими).

См. также:
HTTP: как браузеры и веб-сервера понимают друг друга
— Как поднять свой веб-сервер на NGINX

Как получить бесплатный SSL-сертификат и установить его на Nginx

Иметь сайт без HTTPS — это небезопасно. Особенно критично для интернет-магазинов и сервисов, где пользователь оставляет свои данные.

HTTPS — это защищённый брат HTTP (см. статью Что такое HTTP), который шифрует все пересылаемые от браузера к серверу и обратно данные. Для такого шифрования необходим SSL-сертификат, который позволяет убедиться пользователю, что он видит страницы именно того сайта, на  который он зашёл. Сертификаты бывают разного вида и стоимости в зависимости от уровня проверки владельца сайта, но при этом суть остаётся та же — шифрование пользовательских данных.

SSL-сертификат нужно получить в центрах сертификации (ЦС). Часто регистраторы доменов и провайдеры хостинга партнёрятся с такими центрами и облегачают задачу выпуска и установки сертификата на ваш сайт.

За выпуск сертификата ЦС берут плату, ведь им нужно по крайней мере удостовериться, что вы действительно владеете доменом, на который запрашиваете сертификат. У них такой бизнес. Можно выпустить и свой самоподписанный сертификат бесплатно, но браузеры не смогут ему доверять (ведь они не смогут уточнить его оригинальность у независимого ЦС) и  будут показывать предупреждение.

Как получить SSL-сертификат бесплатно

К счастью, есть ЦС, который выпускает SSL-сертификаты бесплатно, — это LetsEncrypt. Они это делают во имя благой цели — безопасного интернета во всём мире. Такой сертификат подойдёт для большинства небольших сайтов и сервисов, но среднему и крупном бизнесу — нет. Им нужны сертификаты с частичной или полной проверкой компании.

LetsEncrypt позволяет вам выпустить сертификат множеством способов для разных операционных систем, веб-серверов, языков программирования. Cам центр сертификации крайне рекомендует использовать Certbot.

Пример установки сертификатов с помощью Certbot на Ubuntu

Предположим, у нас есть сайты yoursite.ru и yourblog.ru, работающие по HTTP через Nginx. Добавим для них сертификаты и перейдём на HTTPS.

Заходим на сайт Certbot’a и выбираем Nginx и Ubuntu.

Добавляем ppa для установки certbot на нашем сервере, обновляем зависимости и устанавливаем саму утилиту.

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot

# крайне важно выполнить эту команду, иначе следующая команда выдаст ошибку о незнакомом пакете.
$ sudo apt-get update

# Устанавливаем сам certbot
$ sudo apt-get install certbot python-certbot-nginx

Запускаем certbot и проходим через визард, отвечая на простые вопросы.

$ certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: yourblog.ru
2: yoursite.ru
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

Указываем через запятую или пробел номера сайтов из списка, для которых хотим выпустить сертификат, — в нашем случае «1,2» — жмём enter.

Obtaining a new certificate
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/yourblog.ru
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/yoursite.ru

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Certbot настолько заботлив, что предлагает настроить принудительный редирект HTTP->HTTPS за нас. Соглашаемся, введя «2».

Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/yourblog.ru
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/yoursite.ru

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://yourblog.ru and
https://yoursite.ru

Обновление letsencrypt-сертификата

Нужно иметь в виду, что такой SSL-сертификат действителен только на 30 дней и через месяц его нужно обновить, снова подтвердив свои данные.

Но сюрприз! Certbot уже добавил регулярную задачу в systemd или cron и обновит сертификат сам, нам ничего больше делать не нужно.

—-
Для других систем и веб-серверов установка будет слегка отличаться, поэтому обратитесь к официальному сайту certbot’a.

Эгея. Как добавить Яндекс Метрику и Гугл Аналитику

Чтобы добавить метрики в блог,

  1. создайте файл head-extras.tmpl.php;
  2. добавьте в него код обеих метрик, который можно получить в админках Yandex и Google;
  3. залейте файл на сервер с блогом в папку /путь/до/блога/user/extras.

Это специальная папка для добавочных шаблонов, которая сохранится даже при обновлении движка.

Эгея. Редирект с http на https в Nginx

Предположим, вы хотите, чтобы блог http://blog.ru всегда открывался как https://blog.ru.

  1. Заливаем на сервер в папку /etc/ssl сертификат и ключ, которые вам предоставил регистратор SSL-сертификата:
    /etc/ssl/blog.ru.crt
    /etc/ssl/blog.ru.key
  2. Редактируем файл конфига вашего блога /etc/nginx/sites-enabled/blog.ru
    # Включаем редирект http на https
    server {
        listen 80;
    
        server_name blog.ru www.blog.ru;
        return 301 https://blog.ru$request_uri;
    }
    # Настраиваем обработку HTTPS
    server {
      listen 443 ssl;
      ssl_certificate /etc/ssl/blog.ru.crt;
      ssl_certificate_key /etc/ssl/blog.ru.key;
      server_name blog.ru www.blog.ru;
      ... 
      # остальные конфиги сервера, которые были в разделе HTTP
    }
  3. Перезагружаем nginx в консоли сервера:
    $ nginx -s reload
  4. Заходим на https://blog.ru/@sync/ для чистки кэша. Без этого браузер будет по https://blog.ru показывать статус «No secure».

Базы данных, транзакции и ACID

Транзакция — набор команд, которые должны быть выполнены одной пачкой, так как представляют собой одну бизнес операцию.

Пример: транзакция по переводу денег состоит из команд «списать деньги с отправителя», «начислисть деньги адресату».

ACID — это требования к транзакциям и системам, работающим с ними (например, базам данных). ACID требует, чтобы каждая транзакция

  • не зависала в середине пути в случае ошибки, а откатывала все сделанные изменения (атомарность),
  • после своего завершения не оставляла данные неконсистентными (консистентность),
  • не влияла на другие транзакции (на самом деле влияла, но как можно меньше — 4 уровня изолированности),
  • а вся система гарантировала, что выполненные транзакции будут запомнены системой даже при возникновении аварий и форс-мажоров (стойкость, durability).


Подробнее о каждом требовании и с примерами

  1. Atomicity/Атомарность требует, чтобы либо все команды транзакции были выполнены, либо ни одной. То есть транзакция должна действовать как единая атомарная команда.

    На практике атомарность реализуется через версионирование и откаты (rollback) команд транзакции до первоначального состояния базы. Строго говоря, индексы могут обратно не откатиться, но чаще всего СУБД это разруливают сами.
  2. Сonsistency/Консистентность требует, чтобы после завершения транзакции данные оставались консистентными и валидными, т. е. чтобы они не имели логических или технических противоречий.

    Пример: суммарный баланс счетов должен оставаться неизменным (логическая К.), запись одной таблицы не должна ссылаться на удалённый айдишник другой записи (техническая К.).
  3. Isolation/Изолированность — при параллельном выполнении транзакции не должны влиять друг на друга.

    Пример: если два человека одновременно делают денежный перевод третьему, то одна транзакция в теории может перезаписать значения другой, и деньги потеряются. Изолированность исключает такую ситуацию.

  4. Durability/Стойкость — если транзакция завершена успешно, то она не может быть отменена даже при авариях, внезапном отключении света в датацентре и проблем в сети. В этом случае база данных должна сама восстановить последние транзакции.

Уровни изолированности в базах данных

На практике изолированность сложна в реализации и сильно влияет на производительность системы. Поэтому базы данных могут работать с четырьмя уровнями изолированности (от меньшей надёжности к большей).

  1. Read uncommitted — позволяет избежать «потерянных обновлений», когда две транзакции обновляют одно и то же значение/строку.

    На этом уровне UPDATE-транзакции резервируют данные для себя и блокируют для других UPDATE-транзакций. Тем не менее, SELECT-запросы не блокируются и даже могут считать промежуточное состояние данных, возникающие между выполнением команд одной транзакции.

    Пример: транзакция на перевод денег состоит из команды на списание денег с одного счёта и команды пополнения другого счёта. На момент изменения баланса счёта первой транзакцией вторая подобная транзакция встанет в очередь, пока данные не освободятся. Но SELECT-запрос может считать состояние, когда деньги списаны с одного счёта, но на второй ещё не зачислены.

  2. Read committed — то же, что выше + решает проблему чтения «грязных» состояний незавершённых транзакций. Большинство баз данных по умолчанию работает на этом уровне изолированности.

    Однако если транзакция содержит две SELECT-команды и во время между ними другая UPDATE-транзакция успешно завершится, то результат этих SELECT-запросов может отличваться: один вернёт состояние до UPDATE-транзакции, второй — после. Важно, что это не «грязное» состояние, а чистое, после успешной транзакции.

  3. Repeatable read (повторяемость чтения) — оба пункта выше + гарантирует, что SELECT-запросы в рамках одной транзакции всегда будут возвращать один и тот же результат, даже если другие транзакции обновляют или удаляют эти же данные.

    Транзакция блокирует все строки, затрагиваемые её командами, включая SELECT, а другие транзакции с SELECT-, UPDATE- и DELETE-запросами к этим данным ждут её завершения. Естественно, это сильно снижает скорость обработки транзакций базой данных.

  4. Serializable — три пункта выше + исключает «фантомные чтения».

    «Фантомное чтение» похоже на проблему с двумя последовательными SELECT-запросами одной транзакции, но возникает, когда между SELECT-запросами была выполнена именно вставка (INSERT). Пример: аггрегационные запросы SELECT SUM(), SELECT COUNT().

    Это максимальный уровень изолированности. При нём транзакции выполняются так, будто других параллельных транзакций не существует.

  5.  



Принципы работы docker и примеры использования docker-compose

Артём Матяшов записал отличный полуторачасовой урок про основы докера. Можно посмотреть на x1.5 за час.

Подойдёт начинающим бэкендерам, а также фронтендерам, верстальщикам и всем, кому нужно развернуть проект на один раз и удалить без захламления системы.

Однозначно лайк!

Как улучшить терминал в Mac OS X: iTerm2, omyzsh, zsh

Отличная статья про апгрейд встроенного Terminal
https://medium.com/@Clovis_app/configuration-of-a-beautiful-efficient-terminal-and-prompt-on-osx-in-7-minutes-827c29391961

Краткий план действий

  1. Ставим iTerm2 на замену Terminal. Они нормально сосуществуют и можно будет откатиться, если не понравится.
brew cask install iterm2
  1. Ставим цветовую cхему для iTerm2 (сохраняйте именно как .itermcolors) — это набор цветов и ничего больше. На данном этапе терминал всё ещё будет выглядеть уныло.
  2. Качаем шрифт с поддержкой дополнительных символов-иконок: обычный или жирный (он контрастнее) — и устанавливаем в систему. Иначе увидим не иконки, а пустые квадратики.
    Меняем размер шрифта на 12-14pt или какой удобнее.
  3. Через консоль iTerm’a устанавливаем Zsh (вместо стандартного Bash) и Oh my Zsh — само ядро командной строки и оболочку с форматированием вокруг неё.
# Возможно, zsh у вас уже есть по умолчанию. Чтобы проверить, нужно ввести : 
which zsh
# Если вернёт путь, значит есть. Если нет, то ставим:
brew install zsh zsh-completions
# Устанавливаем Oh my Zsh
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
  1. Важно: теперь основной конфигурационный файл консоли — ~/.zshrc, а не ~/.bashrc или ~/.bash_profile.
  2. Скачиваем в дефолтную директорию тему — самую маковку, которая добавит красоты в терминал
git clone https://github.com/bhilburn/powerlevel9k.git ~/.oh-my-zsh/custom/themes/powerlevel9k
# Редактируем ~/.zshrc и меняем конфиг
ZSH_THEME="powerlevel9k/powerlevel9k"
  1. Перезагружаем iTerm и вуаля.

Улучшение вида и поведения терминала

  1. Вид самой строки
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir rbenv vcs)
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs history time)
POWERLEVEL9K_VCS_MODIFIED_BACKGROUND='red' # Будет менять цвет, если есть обновления в гит-репозитории
  1. Я не стал делать перенос строки (POWERLEVEL9K_PROMPT_ON_NEWLINE=true), так как у меня терминал всегда на всю ширину экрана и места хватает.
  2. Обязательно: iTerm → Preferences → Profiles → Keys → Load Preset… → Natural Text Editing, чтобы работала навигация через Option + стрелки и прочее.
  3. Можно добавить автодополнение команд на основе истории
git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions
vim ~/.zshrc
# Внутри файла добавляем через пробел название плагина
plugins=(… zsh-autosuggestions)
  1. Включаем автозагрузку ssh-ключей при старте терминала:
    https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/ssh-agent
vim ~/.zshrc
# Внутри файла добавляем через пробел название плагина
plugins=(… ssh-agent)
# Сразу ниже включаем ssh-agent и указываем ключи через пробел — у меня их два
zstyle :omz:plugins:ssh-agent agent-forwarding on
zstyle :omz:plugins:ssh-agent identities id_rsa id_rsa2
# Эта строка у вас уже будет, главное команды выше поместить до этой строки с source
source $ZSH/oh-my-zsh.sh
  1. Перезагружаем iTerm. Уже всё готово!
  2. Опционально: после всех правок IDE, которые содержат встроенный терминал, могут выглядеть слегка кривовато. Нужно им помочь с определением шрифта. Например, в VS Code в настройках меняем параметры:
"terminal.integrated.fontFamily": "Meslo LG M for Powerline"
"terminal.integrated.fontSize": 12

Как ускорить docker-compose на Mac OS X — docker-sync

Хорошая статья про настройку docker-sync — короче и ёмче, чем в официальной документации:
https://dev.to/kovah/cut-your-docker-for-mac-response-times-in-half-with-docker-sync-1e8j

1. Установка через терминал


gem install --user-install docker-sync
# or globally via
sudo gem install docker-sync

2. Добавить файл docker-sync.yml в корень проекта (пример для Symfony)


version: "2"

options:
    compose-dev-file-path: 'docker-compose-sync.yml' # Если хочется изменить дефолтный файл docker-compose-dev.yml
syncs:
    PROJECT-data-sync:  # Это надо заменить на любое уникальное имя
        src: './'
        host_disk_mount_mode: 'cached'
        sync_excludes:
            - '.git'
            - '.idea'
            - 'app/cache/*'
            - 'app/logs/*'

3. Добавить файл docker-compose-sync.yml (или *-dev.yml по умолчанию) в корень проекта:


version: '3.2'

services:
    web:
        volumes:
            - ./composer.json:/var/www/html/composer.json
            - ./composer.lock:/var/www/html/composer.lock
            - PROJECT-data-sync:/var/www/html:nocopy

volumes:
    PROJECT-data-sync:
        external: true

4. Запускаем в терминале в корне проекта


docker-sync start
# нужно подождать, пока всё синхронизируется
docker-compose -f docker-compose.yml -f docker-compose-sync.yml up -d

Запуск через docker-sync-stack start делает две команды выше, но остаётся висеть в консоли, а не уходит в фоновые процессы.

Чтобы остановить, делаем ровно обратное


docker-compose stop
docker-sync stop

Ранее Ctrl + ↓