Введение: почему продвинутый деплой Rust на VPS — это необходимость
Разработка на Rust — это только половина дела. Вторая, не менее важная часть — это надёжный и безопасный деплой. Базовые методы, такие как ручная компиляция и запуск через cargo run, не подходят для продакшена. На продвинутом уровне требуется автоматизация, изоляция процессов, мониторинг и обеспечение высокой доступности.
В этой статье мы разберём, как настроить деплой Rust-приложения на VPS с использованием Docker, CI/CD (GitHub Actions), systemd для автозапуска и Nginx в качестве reverse proxy. Все примеры кода даны на Rust и Bash.
1. Подготовка VPS и окружения
1.1. Базовая настройка сервера
Предположим, у вас есть VPS под управлением Ubuntu 22.04 LTS. Первым делом обновляем пакеты и устанавливаем необходимые инструменты:
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git build-essential pkg-config libssl-dev
Устанавливаем Rust через rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustc --version # проверка
1.2. Установка Docker
Docker обеспечит изоляцию и воспроизводимость окружения:
sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
newgrp docker
1.3. Установка Nginx
Nginx будет выступать в роли reverse proxy и балансировщика нагрузки:
sudo apt install -y nginx
sudo systemctl enable --now nginx
2. Контейнеризация Rust-приложения с помощью Docker
2.1. Многоступенчатая сборка (multi-stage build)
Для уменьшения размера образа используем многоступенчатую сборку. Создайте Dockerfile в корне проекта:
# Этап сборки
FROM rust:1.75-slim-bookworm AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
# Финальный этап
FROM debian:bookworm-slim
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app/target/release/my_app .
EXPOSE 8080
CMD ["./my_app"]
Здесь my_app — имя вашего бинарного файла. Убедитесь, что в Cargo.toml указано name = "my_app".
2.2. Сборка и запуск контейнера
docker build -t my_app:latest .
docker run -d --name my_app -p 8080:8080 my_app:latest
Проверьте, что приложение отвечает:
curl http://localhost:8080
3. Настройка автозапуска и мониторинга (systemd + Docker Compose)
3.1. Docker Compose для управления сервисами
Создайте docker-compose.yml:
version: '3.8'
services:
app:
image: my_app:latest
restart: always
ports:
- "127.0.0.1:8080:8080"
environment:
- RUST_LOG=info
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
Обратите внимание: ports привязан к 127.0.0.1, чтобы внешние запросы шли только через Nginx.
3.2. Systemd unit для управления сервисом
Создайте файл /etc/systemd/system/my_app.service:
[Unit]
Description=My Rust Application
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/my_app
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
User=deploy
Group=deploy
[Install]
WantedBy=multi-user.target
Включите и запустите:
sudo systemctl daemon-reload
sudo systemctl enable my_app
sudo systemctl start my_app
4. Настройка Nginx и SSL (reverse proxy)
4.1. Конфигурация Nginx
Создайте файл /etc/nginx/sites-available/my_app:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /health {
access_log off;
return 200 "OK";
}
}
Активируйте конфигурацию:
sudo ln -s /etc/nginx/sites-available/my_app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
4.2. SSL через Let's Encrypt
Установите Certbot:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
После этого Nginx автоматически будет перенаправлять HTTP на HTTPS.
5. CI/CD с GitHub Actions
5.1. Настройка workflow
Создайте файл .github/workflows/deploy.yml:
name: Deploy to VPS
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t my_app:latest .
- name: Save image to tar
run: docker save my_app:latest | gzip > my_app.tar.gz
- name: Copy to VPS via SCP
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
source