Coolify Setup: Application Deployment with Self-Hosted PaaS
Coolify installation, Docker and Git integration, application deployment, database management, SSL certificates, environment variables, and self-hosted PaaS alternative to Heroku/Netlify.
Ghost Docker installation, Nginx reverse proxy, SSL certificate, theme setup, membership and subscription system, email newsletter and production configuration.
Ghost is an open-source CMS platform designed for modern blogging and content publishing. Compared to WordPress, it's faster, more secure, and content-focused. It also supports content monetization with membership system, newsletter, and payment integration.
Ghost is a Node.js-based headless CMS and publishing platform. Key features:
# docker-compose.yml
version: '3.8'
services:
ghost:
image: ghost:5-alpine
container_name: ghost
restart: unless-stopped
depends_on:
- db
environment:
database__client: mysql
database__connection__host: db
database__connection__user: ghost
database__connection__password: strong-password
database__connection__database: ghost
url: https://blog.example.com
mail__transport: SMTP
mail__options__host: smtp.mailgun.org
mail__options__port: 587
mail__options__auth__user: postmaster@mg.example.com
mail__options__auth__pass: mailgun-api-key
mail__from: noreply@example.com
volumes:
- ./ghost-content:/var/lib/ghost/content
ports:
- "127.0.0.1:2368:2368"
db:
image: mysql:8.0
container_name: ghost-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root-password
MYSQL_DATABASE: ghost
MYSQL_USER: ghost
MYSQL_PASSWORD: strong-password
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
# Start containers
docker compose up -d
# Check logs
docker logs ghost -f
Ghost automatically creates the database on first start. Access the admin panel at https://blog.example.com/ghost.
services:
ghost:
image: ghost:5-alpine
container_name: ghost
restart: unless-stopped
environment:
url: https://blog.example.com
NODE_ENV: production
volumes:
- ./ghost-content:/var/lib/ghost/content
ports:
- "127.0.0.1:2368:2368"
server {
listen 80;
server_name blog.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name blog.example.com;
ssl_certificate /etc/letsencrypt/live/blog.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://127.0.0.1:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
# Get SSL certificate
certbot --nginx -d blog.example.com
Go to https://blog.example.com/ghost:
Settings → Membership
- Allow free members: Enabled
- Paid subscriptions: Via Stripe
- Default post access: Public / Members only / Paid
Settings → Membership → Stripe
1. Create a Stripe account
2. Enter API keys:
- Publishable key: pk_live_...
- Secret key: sk_live_...
3. Add webhook endpoint:
https://blog.example.com/members/webhooks/stripe
This section is public.
<!--members-only-->
This section is visible only to members.
<!--paid-members-only-->
This section is visible only to paid members.
environment:
mail__transport: SMTP
mail__options__service: Mailgun
mail__options__host: smtp.mailgun.org
mail__options__port: 587
mail__options__auth__user: postmaster@mg.example.com
mail__options__auth__pass: mailgun-smtp-password
mail__from: "Blog Name <noreply@example.com>"
# Backup Ghost content directory
tar -czf ghost-backup-$(date +%Y%m%d).tar.gz ./ghost-content/
# MySQL database backup
docker exec ghost-db mysqldump -u ghost -pstrong-password ghost > \
ghost-db-$(date +%Y%m%d).sql
# Automated backup script
cat > /etc/cron.daily/ghost-backup << 'EOF'
#!/bin/bash
BACKUP_DIR="/backups/ghost"
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/content-$(date +%Y%m%d).tar.gz /opt/ghost/ghost-content/
docker exec ghost-db mysqldump -u ghost -pstrong-password ghost | \
gzip > $BACKUP_DIR/db-$(date +%Y%m%d).sql.gz
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
EOF
chmod +x /etc/cron.daily/ghost-backup
With REXE VPS servers, you can set up a professional blog and content platform with Ghost. 2 GB RAM can serve thousands of readers.
Ghost is a powerful, modern alternative to WordPress for content publishing. Its built-in membership system, newsletter capabilities, and clean editor make it ideal for professional bloggers and publishers. With Docker deployment on REXE servers, you can have a production-ready Ghost instance running in minutes.
Check that the Ghost container is running with docker ps. Make sure the URL environment variable is set correctly (https://blog.example.com). Check the Nginx proxy configuration. Review Ghost logs: docker logs ghost. For first setup, go to the /ghost path: https://blog.example.com/ghost.
Check SMTP settings. If using Mailgun, make sure the domain is verified. Send a test email from Ghost admin panel Settings → Email. In Mailgun sandbox mode, you can only send to verified addresses. Activate the Mailgun domain for production.
Check that Stripe API keys are entered correctly (live key, not test key). Verify the webhook endpoint is added in the Stripe dashboard. Make sure the Ghost URL is HTTPS (Stripe rejects HTTP). Check webhook events from Stripe logs.
Back up before updating (content directory + database). Pull the new image with docker compose pull. Restart the container with docker compose up -d. Ghost automatically runs database migrations. For major version updates (e.g., 4.x → 5.x), read the release notes and test in a staging environment.
Make sure the theme .zip file has the correct structure (package.json and index.hbs are required). Activate the theme via Settings → Design → Activate. Check Ghost logs for theme errors. The theme must be compatible with your Ghost version (you can check with gscan).
If using MySQL, optimize the database connection. Add gzip compression and browser caching in Nginx. Enable caching in Ghost Settings → Labs. Consider using a CDN (Cloudflare free plan). Increase server RAM (minimum 2 GB recommended).
Coolify installation, Docker and Git integration, application deployment, database management, SSL certificates, environment variables, and self-hosted PaaS alternative to Heroku/Netlify.
Nextcloud installation with Docker, Apache/Nginx configuration, database setup, SSL certificate, file synchronization, app store, and performance optimization.
Portainer CE installation, Docker and Kubernetes management, stack deployment, volume/network management, user authorization, webhook and GitOps integration.