---
name: deployment
description: Deploy applications to various targets — Railway, Docker, GitHub Pages, VPS (Contabo), and static hosting.
version: 1.0.0
license: MIT
metadata:
  hermes:
    tags: [deploy, railway, docker, github-pages, vps, hosting, ci-cd]
    category: devops
    requires_toolsets: [terminal]
---

# Deployment

Deploy applications to various targets: Railway (fast prototyping), Docker (self-hosted), GitHub Pages (static sites), and VPS (production).

## When to Use

- Deploy a new service for testing (Railway first, then migrate)
- Self-host on Contabo VPS via Docker
- Publish a static site to GitHub Pages
- Plan deployment strategy (Railway → self-hosted)
- Configure nginx reverse proxy for self-hosted services

## Deployment Flow (Preferred)

1. **Railway** — быстрый тест, zeroconfig
2. **Contabo (Docker)** — production, self-hosted
3. **GitHub Pages** — статические сайты

## Railway

```bash
# Install CLI
npm i -g @railway/cli

# Deploy from project root
railway up

# Link existing project
railway link

# Set environment variables
railway variables set KEY=VALUE
```

**Pros:** Zero config, auto HTTPS, free tier.  
**Cons:** Paid after free quota.

## Docker (self-hosted on Contabo)

```bash
# Build and run
docker compose up -d --build

# Check logs
docker compose logs -f

# Update
git pull && docker compose up -d --build
```

## GitHub Pages

```bash
# Build static site
npm run build

# Deploy to gh-pages branch
npx gh-pages -d dist
```

See `github-pages-custom-domain` skill for custom domain setup.

## VPS Deployment (Contabo 157.173.122.51)

```bash
# Copy files to server
rsync -avz --progress ./ root@157.173.122.51:/opt/app/

# SSH and set up with Docker
ssh root@157.173.122.51
cd /opt/app && docker compose up -d --build
```

## Pitfalls

| Problem | Fix |
|---------|-----|
| Railway deploy fails | Check build command in package.json |
| Docker port conflict | Change host port mapping |
| VPS running out of disk | `docker system df` then prune |
| nginx 502 bad gateway | App not running on expected port |
| SSL cert expired | `certbot renew` |

## Strategy Notes

- **New projects:** сначала Railway для быстрой проверки, потом миграция на Contabo
- **Cost-sensitive:** self-hosted на своём сервере, а не платные облака
- **Static sites:** GitHub Pages с кастомным доменом
- **Databases:** Postgres в Docker контейнере с persist volume
