I have a Node.js app that adds files to ipfs with ipfs-core, like this:
const result = await ipfs.add({
path: file.name,
content: Buffer.from(file.content),
});
I get it’s CID in the result, and if I try to retrieve the file with ipfs.get or ipfs.cat on the same node that runs in the same Node.js app, it works. I have also spawned a local gateway through the app with the package ipfs-http-gateway, and I can get the file through it as well. But, when I spawn a node on the same machine with the CLI ipfs daemon
, and i do ipfs cat <CID>
or ipfs get <CID>
, I get nothing. I also spawned a node on another machine with ipfs daemon, and got nothing. I got nothing when I tried to retrieve the file with ipfs-core on another Node.js app. It seems like the file is only visible to the node that added it. From the ipfs.add docs, I see that the pin is defaulted as true, so the files I add are pinned.
Why are the files not visible to other nodes?
I will paste the node creation inside the app here, and if any more code is required, please let me know:
import { create } from 'ipfs-core';
const IPFS = (() => {
let IPFSInstance = undefined;
const createInstance = async () => {
return await create({
config: {
Addresses: {
Gateway: '/ip4/127.0.0.1/tcp/9090',
},
},
});
};
return {
getInstance: async () => {
if (!IPFSInstance) IPFSInstance = await createInstance();
return IPFSInstance;
},
};
})();
export default IPFS;
Have you tried connecting directly to your first node, from your new nodes? You can also check if you’re getting peers with ipfs.swarm.peers().
If your node isn’t reachable from the outside world, it may have trouble advertising its data too.
ipfs.swarm.peers() returns an empty array. How do I connect directly to my first node from my new node? And why my node might be unreachable? Is there something I might’ve done wrong? Thank you!
1 Like
I’m not 100% sure how js-ipfs does discovery when run in a NodeJS environment. You can try connecting to your own nodes from it via ipfs.swarm.connect
. Depending on your environment, if the node is blocked from reaching the outside world it won’t find peers. Generally I don’t specify anything to get peers, I just run create()
and away I go!
I think a good start might be to see if ipfs.swarm.connect
gives you an error trying to connect to your local node. If you don’t need to use js-ipfs BTW, you can always use Kubo with ipfs-http-client, which is how I’m building Disco Chat.
I think @danieln has been playing around with js-ipfs a bunch lately, I wonder if he might have some insights here .
I couldn’t connect the node running on Node.js (the Node.js server is running on my machine, and my local node is running on the same machine) to my own local node. Seems like the node running in the Node.js server is just undiscoverable.
What about connecting to your local node from the NodeJS node?
Also a bit curious about your config, I asked around and was suggested perhaps you were looking to config this way?
create({
config: {
Addresses: {
Swarm: [
'/ip4/127.0.0.1/tcp/9090'
]
},
},
})
No config might help too: return await create();
Sorry about all your struggles BTW. But if there’s a way to enable more logging, those might have some insights.
I added the swarm config with a port other than 9090, because I alreay have my gateway server on 9090 and it worked! If I do ipfs.swarm.peers()
now I get lots of peers. It’s weird, because the default config of ‘swarm’ already has an address there, and it didn’t work before, but if I give it another, it works. But my problem is still there. Even if I have peers, I can’t connect to my local node or to another node from another machine of mine, and my file is still undiscoverable. I added a file to ipfs from my node in Node.js, and if I close the app, start it again, and try to retreive it with something like like ipfs.cat(myFileCID
) or ipfs.ls(myFileCID)
, I successfully get it, so the files remains saved/pinned even after closing the Node.js server and starting it again, so the node works just fine. But I still can’t get the file from any other node.
Edit 1: Maybe I am not understanding something about IPFS here. So if I do ipfs.swarm.peers()
I get something like 20-50 peers at once. Let’s say that node A is the one that has 20-50 peers connected. If node B tries to get a file that node A has, and node B isn’t one of the 20-50 peers that are concected to node A, it makes sense if it cannot get the file, because node B is not connected to node A, and the peers that node B is connected to don’t have the file. So, if I want my app to work, I have to make sure somehow that every node that uses my app must be connected exactly to another node that also uses my app? That could be doable, I can save the peer id’s to a common centralized db or something. But that still couldn’t work, because I can’t connect the node from my Node.js server to another node with ipfs.swarm.connect()
Edit 2: There is a change that my multiaddr package is not working, hence the failure in connecting directly to other nodes. I am providing a multiaddr to ipfs.swarm.connect()
. I will get back with an answer asap.
1 Like
I shall await your update!
In reply to your first edit, you do need to be connected to a node to download the file. What IPFS will do however though is announce who has a file via the DHT, allowing your node to be discovered and connected to. Bitswap will also try to find peers “most likely” to have information about where to find the file. This concept is called content addressing, where you find who has the content by looking for the content, rather than using a location which points to content.
If your node isn’t reachable (behind NAT), it’s much trickier to get data from it, as when it’s searched for via the DHT or otherwise, your node must connect to them, because they can’t connect to you.
So yea, the multiaddr had a problem, I fixed it. ipfs.swarm.peers()
returns an array of peers, and one of the fields is addr
. If I take the value there which is something like:
/ip4/<public ip adress>/tcp/<port>/p2p/<peer id>
and I put it like this:
await ipfs.swarm.connect(multiaddr(/ip4/<public ip adress>/tcp/<port>/p2p/<peer id>))
it connects. But I was already connected to them. If I put the address of a node that’s running on another machine of mine on another ip, it doesn’t connect. Maybe I am not putting the address correctly, but I rechecked a dozen of times for the public ip port and peer id to be correct.
Until I will find why I can’t connect, my question is: I want the nodes that are running my app to connect to each other, so that every one of them can get files from any other of them. To do that I will have to make sure that a node knows the addresses of every other node and then connect manually to them? So I will have to store those addresses in a centralized place? That seems weird, but it could work. Are there any other options to this?
If you’re not able to connect, it could be an issue with NAT. You can test with this: https://ipfs-check.on.fleek.co/
You shouldn’t need to manually connect to the nodes, as the nodes should be searching the DHT/bitswap to find nodes with the data.
I can’t access the website, nither this https://fleek.co/. Maybe the website is down or something. The NAT may be a good lead to look into, that’s what I’ll do at the moment.
Seems like I have solved one part of the problem. I didn’t provide enough information, and that is my fault. In my app, I run a local gateway with ipfs-http-gateway, and I get the files through that in my app. As you can see in the config, I have made it run on port 9090. If from a node from my app on a different IP I add a file, from another machine with a different IP I can get that file from a public gateway like ipfs.io, so the node kind of works properly, but I cannot get the file from my local gateway spawned by the app on another machine. In order for my app to work, I need to get files from an URL. I can’t rely on a public gateway, since they may not work or they give 429 too many requests status, and I spawned a local gateway server, through which I can get files with an URL. The server is spawning, I can see the open port, but it doesn’t work properly.
Edit: From a different node, I have added a simple file with IPFS Desktop. I can get that file through ipfs.io, but I cannot get it through the local gateway server spawned with my app. The weird thing is that the local gateway server kind of works. If I take the CID from the bottom of this page, which is a file containing a text something like “You did it!”, it works. I have no idea what’s going on.
Edit 2: since this is another problem, I create a new topic on this.