Привет, Хабр! Сегодня я хочу поделится с вами как я перестал быть "сапожником без сапог".

P.S. Я не буду рассказывать как поднять прокси сервер, запустить продакшен приложения и т. д. Этот пост про то как поднять простой сайт

Обо всём по порядку!

Домашний сервер

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

P.S. Потом выпущу отдельную статью с инструкцией как я настроил свой сервер: белый IP, открыл порты, накатил Linux и т. д.

Сам сайт

Я планировал сделать фронт, бек, всё как полагается, но руки чесались быстрее запустить свой продукт (мечты были ещё с детства, но никак не хватало времени на реализацию), я решил не заморачиваться и сделать сначала простую версию используя HTML и CSS, т. к. из-за малого кол-ва технологий не разгуляться, то было принято решение сделать небольшой сайт-резюме.

Нам понадобится:

  1. Домашний или арендованный сервер с Ubuntu

  2. Домен

  3. Docker

  4. Nginx

  5. Certbot

  6. Статический контент(HTML, CSS, JS, и т. д.)

Добавлю, что необходимы навыки работы с Linux: подключение по SSH, обновление репозиториев и пакетов, установка утилит, но я введу вас в курс дела ниже, о том что нам нужно, как установить и как пользоваться. Если что-то будет не понятно - пишите комментарии вам помогу я или другие комментаторы, а так же гуглите, если не нашли ответ.

Реализация

Я предполагаю, что вы уже арендовали сервер, оплатили домен, привязали его к IP и готовы к следующем шагам.

Обновление пакетов Linux

Сначала нам нужно зайти по SSH на сервер. Я использую Terminal в Windows 11, оболочка Git Bash.

ssh <логин>@<ip_адрес_сервера>
<логин>@<ip_адрес_сервера's password: *пароль_от_сервера*

Во время первого соединения система вас спросит, что хотите ли вы продолжить своё подключение по новому отпечатку ключа, то есть, говоря простыми словами - подключение к новому хосту, вам нужно подтвердить, чтобы продолжить (Рисунок 1).

Рисунок 1.
Рисунок 1.

Когда вы войдёте на сервер вы увидите, подобное приветственное окно (Рисунок 2).

Рисунок 2.
Рисунок 2.

Нам надо обновить пакеты Linux, вводим 2 команды.

sudo apt update
sudo apt upgrade

Вам нужно подтвердить, чтобы продолжить (Рисунок 3).

Рисунок 3.
Рисунок 3.

Установка Docker

Требования к Ubuntu

  • Ubuntu Oracular 24.10

  • Ubuntu Noble 24.04 (LTS)

  • Ubuntu Jammy 22.04 (LTS)

Установка через apt репозиторий.

# Добавляем GPG ключ Docker'а:
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Добавляем репозиторий в источники Apt:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

Устанавливаем последнюю версию Docker.

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Проверяем, что Docker установлен.

sudo docker run hello-world

С серверов закончили, теперь перейдём к самому проекту.

Структура проекта

your-project/
├── docker-compose.yml
├── nginx/
│   └── conf.d/
│       └── default.conf   # Nginx конфиг
├── static-files/          # Статический контент
│   ├── index.html
│   └── style.css
└── certbot/               # Certbot сертификаты
    ├── conf/
    └── www/

После того как вы написали разметку для вашего сайта, вы должны её поместить в директорию static-files.

Директория certbot имеет пустые директории conf и www. Let's Encrypt сам наполнит certbot как ему нужно для проверки и создания SSL, ничего самостоятельно помещать туда не нужно.

Конфигурируем Nginx

Перед тем как запустить Nginx на 443 порту с SSL сертификатом, нужно чтобы Let's Encrypt проверил сервер на 80 порте без сертификата и выпустил его новым для вашего домена.

Вставьте данный код в файл default.conf.

server {
    listen 80;
    server_name ваш_домен;

    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}

Конфигурируем docker-compose.yml

