This guide covers the end-to-end process of deploying SWACN using Cloudflare for DNS & Email, DigitalOcean for Hosting, and GitHub for CI/CD.
Note
Hosting on Azure? If you prefer to host on Microsoft Azure at the lowest cost (~$6.86/month), we have a dedicated Azure Deployment Guide that leverages a single Standard_B2ats_v2 Virtual Machine with Caddy and PostgreSQL.
We recommend using Cloudflare as your DNS provider because it offers Free Professional Email Routing (e.g., hello@swacn.com -> your personal email).
- Log in to your Namecheap account.
- Go to your Domain List and click Manage next to
swacn.com. - Find the Nameservers section.
- Select Custom DNS and enter the two nameservers provided by Cloudflare (e.g.,
ashley.ns.cloudflare.comandoliver.ns.cloudflare.com). - Click the green checkmark to save.
- Log in to Cloudflare and add your site
swacn.com. - Go to the DNS tab.
- Create the following records:
- A Record: Name
@, points to your DigitalOcean Droplet IP. (Proxy: Enabled/Orange Cloud). - A Record: Name
www, points to your DigitalOcean Droplet IP. (Proxy: Enabled/Orange Cloud).
- A Record: Name
- Go to the SSL/TLS tab and set the mode to Full or Full (strict).
If you want to send and receive emails from a professional inbox for free:
- Sign up for the Zoho Mail "Forever Free" Plan.
- Verify your domain by adding the
TXTrecord Zoho provides to your Cloudflare DNS. - Add the following MX Records in Cloudflare (delete any existing MX records first):
- Type:
MX, Name:@, Value:mx.zoho.com, Priority:10 - Type:
MX, Name:@, Value:mx2.zoho.com, Priority:20 - Type:
MX, Name:@, Value:mx3.zoho.com, Priority:50
- Type:
- Add the SPF Record (Type:
TXT, Name:@, Value:v=spf1 include:zoho.com ~all). - Enable DKIM in your Zoho Control Panel and add the resulting
TXTrecord to Cloudflare to ensure your emails don't go to spam.
- Go to your GitHub Developer Settings > OAuth Apps > New OAuth App.
- Application Name:
SWACN Production - Homepage URL:
https://swacn.com - Authorization callback URL:
https://swacn.com/api/auth/callback - Generate a Client Secret and save it.
- Go to Google Cloud Console.
- Create a new project.
- Go to APIs & Services > Credentials > Create Credentials > OAuth client ID.
- Application type: Web application.
- Authorized redirect URIs:
https://swacn.com/api/auth/google/callback - Save the Client ID and Client Secret.
- Log in to your Dodo Payments dashboard.
- Go to Developers > API Keys and generate a live key.
- Go to Webhooks and add your production URL:
https://swacn.com/webhooks/dodopayments - Select the following events:
payment.succeeded,payment.failed,subscription.active,subscription.renewed,subscription.cancelled,subscription.expired. - Save the Webhook Secret.
- Click Create > Droplets.
- OS: Ubuntu 22.04 LTS (x64).
- Size: Basic (Regular SSD) - $6 or $12/mo plan is sufficient.
- Authentication: Choose SSH Key. (If you don't have one, follow the "New SSH Key" prompt).
- Finalize: Hostname
swacn-prod.
SSH into your droplet:
ssh root@your_droplet_ipRun these commands to install Caddy and PostgreSQL:
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy postgresql postgresql-contrib
sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddysudo -u postgres psqlCREATE DATABASE swacn_db;
CREATE USER swacn_user WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE swacn_db TO swacn_user;
\qmkdir -p /opt/swacn
nano /opt/swacn/.envPaste and fill with your Production values:
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=swacn_db
DB_USER=swacn_user
DB_PASS=your_secure_password
LISTEN_ADDR=127.0.0.1
LISTEN_PORT=8080
APP_URL=https://swacn.com
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
DODO_PAYMENTS_API_KEY=...
DODO_PAYMENTS_API_URL=https://api.dodopayments.com
DODO_PAYMENTS_WEBHOOK_SECRET=...
DODO_PRO_PRODUCT_ID=...
LOG_PATH=/opt/swacn/logs
LOG_LEVEL=INFOOn your local machine:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_swacn
ssh-copy-id -i ~/.ssh/id_rsa_swacn.pub root@your_droplet_ip
cat ~/.ssh/id_rsa_swacn # Copy this private keyIn your Repo Settings > Secrets > Actions, add:
SSH_HOST: Droplet IPSSH_USER:rootSSH_KEY: [The private key you just copied]DB_PASSWORD: [Your Postgres password]
- Commit and push your code to
main. - Push a version tag to trigger the build:
git tag v1.0.0 git push origin v1.0.0
- GitHub Actions will:
- Build the React frontend.
- Compile the C++ backend (in a Linux container).
- Sync files to
/opt/swacn. - Start the
swacnsystemd service. - Configure Caddy for
swacn.comwith Automatic SSL.
- Check App Status:
systemctl status swacn - View App Logs (Real-time):
journalctl -u swacn -f - Check Backend Log Files:
tail -f /opt/swacn/logs/swacn.log - Check Caddy Access Logs:
tail -f /var/log/caddy/swacn.access.log - Check Web Server:
systemctl status caddy - Initial DB Schema: Run
psql -U swacn_user -d swacn_db -f /opt/swacn/schema.sqlon the server once after the first deploy.
The system is configured to use rotating file-based logs. If you need to set them up or check them manually:
If the directories are not created automatically, run:
# Backend logs
sudo mkdir -p /opt/swacn/logs
sudo chmod 755 /opt/swacn/logs
# Caddy logs
sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddy# Watch backend activity (real-time)
tail -f /opt/swacn/logs/swacn.log
# Watch web traffic (real-time)
tail -f /var/log/caddy/swacn.access.log
# View system service logs (journald)
journalctl -u swacn -fIMPORTANT: Never run your full schema.sql on a production database after the first time, as it may contain DROP TABLE commands that wipe your data.
- SSH into your Droplet.
- Connect to the database:
psql -U swacn_user -d swacn_db - Run an
ALTERcommand. For example, to add a new column:ALTER TABLE users ADD COLUMN bio TEXT;
- If you have many changes, create a new
.sqlfile for just those changes and run it:psql -U swacn_user -d swacn_db -f /opt/swacn/migrations/002_update.sql
- Caddy automatically handles SSL (HTTPS) for
swacn.com. - Ensure your Droplet's firewall (UFW) allows 80, 443, and 22.
ufw allow 80/tcp ufw allow 443/tcp ufw allow 22/tcp ufw enable