Search code examples
nginxdnscloudflarenginx-reverse-proxy

Multiple Servers Running on my Home Computer with CloudFlare?


I have a home server that I want to host multiple websites on. My home server's IP changes once every few months, so I have a script detect IP changes and it update a free DNS provider that I setup with the new IP. The free dns is ugly. Lets say that it is ugly.free-dns.com

I have 2 domains (example1.com, and example2.com). I want CloudFlare to own my 2 domain names, and route the requests to my ugly domain name underneath the hood.

My original plan was to cname each of the urls on CloudFlare to ugly.free-dns.com/example1, and ugly.free-dns.com/example2 respectively, and then use a nginx reverse-proxy to detect the pathing difference, and route to the correct local ports, where each site would be hosted separately in a docker container.

I've never used cnames (or nginx) before, and it turns out that you can't cname with a path, which throws a wrench into my entire plan. Some research suggests that Virtual Hosts may be what I want, but I'm unsure how this would work with CloudFlare. I find myself a bit in over my head, so I thought I'd ask for some help.


Solution

  • You can use the CloudFlare API directly and avoid your ugly.free-dns.com so that every time your IP changes you update it directly in Cloudflare, here is a basic script:

    #!/bin/sh
    
    API=<your API key> 
    [email protected]
    ZONEID=<your ZONE ID>
    RECORDID=<your record ID>
    RECORDNAME=www
    
    IP=$(curl -s http://myip.country/ip)
    
    curl -fs -o /dev/null -XPUT "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORDID" \
      -H "X-Auth-Email: $EMAIL" \
      -H "X-Auth-Key: $API" \
      -H "Content-Type: application/json" \
      --data "{\"type\":\"A\",\"name\":\"$RECORDNAME\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}"
    

    Then you just need to configure Nginx as to handle all the request for your domains, from the docs: http://nginx.org/en/docs/http/server_names.html

    server {
        listen       80;
        server_name  example.org  www.example.org;
        ...
    }
    
    server {
        listen       80;
        server_name  *.example.org;
        ...
    }
    
    server {
        listen       80;
        server_name  mail.*;
        ...
    }
    
    server {
        listen       80;
        server_name  ~^(?<user>.+)\.example\.net$;
        ...
    }