Stateless is cool, but chances are you also need to store some data: Runway services to the rescue.
Services on Runway loosely follow a micro services approach — one database per service. But if your budget is a constraint, worry not.
Create a new database with a random name:
runway service create
This will create a database service and tell you a name.
Use the new name (e.g. new-db
) to set the database URL (DATABASE_URL
environment variable) on your application:
runway app config set $(runway service dsn new-db)
Runway currently offers PostgreSQL database only, so the following example is that of using a PostgreSQL database with your application.
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
var databaseUrl
func init() {
if os.Getenv("DATABASE_URL") == "" {
panic("No DATABASE_URL set!")
}
}
func main() {
// open database
db, err := sql.Open("postgres", psqlconn)
CheckError(err)
// close database
defer db.Close()
// check db
err = db.Ping()
CheckError(err)
fmt.Println("Connected!")
}
func CheckError(err error) {
if err != nil {
panic(err)
}
}
panic()
is not a great way to handle it either. Our objective in this guide is to elevate errors as soon as possible to make it easy to follow along. In a production context, you may want to add a retry, e.g. when the database does not respond right away or display an error message on your application instead of crashing the application.The Golang ecosystem offers a handful or drivers to talk to PostgreSQL database, most notably github.com/lib/pq
and pqx
. On top of that, there are also projects such as gorm and entgo which add additional sugar and make it easy to work with databases.
Using pgx
(which has great support for another Go-ism, the context
), the connection would look similar to this:
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
Or entgo’s connection string would look like this:
client, err := ent.Open("postgres", os.Getenv("DATABASE_URL"))
Or a slightly more sophisticated example with entgo and pgx looks like this:
db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
if err != nil {
panic(err)
}
// Create entgo client with pgx driver
drv := entsql.OpenDB(dialect.Postgres, db)
client := ent.NewClient(ent.Driver(drv))
To access your database directly, e.g. to run your own import, checkout our Tailscale guide, to learn how to connect your database to your own tailnet.
This lets you access your database through e.g. psql
in your terminal, or a graphical UI installed on your computer.
Get the credentials with:
runway service show new-db
PGPASSWORD=the-password psql -U the-username -h name-of-the-database-on-your-tailnet