Как я делал свой блог

Информационная часть

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

Подготовительная часть

Для того, чтобы мой блог функционировал, нам нужна виртуальная машина. Белый IP-адрес у меня имеется на роутере Mikrotik. Внутри виртуальной машины поднимаем docker и создаем docker-контейнер с nginx, передаем ему статическую страницу, делаем проброс, покупаем домен, получаем ssl-сертификат. Приступаем.

Поднятие инфраструктуры

Создание виртуальной машины

Для начала я создам виртуальную машину на своей системе виртуализации Proxmox. ВМ будет на базе Ubuntu 24.04. На Mikrotik у меня DHCP-сервер и он смотрит в сервер. ВМ находятся в бридже с Proxmox, то есть, все ВМ машины у меня получают IP-адрес от Mikrotik. Особых настроек ВМ я не производил. Поэтому выкладывать процесс я не буду. Наша задача просто создать базовую ВМ. Это я сделал. Далее нужно установить Docker на хостовую машину (наша ВМ).

Установка docker

Заходим на официальный сайт в раздел установки. Просто вводим команды для установки. Готово.

Конфигурация nginx

Предварительно настроим файл nginx.conf. Так как мы будем пользоваться docker, то нам предстоит скопировать файл конфигурации в контейнер. Поэтому создаем файл конфигурации типа: real-devops.conf. Вводим следующую конфигурацию:

server {
        listen 80;
        server_name localhost;

        location / {
            root /usr/share/nginx/html;
            index index.html;
        }
}
Здесь мы указываем конфигурацию сервера. Говорим, чтобы он внимательно слушал 80 порт, доменное имя (при наличии). Далее говорим: если обращение идет на корень, то есть либо просто на ip-адрес или доменное имя, то открыть index.html из папки по пути /urs/share/nginx/html С этим разобрались. Двигаемся дальше. И вот на этом моменте нужно было остановиться и задуматься: "а у меня все правильно настроено? Работает ли оно так, как я задумал?" Я не задумался. Но позже вывод сделал.

Конфигурация docker

Следующим шагом я решил создать Dockerfile для того, чтобы вручную не прописывать каждый раз при создании контейнера одни и те же настройки: Dockerfile

FROM nginx:alpine
COPY real-devops.conf /etc/nginx/conf.d/
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
Так, что у вас тут происходит?! Берем image (образ) nginx версии alpine с DockerHub. Затем копируем файл конфигурации в директории ДОПОЛНЯЮЩИХ конфигурационных файлов nginx. Также копируем наш index.html в директорию, где хранятся статические страницы nginx. Ну и открываем на контейнере 80 порт. После этого мы создаем свой image по Dockerfile. То есть мы создаем образ нашего будущего контейнера. Мы сложили туда все, что нужно, а затем создали прародителя наших будущих контейнеров.
docker build -t real-devops-nginx .
Указываем флаг -t для добавления тега real-devops-nginx к нашему образу и директорию, куда он сохранится. Я выбрал текущую, так как по умолчанию нахожусь в папке проекта. Запустим наш контейнер:
docker run -d -p 8080:80 --name real-devops-nginx real-devops-nginx
Здесь мы запускаем контейнер как демона, то есть он не заберёт у нас возможность ввода и будет работать в фоне. Пробрасываем порты с виртуальной машины на 80 порт контейнера. Задаем имя контейнеру для удобной манипуляции с ним. А также указываем наш образ контейнера. Дальше нужно проверить успешно ли запустился контейнер.
docker ps docker logs real-devops-nginx

Настройка сети

После того, как контейнер заработал, все в порядке, сайт открывается по локальному IP-адресу, нужно сделать так, чтобы Вы, читатели, могли увидеть мой сайт со своего мобильного интернета, то есть сделать доступ к сайту по белому (публичному) адресу. Заходим на Mikrotik, пробрасываем порт.

add action=dst-nat chain=dstnat dst-address=95.172.56.27 dst-port=80 \
protocol=tcp to-addresses=192.168.44.105 to-ports=8080
Все, порт проброшен. Пробуем зайти на сайт по белому IP-адресу. Скриншотов не будет) Дело в том, что я пишу это после своих попыток. Покупка и настройка домена Далее я решил, что заходить по домену будет красивее и удобнее. На рег.ру купил домен real-devops.ru. Затем настроил A-запись, то есть привязал real-devops.ru и www.real-devops.ru к IP-адресу 95.172.56.27. Готово. Через несколько часов по всему интернету пробежалась информация и мой IP-адрес начал пинговаться через доменное имя. Но это еще не все. На данный момент, мой nginx не знает, о том, что у меня появилось доменное имя. Надо ему об этом сказать. Меняем файл конфигурации моего nginx - real-devops.conf:
server {
    listen 80;
    server_name real-devops.ru www.real-devops.ru; # меняем здесь localhost на наш домен

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}
Теперь все работает исправно (на первый взгляд :) )

