124 Deploying gqlgen on Railway/Render with PostgreSQL
124 Deploying gqlgen on Railway/Render with PostgreSQL
If you’ve ever built a GraphQL backend in Go using gqlgen , chances are you want to deploy your application to the cloud quickly and easily. Railway and Render are two PaaS (Platform-as-a-Service) offerings that are popular among developers thanks to their simple setup, solid database support, and continuous deployment integration from GitHub. In this article, I’ll walk you through the process of deploying a gqlgen application to Railway and Render, using PostgreSQL as the primary database. We’ll cover folder structure, the Dockerfile, the CI/CD pipeline, and even testing the GraphQL endpoint online.
1. Deployment Flow Overview
Before we dive into the technical details, let’s first look at this deployment workflow using a mermaid flow diagram:
flowchart TD
A[Lokasi project gqlgen di lokal] --> B[Push ke GitHub]
B --> C{Platform}
C --> |Railway| D[Railway mendeteksi perubahan]
C --> |Render| E[Render mendeteksi perubahan]
D --> F[Railway build dan deploy container]
E --> G[Render build dan deploy container]
F --> H[Aplikasi live di Railway]
G --> I[Aplikasi live di Render]
Essentially, our project gets pushed to GitHub, then Railway/Render builds it into a container, connects to PostgreSQL, and exposes the GraphQL endpoint publicly.
2. A Simple gqlgen Project Structure
Suppose we have a project structure like the following:
1mygqlapp/
2├── Dockerfile
3├── go.mod
4├── go.sum
5├── gqlgen.yml
6├── main.go
7├── graph/
8│ ├── resolver.go
9│ ├── schema.graphqls
10│ └── model/
11└── pkg/For this tutorial, here’s a simple example GraphQL schema:
1# graph/schema.graphqls
2type Todo {
3 id: ID!
4 text: String!
5 done: Boolean!
6}
7
8type Query {
9 todos: [Todo!]!
10}And a simple resolver:
1// graph/resolver.go
2package graph
3
4import "mygqlapp/graph/model"
5
6type Resolver struct{}
7
8func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) {
9 // In production, fetch from the PostgreSQL DB
10 return []*model.Todo{
11 {ID: "1", Text: "Belajar gqlgen", Done: false},
12 {ID: "2", Text: "Deployment di Railway/Render", Done: true},
13 }, nil
14}3. Setting Up PostgreSQL on Railway/Render
Railway
Go to Railway → New Project → Add Plugin → PostgreSQL
Railway will automatically generate a connection string like:
1postgres://user:pass@host:port/dbnameNote this string down to use as your
DATABASE_URL.
Render
- Go to the Render Dashboard → Databases → Create a new PostgreSQL DB.
- Once the database is ready, click on the DB and look at the Connection section. Grab the
Internal Database URL/External Database URLto use for theDATABASE_URLenv var.
4. Configuring the Environment Variable
Railway and Render both provide an Environment Variable panel. For Go, simply use the variable name DATABASE_URL.
In Go, use the os package:
1import (
2 "os"
3 "database/sql"
4 _ "github.com/lib/pq"
5)
6
7func dbConnect() (*sql.DB, error) {
8 db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
9 if err != nil {
10 return nil, err
11 }
12 return db, nil
13}Tips:
- Railway automatically injects the env from the PostgreSQL plugin into your service.
- Render: Add a
DATABASE_URLkey with the value from the DB dashboard.
5. Creating the Dockerfile
Both platforms support container deployment. Here’s an example Dockerfile that works well for a gqlgen project:
1# Dockerfile
2FROM golang:1.21-alpine as builder
3
4WORKDIR /app
5
6COPY go.mod go.sum ./
7RUN go mod download
8
9COPY . .
10
11RUN go build -o server main.go
12
13FROM alpine:latest
14
15WORKDIR /app
16
17COPY --from=builder /app/server .
18
19EXPOSE 8080
20
21CMD ["./server"]Note: Most tutorials use port 8080 for Go web apps. Railway/Render will expose this port.
6. Deploying to Railway
Steps:
- Push to GitHub: Make sure your project has been pushed.
- Connect to Railway
- New Project → Deploy from GitHub Repo → Select your repo.
- Railway will detect the Dockerfile, build it, and run it automatically.
- Add the environment variable from step 4.
- Check logs & health: Railway provides live logs and a health check.
7. Deploying to Render
Steps:
- Push to GitHub.
- Create a Web Service
- Render → New → Web Service → From GitHub.
- Fill in the fields:
- Environment: Docker
- Build Command: leave empty if using a Dockerfile
- Start Command: automatic from the Dockerfile
- Port: 8080
- Add the environment variable.
- Confirm the build completes → The webhook will run and your endpoint goes live.
8. Deployment Simulation: Testing the Endpoint
Once the deployment succeeds, you can test the GraphQL query with tools like [Postman], [Insomnia], or curl:
1curl -X POST \
2 -H "Content-Type: application/json" \
3 -d '{"query":"{ todos { id text done } }"}' \
4 https://mygqlapp-railway.up.railway.app/queryExample response:
1{
2 "data": {
3 "todos": [
4 { "id": "1", "text": "Belajar gqlgen", "done": false },
5 { "id": "2", "text": "Deployment di Railway/Render", "done": true }
6 ]
7 }
8}9. Common Troubleshooting
| Issue | Railway/Render | Solution |
|---|---|---|
| App can’t be accessed | Wrong Port/ENV/Health check | Make sure port 8080 is exposed, HEALTHY |
| Failed to connect to DB | DATABASE_URL not set/incorrect | Check the env var, use the one from the panel |
| “pq: SSL off” error | Render requires sslmode=require in the connection | Add ?sslmode=require |
| Build fail | Wrong Dockerfile path/command | Check the working directory and path |
10. Advantages of Railway & Render for gqlgen+PostgreSQL
| Feature | Railway | Render |
|---|---|---|
| Autoscale | Yes, by default | Paid option |
| Database | 1-click plugin | Web dashboard, granular config |
| Custom domain | Free | Free |
| Price | Free plan → affordable | Free plan → affordable |
| CI/CD Deploy | Directly from GitHub | Directly from GitHub |
11. Conclusion
Deploying a gqlgen application on Railway or Render is genuinely straightforward for the modern Go engineer. All we need to do is:
- Prepare the project and the Dockerfile.
- Set up the PostgreSQL database via the plugin/console.
- Define the
DATABASE_URLenv var. - Push to GitHub → the platform will build, deploy, and expose the GraphQL endpoint.
- The endpoint comes online immediately without having to manage a VPS or manual CI.
PaaS platforms like Railway and Render eliminate the devops overhead, so you and your team can focus on building business logic instead of managing servers!
12. References
I hope this was helpful! Don’t hesitate to share your deployment experiences in the comments 👨💻🚀