How to develop serverless PHP application with PostgreSQL database with Vercel and Neon.tech for free
Tags: php, postgres, webdev, beginners
Published: 2023-11-20 15:25:39

In this post, I will describe my experience with building a serverless PHP application for free. I also used PostgreSQL, PHP Composer, Vercel, and Neon.tech. This information might be helpful for students, novice developers, and even experienced developers trying to develop a serverless application.

**Why I think this topic is important.** Usually, to develop a PHP application, you need some kind of server; you need to set up a web server, connect a domain, set up an SSL certificate, and configure and maintain all of that. Serverless saves a lot of time and energy.

I investigated methods to develop and deploy a PHP application and PostgreSQL database for free.

I had requirements:
- It is free, and no credit card is required. 
- Sufficient resources for the application, several gigabytes of data, and thousands of application runs per month.
- HTTPS and the ability to connect my own domain.
- Easy start for an untrained user (me).
- PostgreSQL, PHP, and composer support

So, I found a pretty popular platform called [Vercel](https://vercel.com/pricing), which could deploy PHP applications, too. I'd be glad if you could suggest a similar alternative in the comments. 

With the database, there was more choice; as a database, I wanted to use PostgreSQL or compatible with it, and as a result, I found several services providing it for free:

- [CockroachDB](https://www.cockroachlabs.com/pricing/) - 10 GiB storage
- [Xata.io](https://xata.io/pricing) - 15 GB storage
- [Aiven.io](https://aiven.io/pricing?product=pg) - 5 GB storage
- [Neon.tech](https://neon.tech/pricing) - 3 GiB storage per branch & 10 branches. 

I only chose for a short time, deciding to try all services, and the first would be Neon.tech. I also found Neon.tech in the Vercel marketplace app list, which put me in the mood for my first experiment.

So, I will tell you how to make an application, deploy it to Vercel, and connect Neon.tech PostgreSQL.

## Preparation 

I signed up for [the Vercel](https://vercel.com) service at the Hobby plan, did my first project and installed [the Vercel CLI](https://vercel.com/docs/cli).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9ziaud85s0kdqzn46wc.png)

I registered at [Neon.tech](https://neon.tech/pricing) and created my first free database.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jx7qe965xujt9k309jcu.png)

## Application development and deployment

Vercel community provides two great resources on how to make a PHP application with tons of examples:

- [PHP Runtime for Vercel](https://github.com/vercel-community/php)
- [vercel-examples](https://github.com/juicyfx/vercel-examples)

We need to create a `vercel.json` file in the project folder. I just made an empty folder for the project.

```
{
  "functions": {
    "api/*.php": {
      "runtime": "vercel-php@0.6.0"
    }
  },
  "routes": [
    { "src": "/(.*)",  "dest": "/api/index.php" }
  ]
}
```

Create a simple php file `index.php` for the test in a new folder named `api` 

```
<?php
phpinfo();
```

Make the application deployment with the command.

`vercel --prod`

The first time you will need to log in and do a dev deployment.

```
# Log in
vercel login

# Let's fly
vercel
```

That's it, a few seconds, and you can open a deployment domain or a production domain.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dyaip5gy6ujfau2ffzj.png)

## Let's connect the database

On the dashboard of our database in Neon we can get the connection data, this looks like a string:

```
psql 'postgresql://daniil.bazhenov:************@ep-shrill-disk-******.eu-central-1.aws.neon.tech/php-neon?sslmode=require'
```

I suggest immediately adding the access data as environment variables in the `vercel.json` file.

I added a section `env`, but you can also add variables directly in the code or vercel project page.

```
{
  "functions": {
    "api/*.php": {
      "runtime": "vercel-php@0.6.0"
    }
  },
  "routes": [
    { "src": "/(.*)",  "dest": "/api/index.php" }
  ],
  "env": {
    "PG_HOST": "ep-shrill-disk-******.eu-central-1.aws.neon.tech",
    "PG_PORT": "5432",
    "PG_DB": "php-neon",
    "PG_USER": "daniil.bazhenov",
    "PG_PASSWORD": "**********",
    "PG_ENDPOINT": "ep-shrill-disk-******"
  }
}
```

Now, let's modify the application to connect to PostgreSQL using our data from environment variables.

Let's open the php file api.index.php and modify it as follows:
1. Get the environment variables
2. Make a connection string for pg_connect
3. Check the connection

The example is courtesy of ChatGPT; you can use any other method.

```
<?php

$host = $_ENV['PG_HOST'];
$port = $_ENV['PG_PORT'];
$db = $_ENV['PG_DB'];
$user = $_ENV['PG_USER'];
$password = $_ENV['PG_PASSWORD'];
$endpoint = $_ENV['PG_ENDPOINT'];

$connection_string = "host=" . $host . " port=" . $port . " dbname=" . $db . " user=" . $user . " password=" . $password . " options='endpoint=" . $endpoint . "' sslmode=require";

$dbconn = pg_connect($connection_string);

if (!$dbconn) {
    die("Connection failed: " . pg_last_error());
}
echo "Connected successfully";
```

Let's run the deployment to production.

`vercel --prod`

We'll see the result in the console.

```
➜  start vercel --prod
Vercel CLI 32.5.0
🔍  Inspect: https://vercel.com/dbazhenovs-projects/start/224sUDqro9hi5gfne8oL9F5FaPkM [4s]
✅  Production: https://start-bzq80bkt8-dbazhenovs-projects.vercel.app [4s]
➜  start
```

And we can open the main domain in the browser to see the connection.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hf5aoeiqntdgcdouy1xd.png)

## Let's check the Composer

[Composer](https://getcomposer.org/) is a PHP package manager and it will allow us to use many out-of-the-box packages and features such as HTTP requests, logging, and templates and database management. I use it to develop large, complex applications.

For testing, I'll connect [Guzzle](https://packagist.org/packages/guzzlehttp/guzzle), make a GET request to the GitHub API, and connect [dd](https://packagist.org/packages/larapack/dd) to print the result of the request in a readable form for development and debugging. 

So, my application can request external APIs, save the results to a PostgreSQL database, and do other things like return some results to the user.

You must create a composer.json file in the project directory and add the necessary packages. 

```
{
    "require": {
        "guzzlehttp/guzzle": "^7.0",
        "larapack/dd": "1.*"
    }
}
```

At the beginning of the index.php file let's add the composer packages connection, make a test query with Guzzle and print the result with dd()

```
<?php

require_once __DIR__ . '/../vendor/autoload.php';

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');

$result = json_decode($response->getBody(), true); 

dd($result);
```

As usual, we do the deployment 
`vercel --prod`
and in less than a minute we see the result in production.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z90os8pheebk278acutf.png)

## Conclusion

This is a fantastic technology. 

You can make a website or backend API without worrying about server, hosting, web server configuration, and domains.

You can use the database for free as well, and you have several options for the database.

What to do next:
1. Develop the application and add features.
2. Develop the database, add tables schema, and make queries to insert and select data.