Установка Docker на VPS: пошаговое руководство для веб-приложений

Docker избавляет от классической проблемы «на моей машине работало»: приложение вместе со всеми зависимостями упаковывается в контейнер и одинаково запускается где угодно. Для веб-проектов это ещё и простой деплой — обновление сводится к пересборке образа и перезапуску контейнера.
Запустить Docker можно только там, где есть доступ к ядру системы, то есть на VPS или выделенном сервере: на обычном виртуальном хостинге он невозможен в принципе. Ниже — весь путь от аренды сервера до работающего приложения за HTTPS.
Шаг 1. Взять сервер
В панели NodexGo нажмите «Создать сервер» и пройдите четыре шага: локация (рядом с каждой показан ваш реальный пинг до неё), тариф, образ системы и имя сервера. Дальше выбираете период оплаты — 1, 3, 6 или 12 месяцев — и подтверждаете заказ.
Для Docker берите Ubuntu 24.04: все команды ниже написаны под неё. По ресурсам ориентируйтесь так: пара небольших контейнеров живёт на 2 ГБ памяти, связка «приложение + база + прокси» комфортно себя чувствует на 4 ГБ. Сама сборка образов требовательна к диску, поэтому NVMe здесь ощутимо экономит время.
Примерно через минуту сервер готов: IP-адрес и пароль root придут в панель и на почту.
Ubuntu 24.04, NVMe и root-доступ — всё, что нужно Docker.
Создать серверШаг 2. Первое подключение
Подключаемся по SSH, подставив выданный IP-адрес:
ssh root@IP-адрес-сервераЕсли SSH не отвечает или вы закрыли себе доступ файрволом, в карточке сервера в панели есть web-консоль VNC — она работает в обход сети и всегда пускает в систему.
Обновляем пакеты:
apt update && apt upgrade -yШаг 3. Установить Docker Engine
Ставить Docker из стандартного репозитория Ubuntu не стоит — там почти всегда старая версия. Подключаем официальный репозиторий Docker. Сначала зависимости и ключ:
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpgДобавляем сам репозиторий:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.listИ устанавливаем Docker вместе с плагином Compose:
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginПроверяем, что всё поднялось:
docker run --rm hello-world
docker compose versionЕсли вывелось приветствие Docker и версия Compose — движок работает. Автозапуск после перезагрузки сервера включается так:
systemctl enable --now dockerШаг 4. Работать не под root
Постоянно сидеть под root на сервере не нужно. Заведите обычного пользователя и дайте ему право запускать Docker:
adduser deploy
usermod -aG sudo,docker deployПосле этого переподключитесь по SSH уже под ним. Учтите: членство в группе docker фактически равно правам root — добавляйте туда только тех, кому доверяете.
Шаг 5. Первое приложение через Compose
Compose описывает весь стек в одном файле, поэтому приложение поднимается одной командой. Создаём каталог проекта:
mkdir -p /opt/app && cd /opt/app
nano docker-compose.ymlМинимальный пример: приложение на Node.js и база PostgreSQL. Пароль базы вынесен в переменную окружения, а данные лежат в именованном томе, чтобы пережить перезапуск контейнера.
services:
app:
image: node:22-alpine
working_dir: /srv
volumes:
- ./src:/srv
command: node index.js
environment:
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
depends_on:
- db
restart: always
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: app
volumes:
- dbdata:/var/lib/postgresql/data
restart: always
volumes:
dbdata:Пароль кладём в файл .env рядом с docker-compose.yml — в репозиторий он не попадает:
echo "DB_PASSWORD=придумайте-длинный-пароль" > .env
chmod 600 .envЗапускаем стек в фоне и смотрим, что получилось:
docker compose up -d
docker compose ps
docker compose logs -f appШаг 6. HTTPS и обратный прокси
Открывать контейнеры напрямую в интернет не нужно. Перед ними ставят обратный прокси, который принимает запросы на 80 и 443 портах, сам получает сертификат Let's Encrypt и передаёт трафик внутрь. Проще всего это делает Caddy — сертификат он выпускает и продлевает автоматически.
Добавьте в docker-compose.yml ещё один сервис:
proxy:
image: caddy:2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddydata:/data
restart: alwaysИ создайте рядом файл Caddyfile — две строки, где example.com замените своим доменом, уже направленным A-записью на IP сервера:
example.com {
reverse_proxy app:3000
}После перезапуска стека сайт откроется по HTTPS без единой ручной настройки сертификата:
docker compose up -dШаг 7. Файрвол
Оставляем снаружи только то, что действительно нужно: SSH и веб. Порты самих контейнеров наружу не публикуем — они общаются между собой во внутренней сети Compose.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enableВажно знать особенность: Docker работает с iptables напрямую и умеет обходить правила ufw, если вы публикуете порт строкой вида 5432:5432. Поэтому базы и внутренние сервисы никогда не публикуйте наружу — обращайтесь к ним по имени сервиса внутри Compose.
Обновление приложения и обслуживание
Обновить образы и перезапустить стек:
docker compose pull
docker compose up -dDocker со временем занимает много места старыми образами и слоями сборки. Раз в месяц полезно прибирать за собой:
docker system df
docker system prune -aНе забывайте про резервные копии: том с базой данных нужно выгружать отдельно, сам контейнер бэкапом не является.
docker compose exec -T db pg_dump -U app app > /root/backup-$(date +%F).sqlЕсли не хватает ресурсов
Признак того, что сервер мал: контейнеры начинают падать с кодом 137 — это значит, что процесс убил механизм нехватки памяти. Проверить текущую нагрузку можно так:
docker stats --no-stream
free -hВ такой ситуации в карточке сервера в панели есть кнопка «Увеличить мощности»: тариф меняется на старший, диск и IP-адрес сохраняются, контейнеры продолжают работать — переустанавливать ничего не нужно.
Коротко
Арендовать VPS с Ubuntu 24.04, поставить Docker из официального репозитория, описать приложение в docker-compose.yml, закрыть его обратным прокси с автоматическим HTTPS и оставить открытыми только 22, 80 и 443 порты. Дальше любое обновление — это две команды, а переезд на другой сервер сводится к копированию каталога проекта.
Тарифы от 2 до 32 ГБ памяти — начните с малого, перейти на старший можно в один клик.
Посмотреть тарифы