Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions alchemy-web/src/content/docs/guides/railway.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
title: Railway
description: Learn how to deploy services and infrastructure on Railway using Alchemy.
sidebar:
order: 22
---

import { Steps } from '@astrojs/starlight/components';

This guide walks you through deploying a service to Railway using Alchemy, including environment variables and a public domain.

:::note
For the full Railway API reference, see the [Railway Provider](/providers/railway/) documentation.
:::

<Steps>

1. **Install Alchemy**

::: code-group

```sh [bun]
bun add alchemy
```

```sh [npm]
npm install alchemy
```

```sh [pnpm]
pnpm add alchemy
```

```sh [yarn]
yarn add alchemy
```

:::

2. **Get your Railway API token**

Create an API token from your [Railway account settings](https://railway.com/account/tokens) and add it to your `.env` file:

```bash title=".env"
RAILWAY_API_TOKEN=your-token-here
```

3. **Create `alchemy.run.ts`**

```ts title="alchemy.run.ts"
import alchemy from "alchemy";
import { Project, Service, Variable, Domain } from "alchemy/railway";

const app = await alchemy("railway-app", {
phase: process.argv.includes("--destroy") ? "destroy" : "up",
});

// Create a Railway project
const project = await Project("my-app", {
name: "my-app",
description: "Deployed with Alchemy",
});

// Deploy a service from a Docker image
const service = await Service("web", {
project,
name: "web-server",
source: { image: "nginx:latest" },
});

// Set environment variables
await Variable("web-vars", {
project,
environment: project.defaultEnvironmentId,
service,
variables: {
PORT: "80",
},
});

// Add a public domain
const domain = await Domain("web-domain", {
service,
environment: project.defaultEnvironmentId,
});

console.log(`Service URL: https://${domain.domain}`);

await app.finalize();
```

4. **Deploy**

Run `alchemy.run.ts` to deploy:

::: code-group

```sh [bun]
bun ./alchemy.run
```

```sh [npm]
npx tsx ./alchemy.run
```

```sh [pnpm]
pnpm tsx ./alchemy.run
```

```sh [yarn]
yarn tsx ./alchemy.run
```

:::

It should log out the service URL:
```
Service URL: https://web-server-production-xxxx.up.railway.app
```

5. **Tear Down**

That's it! You can now tear down the app (if you want to):

::: code-group

```sh [bun]
bun ./alchemy.run --destroy
```

```sh [npm]
npx tsx ./alchemy.run --destroy
```

```sh [pnpm]
pnpm tsx ./alchemy.run --destroy
```

```sh [yarn]
yarn tsx ./alchemy.run --destroy
```

:::

</Steps>
68 changes: 68 additions & 0 deletions alchemy-web/src/content/docs/providers/railway/domain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Domain
description: Add domains to Railway services using Alchemy.
---

The `Domain` resource creates and manages domains for [Railway](https://railway.com) services. You can create Railway-generated domains (*.up.railway.app) or attach custom domains.

## Railway Domain

Get a Railway-generated domain:

```ts
import { Project, Service, Domain } from "alchemy/railway";

const project = await Project("my-app", { name: "my-app" });
const api = await Service("api", {
project,
name: "api",
source: { image: "node:20" },
});

const domain = await Domain("api-domain", {
service: api,
environment: project.defaultEnvironmentId,
});

console.log(`https://${domain.domain}`);
// e.g. https://api-production-xxxx.up.railway.app
```

## Custom Domain

Attach a custom domain to a service:

```ts
import { Project, Service, Domain } from "alchemy/railway";

const project = await Project("my-app", { name: "my-app" });
const api = await Service("api", { project, name: "api" });

const domain = await Domain("custom", {
service: api,
environment: project.defaultEnvironmentId,
domain: "api.example.com",
projectId: project.projectId,
});
```

## With Target Port

Route traffic to a specific port:

```ts
import { Project, Service, Domain } from "alchemy/railway";

const project = await Project("my-app", { name: "my-app" });
const api = await Service("api", { project, name: "api" });

const domain = await Domain("api-domain", {
service: api,
environment: project.defaultEnvironmentId,
targetPort: 3000,
});
```

:::note
Domain names are immutable. If the custom domain changes, the domain will be replaced (deleted and recreated).
:::
54 changes: 54 additions & 0 deletions alchemy-web/src/content/docs/providers/railway/environment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: Environment
description: Create and manage Railway environments using Alchemy.
---

The `Environment` resource creates and manages environments within a [Railway](https://railway.com) project. Environments provide isolated deployments for staging, development, or feature branches.

## Minimal Example

Create a staging environment:

```ts
import { Project, Environment } from "alchemy/railway";

const project = await Project("my-app", { name: "my-app" });

const staging = await Environment("staging", {
project,
name: "staging",
});
```

## With Project ID

Reference a project by its ID string:

```ts
import { Environment } from "alchemy/railway";

const env = await Environment("dev", {
project: "project-id-123",
name: "development",
});
```

## Adopt Existing

Adopt an environment that already exists:

```ts
import { Project, Environment } from "alchemy/railway";

const project = await Project("my-app", { name: "my-app" });

const env = await Environment("staging", {
project,
name: "staging",
adopt: true,
});
```

:::note
Environment names are immutable in Railway. If the name changes, the environment will be replaced (deleted and recreated).
:::
73 changes: 73 additions & 0 deletions alchemy-web/src/content/docs/providers/railway/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Railway
description: Deploy and manage Railway projects, services, environments, variables, volumes, domains, and TCP proxies using Alchemy.
---

Railway is a cloud infrastructure platform for deploying applications, databases, and services with zero configuration. Alchemy provides resources to manage Railway infrastructure programmatically using the Railway GraphQL API.

[Official Railway Documentation](https://docs.railway.com) | [Railway API Reference](https://docs.railway.com/guides/public-api)

## Resources

- [Project](/providers/railway/project) - Create and manage Railway projects
- [Service](/providers/railway/service) - Deploy and configure services within projects
- [Environment](/providers/railway/environment) - Create isolated environments for staging, development, etc.
- [Variable](/providers/railway/variable) - Manage environment variables for services
- [Volume](/providers/railway/volume) - Attach persistent storage to services
- [Domain](/providers/railway/domain) - Add Railway-generated or custom domains to services
- [TCPProxy](/providers/railway/tcp-proxy) - Expose non-HTTP services via TCP

## Authentication

Railway uses API tokens for authentication. Set the `RAILWAY_API_TOKEN` environment variable, or pass the token directly via the `apiToken` property on any resource.

```bash
export RAILWAY_API_TOKEN=your-token-here
```

You can create an API token from your [Railway account settings](https://railway.com/account/tokens).

## Example Usage

```ts
import {
Project,
Service,
Variable,
Domain,
} from "alchemy/railway";

// Create a project
const project = await Project("my-app", {
name: "my-app",
description: "Production application",
});

// Deploy a service
const api = await Service("api", {
project,
name: "api-service",
source: { image: "node:20" },
startCommand: "node server.js",
});

// Set environment variables
await Variable("api-vars", {
project,
environment: project.defaultEnvironmentId,
service: api,
variables: {
NODE_ENV: "production",
PORT: "3000",
DATABASE_URL: alchemy.secret.env.DATABASE_URL,
},
});

// Add a domain
const domain = await Domain("api-domain", {
service: api,
environment: project.defaultEnvironmentId,
});

console.log(`API available at: https://${domain.domain}`);
```
Loading
Loading