Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
- Create Gitea Actions workflow for automated Docker builds on push to main - Add docker-compose.portainer.yml for production Portainer deployment - Create comprehensive DEPLOYMENT.md guide with step-by-step instructions - Update CLAUDE.md with CI/CD pipeline documentation Images are built and pushed to Gitea registry at: code.puffinoffset.com/matt/puffin-app:latest code.puffinoffset.com/matt/puffin-app:main-<sha> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.8 KiB
6.8 KiB
Puffin Offset - Deployment Guide
This guide covers deploying the Puffin Offset application using Gitea Actions for automated builds and Portainer for container orchestration.
Architecture Overview
Push to main → Gitea Actions → Build Docker Image → Push to Registry → Manual Deploy via Portainer
CI/CD Pipeline
Automated Build Process
When code is pushed to the main branch:
- Gitea Actions triggers automatically
- Docker image is built using the multi-stage Dockerfile
- Image is pushed to Gitea's container registry with two tags:
latest- Always points to the most recent buildmain-<commit-sha>- Specific commit for rollback capability
Registry Location
Images are stored at:
code.puffinoffset.com/matt/puffin-app:latest
code.puffinoffset.com/matt/puffin-app:main-<sha>
Portainer Deployment
Prerequisites
- Portainer installed and accessible
- Gitea registry credentials configured in Portainer
- Environment variables prepared (see below)
Step 1: Configure Gitea Registry in Portainer
- Navigate to Portainer → Registries
- Click "Add registry"
- Configure:
- Name:
Gitea - code.puffinoffset.com - Registry URL:
code.puffinoffset.com - Authentication: Enabled
- Username: Your Gitea username (e.g.,
matt) - Password: Gitea access token or password
- Name:
- Click "Add registry"
Step 2: Prepare Environment Variables
Create a .env file on your server with the required variables:
# Example: /path/to/puffin-app/.env
VITE_WREN_API_TOKEN=your-wren-api-token
VITE_FORMSPREE_CONTACT_ID=your-formspree-contact-id
VITE_FORMSPREE_OFFSET_ID=your-formspree-offset-id
Note: The env.sh script in the Docker image will inject these at runtime.
Step 3: Create Portainer Stack
Option A: Using Portainer UI
- Navigate to Portainer → Stacks
- Click "Add stack"
- Configure:
- Name:
puffin-app - Build method: "Web editor"
- Name:
- Paste the contents of
docker-compose.portainer.yml - In Environment variables section, add:
- Name:
ENV_FILE_PATH - Value:
/path/to/your/.env
- Name:
- Click "Deploy the stack"
Option B: Using Git Repository
- Navigate to Portainer → Stacks
- Click "Add stack"
- Configure:
- Name:
puffin-app - Build method: "Repository"
- Repository URL:
https://code.puffinoffset.com/matt/puffin-app.git - Repository reference:
refs/heads/main - Compose path:
docker-compose.portainer.yml - Authentication: Configure with your Gitea credentials
- Name:
- Click "Deploy the stack"
Step 4: Verify Deployment
-
Check that the container is running:
- Navigate to Portainer → Containers
- Look for
puffin-app-web-1or similar - Status should be "running"
-
Test the application:
- Access:
http://your-server:3800 - Or via your Nginx reverse proxy configuration
- Access:
-
Check logs if needed:
- Click on the container
- Select "Logs" tab
Updating to New Versions
Method 1: Using Portainer UI (Recommended)
- Navigate to Portainer → Stacks
- Click on puffin-app stack
- Click "Update the stack"
- Enable "Pull latest image version"
- Enable "Re-pull image and redeploy"
- Click "Update"
Portainer will:
- Pull the latest image from Gitea registry
- Recreate the container with the new image
- Maintain your environment variables and configuration
Method 2: Pull Specific Version
To rollback or deploy a specific commit:
- Edit the stack in Portainer
- Change the image tag from
latesttomain-<commit-sha>image: code.puffinoffset.com/matt/puffin-app:main-abc1234 - Update the stack
Monitoring Build Status
Check Gitea Actions
- Go to your Gitea repository:
https://code.puffinoffset.com/matt/puffin-app - Navigate to "Actions" tab
- View recent workflow runs
- Click on a run to see detailed logs
Verify Image in Registry
- In Gitea, navigate to "Packages" or "Registry"
- Look for
puffin-appimages - Verify tags:
latestandmain-<sha>tags should be present
Troubleshooting
Build Failed in Gitea Actions
Check the workflow logs:
- Go to Gitea → puffin-app → Actions
- Click on the failed run
- Review error messages
Common issues:
- Registry authentication failed: Check secrets.GITHUB_TOKEN is available
- Build errors: Review Dockerfile and build logs
- Network issues: Check runner connectivity
Image Pull Failed in Portainer
Error: unauthorized: authentication required
Solution:
- Verify registry is configured in Portainer (Step 1)
- Check credentials are correct
- Ensure registry URL is
code.puffinoffset.com(nohttps://)
Container Won't Start
Check environment variables:
- Verify
.envfile exists on the host - Ensure volume mount path is correct in docker-compose.portainer.yml
- Check container logs for missing env var errors
Check port conflicts:
- Ensure port 3800 is not already in use
- Run
netstat -tuln | grep 3800on the host
Application Not Accessible
Verify container is running:
docker ps | grep puffin-app
Check nginx reverse proxy:
- Review host Nginx configuration (
nginx-host.conf) - Ensure proxy_pass points to correct container port
- Test direct access:
http://server-ip:3800
Check firewall:
# Example for ufw
sudo ufw status
sudo ufw allow 3800/tcp
Environment Variables Reference
| Variable | Description | Required |
|---|---|---|
VITE_WREN_API_TOKEN |
Wren Climate API authentication token | Yes |
VITE_FORMSPREE_CONTACT_ID |
Formspree contact form endpoint ID | Yes |
VITE_FORMSPREE_OFFSET_ID |
Formspree offset order form endpoint ID | Yes |
NODE_ENV |
Node environment (set to production) |
Auto-set |
Rollback Procedure
To rollback to a previous version:
- Find the commit SHA of the working version
- In Portainer, edit the stack
- Change image tag to
main-<previous-sha> - Update the stack
Example:
# Before (current broken version)
image: code.puffinoffset.com/matt/puffin-app:latest
# After (rollback to specific commit)
image: code.puffinoffset.com/matt/puffin-app:main-ab0dbbd
Security Best Practices
- Never commit
.envfile to git (already in .gitignore) - Use Gitea access tokens instead of passwords for registry auth
- Restrict registry access to necessary users
- Review Gitea Actions logs for sensitive data exposure
- Keep base images updated (node:20-alpine, nginx:alpine)
Next Steps
- Set up monitoring/alerting for failed builds
- Configure automatic backups of
.envfile - Implement health checks in docker-compose
- Set up SSL certificates via Let's Encrypt
- Configure log aggregation for production debugging