If you’re like me and are looking for a way to decrease your Heroku (or any other PaaS) costs while maintaining a similar level of development convenience, then this article is definitely for you.
If you are part of the GitHub student pack, you can do this entire process for free. (assuming you have a credit card to verify your account)
I will be showing you how to set up your own Platform as a Service, and cut your costs by 80%, and have 10x better server diagnostics metrics.
If you are like me and started off by hosting on Heroku. You will quickly notice that the costs can rack up considerably. If you want to run a website, you will probably need SSL and thus get a $7/m Hobby Dyno. Additionally, If you are running a PostgreSQL database with more than 10,000 rows then factor in another $9 a month. Sure it can be worth it, Heroku saves you a lot of work. Then again, if you have some free time on your hands you could follow along with me and set up your own Heroku like clone, with a similar online ‘app’ dashboard and Command-line interface.
Our secret to making this work is a free app/database deployment & web server manager called CapRover.
What is CapRover you might ask? – I will let them answer it for you.
CapRover is an extremely easy to use app/database deployment & web server manager for your NodeJS, Python, PHP, ASP.NET, Ruby, MySQL, MongoDB, Postgres, WordPress (and etc…) applications!https://caprover.com/
Infact, this webpage right now is being hosted on a machine running CapRover.
What you will need
- A DigitalOcean account. We will be using DigitalOcean to host our server. Why? – It’s cheap. A $5 Virtual Private Server (aptly named a ‘Droplet’), costs $5 a month. and has a similar performance to the $25 Heroku Standard 1x Dyno. Another thing I love about DigitalOcean is that the price scales a lot better. 1GB RAM is $5, 2GB RAM is $10, 3GB RAM is $15/month etc. Whereas, at Heroku, for example the PostgreSQL database goes from $9/month to $50/month, nothing inbetween..
- npm installed. Get npm here.
- A domain.
- Python 3.
- Github or similar.
- If you are a student, you can sign up to GitHub’s student pack, and receive $50 of DigitalOcean credit which can go towards this Droplet completely free.
- Additionally, If you sign up using my referral link you get $100 in credit over 60 days absolutely free. [Referral link] [non-Referal link]
Setting up DigitalOcean
Now that you have an account on DigitalOcean, let’s create our first Droplet. DigitalOcean actually lets you do one-click setup’s which is perfect for us.
Click here to instantly create a CapRover Droplet.
Next, you should see a screen allowing you to choose a plan.
- Keep everything default. (standard plan, $5/mo, 1GB/1CPU/1TB transfer.)
- No block storage.
- choose a datacenter region near you.
- For additional options, select ‘Monitoring’.
- Setup an authentication method. I highly recommend you connect an SSH key. Click on ‘New SSH Key’. Instructions on how to generate an SSH key in Linux, Mac, or Windows will pop up on the right side of the modal.
- Give a fitting hostname. The hostname does not really matter, it’s just how you can recognize it from your dashboard on DigitalOcean later. I will name my host ‘django-test-droplet’.
- Add tags if necessary. Again this is just for your convenience. Incase in the future you will have a lot of droplets, it allows you to set ‘ CPU usage alarms’ and such based on tags.
- Add backups if necessary, otherwise, you can always do this later.
- Click ‘Create Droplet’. Congratulations you just created your first DigitalOcean Droplet. Now, wait a minute, while the droplet is being created. You can see the progress from your project overview.
Configuring your Domain’s DNS
We will need some kind of portal to login to and see an overview of what is happening on our CapRover Droplet. For this, we will have to use a domain to connect with.
First, we will have to get the ipv4 address of our new droplet. Head on over to your droplet and you should see the ipv4 address in the upper left corner. Take note of this as you will need it later.
Assuming you own a domain, go to your favorite domain registrar (GoDaddy, NameCheap, Name), etc. and head to the ‘Manage DNS’ area of the domain you want to use.
P.S. Again if you are a student you can get a free domain with the student pack. E.g. The Namecheap or Name.com offer gives you a domain for free.
Now Set the following:
Answer: <ipv4 of the droplet you just created>
TTL: 600 (doesn’t matter)
Note: you can change the host if you would like. just make sure there is a *. wildcard as CapRover will append its own subdomain on top of this.
Once everything is added, click update.
Setting up CapRover
Head over to your droplet and look for the ipv4 address.
Assuming that you’ve installed npm on your own computer, you will now have to install the CapRover CLI. Open up your command-line interface and run (again on your own computer, not the droplet.):
npm install -g caprover
if something goes wrong, try running it with the sudo command.
Now lets setup CapRover on the droplet.
Enter the following:
- have you already started CapRover container on your server? y
- IP address of your server: <ENTER_YOUR_DROPLETS_IPV4>
- CapRover server root domain:<DOMAIN_WITH_WILDCARD>
- new CapRover password (min 8 characters): [hidden] <ENTER_PASSWORD>
- enter new CapRover password again: [hidden] <ENTER_PASSWORD>
- “valid” email address to get certificate and enable HTTPS: <ENTER_YOUR_EMAIL>
- CapRover machine name, with whom the login credentials are stored locally: (captain-01) <PRESS_ENTER>
On completion, you should see something similar to the picture below:
The CapRover machine name in the last question is just a way of distinguishing different machines running the CapRover software.
Logging into your CapRover Server
Upon successfully completing the tutorial so far you should be greeted by a simple login screen when visiting the domain in your console in yellow text. (captain.<YOUR_DOMAIN>). In my case this was captain.testing.alfred.software.
If you made it this far, congratulations. You now have a CapRover setup correctly.
Now let’s update CapRover to the latest version. Goto, Settings and click Install Update. This will take a moment.
If you receive a 502 Bad Gateway. Don’t panic, this is okay. Wait a moment, and refresh. You should see the CapRover Login screen again. Proceed to log in again.
Once logged in, you can go back to Settings and check if you’re on the latest version.
Setting up Monitoring
This is optional, but I highly recommend it, since it literally takes 20 seconds.
Go to the Monitoring tab, at the bottom of the page click on ‘Start NetData Engine’.
Setup Notification’s if you like. I set up Telegram notifications personally. Otherwise, you can click on ‘Open NetData’ to see how your server is doing. If you are installing a lot of programs on your server make sure to frequently check the RAM usage.
Creating a Django project, with a Postgres DB on our new server
Now let’s get Django working. First, we will set up the Postgres database, however.
Setting up Postgres on CapRover
Head on over to ‘Apps’ in your CapRover server.
Click on the button ‘One-Click Apps/Databases’.
Scroll down to PostgreSQL, and click on it.
Fill in the following information. Note down the username, password, and database.
- App Name: give a name to the app, similar to in Heroku. It’s just a way of you recognizing what this app is about from the dashboard. CapRover will automatically append ‘-db’ to the end of the name.
- Postgres Version: Leave as is.
- Postgres Username: come up with a username
- Postgres Password: come up with a strong password
- Postgres Default Database: default
Once done, click Deploy.
Upon successful completion, you should see your new database in the ‘Apps’ tab under ‘Your Apps’.
Setting up Django on CapRover
Now lets setup the Django App. We have to create another new app. This time however we cannot use the one-click method.
Create a new app and call it whatever you like. I’m calling it ‘django-testing’. If your Django app will store information locally, as in it doesn’t use a cloud to store images, then check the box saying ‘Persistent data’
Once created, click on the new app. In my case called ‘django-testing’.
Now go to the tab that says ‘App Config’, we will now have to add some Environmental variables so that we can connect to our PostgreSQL database.
On the right-hand side check the box ‘Bulk Edit’ and paste in the following information. Changing as given.
CAPROVER=True CR_SECRET_KEY=YOUR_KEY CR_HOSTS=demo-django.YOUR_CAPROVER_DOMAIN CR_DB_NAME=XXX CR_DB_USER=XXX CR_DB_PASSWORD=XXX CR_DB_HOST=srv-captain--<DB_NAME_HERE> CR_DB_PORT=5432
So in my case, I would add the following:
Once filled in click ‘Save & Update’.
Deploying a Django template
First, clone this repo.
Once cloned, if you want to set up the template for local development. I recommend you set up a virtual environment.
If you don’t have virtual environment downloaded do so with:
pip install virtualenv
Then to create a virtual environment run the following:
virtualenv -p /usr/bin/python3 py3env source py3env/bin/activate
Simply install the dependencies from the given requirements.txt file by opening a command line in the folder containing the requirements.txt file and then running.
pip install -r requirements.txt
Now let’s make sure the Django project runs correctly, run the following (while in the directory containing manage.py):
python manage.py migrate
There is actually a small thing we must change in the Django template because it is actually in German. To change it to English go to django_project/settings.py. On line 75, change
LANGUAGE_CODE = “de-DE”
LANGUAGE_CODE = “en-EN”
Don’t forget to save. Now let’s create a Django administrator account locally.
python manage.py createsuperuser
Okay, let’s run the server locally and see if it works.
python manage.py runserver
If all is well, you should see ‘Hello World!’ when now going to http://127.0.0.1:8000
Now we can develop locally and push our changes to the CapRover server when we are done.
Assuming you committed + pushed your code to GitHub or similar, we can now move on to deploying the code on CapRover.
Open a command line again in your project directory. And Run the following command (get used to this, as you will do this often).
select ‘captain-01’ at https://captain.testing.alfred.software, or whatever you named it in previous steps.
Now follow the steps, log in. Select the correct app: ‘django-testing’ for me.
press <ENTER> when prompted to deploy master branch
note that uncommitted and gitignored files (if any) will not be pushed to server! Are you sure you want to deploy? y
You should now see your code being built. Give it a minute.
Upon successful completion you should see the following:
Let’s check the URL if you see ‘Hello World’. Then congratulations, you did it correctly.
Creating a superuser on the remote Django
assuming your ssh works. SSH into the Droplet.
in my case this is, you need to enter your IP though (the default username is root.):
if asked about fingerprint, type ‘yes’
Once inside, run the following command to run a shell inside your Django project. change myappname, with your app name that you specified for the Django app on CapRover previously.
docker exec -it $(docker ps --filter name=srv-captain--myappname -q) /bin/sh
So in my case, I ran this:
root@django-test-droplet:~# docker exec -it $(docker ps --filter name=srv-captain--django-testing -q) /bin/sh
once inside the /usr/src/app directory. Run the following:
python manage.py createsuperuser
and fill in the superuser information as before. if you get the message: ‘Superuser created successfully’, then you did it correctly. You can close the command line now.
Note: If you are ever having problems and would like to see the console of the Django server. Simply SSH into the server again and then run the following (replace ‘my-app’, with name of your CapRover app):
docker service logs srv-captain--my-app --since 60m --follow
Now if you wish you can log in to your Django remote server and login to the admin account with the information you just provided. In my case this is:
Now let us set up SSL to get that beautiful green lock in the search bar.
Go back to CapRover, then go to Apps, click on your Django app (‘django-testing’ in my case). This is the best part. Just click on ‘Enable HTTPS’, and also tick the box that says ‘Force HTTPS by redirecting all HTTP traffic to HTTPS’. Now click ‘Save & Update’.
Nice(r) Domain name
as you might have noticed, the current domain name doesn’t look that nice. Let’s change it.
Go back to your domain DNS Records management settings.
let’s say I want this Django webserver to be available under ‘cheese.alfred.software’. I add a new row to my DNS, as follows
- Type: CNAME
- Host: cheese.alfred.software
- Answer: django-testing.testing.alfred.software
- TTL: 600
So the Host, is what you want it to be, and the Answer is what your Django server should be under right now by default.
Now we have to register the change in CapRover.
Go to your Django app, and where it says ‘Connect New Domain’ add the domain you just added to the DNS records. You should get a message ‘New Domain Is Now Successfully Connected.’. Finally, a new box is enabled that says ‘Enable HTTPS’. Click that, and then click ‘Save & Update’.
We’re almost done. Now we need to add the new domain to Django, otherwise, we will get a Bad Request (400) error. In your Django App, goto Environmental variables. Under CR_HOSTS, add your new domain (comma separated). Finally, Save (DO NOT PUT SPACES BETWEEN THE COMMA’S).
On my Phone. A nice subdomain and that green lock 🙂
And that’s it.
Actually, one more thing.
once, you can actually instantly deploy after by doing the following:
caprover deploy --default
The previous setup will be used, allowing for quicker deployments.
If you want to migrate your Heroku Postgres database over to your new Caprover Postgres database, check out this article.
I hope this tutorial helped you in some way. Thanks for reading.