Get Serverpod running on your VPS with Plesk

sWimmie
4 min readSep 4, 2024

First of let me tell you that I really like using Serverpod as a development platform. And now in version 2, I really think it is out there to be ready to be shipped for real world apps.

For really understanding Serverpod I read the docs but also found a wonderful series on YouTube from Tyler Codes. On his page you will find a lot of different tutorials on Flutter and Serverpod. But his biggest effort for us “newbies” to Serverpod is his journey to develop a complete app from A to Z and recording while he is going. The series is still going on and I highly recommend it to go and see Link is here!
And while you are at it subscribe to the channel as well so you get the invite for his Discord channel (where we can chat if you want) and acces to the actual repo from the app he is building. And for the record no I do not get something for this commercial but it just helped me a lot on my Serverpod journey and I hope it will do for you as well.

By default Serverpod comes with Terraform scripts for deployment on AWS or Google Cloud Platform. But what if you want to deploy it on your own VPS?

On your VPS you need to configure a website. Since I’m wanting to setup an staging environment I picked staging.example.com. Next to the site I also create a PostgreSQL database with the name staging and user postgres and assign this database to the website.

Next steps I took was adding the Docker extension to my Plesk server and installed Redis on the server in the cmd.

The solution for running Serverpod on your own VPS is obviously making use of Docker. The package has already a build in Dockerfile and let you compile your project into a Docker image. But just out of the box it will not take in your migrations folder so that is a thing you need to add to it:

COPY — from=build /app/migrations/ migrations/

Next to adding the migrations folder you also need to change the Entrypoint line (ENTRYPOINT ./server --mode=$runmode --server-id=$serverid --logging=$logging --role=$role) at the end of the file into this:

CMD ./server — apply-migrations — mode $runmode — server-id $serverid — logging $logging — role $role

Now your Dockerfile is ready and since I’m wanting a staging environment let’s get over to the staging.yaml file inside the _server/config folder.

The host for the apiServer I have set to staging.example.com/api, for the webServer I set the host to staging.example.com/web and for the insights I set the host differently. Here I set the configuration like this:

insightsServer:
port: 8081
publicHost: <actual ip address of your VPS>
publicPort: 8081
publicScheme: http

This way I can get to the insights for the staging environment within the Serverpod app. Offcourse I also added the settings for my PostgreSQL database like this:

database:
host: staging.example.com
port: 5432
name: staging
user: postgres

And finally I also wanted Redis for my server so I added this as the Redis setup:

redis:
enabled: true
host: <<actual ip address of your VPS>
port: 6379

An example of these changes can be found in this Gist.

Now everything is ready you can now build your Docker image, I’m using a Linux server so build it for the platform specific version:
docker build — platform linux/amd64 -t nameofyourproject_server:staging After that I copied the image to my Documents folder so I can find it to upload the project to the server with the upload function in the Docker Extension:

docker save -o ~/Documents/nameofyourproject-staging.tar nameofyourproject_server

You can now upload the image and select run staging (local). Inside the settings unset Automatic port mapping and unset Make the port inaccessible from the Internet

Now you need to set the Docker Proxy Rules for staging.example.com like this:

port 8080 needs to be set to URL staging.example.com/api/
port 8081 needs to be set to URL staging.example.com/insights/
port 8082 needs to be set to URL staging.example.com/web/
Do not forget the trailing slash!

Now to access these different URL’s you also need to add a NGINX dirrective inside the staging.example.com. In Plesk under hosting & dns you find the Apache and nginx. Here you can set the Additional nginx directives. For this example it would look like this:

location = /api/ {
proxy_pass http://<ip address of your VPS>:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /insights/ {
proxy_pass http://<ip address of your VPS>:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /web/ {
proxy_pass http://<ip address of your VPS>:8082/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

Save and restart nginx and apache and you would be good to go!

These are the steps I took to get it all running so we now can test the api. Next step is to get the Flutter app ready for testing on the different platforms.

My setup is:
Plesk Obsidian Web Pro Edition Version 18.0.63 Update #4
Ubuntu 24.04 64bit
And all my extensions are up-to-date (sept. 4th 2024)

Happy Coding all!

--

--

sWimmie

On a journey from Urban Designer to Software - / Front end developer to iOS developer