Cloning a repository over HTTPS requires entering your username and password (or a personal access token) on every push. SSH authentication uses a key pair instead — set it up once and you never enter credentials again. Here’s the complete workflow for a fresh Linux server.
Problem: After setting up a remote server, git clone or git pull with a Bitbucket repository fails because no SSH key has been generated or registered on the server.
Solution: Generate an SSH key pair on the server with ssh-keygen -t ed25519, copy the public key, add it to Bitbucket under Personal Settings → SSH Keys, then verify the connection with ssh -T git@bitbucket.org before running any Git commands.
# Step 1 — connect to the server
ssh username@server-ip-or-hostname
# Step 2 — check for an existing key pair
ls ~/.ssh/id_*.pub 2>/dev/null || echo "No key found"
# Step 3 — generate a new Ed25519 key pair (recommended over RSA)
ssh-keygen -t ed25519 -C "deploy@example.com"
# Press Enter to accept the default path (~/.ssh/id_ed25519)
# Optionally set a passphrase for additional security
# Step 4 — view and copy the public key
cat ~/.ssh/id_ed25519.pub
Add the public key to Bitbucket: go to Account Settings → SSH Keys → Add key, paste the key, and save. For GitHub it's Settings → SSH and GPG keys → New SSH key.
# Step 5 — test the connection
ssh -T git@bitbucket.org
# Expected: "logged in as username"
# Step 6 — create the project directory and initialise Git
mkdir -p /var/www/my-project && cd /var/www/my-project
git init
# Step 7 — add the remote (copy the SSH URL from Bitbucket/GitHub)
git remote add origin git@bitbucket.org:username/my-repo.git
# Step 8 — fetch and check out the main branch
git fetch origin
git checkout -t origin/main # or 'master' for older repos
Verify your working tree after checkout:
ls -la # list files
pwd # confirm current directory
git status # should say "nothing to commit, working tree clean"
NOTE: If Git clones the repository into a nested subfolder (project/project/files instead of project/files), the remote URL was pointing to a repository with a directory at its root. Move all files up one level with mv project/* . && rmdir project, then verify with ls -la.