В коде ниже мы создаём связанные сервисы, состоящие из двух отдельных, они будут работать и запускаться вместе, а именно сервис Nginx и сервис Certbot.

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80    # HTTP (для валидации Certbot)
      - 443:443  # HTTPS
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d          # Nginx конфиг
      - ./static-files:/usr/share/nginx/html      # Добавляем статические файлы в nginx в Docker'е
      - ./certbot/www:/var/www/certbot            # Certbot HTTP challenge
      - ./certbot/conf:/etc/letsencrypt           # SSL certificates
    restart: unless-stopped

  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    command: certonly --webroot -w /var/www/certbot --force-renewal --email ваша_почта --agree-tos -d ваш_домен
    restart: unless-stopped

Обратите внимание на command(19 строка) в сервисе certbot, эта команда отвечает за запуск челленджей, вам нужно поменять переменные на свои.

Деплой на сервер

На данном этапе нам нужно перенести наш проект на сервер, это вы можете сделать через такие программы как FileZilla Client, WinSCP и др. или через терминал. Если вы не знаете как это сделать, ниже я объясню на примере FileZilla Client.

Для начала её нужно скачать с официального сайта и установить.

Чтобы осуществить подключение к серверу нужно ввести данные.

  • Хост - sftp://ваш_ip_сервера

  • Имя пользователя - root

  • Пароль - ваш пароль от сервера

  • Порт - ничего вводить не нужно, он по умолчанию уже есть

Рисунок 4.
Рисунок 4.

Нажмите кнопку быстрое соединение. Если вы успешно подключились - вы увидите слева директории с файлами на вашем ПК, а справа сервера, если нет, попробуйте повторить шаги заново. Совсем не получается? Пишите вопросы в комментарии.

Перенесите файлы проекта с вашего ПК на сервер, лучше перенести директорию в которой лежит проект или создать новую на сервере с названием вашего проекта и перенести туда файлы.

Теперь когда вы успешно перенесли проект на сервер открывайте терминал на вашем ПК и подключайтесь по SSH к серверу и следуйте шагам далее.

После входа на сервер нужно написать команду ниже, чтобы перейти в директорию с вашим проектом.

cd название_директории

Отлично, переходим к работе с Docker и Docker Compose!

Для генерации SSL нужно просто запустить в Docker Compose наши сервисы командой ниже.

sudo docker compose up

Вы увидите запуск Nginx, затем запуск челленджей от Let's Encrypt через Certbot. В случае успешного прохождения челленджей у вас появится сертификат в директории расположенной в volumes, которую вы указали для Let's Encrypt.

Рисунок 5.
Рисунок 5.

Запуск Nginx на 443 порте с SSL сертификатом

Мы имеем на текущем этапе.

  • Готовый Dcoker Compose

  • Сгенерированный SSL

  • Настроенный Nginx на получение сертификата и перенаправление на 443 порт

Нам не хватает обработки 443 порта в Nginx и чтобы ваш сайт работал. Давайте добавим в конфигурацию Nginx прослушивание и обработку 443 порта и выдачу статического контента, который уже лежит в volumes в Docker на сервере.

Откройте конфигурационный файл Nginx - default.conf на вашем ПК и внесите код ниже.

