9.8 KiB
Portainer Deployment Guide
This guide provides step-by-step instructions for deploying the Shopify AI App Builder to Portainer.
Quick Start
- Go to Portainer → Stacks → Add Stack
- Name your stack: e.g.,
shopify-ai-builder - Upload
stack-portainer.ymlor paste its contents - Set environment variables (see below)
- Deploy
Environment Variables Setup
Critical: Avoid Copy-Paste Issues
UPDATE: The latest version of the container automatically sanitizes environment variables on startup, removing invisible Unicode characters. However, it's still best practice to manually type variable names when possible.
When setting environment variables in Portainer, manually type the variable names and values instead of copying and pasting. This prevents invisible Unicode characters (like U+200E) from being inserted, which could cause deployment failures on older versions.
Required Variables
# OpenRouter API key (for AI planning mode)
OPENROUTER_API_KEY=your_openrouter_key
# Admin credentials for /admin dashboard
ADMIN_USER=admin
ADMIN_PASSWORD=your_secure_password
# Terminal password (for port 4001)
ACCESS_PASSWORD=your_terminal_password
Optional Variables
# OpenCode API key (required for some providers/models)
OPENCODE_API_KEY=your_opencode_key
# GitHub integration
GITHUB_PAT=your_github_token
GITHUB_USERNAME=your_github_username
GITHUB_CLIENT_ID=your_github_oauth_client_id
GITHUB_CLIENT_SECRET=your_github_oauth_client_secret
# Dodo Payments integration
DODO_PAYMENTS_API_KEY=dp_test_...
DODO_PAYMENTS_ENV=test
DODO_PAYMENTS_WEBHOOK_KEY=whsec_...
DODO_TOPUP_PRODUCT_FREE=prod_free_topup
DODO_TOPUP_PRODUCT_PLUS=prod_plus_topup
DODO_TOPUP_PRODUCT_PRO=prod_pro_topup
DODO_TOPUP_TOKENS_FREE=500000
DODO_TOPUP_TOKENS_PLUS=1000000
DODO_TOPUP_TOKENS_PRO=1000000
DODO_MIN_AMOUNT=50
# Google OAuth
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
# OAuth callback base URL (optional, for reverse proxies)
PUBLIC_BASE_URL=https://your-domain.com
# Session configuration
SESSION_SECRET=your_random_secret_key
# OpenRouter model configuration
OPENROUTER_MODEL_PRIMARY=anthropic/claude-3.5-sonnet
OPENROUTER_DEFAULT_MODEL=openai/gpt-4o-mini
Common Deployment Errors
Error: "unexpected character \u200e in variable name"
Full error message:
Failed to deploy a stack: unable to get the environment from the env file:
failed to read /data/compose/42/stack.env: line 8: unexpected character "\u200e"
in variable name "ADMIN_USER\u200e=user"
Cause: Invisible Unicode characters (U+200E Left-to-Right Mark, U+200B Zero-Width Space, etc.) were copied into the variable names or values. This typically happens when:
- Copying from web pages or documentation
- Pasting from certain text editors (especially rich text editors)
- Copying from PDFs or formatted documents
Automatic Fix (Latest Version): The container now automatically sanitizes environment variables on startup, removing these invisible characters. Simply rebuild or pull the latest image:
# Pull latest image
docker pull your-registry/shopify-ai-builder:latest
# Or rebuild locally
docker compose build --no-cache
# Redeploy in Portainer
Manual Solutions (if automatic fix doesn't work):
Solution 1: Recreate Variables Manually (Recommended)
- In Portainer, delete all environment variables
- Manually type each variable name and value (don't copy-paste)
- Save and redeploy
Solution 2: Use a Clean .env File
- Download the clean
.env.examplefrom the repository - Fill in your values using a plain text editor (Notepad++, VS Code, nano, vim)
- Run the validation script:
./scripts/validate-env.sh .env - If issues are found, clean the file:
./scripts/clean-env.sh .env - Upload to Portainer or copy-paste the cleaned values
Solution 3: Use the Cleanup Script
If you already have a .env file with invisible characters:
# Validate the file
./scripts/validate-env.sh your-file.env
# Clean invisible characters
./scripts/clean-env.sh your-file.env
# Verify it's clean
./scripts/validate-env.sh your-file.env
Error: "secret GITHUB_PAT not found"
Cause:
The stack references a Docker secret GITHUB_PAT that doesn't exist in Portainer.
Solutions:
Option 1: Remove the secret reference
Edit stack-portainer.yml and remove these sections:
# Remove this from the service:
secrets:
- GITHUB_PAT
# Remove this entire section at the bottom:
secrets:
GITHUB_PAT:
external: true
Then set GITHUB_PAT as a regular environment variable instead.
Option 2: Create the secret in Portainer
- Go to Portainer → Secrets → Add Secret
- Name:
GITHUB_PAT - Secret: paste your GitHub Personal Access Token
- Save and redeploy the stack
Error: Port conflicts
Cause: Ports 4000 or 4001 are already in use by another service.
Solution: Change the ports in the stack configuration:
ports:
- "5000:4000" # Map external 5000 to internal 4000
- "5001:4001" # Map external 5001 to internal 4001
Error: Architecture mismatch / Exit code 139 / Segmentation fault
Full error message:
ERROR: process "/bin/sh -c ..." did not complete successfully: exit code: 139
Cause: Exit code 139 indicates a segmentation fault, which typically occurs when:
- Building an image on one architecture (e.g., ARM64) but trying to run binaries compiled for another (e.g., AMD64)
- The build process isn't properly detecting the target platform
- Cross-architecture builds without proper emulation (QEMU)
- Docker buildx not properly passing
TARGETARCHbuild argument
Solution:
The Dockerfile has been updated to properly use Docker's TARGETARCH build argument, which Portainer automatically provides. This ensures the correct binaries are downloaded for your host architecture.
If you still encounter this error:
-
Check your host architecture:
# On the Portainer host uname -m # x86_64 = amd64 # aarch64 = arm64 -
Rebuild with --no-cache to ensure fresh build:
- In Portainer → Stacks → Your Stack → Editor
- Check "Re-pull image and re-deploy" or use "Build" option
- Enable "No cache" if available
-
Verify build logs:
- Look for messages like "Unsupported architecture" in the build logs
- Check if the correct binaries are being downloaded (should match your host arch)
-
For ARM hosts (Raspberry Pi, Apple Silicon, AWS Graviton, etc.):
- Ensure your Portainer is up-to-date (needs buildx support)
- The Dockerfile will automatically download ARM64 binaries
-
For AMD64 hosts:
- Standard x86_64 servers should work without any changes
-
Advanced: Force specific platform (not recommended):
# Only use if auto-detection fails services: shopify-ai-builder: platform: linux/amd64 # or linux/arm64
Why this was happening:
The previous version used dpkg --print-architecture to detect the architecture, which doesn't work reliably in cross-platform Docker builds. The updated Dockerfile now:
- Prioritizes Docker's
TARGETARCHbuild argument (passed by Portainer/buildx) - Falls back to
dpkgifTARGETARCHis not available - Provides detailed error messages showing the detected platform
This ensures reliable builds on both AMD64 and ARM64 architectures in Portainer.
Post-Deployment
Access Points
- Web UI:
http://your-server:4000 - Terminal:
http://your-server:4001 - Admin Dashboard:
http://your-server:4000/admin
Health Check
# Check if the container is running
docker ps | grep shopify-ai-builder
# View logs
docker logs -f <container-id>
# Check health status
docker inspect <container-id> | grep -A 10 Health
Testing the Deployment
- Open
http://your-server:4000in a browser - You should see the Shopify AI App Builder homepage
- Click "Get Started" to create your first app
- Enter a test message to verify the AI responds
Production Recommendations
- Use HTTPS: Set up a reverse proxy (NGINX, Traefik, or Caddy) with SSL/TLS
- Set strong passwords: For
ADMIN_PASSWORDandACCESS_PASSWORD - Use secrets: For sensitive values like API keys and tokens
- Enable secure cookies: Set
COOKIE_SECURE=1when using HTTPS - Configure firewall: Restrict access to ports 4000 and 4001
- Regular backups: Backup the
web_datavolume regularly - Resource limits: Adjust CPU and memory limits based on your usage
Volume Management
The stack creates two volumes:
- shopify_ai_pwsh_profile: PowerShell profile and configuration
- shopify_ai_data: All app data, sessions, and workspaces
To backup:
# Create backup directory
mkdir -p backups
# Backup data volume
docker run --rm \
-v shopify_ai_data:/data \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/shopify-data-$(date +%Y%m%d).tar.gz /data
To restore:
# Restore data volume
docker run --rm \
-v shopify_ai_data:/data \
-v $(pwd)/backups:/backup \
alpine tar xzf /backup/shopify-data-20240101.tar.gz -C /
Troubleshooting Commands
# View real-time logs
docker logs -f shopify-ai-builder
# Enter the container
docker exec -it shopify-ai-builder bash
# Check OpenCode installation
docker exec shopify-ai-builder opencode --version
# Restart the container
docker restart shopify-ai-builder
# Check environment variables
docker exec shopify-ai-builder env | grep -E "(ADMIN|OPENROUTER|GITHUB)"
Support
If you encounter issues not covered here:
- Check the main README.md troubleshooting section
- Review container logs for error messages
- Open a GitHub issue with:
- Error message
- Deployment method (Portainer)
- Stack configuration (redact sensitive values)
- Container logs