如何在 GitHub Actions 中查询 Railway SQLite 数据库
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 必须是 项目令牌,而不是账户令牌。
- 前往你的 Railway 项目仪表盘。
- 进入 Settings → Tokens。
- 点击 Generate Token。
- 将令牌添加为名为
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