0x01

It has been running blockchain daily for some time, and the traffic volume is also increasing. However, because it is built on foreign VPS, some students often complain that the website cannot be opened. During this period, I tried some schemes and found that the decentralized scheme of IPFS could perfect this problem.

Those of you who are interested in blockchain may already have some knowledge of IPFS. I have also published several articles on ipFS in daily newspapers. Those who are interested in ipFS may follow them. Ipfs is a point-to-point distributed file system. Whenever a file is added to an IPFS node, it has a hash value to represent its existence. Even if you modify just one bit of data in the file, the hash will be completely different. When the next step is to look up the hash on the IPFS distributed network, it uses a distributed hash table to quickly find the node that has the data, retrieve the data, and use the hash to verify that it is the correct data. The nodes where these files are stored can be thought of as a form of miner, except that unlike Bitcoin, which uses computational power for proof of work, it uses storage and bandwidth. The IPFS team is currently working to release Filecoin based on POR (a common understanding of resources related to bandwidth with incentives, storage capacity, etc.).

0x02

Well, with ipFS out of the way, let’s take a look at how IPFS can be combined with Django to build its own decentralized CDN.

Since djangos web pages are dynamically rendered, and IPFS can only store static files, you need to make django web pages static before you upload them to IPFS.

Taking blockchain Daily as an example, there are two scenarios that can be implemented

  1. Generate a static web page file every time you create a daily save in admin background
def generate_static_html(issue):
    articles = Article.objects.filter(issue=issue, status=2).order_by("-created")
    context = {'articles': articles, "issue": issue}
    static_html = os.path.join(settings.IPFS_ROOT, "%s.html" % issue.id)
    content = render_to_string('articles_ipfs.html', context)
    with open(static_html, 'w') as static_file:
        static_file.write(content.encode("utf-8"))

class IssueAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        obj.save()
        if obj.status == Issue.PUBLISHED:
            generate_static_html(obj)
Copy the code

2. Generate site-wide static files periodically and synchronize them to IPFS

0x03

Next we use IPFS to upload the static files generated above.

  1. To install IPFS, refer directly to the official tutorial.Ipfs. IO/docs/instal…, assuming that is installedgo-ipfs
  2. Then performipfs init, an IPFS node is set up locally.
  3. Viewing node IDSipfs id
{ "ID": "QmYpbbyrVQspuNNqowRip3ShmYFcXvnUkAvB23GVyjfenV", "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDFsZQi+VdfZIHTcNwsAMfjaAo9fe7GtiusbF4ZWqGxo3v05sHXrHbM1fb+FRnCmzZ7tZ6 79EfgxCzN38q1bAvOQVtdD/TzDQQKrLJEOyorhnML8cOtMWua/Rkvfs56Ut6fPgVHvCFpuhrUZE8eBTwKInf5kJaEOZfT/u9pi3BO5HJMUO1oHE6R66IKO3Q Qda3QXahx4dndc3Sx7HX+MeBd6kUPTpOtqmeFIRJE0rDSXnIxiUGlqkMbfIAgBo4XKBuajm+UMLTCT5Wo/0cNu+j8mLuNLqwcOWNR7KKKCZzUFrm+TCxMjAu Sy2ujgunH19vIMluGlOgiXvydwrbmZiU1AgMBAAE = ", "Addresses", null, "AgentVersion" : "go - ipfs / 0.4.13 /", "ProtocolVersion" : "Ipfs / 0.1.0 from"}Copy the code

4. Start the ipfs daemon on the node

Initializing daemon... Swarm listening on/ip4 127.0.0.1 / TCP / 4001 Swarm listening on/ip4 172.22.0.29 / TCP / 4001 Swarm listening on / ip4 192.168.99.172 / TCP / 4001 Swarm listening on ip6 / : : 1 / TCP / 4001 Swarm listening on P2p - circuit/ipfs/QmYpbbyrVQspuNNqowRip3ShmYFcXvnUkAvB23GVyjfenV Swarm announcing/ip4/127.0.0.1 / TCP / 4001 Swarm Announcing/ip4 172.22.0.29 / TCP / 4001 Swarm announcing/ip4 192.168.1.2 instead/TCP / 36734 Swarm announcing / ip4 192.168.99.172 / TCP / 4001 Swarm announcing ip6 / : : 1 / TCP/API server listening on 4001 / ip4/127.0.0.1 / TCP / 5001 Gateway (readonly) Server listening on /ip4/127.0.0.1/ TCP /8080 Daemon is readyCopy the code

5. Visit http://localhost:5001/webui at this time, you can see some of the local node information, including file hash, connecting nodes, configuration items. You can also choose to upload files directly here.

6. You can run the ipfs add -r ipfs command to upload the entire static file directory. Ipfs is the static file directory generated in the preceding section.


7. You can see the root of the hash for QmQ19m1wLVpvi4142Mr3HHJJBx5QmuS95ibLt8ivZyG9GE, direct access to the ipfs. IO/ipfs/QmQ19m…


8. Now the website can be accessed, but there is a problem, the hash value will change with the change of the file, that is, once the website is updated, the above address will change, so we can publish the website to IPNS. Bind the node ID (which does not change from file to file) to the project root hash so that when updating the blog, it can be republished to IPNS.

9. Run ipfs name publish < root directory hash>. After publishing, run ipfs name resolve < node ID > to check whether the binding is complete.


IO /ipns/QmYpbb… You can also get the page you want.

0x04

Finally, a quick word on Blockchain Daily, a blog inspired by the Bay Area Daily. It mainly records the high-quality blockchain articles that bloggers read in learning blockchain, and regularly releases push through some channels (Weibo, Zhihu, Twitter, RSS, Medium).

The site is built using Django, nginx is responsible for load balancing, the container is handling processes, and the Task Queue is Redis. Tasks that Scheduler uses Celery Beat while Async Worker uses Celery