Connecting Your Git Provider
Coolify can pull code directly from GitHub, GitLab, Bitbucket, or any Git repository. Let's connect GitHub first—it's the most common setup.
🔗 Option 1: GitHub App (Recommended)
The GitHub App integration gives you the smoothest experience with automatic webhooks and fine-grained permissions.
- In Coolify, go to Sources → Add Source → GitHub App
- Click Register GitHub App
- You'll be redirected to GitHub to create and install the app
- Choose which repositories Coolify can access (all or selected)
- Authorize and return to Coolify
When you push to any authorized repository, Coolify will automatically trigger a deployment.
🔑 Option 2: Deploy Key (Public Repos)
For quick tests or public repositories:
- Go to Sources → Add Source → Public Repository
- Paste the repository URL (e.g.,
https://github.com/username/repo)
This method doesn't support automatic deployments—you'll trigger builds manually or via API.
🔄 Option 3: GitLab / Bitbucket
The process is similar for other providers:
- Go to Sources → Add Source → GitLab (or Bitbucket)
- Follow the OAuth flow to connect your account
- Select repositories to authorize
Your First Deploy: A Static Site
Let's start with something simple—a static HTML/CSS site. This takes about two minutes and validates your entire setup.
Create a Test Repository
If you don't have a static site ready, create a quick one:
mkdir my-static-site && cd my-static-site
git init<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Deployed with Coolify</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 100px auto;
padding: 20px;
text-align: center;
}
h1 { color: #6b46c1; }
</style>
</head>
<body>
<h1>Hello from Coolify! 🚀</h1>
<p>Deployed on RamNode infrastructure.</p>
</body>
</html>git add .
git commit -m "Initial commit"
gh repo create my-static-site --public --pushDeploy in Coolify
- Go to Projects → Add Project → Give it a name (e.g., "My Sites")
- Inside the project, click Add Resource → Public Repository
- Paste your repository URL or select it from the list
- Coolify auto-detects it as a Static site
| Setting | Value |
|---|---|
| Build Pack | Static |
| Base Directory | / (or where your index.html lives) |
| Publish Directory | / (same for simple sites) |
Click Deploy and watch the build logs. For a static site, this takes 10-30 seconds.
Automatic Deployments: If you used the GitHub App, push a change and Coolify will automatically redeploy within seconds. Zero configuration required.
Deploying a Node.js Application
Now let's deploy something with a build step and runtime—a simple Express API.
Sample Express App
{
"name": "my-node-api",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.2"
}
}const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Coolify!',
environment: process.env.NODE_ENV || 'development',
timestamp: new Date().toISOString()
});
});
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
app.listen(port, '0.0.0.0', () => {
console.log(`API running on port ${port}`);
});node_modules/
.envConfigure the Node.js Build
Coolify auto-detects Node.js from your package.json. Verify these settings:
| Setting | Value |
|---|---|
| Build Pack | Nixpacks (auto-detected) |
| Port | 3000 |
| Start Command | npm start (auto-detected) |
Understanding Nixpacks: Coolify uses Nixpacks by default—an intelligent build system that analyzes your code and generates an optimized container. It detects your runtime, installs dependencies, and configures the start command automatically. No Dockerfile needed.
Environment Variables
Most real applications need configuration—API keys, database URLs, feature flags. Coolify handles these securely.
In your resource settings, find the Environment Variables section:
NODE_ENV=production
API_KEY=your-secret-key
DATABASE_URL=postgres://user:pass@host:5432/dbVariables are encrypted at rest, injected at runtime (not baked into images), and available during build if marked as "Build Variable".
Build vs Runtime Variables
| Type | When Available | Use Case |
|---|---|---|
| Runtime | App execution only | API keys, database URLs, secrets |
| Build | During npm install, etc. | Private npm tokens, build-time configs |
Deploying a Python Flask API
Let's add a Python application to see how Coolify handles different runtimes.
flask==3.0.0
gunicorn==21.2.0import os
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({
'message': 'Hello from Flask on Coolify!',
'environment': os.environ.get('FLASK_ENV', 'development')
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)Configure the Flask Build
| Setting | Value |
|---|---|
| Build Pack | Nixpacks |
| Port | 5000 |
| Start Command | gunicorn app:app --bind 0.0.0.0:$PORT |
Important: Nixpacks might default to python app.py. For production, override the start command to use Gunicorn (a production WSGI server).
Build Packs: Nixpacks vs Dockerfile
Coolify offers multiple ways to build your applications:
🚀 Nixpacks (Default)
Best for standard applications in common languages. Supports Node.js, Python, Go, Rust, Ruby, PHP, Java, and more.
Pros:
- Zero configuration for most apps
- Optimized caching and layer reuse
- Automatic security updates
Cons:
- Less control over build environment
- May not support niche dependencies
🐳 Dockerfile
Best for custom requirements, specific base images, complex builds.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]To force Dockerfile builds, set Build Pack to Dockerfile in your resource settings.
📦 Docker Compose
Best for multi-container applications. Coolify can deploy entire stacks defined in docker-compose.yml files—covered in Part 4.
Custom Domains and SSL
Every app deployed on Coolify gets a random subdomain by default. Let's configure a proper domain.
Add a Custom Domain
- In your resource settings, find Domains
- Add your domain:
api.yourdomain.com - Save
Configure DNS
Add an A record pointing to your Coolify server:
Type: A
Name: api
Value: your-coolify-server-ip
TTL: 300Automatic SSL: Once DNS propagates (usually 1-5 minutes), Coolify automatically provisions a Let's Encrypt certificate. You'll see the lock icon appear in your browser.
Wildcard SSL
If you configured a wildcard domain in Part 1 (e.g., *.apps.yourdomain.com), any app can use subdomains without additional DNS records:
my-api.apps.yourdomain.comstaging.apps.yourdomain.comclient-demo.apps.yourdomain.com
Deployment Settings Deep Dive
Health Checks
Coolify can verify your app is running before routing traffic:
| Setting | Recommended Value |
|---|---|
| Health Check Path | /health |
| Health Check Interval | 30 seconds |
| Health Check Timeout | 5 seconds |
Resource Limits
Prevent runaway apps from consuming your entire server:
| App Size | Memory | CPU |
|---|---|---|
| Small apps | 256M | 0.5 |
| Medium apps | 512M | 1 |
| Large apps | 1G+ | 2 |
Persistent Storage
By default, container storage is ephemeral. For apps that need to persist files:
- Go to Persistent Storage in resource settings
- Add a volume: Source
/data/my-app/uploads→ Destination/app/uploads
Monitoring Your Deployments
📋 Build Logs
Every deployment shows real-time build logs. Common issues:
- Dependency failures: Check package.json or requirements.txt for typos
- Port mismatch: Ensure your app listens on the expected port
- Missing env vars: Build-time failures often indicate missing config
📝 Application Logs
For runtime issues, check Logs in your resource view. This streams stdout and stderr from your container.
Quick Debugging
SSH into your server and inspect directly:
# List running containers
docker ps
# View logs for a specific app
docker logs <container-id> --tail 100 -f
# Shell into a container
docker exec -it <container-id> /bin/shRollbacks
Coolify keeps your previous deployments. If something breaks:
- Go to Deployments in your resource
- Find a working previous deployment
- Click Rollback
Traffic switches back to the previous version within seconds. No downtime, no stress.
What's Next
You've now deployed three different types of applications with custom domains, environment variables, and automatic SSL. Your self-hosted PaaS is doing real work.
In Part 3, we'll add databases to the mix—spinning up PostgreSQL, MySQL, and Redis instances, connecting them to your apps, and setting up automated backups.