SSL-сертификат

А вот здесь и начинается самое интересное. Казалось бы, просто устанавливаем бота, указываем домены и все должно работать, получаем заветную s в протоколе http. Но нет. Проверку не проходит вообще ни в какую. Просто выдает 404 ошибку. То есть он бот не может получить файл, который он создал по адресу http://real-devops.ru/.well-khown/acme-challenge/adsdkwqfwk342fmsf234fdsf2hjhgt434 При этом, если я создаю тестовый файл, например test по адресу: http://real-devops.ry/.well-khown/acme-challange/test, то я могу скачать это файл, а бот не может. Я изломал всю голову, подключил ChatGPT, DeepSeek к решению этого вопроса. Ничего не помогло. Проверили конфиг nginx, правильность путей, доступность домена. Ничего не помогало.

Провал

И вот, я пришел в тупик. В чем была проблема? Конкретно - не знаю. Глобально - в моем желании сделать всё и сразу. Если бы я начал с простого, то знал бы, где и на каком этапе проблема. Что происходит внутри контейнера? Надо заходить, смотреть логи, подключаться к нему. Это очень затруднительно. Поэтому я решил удалить эту виртуальную машину и провести декомпозицию.

Декомпозиция

Я решил, что нужно идти от простого к сложному. Сначала поднять обычный nginx без docker и вдумчиво его настроить. Это даст мне понимание, что если что-то не работает, то проблема в nginx, а не в неправильно настроенном docker.

Всё делаем правильно

На этом этапе я снова создал виртуальную машину для nginx. Посмотрел видео, почитал статьи о том, как выполнить базовую конфигурацию nginx. Оказалось, что не все так просто. Если делать по документации на официальном сайте nginx, то файл nginx.conf у них один, а у меня другой. Совершенно другой. У меня нет директивы server. Я пробежался по всем дополняющим конфигам - ничего. Создал сам директиву, прописал настройки. И сервис nginx не запустился. Выдавал ошибку конфигурации и на конфликт директивы, которая использовалась непонятно для чего. Я решил, что не буду пинать труп, а сделаю все нормально. Откатил файл конфигурации к состоянию по умолчанию, открыл видео и знаете что? На видео вообще другая конфигурация. Почему так вышло? Если брать репозиторий с официального сайта nginx, то там один файл конфига. А вот если скачать с базовых репозиториев ubuntu, то nginx устанавливается именно с таким конфигом, как на видео. Стало спокойнее. Далее все шло как по маслу. И вот на этом этапе я наконец разобрался с файлами конфигурации nginx. Если добавлять их в /etc/nginx/sites-available/название_сайта, то конфиг работает как нужно. Но не совсем. В видео все работало, а у меня нет. Я проверил конфиг, вроде все в норме. С помощью chatGPT я выяснил, что конфиг подхватывается ТОЛЬКО если он есть в /etc/nginx/sites-enabled/, а именно если есть симлинк. После создания симлинка все завелось и работало исправно. Наконец-то. Следующим шагом я установил certbot для получения SSL-сертификата.

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d real-devops.ru -d www.real-devops.ru
Теперь все должно было пройти без проблем, так как я уже настроил Nginx без Docker и проверил его работу.

Вывод

Проблема была в том, что я пытался сразу запустить все в контейнере, не разобравшись, как работает сам Nginx. После ручной настройки на хосте стало ясно, какие файлы нужны, как они подключаются и где могла быть ошибка. Теперь, когда Nginx работает корректно, можно вернуться к контейнеризации, но уже с четким пониманием, какие конфигурации нужны и как их правильно настроить. Таким образом, я полностью своими силами сделал хостинг своего же сайта. Всё на этом сайте реализовано мной. Это позволяет понять то, как изнутри работает хостинг. Далее я буду усложнять свой проект. Frontend, backend и DevOps-практики добавят сайту увесистости. Все изменения вы можете наблюдать в этой статье. Она будет обновляться по мере моего развития и работы над этим сайтом.

Вернуться