Introduction
A common problem when getting started on a new private tracker is building ratio. You have to download before you can upload, making it very difficult to build your ratio initially without purchasing VIP or waiting a long time for points to accrue.
cross-seed exists to solve this problem, or at least help alleviate the pain. As an example:
You participate in Tracker A and Tracker B. Tracker A you have participated in for a while, and Tracker B is new to you so you are trying to build ratio. cross-seed checks through various means to see if any of the torrents you are seeding on Tracker A have identical copies on Tracker B. If so, it downloads those torrent files from Tracker B and before your client is able to download anything, hardlinks the files you have already downloaded into the directory the Tracker B torrents would have downloaded to. Your torrent client recognizes the files and begins seeding, and you have another torrent to get you ratio on your new tracker without adding any more download to the other side of the equation. The additional benefit of this is that you are able to seed the same files on multiple trackers without having multiple copies on your drive, as hardlinks take up effectively no storage.
This guide will cover setting up cross-seed in a docker container and linking it to your download client/trackers. In this guide, I will be assuming that you have a basic knowledge of docker, and because it is a guide on integrating cross-seed into an existing stack, I will assume you are already using both qbittorrent and jackett or prowlarr. In the future I may make posts on setting up the *arr stack, if so I will link it here then.
Step 1: Your docker-compose
Right before we start that part, you'll want to make a two directories on your machine./cross-seed/config
/cross-seed/cross-seeds
/yourdrive/cross-seed-links/
services:
cross-seed:
image: ghcr.io/cross-seed/cross-seed:latest
container_name: cross-seed
user: 1000:1000
environment:
- TZ=Your/TZ
ports:
- 2468:2468
volumes:
- /yourdrive/cross-seed/config:/config
- /yourdrive/cross-seed/cross-seeds:/cross-seeds
- /yourdrive:/data #Make this one directory back from your /torrents directory as it will look in /data/torrents on the virtual disk
command: daemon
network_mode: bridge
# depends_on:
# container:qbittorrent:
# condition: service_started
restart: unless-stopped
This is an example docker compose that you can use to get started. I'll explain it piece by piece below:
-
First, we declare our services, so far only the one named "cross-seed".
-
image: Here we are setting what docker image our container is using, and after the colon we have set it to grab whatever release is tagged "latest" on their docker repository.
-
container_name: This decides what the name of the container will be in things like the command line for the purposes of referring to the container from elsewhere.
-
user: Sets your user ID before the colon and group ID after the colon. If you have a limited permission docker user, use that UID and GID. Otherwise, you want to use whatever user has ownership or permission to edit the directories you have your data in.
-
Environment: Under this section you set any environment variables needed to configure your container. In this case, to make sure the times for the logs actually make sense to your timezone. Replace "Your/Tz" with the relevant "TZ Identifier" found at the TZ page on wikipedia, just ctrl+F and find your town or a town/city in the same time zone as you are.
-
Ports: This maps the "virtual" ports inside the container to the actual ports on your system. The port on the left side is the actual port being mapped to on your machine, so this can be changed to whatever a free port is if 2468 is already in use for you. The port on the right side of the colon must remain the same, though, because that is the "virtual" port that cross-seed will be looking for to pass data. If you have cross-seed only connecting to other containers in the same docker compose this can be ignored, but otherwise it is necessary if you would like it accessible from the rest of the system or from another machine on your LAN.
-
Volumes: This section is mapping real directories on your system (left side of the colon) to the "virtual" directories in the docker container(right side of the colon). The first line you will want to replace what is on the left side of the colon with wherever you would like your cross-seed configs to go. If you're following this guide to the letter that will be the /cross-seed/config directory we set up earlier.
Next line down you will want to set where the .torrent files cross-seed downloads will go. In our case, that'll be /cross-seed/cross-seeds
Lastly, you'll want to map the /data directory to your torrent client's download directory so that all of your downloads will be visible to cross-seed to analyze.
- command: daemon tells cross-seed that you want it to start the background process that will monitor torrents/add cross-seeds automatically
- network_mode: bridge is only necessary if you are running cross-seed in a separate docker-compose than your torrent client/jackett/whatever. If they are all in one docker-compose, they will be able to communicate within their compose network that is automatically set up by docker.
- depends_on: and the whole commented out block associated with it should be uncommented if you are putting cross-seed in the same compose as your download client. If not, this can be ignored but may lead to errors if cross-seed starts before your download client. This is easily fixed by simply restarting cross-seed.
- restart: unless-stopped tells the container to attempt to restart itself if it crashes or if your system restarts.
Step 2: Configuration
Once you have set up and saved everything in step 1, start up your docker-compose, let it run for around 30 seconds, and then shut it back down. This will get cross-seed to generate the config files for us to edit. If you followed the guide to the letter, that will be in our /cross-seeds/config folder.
If you are unable to open the config.js file due to permissions errors, running this command should solve the issue for you:
sudo chmod o+rw /yourdrive/cross-seed/config/config.js
Now, navigate into your config folder to that config.js, and open it up in your text editor of choice. Contained in here is much of the configuration for your cross-seed installation. First off, you will want to set your cross-seed api key. You can generate one by running
tr -dc A-Za-z0-9 </dev/urandom | head -c 24; echo
in your command line (likely Linux only). Alternatively, you can generate one by running
sudo docker exec -it cross-seed cross-seed api-key
Scrolling down the config file, you'll come along a section labeled "torznab:". Within it's square brackets, you will want to copy your torznab tracker links from either jackett or prowlarr. For the IP address, use the IP of your machine that is hosting jackett/prowlarr. Additionally, to each link, you'll want to append this to each of your links:
/api?apikey=yourjackettorprowlarrAPIkeyhere
Note: only add the trackers to this section that you would like to enable cross-linking between. I personally only add my private trackers to ease load on my system, but do what you want I'm not a cop.
Once you've finished that, your torznab section should look something like this:
torznab: [
"http://put.machine.ip.here:9117/api/v2.0/indexers/tracker#1/api?apikey=yourjackettorprowlarrAPIkeyhere"
"http://put.machine.ip.here:9117/api/v2.0/indexers/tracker#2/api?apikey=yourjackettorprowlarrAPIkeyhere"
"http://put.machine.ip.here:9117/api/v2.0/indexers/tracker#3/api?apikey=yourjackettorprowlarrAPIkeyhere"
],
Scrolling down further is our *arr integration, which helps cross-seed reduce false positives by adding ID matching to its tools for matching torrents and ensuring that there are no false positives:
...
sonarr: ["http://put.machine.ip.here:8989?apikey=yoursonarrAPIkeyhere"]
...
radarr: ["http://put.machine.ip.here:7878?apikey=yourradarrAPIkeyhere"]
...
Additionally, we'll want to set up the connection to our torrent client so that cross-seed can inject the new downloads directly.
If you are a qBittorrent user, you will want your torrentClients section to look like this:
torrentClients: ["qbittorrent:http://username:password@put.machine.ip.here:8090/"],
Next, we need to set a couple of directories. Scroll down further until you find "linkDirs". I perfer to set this within my torrent directory. If you're following this guide to the letter, you'll want to set it to something like this:
linkDirs: ["/data/cross-seed-links"],
Now scroll down to where you see "outputDir", this is where cross-seed will be putting the .torrent files it downloads. We have a directory set up for that, so it should look like:
outputDir: "/cross-seeds"
Scrolling down further in our config file, you want to make sure "action" is set to "inject", which for me it was done by default. Now we are finally done with configuration.
Step 3: Client integration
In your qBittorrent client, navigate to Tools -> Options -> Downloads and make sure "Run external program on torrent completion" is enabled. Then, add this to the commands to run:
curl -XPOST http://put.machine.ip.here:2468/api/webhook?apikey=YOURapiKEY --data-urlencode "infoHash=%I"
Make sure to replace YOURapiKEY with whatever you set your API key to be, and change the ip and port to match whatever you have set up cross-seed to be mapped to.
Now, run your docker-compose project through your GUI client of choice or by using docker up -d From here on the daemon should work in the background finding things you can seed on multiple trackers as well as tagging them all properly in your torrent client so you can see what is a cross-seed and what is a true torrent. If you run into trouble, pay close attention to the cross-seed container logs because I found them to be very useful and are one of the better implementations of error logging I've seen.
Happy seeding! Any questions feel free to drop by the group or contact me at cenotaph.contact@pm.me