simple-ddns is a little flask application that can be run on a VPS to keep track of something elses IP address (a home network for example). The flask app provides a get method to view the ip and a post method to set the ip. It can edit an nginx configuration to redirect a subdomain or url to the ip. An included python script can be used on the client (via cron job or manually) to update the flask app.

This will walk through setting it up with an nginx server on a Ubuntu machine.

First clone the repo from:

Set Up

Flask Server

Install python3, virtualenv, rabbitmq.

We use Flask as the http api framework for our app. Because we want it to respond to http requests quickly we run the bulk of the logic in a Celery task. Celery is asynchronous task queue so we can add our task there and the flask app can carry on to respond to the http request. Celery needs a broker, a place for the flask app to queue its tasks and celery to read from. We use rabbitmq because its the default supported by celery and you literally just have to install it and it will work.

git clone
cd simple-ddns
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.txt

Generate secure random hex string. Github recommends:

ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'

Create a file,


Create a file


You can now test it by running but it will run on localhost, in this case localhost/dns/. You can use a tool like httpie to test post-ing to it.

http --json PUT localhost/dns/ ip=

To set it up with nginx read on. In your nginx site conf file:

location = /dns {
        rewrite ^ /dns/;
location /dns/ {
        try_files $uri @dns;
location @dns {
        include uwsgi_params;
        uwsgi_pass unix:/path/to/simpleddns/dns.sock;

The APP_ROUTE setting should match whatver url you use in the nginx conf. You can then run:

sudo nginx -t

To test the config. And if it works:

sudo nginx -s reload

You probably want to run these as systemd services so they start on boot and restart themselves. Create two files in /etc/systemd/system/:


Description=uWSGI instance to serve dns project

ExecStart=/path/to/simple-ddns/venv/bin/uwsgi --ini wsgi.ini



Description=Celery instance to serve deploy dns

ExecStart=/path/to/simple-ddns/dns/venv/bin/celery worker -A dns.celery -f /path/to/simple-ddns/log-celery.log --concurrency=1 -n dnsWorker  -Q dns


Ensuring that you replace the user name and the paths. Then:

sudo systemctl enable dns.service
sudo systemctl enable dns_celery.service
sudo systemctl start dns.service
sudo systemctl start dns_celery.service

To set up the subdomain redirect you will need to add something like this to your nginx config:


root /var/www/;

location / {
    include /path/to/simple-dddns/nginx/;

The name of the conf file should match the NGINX_CONF_NAME in

Because we need to be able to restart nginx we will add some commands to our sudoers file so that flask won't need to authenticate.

visudo /etc/sudoers.d/your_user

Always use visudo to edit this file. Then add

your_user ALL=(ALL) NOPASSWD: /usr/sbin/service nginx start,/usr/sbin/service nginx stop,/usr/sbin/service nginx restart,/usr/sbin/nginx -t,/usr/sbin/nginx -s reload

And then because nginx will want to read the conf file thats generated in the nginx folder we need to add ourselves to the www-data group:

usermod -a -G www-data your-user

That should all work now.


Install python3, virtualenv, dnsutils.

git clone
cd simple-ddns/client
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.client.txt

You'll need to make two files.

DNS_URL="url to your flask app"



Then to run:


To automate it:

crontab -e

Then append

30 * * * * /path/to/simple-ddns/client/venv/bin/python3 /path/to/simple-ddns/client/