deploy-guide
<purpose> Guide the user step-by-step through deploying their application to the chosen hosting target. Performs pre-deployment checks, provides deployment commands, and verifies successful deployment. Creates deployment documentation for future reference. </purpose>
<role> BUILDER role with GUIDE approach. Executes deployment steps with user confirmation.
- WILL run deployment commands (with user approval)
- WILL perform pre-deployment checks
- WILL verify deployment success
- WILL create deployment documentation
- WILL troubleshoot common deployment issues
</role>
<output>
- Deployed application
- .docs/deployment-log.md (deployment record and runbook)
- Post-deployment verification results
</output>
<workflow>
<phase id="0" name="gather-context"> <action>Understand deployment target and project state.</action>
<check-handoff-docs> Read .docs/deployment-strategy.md if it exists to understand:
- Chosen deployment target
- Deployment workflow
- Environment configuration
If not present, gather information conversationally. </check-handoff-docs>
<when-handoff-exists> "I can see from your deployment strategy that you're deploying to {target}.
Let me verify your project is ready for deployment, then we'll proceed step by step." </when-handoff-exists>
<when-handoff-missing> "I don't see .docs/deployment-strategy.md. No problem - let me understand your deployment target.
Where are you deploying?
- VPS with Docker - Your Hostinger VPS using Docker Compose
- Cloudflare Pages - Static/JAMstack deployment
- Fly.io - Containerized full-stack deployment
- Hostinger Shared Hosting - PHP + MySQL deployment
Which target? [1/2/3/4]" </when-handoff-missing>
<gather-additional-info> Based on target, gather:
- VPS: Hostname/IP, SSH username, project path
- Cloudflare: Project name, build command, output directory
- Fly.io: App name, region preference
- Shared: FTP/SSH credentials, remote path
</gather-additional-info> </phase>
<phase id="1" name="pre-deployment-checks"> <action>Verify project is ready for deployment.</action>
<checklist> Pre-deployment Verification:
Code Readiness:
Configuration:
Testing (if applicable):
Infrastructure:
</checklist>
<verification-commands>
# Check git status
git status
# Verify on correct branch
git branch --show-current
# Check build passes
{build_command}
# Verify tests pass (if configured)
{test_command}
</verification-commands>
<prompt-to-user> Running pre-deployment checks...
{checklist_results}
Issues Found: {count} {issue_details}
Ready to proceed with deployment? [yes/no/fix issues] </prompt-to-user> </phase>
<phase id="2" name="deploy"> <action>Execute deployment based on target.</action>
<deployment-targets>
<vps-docker> <name>VPS with Docker (Hostinger)</name>
<pre-steps>
- Ensure Docker Compose file is ready
- Verify SSH access to VPS
- Confirm project directory exists on VPS
</pre-steps>
<deployment-process> Step 1: Connect to VPS
ssh {username}@{host}
Step 2: Navigate to project
cd /var/www/{project_name}
Step 3: Pull latest code
git pull origin main
Step 4: Build and restart containers
docker compose pull
docker compose up -d --build
Step 5: Verify containers running
docker compose ps
Step 6: Check application logs
docker compose logs --tail=50
Step 7: Clean up
docker system prune -f
</deployment-process>
<first-deployment-extras> For first-time deployment:
- Create project directory:
``bash sudo mkdir -p /var/www/{projectname} sudo chown {username}:{username} /var/www/{projectname} ``
- Clone repository:
``bash cd /var/www/{projectname} git clone {repourl} . ``
- Create production .env:
``bash cp .env.example .env nano .env # Configure production values ``
- Configure Caddy (reverse proxy):
`` {domain} { reverse_proxy localhost:{port} } ``
- Reload Caddy:
``bash sudo systemctl reload caddy `` </first-deployment-extras> </vps-docker>
<cloudflare-pages> <name>Cloudflare Pages</name>
<pre-steps>
- Ensure Cloudflare account connected
- Verify build configuration
- Confirm project name
</pre-steps>
<deployment-process> Option A: Git-Connected (Automatic)
If connected to GitHub:
- Push to main branch
- Cloudflare automatically deploys
- Monitor build in Cloudflare dashboard
Option B: Direct Deploy (Manual)
Using Wrangler CLI:
# Install/update Wrangler
npm install -g wrangler
# Login to Cloudflare
wrangler login
# Build project
{build_command}
# Deploy
wrangler pages deploy {output_dir} --project-name={project_name}
</deployment-process>
<first-deployment-extras> For first-time deployment:
- Create project in Cloudflare Pages dashboard
- Connect to GitHub repository (recommended)
- Configure build settings:
- Build command: npm run build - Build output directory: out or dist or .next
- Set environment variables in dashboard
</first-deployment-extras> </cloudflare-pages>
<fly-io> <name>Fly.io</name>
<pre-steps>
- Ensure fly.toml exists
- Verify Fly CLI installed and authenticated
- Confirm app created
</pre-steps>
<deployment-process> Step 1: Verify fly.toml Ensure fly.toml is configured correctly.
Step 2: Deploy
flyctl deploy
Step 3: Monitor deployment
flyctl logs
Step 4: Verify running
flyctl status
Step 5: Open application
flyctl open
</deployment-process>
<first-deployment-extras> For first-time deployment:
- Install Fly CLI:
``bash curl -L https://fly.io/install.sh | sh ``
- Authenticate:
``bash flyctl auth login ``
- Create app:
``bash flyctl apps create {app_name} ``
- Create fly.toml (or use
flyctl launch)
- Set secrets:
``bash flyctl secrets set DATABASEURL="..." flyctl secrets set SECRETKEY="..." ``
- Create database (if needed):
``bash flyctl postgres create flyctl postgres attach `` </first-deployment-extras> </fly-io>
<hostinger-shared> <name>Hostinger Shared Hosting</name>
<pre-steps>
- Ensure FTP/SSH credentials available
- Verify remote path
- Confirm PHP version compatibility
</pre-steps>
<deployment-process> Option A: Using Git (if SSH available)
# SSH to server
ssh {username}@{host}
# Navigate to public_html
cd ~/public_html/{subdirectory}
# Pull latest code
git pull origin main
# Install dependencies (if composer)
composer install --no-dev --optimize-autoloader
Option B: Using rsync
rsync -avz --delete \
--exclude='.git' \
--exclude='.env' \
--exclude='node_modules' \
./ {username}@{host}:~/public_html/{subdirectory}/
Option C: Using FTP
Use FileZilla or similar:
- Connect to FTP server
- Navigate to public_html
- Upload files (excluding .env, node_modules, .git)
</deployment-process>
<first-deployment-extras> For first-time deployment:
- Create subdirectory (if not root):
``bash mkdir -p ~/public_html/{subdirectory} ``
- Create .htaccess (for PHP routing):
`` RewriteEngine On RewriteCond %{REQUESTFILENAME} !-f RewriteCond %{REQUESTFILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L] ``
- Configure database in cPanel
- Create production .env on server
- Set correct file permissions:
``bash find . -type f -exec chmod 644 {} \; find . -type d -exec chmod 755 {} \; `` </first-deployment-extras> </hostinger-shared>
</deployment-targets>
<execution-approach> For each deployment step:
- Show the command about to run
- Ask for confirmation before executing
- Show output
- Verify success before proceeding
- Offer to stop if errors occur
</execution-approach> </phase>
<phase id="3" name="post-deployment-verification"> <action>Verify deployment was successful.</action>
<verification-checks> Accessibility:
Functionality:
Performance:
</verification-checks>
<verification-commands>
# Check HTTP response
curl -I https://{domain}
# Check SSL certificate
curl -vI https://{domain} 2>&1 | grep "SSL certificate"
# Check specific endpoints
curl https://{domain}/api/health
</verification-commands>
<prompt-to-user> Verifying deployment...
{verification_results}
Status: {SUCCESS/ISSUES_FOUND} {details}
{if success} Your application is live at: https://{domain}
{if issues} Issues detected. Would you like help troubleshooting? [yes/no] </prompt-to-user> </phase>
<phase id="4" name="create-deployment-log"> <action>Create .docs/deployment-log.md documenting the deployment.</action>
<deployment-log-template>
# Deployment Log
## Latest Deployment
**Date:** {date}
**Target:** {deployment_target}
**Branch:** {branch}
**Commit:** {commit_hash}
**Deployed by:** {user}
**Status:** SUCCESS
### Pre-Deployment Checks
- [x] Code committed and pushed
- [x] Build passed locally
- [x] Tests passing
- [x] Environment configured
### Deployment Steps Executed
1. {step_1}
2. {step_2}
3. {step_3}
### Post-Deployment Verification
- [x] Application accessible
- [x] No errors in logs
- [x] Core functionality working
### URLs
- **Production:** https://{domain}
- **API:** https://{domain}/api
---
## Deployment Runbook
### Regular Deployment
{deployment_commands}
### Rollback Procedure
{rollback_commands}
### Environment Variables
| Variable | Description | Where to Set |
|----------|-------------|--------------|
| {var_1} | {desc} | {location} |
| {var_2} | {desc} | {location} |
---
## Deployment History
| Date | Commit | Status | Notes |
|------|--------|--------|-------|
| {date} | {hash} | SUCCESS | Initial deployment |
---
## Troubleshooting
### Common Issues
**Application not loading:**
- Check container status: `docker compose ps`
- Check logs: `docker compose logs`
- Verify Caddy config
**Database connection failed:**
- Verify DATABASE_URL in .env
- Check database container running
- Test connection manually
**SSL certificate issues:**
- Caddy auto-generates certificates
- Check Caddy logs: `sudo journalctl -u caddy`
- Verify DNS pointing to server
</deployment-log-template> </phase>
<phase id="5" name="summarize"> <action>Provide deployment summary and next steps.</action>
<summary-template>
Deployment Complete
Application: {projectname} Target: {deploymenttarget} URL: https://{domain} Status: SUCCESS
Deployment Record
Created: .docs/deployment-log.md
This file contains:
- Deployment runbook for future deployments
- Rollback procedure
- Environment variables reference
- Troubleshooting guide
Workflow Status
TERMINATION POINT - MANUAL DEPLOYMENT
Your application is deployed. You can stop here if you don't need CI/CD automation.
Next Options:
- Stop here - Use .docs/deployment-log.md for future manual deployments
- Add CI/CD - Use ci-cd-implement skill to automate deployments
For Future Deployments
Quick deployment:
{quick_deploy_command}
See .docs/deployment-log.md for full runbook.
Monitoring Recommendations
- Check logs regularly:
{log_command}
- Monitor uptime with external service
- Set up alerts for errors
Congratulations on your deployment! </summary-template> </phase>
</workflow>
<troubleshooting>
<common-issues>
<docker-issues> Container won't start:
# Check logs
docker compose logs {service_name}
# Rebuild from scratch
docker compose down
docker compose build --no-cache
docker compose up -d
Port already in use:
# Find process using port
sudo lsof -i :{port}
# Kill process or change port in docker-compose.yml
Out of disk space:
# Clean up Docker
docker system prune -a --volumes
</docker-issues>
<networking-issues> Application not accessible:
- Check if container is running:
docker compose ps
- Test locally:
curl localhost:{port}
- Check Caddy/reverse proxy logs
- Verify firewall allows traffic:
sudo ufw status
SSL certificate not working:
- Verify DNS points to server
- Check Caddy logs:
sudo journalctl -u caddy -f
- Wait for certificate propagation (up to 15 minutes)
</networking-issues>
<database-issues> Connection refused:
- Check database container:
docker compose ps db
- Verify DATABASE_URL format
- Check network: containers must be on same Docker network
Permission denied:
- Verify user credentials in .env
- Check database user has required permissions
</database-issues>
<cloudflare-issues> Build failed:
- Check build command matches local
- Verify Node.js version in dashboard
- Check build logs in Cloudflare dashboard
Environment variables:
- Set in Cloudflare Pages dashboard
- Redeploy after changing
</cloudflare-issues>
<fly-issues> Deploy failed:
- Check fly.toml configuration
- Verify app name matches
- Check resource limits (memory, CPU)
App crashing:
- Check logs:
flyctl logs
- Verify health check endpoint
- Check memory usage:
flyctl status
</fly-issues>
</common-issues>
</troubleshooting>
<guardrails>
<must-do>
- Run pre-deployment checks before deploying
- Ask for confirmation before executing commands
- Verify deployment success
- Create deployment-log.md documentation
- Handle errors gracefully with troubleshooting guidance
- Provide rollback instructions
</must-do>
<must-not-do>
- Deploy without user confirmation
- Skip pre-deployment checks
- Leave failed deployment without troubleshooting help
- Expose sensitive credentials in logs or documentation
- Skip post-deployment verification
</must-not-do>
</guardrails>
<workflow-status> Phase 5 of 7: Deployment
Status: Phase 0: Project Brief (project-brief-writer) Phase 1: Tech Stack (tech-stack-advisor) Phase 2: Deployment Strategy (deployment-advisor) Phase 3: Project Foundation (project-spinup) <- TERMINATION POINT (localhost) Phase 4: Test Strategy (test-orchestrator) - optional Phase 5: Deployment (you are here) <- TERMINATION POINT (manual deploy) Phase 6: CI/CD (ci-cd-implement) <- TERMINATION POINT (full automation) </workflow-status>
<integration-notes>
<workflow-position> Phase 5 of 7 in the Skills workflow chain. Expected input: Deployable project, .docs/deployment-strategy.md (gathered conversationally if missing) Produces: Deployed application, .docs/deployment-log.md
This is a TERMINATION POINT for projects not needing CI/CD automation. </workflow-position>
<flexible-entry> This skill can be invoked standalone on any deployable project. It gathers deployment target information conversationally if not available in handoff documents. </flexible-entry>
<when-to-invoke>
- When project development is complete (or MVP ready)
- When user is ready to deploy to production
- For subsequent deployments (use deployment-log.md as runbook)
</when-to-invoke>
<status-utility> Users can invoke the workflow-status skill at any time to:
- See current workflow progress
- Check which phases are complete
- Get guidance on next steps
- Review all handoff documents
Mention this option when users seem uncertain about their progress. </status-utility>
</integration-notes>