server {
    listen 443 ssl;
    server_name ваш_домен;
    ssl_certificate /etc/letsencrypt/live/ваш_домен/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ваш_домен/privkey.pem;
    root /usr/share/nginx/html;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

У вас должен получится файл default.conf с таким кодом.

server {
    listen 80;
    server_name ваш_домен;

    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name ваш_домен;
    ssl_certificate /etc/letsencrypt/live/ваш_домен/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ваш_домен/privkey.pem;
    root /usr/share/nginx/html;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

Заливаем обновлённый конфигурационный файл на сервер в ту же директорию где хранится старая версия.

Заходим на сервер по SSH переходим в директорию проекта и пишем команду ниже.

sudo docker compose up -d

Отлично! Теперь ваш сайт должен быть доступен из интернета по домену, который вы указали.

Но есть маленькая проблемка, т. к. у вас постоянно запущен сервис certbot он будет пытаться получать новый SSL, рекомендую его отключить командой ниже. Чтобы команда работала вам нужно находится в директории проекта.

sudo docker compose stop certbot

В следующей статье расскажу, как можно сделать авто-обновление SSL.

Подсказки

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

  • Проверка логов сервисов для выявления ошибок.

sudo docker compose logs nginx
sudo docker compose logs certbot
  • Проверка доступности вашего сайте

curl -I http://localhost
curl -I http://yourip
curl -I http://yourdomain.com
curl -I https://yourdomain.com

P.S. Проверка доступности поможет понять работает ли у вас Nginx, лучше это делать в связке с проверкой логов.

Обязательно поменяйте все переменные на свои, иначе ваш проект не будет работать!

Список переменных

  • <логин>

  • <ip_адрес_сервера>

  • ваш_домен

  • ваша_почта

  • ваш_ip_сервера

Итог

Надеюсь, что эта статья рассказала вам о моём, по-своему, интересном опыте и за одно дала новые знания и понимание как работают сервисы, как начать пользоваться Nginx и бесплатно создавать SSL для ваших проектов. Вам остаётся только продолжать изучать дальше Docker и Nginx, добавляя эти инструменты в ваши работы.

Прошу дать честную критику и предлагать свои исправления, которые будут полезны людям, только начинающим пользоваться профессиональными инструментами.

Комментарии (30)


  1. NikaLapka
    15.06.2025 08:05

    У вас получилось антирезюме.

    Необходимые и достаточные условия и для установки:

    apt install nginx

    ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

    apt install certbot python3-certbot-nginx

    certbot --nginx -d example.com

    Изучайте документацию.


    1. SeRzZzJ Автор
      15.06.2025 08:05

      Здравствуйте, я согласен с Вашим решением, но в моё решение заложена масштабируемость. Я дальше планирую внедрять другие технологии, а не останавливаться на том результате, что получился сейчас. И мне не хочется потом всё переносить на Docker, я решил это сделать сразу, а за одно рассказать, то как я это сделал.


      1. Norgat
        15.06.2025 08:05

        Напишите через полгода сколько раз серт отвалился)


        1. Alexufo
          15.06.2025 08:05

          1 раз же)


      1. Alexufo
        15.06.2025 08:05

        Работа с certbot в docker-compose чувствительна к ошибкам, если проблем nginx и certbot конкурировать за 80 порт можно решить без проблем, то в отладке certbot контейнера очень легко попасть на бан частых запросов сертификата. Далее узнается, что нет возможности перезагрузить Nginx контейнер из контейнера certbot не давая ему особых прав на управление. Так и остановился на двух таймерах для двух контейнеров. Они nginx reload, а другой - на истечение сетификатов. Более минималистично разве что с другим вебсервером.


    1. Alexufo
      15.06.2025 08:05

      А зачем плагин какой то? Certbot имеет post hooks где можно указать nginx reload


      1. RolexStrider
        15.06.2025 08:05

        Сертификаты letsencrypt нужно регулярно обновлять. Таймеры systemd / cron? Не слышали?


        1. Alexufo
          15.06.2025 08:05

          Я про них же и говорю, certbot умеет прописываться туда сам. Он же и чекает сертификаты на срок годности.

          А дальше в настройках certbot можно прописать, `deploy-hook = systemctl reload nginx` Хук сработает после получения нового сертификата.


  1. yeezussniper
    15.06.2025 08:05

    Рекомендую Traefik. Я для своих домашних проектов использую за место Nginx. Он настраивается легко, работает в рамках docker-compose и автоматом перевыпускает сертификаты.


    1. baldr
      15.06.2025 08:05

      И, конечно же, он у вас отдаёт статику?


    1. SeRzZzJ Автор
      15.06.2025 08:05

      Здравствуйте, я не знаком с Вашим решением, спасибо. Возьму на вооружение.


      1. Alexufo
        15.06.2025 08:05

        поковыряйся еще с nginx-unit)


  1. zartdinov
    15.06.2025 08:05

    Посмотрите Caddy еще


  1. eaa
    15.06.2025 08:05

    Навернуть кучу всего ради одной html-странички... напомнило ощущение от первого "Hello, world" на Java


  1. zmiuko
    15.06.2025 08:05

    Че я сижу просто тау? Дай вместо изучения техник папку расшарю в сеть, что протоколу читать про себя красивого. Не осуждаю.


  1. olku
    15.06.2025 08:05

    В мире докер не принято переносить файлы по серверам. Образы же. Для деплоя можно создать ssh туннель в кластер и выполнить команду развертывания локально. Nginx на файлах конфигурации это все же наследие додокерной эпохи. Выше порекомендовали Traefik. Посмотрите Labels. В Кубере они везде.


    1. SeRzZzJ Автор
      15.06.2025 08:05

      Здравствуйте! В своей статье я хотел рассказать, свой способ, но в будущих статьях хочу осветить внедрение Вашего улучшения.


  1. empenoso
    15.06.2025 08:05

    Почему не github pages или аналоги?


    1. Zeus42
      15.06.2025 08:05

      Кстати есть уже готовые решения для Github Pages, грубо говоря свой сайт с резюме и прочим.

      Как пример: al-folio и academicpages. Уверен есть ещё похожие, но для себя пометил именно эти.


      1. 0xC0CAC01A
        15.06.2025 08:05

        Кстати, давайте сюда накидаем полный список аналогов


        1. Cregennan
          15.06.2025 08:05

          Vercel, бесплатного плана хватает с головой на одностраничник/резюме


  1. DennisP
    15.06.2025 08:05

    Можете объяснить, для чего тут докер?


    1. RolexStrider
      15.06.2025 08:05

      Для резюме вероятно)


  1. kneaded
    15.06.2025 08:05

    Я бы рекомендовал людям, то что описано в статье - побаловаться локально, а резюме оформлять где-то а-ля github, LinkedIn. Ну или если сайт хочется резюме, то Tilda вам в помощь. Короче не покупайте домен, он вам в целях тренировки не нужен


  1. iAVKi
    15.06.2025 08:05

    У меня тоже мысль крутится заточить сайт на домашнем компе. Думаю установить на WM Vare Линукс с nginx, затем с вм-варе пробросить порт на роутер (у меня белый ip), думаю будет так если набрать мой ай пи, то роутер переадресует на ай пи виртуальной машины, а там Линукс с нджингсом, а значит сайт будет лежать в www/HTML которую делает нджинкс. А там уже можно что-накручивать. Сам ещё не пробовал, идея только крутится в голове. Если заработает, то это же проще предложенного варианта, и можно даже будет из Виндоус что-то прикрутить через общую папку с виртуальной машиной. Причем не надо пока париться с доменными именами и вообще минимум настроек, по идее всё по дефолту должно работать.


    1. Jon7
      15.06.2025 08:05

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


      1. DennisP
        15.06.2025 08:05

        Возможно, разработка и так идёт на VM в линуксе, тогда остаётся только настроить роутер. Устанавливать VM только для Nginx то это да, избыточно


    1. DennisP
      15.06.2025 08:05

      Я так делал, правда на Oracle Virtualbox, никаких проблем и сложностей не было. Единственное, надо настроить сеть в режиме моста с сетевым адаптером на хосте.



  1. Mr_Cheater
    15.06.2025 08:05

    А зачем Вам Докер на домашнем сервере? Это не претензия, просто любопытство. Он же съест памяти х80 от того, что занимает сам сайт-резюме (достаточно простой). Или нет?