Step by step guide to deploy a private IPFS cluster on Ubuntu

In this article, we will be creating a private IPFS network. It means that it won't connect to the public IPFS network and the data you put on the nodes of this cluster will be localised to your private network. So let's start.

IPFS stands for InterPlanetary File System. It is a protocol and network somewhat similar to BitTorrent. If you want to know what IPFS is, go to their official website for a demo -

Step 1 - Install IPFS using the command line

  • Before you start with this, please go to and copy the link of the latest Go implementation of IPFS. At the time of writing this, the latest version is Version v0.4.17 for Linux 64bit.
  • Now let us install the latest version of IPFS. For this, first, you need to install Go and then we will install IPFS. Installing the distribution won't start the IPFS filesystem so don't worry about it connecting it to the public network. Execute these commands one by one:
    sudo apt-get update
    sudo apt-get install golang-go -y
    tar xvfz go-ipfs_v0.4.13_linux-amd64.tar.gz
    sudo mv go-ipfs/ipfs /usr/local/bin/ipfs

  • To verify your installation is working, type "ipfs version". You should get an output like this:
    ankit@ankit-K54C:~$ ipfs version
    ipfs version 0.4.13

Step 2 - Initialize the first and second private node

The participants of the public network of IPFS usually have just one IPFS node on their machines since that is all they require to participate. However, in our case, we will deploy 2 IPFS nodes on the same machine. You can do it on 2 different machines too which are on the same network and are able to ping each other. By default, IPFS is initialized in a hidden directory in your user home directory - ~/.ipfs. Since we will be deploying 2 nodes on the same machine, we will be doing so in two difference directories - ~/.ipfs1 and ~/.ipfs2. You can do it in the default ~/.ipfs and at any other location or if you are using different machines then you don't need to worry about the directories. Let us start the deployment:
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs1 ipfs init
initializing IPFS node at /home/ankit/.ipfs1
generating 2048-bit RSA keypair...done
peer identity: QmQVvZEmvjhYgsyEC7NvMn8EWf131EcgTXFFJQYGSz4Y83
to get started, enter:

ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs2 ipfs init
initializing IPFS node at /home/ankit/.ipfs2
generating 2048-bit RSA keypair...done
peer identity: QmToxF88PoBFEkbSLzZ3WLePJn6tvGAM8ZDrJuPrhGhj7P
to get started, enter:

ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

You should be able to see two directories ~/.ipfs1 and ~/.ipfs2

ankit@ankit-K54C:~$ ls .ipfs*
blocks config datastore datastore_spec Keystore version

blocks config datastore datastore_spec keystore version

If you are getting the same output then you have successfully initialized 2 IPFS nodes. You can initialize any number of nodes you want.

Creating a Private network

Till now we have just created your IPFS nodes which are one step behind in joining the public IPFS network. However, since we are creating a private IPFS cluster we need to use the still-in-experimental-stage features of IPFS to create a private network.
Create swarm.key file to enable private network feature of IPFS
We will start by adding a key called the swarm.key that tells the IPFS nodes that they will be a part of a private network which all will share this swarm.key file.

There is an application which generates this swarm file but for that, you need to have Go language installed on your system. Install Go before proceeding with the next step.

Once you have Go installed, run the following command to install the swarm.key generation utility:
go get -u

Now run this utility in one of your node like this:
ipfs-swarm-key-gen > ~/.ipfs1/swarm.key

Copy the file generated to the IPFS directory of each node.

Bootstraping IPFS node

IPFS requires one or more bootstrap nodes which are used by the IPFS daemon to learn about the other nodes that are present in the network. In the case of a private network, we need to set up our own bootstrap node since we won't be connecting to the public network node and hence won't have access to the bootstrap nodes of IPFS developers. A bootstrap node is basically the same IPFS node just with the added feature of acting as the bootstrap. There is no separate installation required for this but just a config file entry.

First of all, you need to remove the default entries of bootstrap nodes from all the nodes you have created. Do this by using this command:
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs1 ipfs bootstrap rm --all

Now add the hash address of your bootnode to each of the nodes including the bootnode.
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs1 ipfs bootstrap add /ip4/

The IP part - will be changed to your machine IP in case you are using different machines. The last part is the node hash key which is generated when you create your node. You can see it above where it shows "peer identity: QmQVvZEmvjhYgsyEC7NvMn8EWf131EcgTXFFJQYGSz4Y83". Run this for all of your nodes.

Assigning port number for gateway and configuring IP for communication

