The introduction of the development is completed and now it's time to talk about how to set up a website with the code I've written.
Deployment
MongoDB Atlas
For my database, I chose MongoDB Atlas. It offers a free-tier service and removes the need to manage servers manually. The cluster setup ensures reliability with minimal intervention.
DigitalOcean Droplet
MongoDB Atlas places certain constraints on hosting options for my API and web servers. The API server requires access to MongoDB, which must be available on a public network. By default, MongoDB Atlas is not publicly accessible. During development, I added my IP address to the Atlas network access allowlist.
MongoDB Atlas offers Peering Connection and Private Endpoints. However:
- Peering Connection is only available on AWS, Google Cloud, and Azure.
- Private Endpoints are unavailable on the free-tier service.
Thus, I needed a host provider with a static IP address, like AWS, Google Cloud, Azure, or another option. I ultimately chose DigitalOcean Droplet for its simplicity and affordability, which perfectly fit my personal project.
Docker
To deploy web and API servers, I containerized both services using Docker. This simplifies dependency management. Using a docker-compose.yml
file, I can deploy all services with one command. You can find my docker-compose.yml here.
In addition to zink-web
and zink-api
, the file includes:
- NGINX: Used as a reverse proxy, exposing only its ports to the public Internet for security reasons.
- Waline: Originally deployed on Vercel, I migrated it to DigitalOcean Droplet due to high latency.
DNS Management
After deploying the services, I purchased a domain and configured its DNS records. Here’s an example of my setup:
Record Type | Host | Value |
---|---|---|
A | @ | 192.168.1.1 |
CNAME | blobs | zink.top |
CNAME | www | zink.top |
- The
@
symbol represents the root domain. - The A record points the root domain to the DigitalOcean Droplet’s IP address.
- The CNAME records map aliases (
blobs.zink.top
andwww.zink.top
) tozink.top
.
Once DNS records are updated, it may take up to 48 hours to propagate fully.
HTTPS Configuration
Why HTTPS?
HTTP transmits data in plain text, making it vulnerable to interception (e.g., man-in-the-middle attacks). Since I use JWT tokens for authentication, HTTPS is essential to protect sensitive data.
SSL/TLS Certificate
I used Let's Encrypt to obtain a free SSL/TLS certificate from a trusted Certificate Authority.
NGINX Configuration
After obtaining the certificate, I updated the NGINX configuration to enable HTTPS:
- Redirected all HTTP requests to HTTPS for security, except for the webroot used by Certbot.
- Configured the HTTPS block to include paths for the certificate and key files.
Since I run NGINX in a Docker container and generate certificates outside the container, I mapped the certificate files from the host to the container in the docker-compose
file. You can view my NGINX configuration here.
blobs.zink.top
Why did I create this alias domain? It serves as a media hosting service. To insert an image into a markdown post:
- Upload the image to the DigitalOcean Droplet using
scp
. - Access it via the
blobs.zink.top
domain.
This setup ensures a seamless and efficient workflow for managing media files.