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 well established ways to manage your self-hosted deployment is Caprover.
Deploying Wasp apps to Caprover is straightforward:
- create your Caprover apps (client, server and db)
- build your app's Docker images (e.g. using Github Actions),
- trigger Caprover 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 Caprover installed and set up on your server. I'll be using Hetzner to rent my server.
Follow the Caprover install instructions: https://caprover.com/docs/get-started.html#prerequisites
Note
Following the install instructions, I've pointed an A
record with value *.apps
to my server IP. This gives me https://captain.apps.mydomain.com
as my Caprover URL and enables me to have quick sub-domains i.e. https://<app-name>.apps.mydomain.com
for testing stuff out.
To get Caprover 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.
- Create a new one-click app, select
PostgreSQL
- Name it
myapp-db
- Enter the version to be one the latest version e.g.
17
- Deploy it
- Write down the connection string based on the info you get:
postgresql://postgres:<password>@srv-captain--myapp-db:5432/postgres
(srv-captain--myapp-db
is based on the DB app name)
- Name it
- Create a new app named
myapp-server
- Connect a new domain as
https://api.<your-domain>
- Press
Enable HTTPS
for the domain - Set the
Container HTTP Port
to3001
- Enable
Force HTTPS by redirecting all HTTP traffic to HTTPS
andWebsocket Support
- Make sure to hit the
Save & Restart
button after you change stuff
- Connect a new domain as
- Create a new app named
myapp-client
- Connect a new domain as
https://<your-domain>
- Press
Enable HTTPS
for the domain - Set the
Container HTTP Port
to8043
- Enable
Force HTTPS by redirecting all HTTP traffic to HTTPS
andWebsocket Support
- Make sure to hit the
Save & Restart
button after you change stuff
- Connect a new domain as
Let's go back into the server app and configure the required env vars:
- Go under
App Configs
andEnvironment Variables
- Add the following env vars:
DATABASE_URL
with value of the database connection stringJWT_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:
CAPROVER_SERVER
secret- Write your dashboard URL e.g.
https://captain.apps.mydomain.com
- Write your dashboard URL e.g.
SERVER_APP_TOKEN
secret- Go to your
server
app - Under
Deployment
findMethod 1: Official CLI
- Press
Enable App Token
- Paste it as the secret value
- Go to your
CLIENT_APP_TOKEN
secret- Go to your
client
app - Under
Deployment
findMethod 1: Official CLI
- Press
Enable App Token
- Paste it as the secret value
- Go to your
- Under
Cluster
in Caprover add a new Remote Registry - Set
Username
to your Github username - Set
Password
to your Github token - Set
Domain
toghcr.io
- Set
Image Prefix
to your Github username
You can move your domain's nameservers to Cloudflare to get the benefits of their CDN and DDoS protections.
I've had to keep my A
record with the value *.apps
as DNS Only
since Cloudflare doesn't do multiple level free SSL. But I use Full
SSL for the custom domains.
Looks like the .github/workflows/deploy.yml need to be in the root directory of the repository (where .git is located). Once that's moved the working directory needs to be updated from './app' to 'mySaaS/app' where mySaaS is your app's name. './app' needs to be replaced in all places.