Skip to content

MySQL

Source: src/Railway/MySQL.ts

A Railway.MySQL is a MySQL-as-a-Service: the official mysql image, a Volume at /var/lib/mysql, MYSQL_* / MYSQL_URL variables, and an optional TCP proxy for the public URL. This is Alchemy’s mysql() helper (Railway IaC: mysql("mysql")).

Private hostname is {name}.railway.internal. From a Service, yield ConnectMySQL. From a laptop, use publicConnectionUri.

Pass a Project. Alchemy generates a unique name, password, volume, and a public TCP proxy.

const site = yield* Railway.Project("Site");
const db = yield* Railway.MySQL("Db", { project: site });

Yield ConnectMySQL inside init. Provide ConnectMySQLHttp. Pass conn.connectionString to Drizzle.MySQL or SQL.MySQL. The binding packs the private URI ({name}.railway.internal).

import * as Drizzle from "alchemy/Drizzle/MySQL";
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
export default class Api extends Railway.Service<Api>()(
"Api",
{ project: Site, main: import.meta.url, build: { install: ["mysql2"] } },
Effect.gen(function* () {
const conn = yield* Railway.ConnectMySQL(Db);
const db = yield* Drizzle.MySQL(conn.connectionString);
return {
fetch: Effect.gen(function* () {
const rows = yield* db.execute("select 1 as ok", "objects");
return HttpServerResponse.json({ rows });
}),
};
}).pipe(Effect.provide(Railway.ConnectMySQLHttp)),
) {}

public (default true) creates a TCP proxy on 3306. publicConnectionUri is {domain}:{proxyPort} for laptop access and deploy-time migrations.

const db = yield* Railway.MySQL("Db", {
project: site,
public: false,
});

Default is official MySQL 9. Pass image to pin another tag.

const db = yield* Railway.MySQL("Db", {
project: site,
image: "mysql:8",
});

Resource-valued props accept the resource or an Effect producing it.

src/db.ts
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");
export const Db = Railway.MySQL("Db", { project: Site });