Becoming a Storage Provider
The Gitopia Storage Provider is a self-hosted server that provides storage for Gitopia repositories, LFS objects, and attachments. It integrates with IPFS and IPFS Cluster to ensure data is decentralized, persistent, and content-addressable.
System Requirements
Hardware
- CPU: 2+ Cores
- RAM: 4GB+ (8GB+ recommended for production)
- Disk: 4TB
Storage
The Gitopia Storage Provider leverages a layered storage architecture, with the primary and most significant storage requirement being the IPFS data directory. This ensures all repository content is decentralized, persistent, and content-addressable, while local directories act as caches to optimize performance.
IPFS Data Directory:
- The main storage location for all repository data, LFS objects, and attachments is the IPFS data directory (typically
~/.ipfs
inside the container or mapped to a host directory). This directory should be allocated the majority of your disk space, as it is responsible for persisting and pinning all content. - For production, it is strongly recommended to map the IPFS data directory to a dedicated, high-performance external disk (such as an NVMe SSD) for optimal reliability and speed.
- The main storage location for all repository data, LFS objects, and attachments is the IPFS data directory (typically
Cache Directories:
- /var/repos: Acts as a cache for bare Git repositories (git objects, refs, and hooks). Storage usage depends on your cache configuration and retention policy.
- /var/lfs-objects: Stores Git LFS (Large File Storage) objects. This can be configured to point to a preferred directory.
- /var/attachments: Caches attachments (releases, issues, pull requests). Storage usage is also determined by your cache settings.
- These directories are configurable and serve to speed up access and operations. Their disk usage can be tuned by adjusting cache size and retention policies. They do not serve as the main persistent storage.
Note: Only the IPFS data directory is responsible for long-term, reliable storage. The cache directories are secondary and can be sized according to your operational needs.
Planning for Storage:
- Allocate most disk space to the IPFS data directory.
- Adjust cache directory sizes and policies as appropriate for your environment.
- For Docker, map the relevant host directories to the container volumes. For manual installs, set
GIT_REPOS_DIR
,LFS_OBJECTS_DIR
, andATTACHMENT_DIR
in your config file to desired paths.
Software Dependencies
- git
- go 1.23+ (for building from source)
- IPFS Kubo v0.25+
- IPFS Cluster v1.0+
- Docker & Docker Compose (for Docker-based installation)
Installation Guide
We offer two methods for installation. The Docker method is recommended for ease of deployment and management.
Installation using Docker (Recommended)
This method uses Docker Compose to set up the entire stack, including the Gitopia Storage Provider, IPFS, and IPFS Cluster.
1. Prerequisites
- Docker and Docker Compose are installed on your server.
2. Configuration
- Clone the repository (if you haven't already).
- Create a
.env
file from the example provided:cp .env.example .env
- Edit the
.env
file:CLUSTER_SECRET
: This is critical for security. You must obtain a secret from the Gitopia team. This secret ensures that only authorized peers can join the cluster and request pinning/unpinning of data.CLUSTER_PEERNAME
: A unique name for your node in the cluster.GITOPIA_OPERATOR_MNEMONIC
: The mnemonic for the wallet that will operate the storage provider on the Gitopia chain. Store this securely.
3. Running the Service
- Start all services in the background:
docker-compose up -d
- Check the logs to ensure everything started correctly:
docker-compose logs -f gitopia-storage
docker-compose logs -f cluster
4. One-Time Setup (Registration)
You need to register your provider on the Gitopia blockchain. You only need to do this once.
Import your key: The container automatically imports the key from the
GITOPIA_OPERATOR_MNEMONIC
in your.env
file on startup.Register the Provider: Execute the registration command inside the
gitopia-storage
container.# Replace <your-public-domain> with the public address of your server
# Example: http://storage.mydomain.com:5000
# Replace <your-cluster-peer-multiaddress> with the multiaddress of your cluster peer
# You can get the multiaddress of your cluster peer by running the following command
# ipfs-cluster-ctl id
# Example: /ip4/104.244.178.22/tcp/9096/p2p/12D3KooWHWG333xgo3QnZTSP9trGmGBvs37JsqwiUz5XYHjMpgfA
# The amount 1000000000000ulore is an example stake. Adjust as needed.
docker-compose exec gitopia-storage gitopia-storaged register-provider http://<your-public-domain>:5000 "My Provider Description" 1000000000000ulore <your-cluster-peer-multiaddress> --from gitopia-storage --keyring-backend test --fees 200uloreYou can update the provider api url, description and multiaddress by running the following command:
docker-compose exec gitopia-storage gitopia-storaged update-provider http://<your-public-domain>:5000 "New Provider Description" <your-cluster-peer-multiaddress> --from gitopia-storage --keyring-backend test --fees 200ulore
Your storage provider is now set up and registered.
5. Managing Data and External Disks
The docker-compose.yml
file maps host directories to container volumes for data persistence.
./data/repos
->/var/repos
in container./data/attachments
->/var/attachments
in container./data/lfs-objects
->/var/lfs-objects
in container
To use an external disk, mount it on your host (e.g., at /mnt/gitopia_data
) and change the mappings in docker-compose.yml
:
volumes:
- /mnt/gitopia_data/repos:/var/repos
- /mnt/gitopia_data/attachments:/var/attachments
- /mnt/gitopia_data/lfs-objects:/var/lfs-objects
Manual Installation
This method is for advanced users who want to manage each service directly on the host machine.
1. Install Dependencies
Install Go, Git, IPFS Kubo, and IPFS Cluster by following their official documentation.
2. IPFS and IPFS Cluster Setup
A. IPFS Setup
- Initialize IPFS with the server profile:
ipfs init --profile=server
- We recommend running IPFS as a
systemd
service for production. See the Production Setup (systemd) section below. For now, you can start it manually:ipfs daemon &
B. IPFS Cluster Setup
Initialize IPFS Cluster:
ipfs-cluster-service init
Configure IPFS Cluster: Edit
~/.ipfs-cluster/service.json
. This is a critical step.{
"cluster": {
"peername": "your-unique-peer-name",
"secret": "your-cluster-secret",
"trusted_peers": ["/ip4/1.2.3.4/tcp/9096/p2p/Qm..."],
// ... other settings
}
}secret
: A shared secret required to join the cluster. You must get this from the Gitopia team. It prevents unauthorized peers from connecting.trusted_peers
: An explicit list of peer IDs that are allowed to make changes to the cluster's pinset. This is a crucial security measure. Using"*"
is highly discouraged as it allows any peer in the cluster to pin or unpin content.
You can retrieve the multiaddresses of all active storage providers (to use as trusted peers) by running the following command:
./gitopia-storaged get-ipfs-cluster-peer-addresses
This command will output a comma-separated list of peer multiaddresses. Copy these addresses and add them to the trusted_peers
field in your IPFS Cluster configuration file (usually service.json
).
Example:
"trusted_peers": [
"/ip4/1.2.3.4/tcp/9096/p2p/12D3KooW...",
"/ip4/5.6.7.8/tcp/9096/p2p/12D3KooX..."
]
Be sure to update this list whenever the set of active storage providers changes.
- Start the IPFS Cluster service. We recommend using
systemd
. See the Production Setup (systemd) section. For now, you can start it manually with the bootstrap peers provided by the Gitopia team:ipfs-cluster-service daemon --bootstrap <peer-multiaddress1,peer-multiaddress2> &
3. Build and Install Gitopia Storage Provider
- Clone the repository and build the binaries:
git clone https://github.com/gitopia/gitopia-storage.git
cd gitopia-storage
make build - Install the binaries to your system's PATH:This will copy
sudo make install
gitopia-storaged
,gitopia-pre-receive
, andgitopia-post-receive
to/usr/local/bin
.
4. Configure Gitopia Storage Provider
- Copy the production config file to a system location:
sudo mkdir -p /etc/gitopia-storage
sudo cp config_prod.toml /etc/gitopia-storage/config.toml - Edit
/etc/gitopia-storage/config.toml
and set the correct paths and values, especially for your data directories.
5. Run the Service
Create necessary directories:
sudo mkdir -p /var/repos /var/attachments /var/lfs-objects
sudo chown -R <your-service-user>:<your-service-user> /var/repos /var/attachments /var/lfs-objectsSet up your provider key:
noteBefore proceeding with registration, ensure your wallet has sufficient balance to cover:
- Minimum stake required to join as a storage provider
- Transaction fees for registration and ongoing operations
# Run as the user that will run the service
gitopia-storaged keys add gitopia-storage --recoverRegister the provider (see Docker section for command details, but run it directly instead of with
docker-compose exec
).Start the service. We strongly recommend using the
systemd
service file provided below.
Production Setup (systemd)
For a manual installation in a production environment, you should run ipfs
, ipfs-cluster-service
, and gitopia-storaged
as systemd services.
Create a dedicated user to run the services:
sudo useradd --system --no-create-home --shell /bin/false gitopia
# Grant ownership of data directories
sudo chown -R gitopia:gitopia /var/repos /var/lfs-objects /var/attachments /etc/gitopia-storage
# Grant ownership of IPFS/IPFS-Cluster config
sudo chown -R gitopia:gitopia /home/gitopia/.ipfs /home/gitopia/.ipfs-cluster
1. ipfs.service
File: /etc/systemd/system/ipfs.service
[Unit]
Description=IPFS Daemon
After=network.target
[Service]
User=gitopia
Group=gitopia
ExecStart=/usr/local/bin/ipfs daemon
Restart=always
LimitNOFILE=10240
[Install]
WantedBy=multi-user.target
2. ipfs-cluster.service
File: /etc/systemd/system/ipfs-cluster.service
[Unit]
Description=IPFS Cluster Daemon
After=ipfs.service
Requires=ipfs.service
[Service]
User=gitopia
Group=gitopia
ExecStart=/usr/local/bin/ipfs-cluster-service daemon
Restart=always
[Install]
WantedBy=multi-user.target
3. gitopia-storaged.service
File: /etc/systemd/system/gitopia-storaged.service
[Unit]
Description=Gitopia Storage Provider
After=network.target ipfs-cluster.service
Requires=ipfs-cluster.service
[Service]
User=gitopia
Group=gitopia
Type=simple
ExecStart=/usr/local/bin/gitopia-storaged start --from gitopia-storage --config /etc/gitopia-storage/config.toml
Restart=on-failure
RestartSec=10
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
Enable and Start Services
sudo systemctl daemon-reload
sudo systemctl enable --now ipfs ipfs-cluster gitopia-storaged
sudo systemctl status ipfs ipfs-cluster gitopia-storaged
API and Configuration Details
Configuration
The storage provider can be configured using a TOML configuration file. Here's the complete configuration structure:
# Server Configuration
WEB_SERVER_PORT = 5000
GIT_REPOS_DIR = "/var/repos"
LFS_OBJECTS_DIR = "/var/lfs-objects"
ATTACHMENT_DIR = "/var/attachments"
WORKING_DIR = "/home/ubuntu/gitopia-storage/"
# Gitopia Network Configuration
GITOPIA_ADDR = "gitopia-grpc.polkachu.com:11390"
TM_ADDR = "https://gitopia-rpc.polkachu.com:443"
GIT_SERVER_EXTERNAL_ADDR = "public-address"
CHAIN_ID = "gitopia"
GAS_PRICES = "0.001ulore"
# IPFS Configuration
IPFS_CLUSTER_PEER_HOST = "your-ipfs-host"
IPFS_CLUSTER_PEER_PORT = "your-ipfs-port"
IPFS_HOST = "your-ipfs-host"
IPFS_PORT = "your-ipfs-port"
ENABLE_EXTERNAL_PINNING = false
PINATA_JWT = "your-pinata-jwt" # Required if ENABLE_EXTERNAL_PINNING is true
# Cache Configuration
CACHE_REPO_MAX_AGE = "24h" # Maximum age for repository cache entries
CACHE_REPO_MAX_SIZE = 10737418240 # Maximum size for repository cache (10GB in bytes)
CACHE_ASSET_MAX_AGE = "168h" # Maximum age for asset cache entries (7 days)
CACHE_ASSET_MAX_SIZE = 5368709120 # Maximum size for asset cache (5GB in bytes)
CACHE_CLEAR_INTERVAL = "1h" # Interval for cache cleanup
Git Hooks Configuration
The git hooks (gitopia-pre-receive
and gitopia-post-receive
) are essential components that integrate with Git's hook system to handle repository operations. These hooks need to be properly configured and available in your system's PATH.
Configure the gRPC host for gitopia-pre-receive:
- The gRPC host is configured in
hooks/gitopia-pre-receive/config/config_prod.go
- For production, it's set to
gitopia-grpc.polkachu.com:11390
- You can modify this if you're using a different gRPC endpoint
- The gRPC host is configured in
Make the hooks available in PATH:
# After building, copy the hooks to a directory in your PATH
sudo cp build/gitopia-pre-receive /usr/local/bin/
sudo cp build/gitopia-post-receive /usr/local/bin/
# Verify the hooks are available
which gitopia-pre-receive
which gitopia-post-receive
Purpose of the hooks:
gitopia-pre-receive
: Runs before changes are accepted into the repository. It validates pushes by checking if force pushes are allowed for the target branch. If force pushes are not allowed, it will reject non-fast-forward pushes to protect repository history.gitopia-post-receive
: Runs after changes are accepted. It handles post-push operations by creating dangling references for force pushes and deletions. This ensures that even when history is rewritten or branches are deleted, the previous state is preserved in the repository's reference history.