Manually uploading bot files via FTP or SFTP every time you make a change is slow, error-prone, and unnecessary. Modern deployment workflows use Git-based automation: push your code to GitHub, and your hosting panel pulls the update and restarts your bot automatically.
This guide shows how to set up automated deployments from GitHub to a Pterodactyl-based hosting panel like Space-Node, eliminating FTP entirely.
Why FTP deployments are a problem
Traditional bot deployment looks like this:
- Edit code locally
- Open FileZilla or SFTP client
- Connect to your server
- Navigate to the right directory
- Upload changed files (hoping you don't miss any)
- SSH in or use the panel to restart your bot
- Check logs to make sure it started correctly
This takes 5-15 minutes per deployment and introduces human error at every step. Forgot to upload a dependency file? Your bot crashes. Uploaded to the wrong directory? Hours of debugging.
The modern alternative: Git-based deployment
With Git-based deployment, the workflow becomes:
- Edit code locally
git commitandgit push- Done. Bot updates automatically.
Here is how to set this up.
Step 1: Prepare your repository
Make sure your bot project is in a Git repository with the essential files:
my-discord-bot/
├── src/
│ └── index.js
├── package.json # or requirements.txt for Python
├── .env.example # template (never commit actual .env)
├── .gitignore
└── README.md
Your .gitignore should include:
node_modules/
.env
*.log
Step 2: Configure the Pterodactyl egg for Git
Pterodactyl uses "Eggs" to define how containers are configured. A Git-enabled egg includes a startup script that:
- Clones or pulls your repository
- Installs dependencies
- Starts your bot
Here is an example startup command for a Node.js bot:
# Startup command (set in Pterodactyl panel)
if [ -d .git ]; then
git pull origin main
else
git clone {{GIT_REPO_URL}} .
fi
npm install --production
node {{STARTUP_FILE}}
For Python:
if [ -d .git ]; then
git pull origin main
else
git clone {{GIT_REPO_URL}} .
fi
pip install -r requirements.txt
python {{STARTUP_FILE}}
On Space-Node, these Git-aware eggs are preconfigured. You enter your repository URL in the panel settings and the rest is automatic.
Step 3: Set up GitHub webhooks
To trigger a deployment when you push code:
On GitHub:
- Go to your repository → Settings → Webhooks
- Click "Add webhook"
- Set the Payload URL to your server's webhook endpoint
- Set Content type to
application/json - Select "Just the push event"
- Click "Add webhook"
Webhook receiver (if your panel supports it):
Some Pterodactyl setups include a webhook listener that receives the GitHub notification and triggers a server restart, which in turn runs the startup script (including git pull).
Alternatively, you can use a simple webhook receiver:
// webhook-receiver.js — runs alongside your bot or as a separate service
const http = require('http');
const { exec } = require('child_process');
const server = http.createServer((req, res) => {
if (req.method === 'POST' && req.url === '/deploy') {
console.log('Deployment webhook received');
exec('git pull origin main && npm install --production', (error, stdout) => {
if (error) {
console.error('Deploy failed:', error);
res.writeHead(500);
res.end('Deploy failed');
return;
}
console.log('Deploy success:', stdout);
res.writeHead(200);
res.end('OK');
// Restart the bot process
process.exit(0); // Pterodactyl auto-restart will handle this
});
} else {
res.writeHead(404);
res.end();
}
});
server.listen(8080);
Step 4: Handle private repositories
For private repositories, you need authentication. The two main approaches:
Personal Access Token (recommended)
- Create a GitHub Personal Access Token with
reposcope - Use it in your Git URL:
https://{TOKEN}@github.com/user/repo.git - Store the token as an environment variable in your panel
Deploy Keys
- Generate an SSH key pair on your server
- Add the public key as a Deploy Key in your GitHub repository settings
- Configure Git to use the SSH key
On Space-Node, you can store your Git credentials as environment variables in the panel's secure variable section, keeping tokens out of your code.
Step 5: Environment variables
Never commit your .env file or Discord bot token to Git. Instead:
- Create a
.env.examplefile with placeholder values - Set actual values in your hosting panel's Environment Variables section
- Your code reads from
process.env.DISCORD_TOKEN(or equivalent)
// ✅ Correct: read from environment
client.login(process.env.DISCORD_TOKEN);
// ❌ Wrong: hardcoded token
client.login('MTIzNDU2Nzg5MDEyMzQ1Njc4.GP4XYZ.abc123...');
The complete automated workflow
After setup, your deployment workflow becomes:
# Make your changes
git add .
git commit -m "Add new slash command"
git push origin main
# GitHub webhook fires → Server restarts →
# Startup script runs git pull → npm install → bot starts
# Total time: ~30 seconds
No FTP. No SSH. No manual file management. Your bot is updated and running with a single git push.
Why this matters for production bots
Automated deployments are not just convenient — they are essential for:
- Consistency: Every deployment follows the same steps
- Speed: Deploy in 30 seconds instead of 15 minutes
- Reliability: No forgotten files or wrong directories
- Rollback: Revert to any previous commit with
git revert - Team collaboration: Multiple developers can push without FTP credentials
Setting this up on Space-Node
Space-Node's Pterodactyl panel comes with Git-aware Eggs for Node.js and Python bots. The setup process:
- Create a bot server in the panel
- Enter your GitHub repository URL in the startup configuration
- Set your DISCORD_TOKEN and other secrets as environment variables
- Click start — your code is pulled, dependencies installed, and bot launched
All screenshots and configuration examples in this guide were created using the Space-Node panel.