Inside the .ipfs folder, like in my case .ipfs1 folder, there is a "config" file. It contains a lot of details including the network details on which our IPFS nodes will work on.
Open this config file and find "Addresses". It will look like this:
"Addresses": {
"API": "/ip4/",
"Announce": [],
"Gateway": "/ip4/",
"NoAnnounce": [],
"Swarm": [

The IP mentioned in the API key is the one on which IPFS will bind on for communication. If you are using different machines then mention the IP address of your computer. In our case, since we are using localhost/, we will just select different ports for each of the machines and will leave IP as it is. For the first node there is no need to change anything, but for the second, we will increment each of the port values like below:
"Addresses": {
"API": "/ip4/",
"Announce": [],
"Gateway": "/ip4/",
"NoAnnounce": [],
"Swarm": [

Start the node and test!

We are done with all the configurations and now it is time to start both the nodes to see if everything went fine. To do this, open two consoles since we need to keep both the nodes running. You can do this by sending the process background too if you prefer that.
We will use an environment variable to make sure that just in case if there is some mistake in our configuration and the private network is not fully configured, the nodes don't connect to the public IPFS network and the daemons just fail.
The environment variable for the same is "LIBP2P_FORCE_PNET" and to start the IPFS nodes you just need to start the daemon using "ipfs daemon" command. In our case the command and the output look like this:
ankit@ankit-K54C:~$ export LIBP2P_FORCE_PNET=1 && IPFS_PATH=~/.ipfs1 ipfs daemon
ankit@ankit-K54C:~$ export LIBP2P_FORCE_PNET=1 && IPFS_PATH=~/.ipfs2 ipfs daemon

Do note the message log stating "Swarm is limited to the private network of peers with the swarm key" which means that our private network is working perfectly. Now let's add the file from ipfs1 and try to access it from ipfs2.
ankit@ankit-K54C:~$ mkdir ankit
ankit@ankit-K54C:~$ cd ankit/
ankit@ankit-K54C:~/ankit$ echo hello > file1.txt
ankit@ankit-K54C:~/ankit$ IPFS_PATH=~/.ipfs1 ipfs add file1.txt
added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN file1.txt
ankit@ankit-K54C:~/ankit$ IPFS_PATH=~/.ipfs2 ipfs cat file1.txt
Error: invalid 'ipfs ref' path
ankit@ankit-K54C:~/ankit$ IPFS_PATH=~/.ipfs2 ipfs cat QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN

Note that we have added the file to ipfs1 which gave us back a hash. Now when you try to access the same file from ipfs2 with the file name, it won't work, but replace that with the hash and you can see the contents of the file. Now we will try to access the file from the browser.

You can access the file by using the gateway address like this:
You should be able to see the content of the file on the browser.

You can similarly add a whole directory too.
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs1 ipfs add ankit/ -r
added QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN ankit/file1.txt
added QmUs71TZY6Vy47vYrgu5baJwfGQNpMQKeHE2eAn3k2r5kv ankit

and when you try to access it you will see the hash of the file inside if any along with the file name:
ankit@ankit-K54C:~$ IPFS_PATH=~/.ipfs2 ipfs ls QmUs71TZY6Vy47vYrgu5baJwfGQNpMQKeHE2eAn3k2r5kv

If you face any problems in any of the steps please do feel free to communicate with me through the comments section.


Guest Author: Rohit Khatri24 Sep 2018

When I do IPFS_PATH=~/.ipfs1 ipfs swarm peers, It doesn't show anything, can you tell me what's wrong?

Author: Ankit24 Sep 2018 Member Level: Platinum   Points : 2

Hi Rohit,
Which operating system are you using?
If you are following the steps mentioned above, have you created its peer on the same network?
Please refer this thread which seems similar to your problem -

Guest Author: Gautam Raj22 Oct 2018

How do I write something to another system from my system using IPFS?

Guest Author: lee12 Nov 2018

Hi, when i try to use "ipfs-swarm-key-gen > ~/.ipfs/swarm.key" , it will display:ipfs-swarm-key-gen: command not found. could you tell me what's wrong about this?
i use ubuntu

Guest Author: adoley18 Jan 2019

Hi Ankit,
When I execute the command

export LIBP2P_FORCE_PNET=1 && IPFS_PATH=~/.ipfs1 ipfs daemon

I get the below error
Initializing daemon...
go-ipfs version: 0.4.18-
Repo version: 7
System version: amd64/darwin
Golang version: go1.11.1
14:06:44.498 ERROR cmd/ipfs: error from node construction: failed to configure private network: malformed private network key: no codec for /base16/

Any suggestion.

Author: Ankit19 Jan 2019 Member Level: Platinum   Points : 2

Hi Adoley,
Looks like there is a problem decoding the swarm key.
The error is being generated from one of the Go module of IPFS - line 14.

Can you try using an older version of swarm key generator? It might be a problem with your current version of key generator.

Guest Author: adoley19 Jan 2019

Hi Ankit,
Thanks for your quick response. This article is really helpful.

I have found a work around.

If I execute the below command
ipfs-swarm-key-gen > ~/.ipfs1/swarm.key

then the content of the swarm.key is as below and I get the above mention error


If I remove the space before /base16/ and 65a2....... as below

then I am able to create the private network.

Author: Ankit19 Jan 2019 Member Level: Platinum   Points : 0

Thanks Adoley for sharing the solution!

Guest Author: Saritha25 Jan 2019

hi there.. a question.
Am working behind a corporate proxy env and trying tos etup P2P Private network.
After exporting the LIBP2P_FORCE_PNET variable, and starting the ipfs daemon , I get the following error.
Successfully raised file descriptor limit to 2048.
09:18:47.468 ERROR p2p-config: tried to create a libp2p node with no Private Network Protector but usage of Private Networks is forced by the enviroment config.go:69
09:18:47.514 ERROR cmd/ipfs: error from node construction: privnet: private network was not configured but is enforced by the environment daemon.go:332
Error: privnet: private network was not configured but is enforced by the environment
Could you please help.

Author: Ankit25 Jan 2019 Member Level: Platinum   Points : 2

Hi Saritha,
I need a bit more information on your problem. From the error message, it looks like you have not done the steps required specifically for setting up a private network.

Have you done the steps mentioned under the "Bootstrapping IPFS node" and generating the Swarm key?

Guest Author: Rajat05 Feb 2019

my boot node build was fine.

now when building the 2nd node... do I run this commaand on the 2nd node as well as the bootnode ?
IPFS_PATH=/opt/ipfs-data ipfs bootstrap add /ip4/NODEIPADDRESS/tcp/4001/ipfs/QmToxF88PoBFEkbSLzZ3WLePJn6tvGAM8ZDrJuPrhGhj7P

additionally would I have to also re-run the bootstrap add command that I ran on the bootnode on the 2nd node ?
IPFS_PATH=/opt/ipfs-data ipfs bootstrap add /ip4/BOOTNODEIPADDRESS/tcp/4001/ipfs/QmQVvZEmvjhYgsyEC7NvMn8EWf131EcgTXFFJQYGSz4Y83

Author: Ankit05 Feb 2019 Member Level: Platinum   Points : 2

You have to run the "bootstrap add" command for all the nodes because that need to tell each node what is their new bootstrap node. Don't forget to run the command to remove default bootstrap nodes details before you run the bootstrap add command for the private network.

Guest Author: Dattatray13 Mar 2019

This is awesome article Ankit. Thanks for explaining all the steps. Just a request if possible can you please update this with latest changes. There might be considerable changes since you have written this post. Thanks once again

Guest Author: Shrey02 Apr 2019

Hi Ankit, I am unable to try this on with local system and AWS instance. My local system was unable to access the file which I uploaded to the server. And with server also unable to access that file in browser. Can you please help me with this?

Guest Author: madesh03 Apr 2019

Hi, I created a private network. All the commands seem to work fine with no errors. But when I upload the file in the second node, it gets uploaded to the public IPFS node too.

Author: Ankit03 Apr 2019 Member Level: Platinum   Points : 4

@Shrey, can your local system ping your AWS instance? It is a network connectivity problem which I honestly can't help much with. I would suggest using 2 AWS instances or some machines on the same network to set up the IPFS cluster.

@Madesh, I guess you are trying to say that your files are getting uploaded to the public IPFS node too? Please go through my article. You need to delete the default bootnode configurations so that your IPFS nodes don't connect to the public network. Also, use the environment variable "LIBP2P_FORCE_PNET" while starting the node to make sure you are working in a private network.

Guest Author: Dattatray14 Jun 2019

HI Ankit,
I am having difficulty when i have trying to this setup on different machine(NOT at one machine). My Machines are not able to communicate with each other. When i do it on one single machine then it works fine. Can you please suggest where i have to make the changes according to the steps that you provided

Author: Ankit15 Jun 2019 Member Level: Platinum   Points : 3

Hi Dattatray,
It looks to be a network configuration issue.
1. Are both the servers able to ping each other?
2. Is a firewall or some authentication method preventing connections in case you are working on a corporate network which might have some security configurations.
3. Please make sure your IPFS configurations are proper as mentioned under the "Assigning port number for gateway and configuring IP for communication" section

Guest Author: Jeff Moray12 Sep 2019

Is it possible to convert an existing public IPFS server to a private one by replacing the bootstrap entries with the swarm private key as described here?

Author: Ankit13 Sep 2019 Member Level: Platinum   Points : 2

Hi Jeff,
I haven't tried it so can't say for sure. Theoritically however, I don't see any problem with it. Whatever data your cluster has already replicate locally should also be available after you change the configuration. Let me know if it works when you try this.

Guest Author: Vinay30 Sep 2019

Hi, when I try to use "ipfs-swarm-key-gen > ~/.ipfs/swarm.key" , it displays :ipfs-swarm-key-gen: command not found. could you tell me what's wrong about this?

Author: Ankit01 Oct 2019 Member Level: Platinum   Points : 1

@Vinay, did you install the utility for generating the key?
Here is the command - go get -u

  • Do not include your name, "with regards" etc in the comment. Write detailed comment, relevant to the topic.
  • No HTML formatting and links to other web sites are allowed.
  • This is a strictly moderated site. Absolutely no spam allowed.
  • Name: