Self-hosting is a great way to have control over your deployment infrastructure (you own the data) and a great way to keep the costs down (you pay a fixed amount per month). One of the smoothest way to manage your self-hosted deployment is Coolify.
Deploying Wasp apps to Coolify is straightforward:
- create your Coolify apps (client, server and db)
- build your app's Docker images (e.g. using Github Actions),
- trigger Coolify to pull the Docker images and deploy them.
It'll take you ~1 hour depending on your level of experience with servers and Github Actions.
You should have Coolify installed and set up on your server. I'll be using Hetzner to rent my server.
Follow the Coolify install instructions: https://coolify.io/self-hosted
To get Coolify apps working with your domain - you'll need to point a A
record to your server IP:
-
To use
myapp.com
as your client domain, point theA
record with the value of@
to your server IP. -
To use
api.myapp.com
as your server domain, point theA
record with the value ofapi
to your server IP.
We'll set up the domains for our server and client apps below.
Tip
You can point an A
record with value of coolify
to your server IP and set Instance's Domain
in the Settings
as https://coolify.myapp.com
so you can access the Coolify dashboard via the subdomain. Read more on Coolify domain setup here: https://coolify.io/docs/knowledge-base/dns-configuration
- Create a new project or use the default one
- Create a new resource, select
PostgreSQL
- I pick the default PostgreSQL 16 variant, you can try others as well - they should work just fine
- Name it
db
(to keep things clean) - Click
Start
to set up the database - Copy the
Postgres URL (internal)
- we'll need it later
- Create a new resource, select
Docker Image
underDocker Based
- We'll write
ghcr.io/<your-github-username>/<something>
as the Docker image name since we'll be using the Github Container Registry (ghcr.io) to store our Docker images - I'll write
ghcr.io/infomiho/pokemon-server
for my server image (I'll usepokemon-server
as my app name later in the Github Action) - Name the app
server
to keep things clean - Set the
Domains
tohttps://api.<your-domain>
- Set the
Docker Image Tag
tomain
since we'll use that tag later - Set the
Port Exposes
to3001
- Make sure to hit the
Save
button after you change stuff
- We'll write
- Create a new resource, select
Docker Image
underDocker Based
- I'll write
ghcr.io/infomiho/pokemon-client
for my client image (I'll usepokemon-client
as my app name later in the Github Action) - Name the app
client
to keep things clean - Set the
Domains
tohttps://<your-domain>
- Set the
Docker Image Tag
tomain
since we'll use that tag later - Set the
Port Exposes
to8043
- Make sure to hit the
Save
button after you change stuff
- I'll write
Let's go back into the server app and configure the required env vars:
- Go under
Environment Variables
- Add the following env vars:
DATABASE_URL
with value of thePostgres URL (internal)
JWT_SECRET
generate it with some online generatorPORT
set it to3001
WASP_WEB_CLIENT_URL
set it tohttps://<your-domain>
WASP_SERVER_URL
set it tohttps://api.<your-domain>
- Add any other env vars you might have defined locally in the
.env.server
file
- In your app root dir create a new
.github
folder - Inside of
.github
folder, create a newworkflows
folder - Copy the
deploy.yml
file from this gist to theworkflows
folder
Once you copy the deploy.yml
, make sure to modify the:
WASP_VERSION
env varSERVER_APP_NAME
env var - this will be used in the Docker image nameSERVER_APP_URL
env varCLIENT_APP_NAME
env var - this will be used in the Docker image name
The DOCKER_REGISTRY
, DOCKER_REGISTRY_USERNAME
and DOCKER_REGISTRY_PASSWORD
env vars will work out of the box for Github Container Registry.
Warning
If your app is located in the app
folder (e.g. Open Saas has the app in the app
folder) you can use the action as-is.
If your app is not in the app
folder, follow the comments on lines 70, 87, 89, 98 and 100 to modify some paths.
The Github Action depends on some repository secrets to work properly - these are some values that can't be public. You add them by going into your repository Settings
and then find Secrets and variables
and select Actions
.
Let's add the:
SERVER_COOLIFY_WEBHOOK
secret- Go to your
server
app - Click
Webhooks
and copy theDeploy Webhook
- Paste it as the secret value
- Go to your
CLIENT_COOLIFY_WEBHOOK
secret- Go to your
client
app - Click
Webhooks
and copy theDeploy Webhook
- Paste it as the secret value
- Go to your
COOLIFY_TOKEN
secret- Go to
Settings
and enable API - Go to
Keys & Tokens
next and clickAPI tokens
- Create a new API token with
Root Access
- Copy it and paste it under the secret value
- Go to
You can move your domain's nameservers to Cloudflare to get the benefits of their CDN and DDoS protections.
I've had to set my SSL mode to Full
to get it working.
Im getting the error in coolify logs that I am unauthorised to pull the images