Sammy's Travels is a demo project used to showcase multiple technologies and ways of doing things, like infrastructure deployment on DigitalOcean via Terraform, Secret Storage on Doopler or creating Distributed, Immutable and Ephemeral infrastructure. The project was inspired by the following DigitalOcean community repo by @erikaheidi.
- docker compose. # For local development
- DigitalOcean account (Haven't got one? Start your free trail now and grab $200 in credits.);
- Doppler account (There is a free tier for developer projects);
- packer cli;
- terraform cli;
- A Domain you own added to DigitalOceans' Domain section and the nameservers in your chosen domain registrar pointed towards DigitalOceans' own NS records(docs).
- A container registry like Docker Hub or DigitalOcean's Container Registry.
A docker-compose.yml file is used to run the application. The following provides a description of each of the components:
- nginx - an HTTP and reverse proxy server.
- db_migrate - a DB migration tool written in Go.
- backend - The backend of the website written in Go.
- frontend - The frontend of the website written in React.
In addition to the above components, we will need somewhere to store our images, like a Spaces bucket, and a PostgreSQL database to store information of the places Sammy has travelled, or wants to travel, to.
The application can be run locally by running a docker compose up -d
command from the local folder. This will build the frontend
, backend
and db_migrate
containers from source as well as deploy a PostgreSQL database container and a localstack container to simulate the bucket. Once the containers are up and running point your browser to http://localhost to access the application.
The only differences between the docker-compose.yml
file used for local development and that used in production are disabling sslmode
in the db_migrate
container and the following environment variables used in the backend container:
backend:
...
environment: # Only needed for local development
- DB_SSL_MODE=disable # SSL connection to the database disabled for local development
- FORCE_PATH_STYLE=true # Forces bucket path to adhere to the following format http://localhost:4572/{bucket_name}
The project deploys the following architecture on DigitalOcean:
All of the above will be deployed on DigitalOcean and running on DigitalOcean Droplets. A Managed PostgreSQL Database is also used as well as a Spaces bucket for object storage. A Domain with SSL certificate, Load Balancer and a Firewall are also setup to ensure we can securely access the website from the web.
Secrets are managed and stored on Doppler. There are multiple ways to initially store secrets on Doppler but we will be using their terraform provider to store and subsequently access the secrets.
We will use Packer and Terraform to automate the build and provision the resources.
- Create a DigitalOcean API token with read/write permissions (docs)
- Create a DO Spaces access key and secret (docs)
- Create a Doppler personal token, or service account if you are on the Team or Enterprise plan, for terraform (docs)
- Create a Domain in DO and change nameservers in your domain registrar (docs)
- (Optional) If using Terraform Cloud to manage your state file, create a user API token
We're going to run some cli commands within our terminal which can be automated within a CI/CD process.
Once we've setup and created all of the above, clone the repository:
git clone https://github.com/digitalocean/supabase-on-do.git
cd supabase-on-do
- Our first step is to push our frontend, backend and db_migrate containers to our container registry.
- Next is to build a snapshot of the Droplet we will be running, by following the documentation in the packer directory.
- Finally we will deploy our resources using terraform as specified here.
Each container needs to be pushed to a container registry so that the deployed Droplets can download the images and spin them up. The example below shows you how to do this to Docker Hub via the docker cli.
You will first have to login to docker by running the login command, substituting USER with your Docker Hub username.
docker login -u USER
From the directory containing the Dockerfile
run the following command with the appropriate name for CONTAINER_NAME (for example be-sammys-travels for the backend container)
docker build -t <CONTAINER_NAME> .
Then tag and push the image to the container registry substituting for USER and TAG, where TAG can be the version number of your build.
docker image tag <CONTAINER_NAME> <USER>/<CONTAINER_NAME>:<TAG>
docker image push <USER>/<CONTAINER_NAME>:<TAG>