如何在 GitHub Actions 中查询 Railway SQLite 数据库

发布: (2025年12月4日 GMT+8 04:44)
3 min read
原文: Dev.to

Source: Dev.to

为什么使用 SSH?

Railway 不会将 SQLite 数据库暴露到互联网,所以数据库文件位于已部署容器的磁盘内部。SSH 是唯一的访问方式。

railway ssh "node -e \"const db = require('better-sqlite3')('./data/my-demo.db'); const all = db.prepare('SELECT * FROM signups ORDER BY created_at DESC').all(); console.log(JSON.stringify(all)); db.close();\""

问题 1:获取正确的令牌

RAILWAY_TOKEN 必须是 项目令牌,而不是账户令牌。

  1. 前往你的 Railway 项目仪表盘。
  2. 进入 Settings → Tokens
  3. 点击 Generate Token
  4. 将令牌添加为名为 RAILWAY_TOKEN 的 GitHub Actions secret。

问题 2:交互式登录在 CI 中无效

运行 railway login --browserless 会失败,因为它仍然需要手动粘贴令牌。

解决方案: 删除所有登录命令。只要设置了 RAILWAY_TOKEN 环境变量,Railway CLI 会自动使用它。

问题 3:服务名称 vs. 服务 ID

在 CI 中使用 --project 或服务 ID 会导致 CLI 忽略 RAILWAY_TOKEN,并期待交互式登录。

解决方案: 只使用友好的服务名称配合 --service,并省略 --project

railway ssh --service your-service-name --environment production \
  "node -e \"const db = require('better-sqlite3')('./path/to/database.db'); const rows = db.prepare('SELECT * FROM your_table').all(); console.log(JSON.stringify(rows)); db.close();\""

问题 4:转义引号

多层引用(shell → GitHub Actions → YAML)导致命令失效。

解决方案: 将逻辑移到单独的 TypeScript 脚本中,并在工作流中调用它。

// scripts/query-railway.ts
import { execSync } from 'child_process';

interface Record {
  id: number;
  email: string;
  created_at: string;
}

function queryRailway(): Record[] {
  const serviceName = process.env.RAILWAY_SERVICE_NAME || 'my-app-service';
  const environment = process.env.RAILWAY_ENVIRONMENT || 'production';
  const token = process.env.RAILWAY_TOKEN;

  if (!token) {
    console.error('RAILWAY_TOKEN not set');
    process.exit(1);
  }

  const command = `railway ssh --service ${serviceName} --environment ${environment} "node -e \\"const db = require('better-sqlite3')('./data/database.db'); const rows = db.prepare('SELECT * FROM users').all(); console.log(JSON.stringify(rows)); db.close();\\""`; 

  try {
    const output = execSync(command, { encoding: 'utf-8' });
    const lines = output.trim().split('\n');
    for (const line of lines) {
      if (line.trim().startsWith('[') || line.trim().startsWith('{')) {
        return JSON.parse(line.trim());
      }
    }
    console.error('Output from Railway:', output);
    throw new Error('Could not find JSON output from Railway');
  } catch (error) {
    console.error('Failed to query Railway:', error);
    process.exit(1);
  }
}

const records = queryRailway();
console.log(`Successfully fetched ${records.length} records`);

工作流步骤:运行脚本

- name: Query db
  env:
    RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
    RAILWAY_SERVICE_NAME: my-app-service
    RAILWAY_ENVIRONMENT: production
  run: npx tsx scripts/query-railway.ts

完整工作流

name: My workflow

on:
  workflow_dispatch:
  schedule:
    - cron: '0 */6 * * *'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Install Railway CLI
        run: npm install -g @railway/cli

      - name: Query db
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
          RAILWAY_SERVICE_NAME: my-app-service
          RAILWAY_ENVIRONMENT: production
        run: npx tsx scripts/query-railway.ts
Back to Blog

相关文章

阅读更多 »

SaaS IA 新闻

SaaS IA 新闻的封面图片 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazon...

从混沌到代码:ALPHALABS

让我彻夜难眠的问题 我想要构建一个平台,让任何人都能创建 AI trading agents、backtest strategies,并证明其 performance……