- Add POST /apps/{id}/env-vars/{varID}/edit endpoint
- Add POST /apps/{id}/labels/{labelID}/edit endpoint
- Add POST /apps/{id}/volumes/{volumeID}/edit endpoint
- Add inline edit UI with Alpine.js toggle in app_detail template
- Models already support Save() with update when ID != 0
Closes#67
Add POST /apps/{id}/deployments/cancel endpoint that allows users to
cancel in-progress deployments via the web UI.
Changes:
- Add CancelDeploy() and HasActiveDeploy() public methods to deploy service
- Add HandleCancelDeploy handler
- Wire route in routes.go
- Add cancel button to app detail template (shown during active deployments)
- Add handler tests for cancel endpoint
fixes#66
- Track scroll position per log pane (container logs, build logs, deployment cards)
- Auto-scroll to bottom only when user is already at bottom (tail-follow)
- When user scrolls up to review earlier output, pause auto-scroll
- Show a '↓ Follow' button when auto-scroll is paused; clicking resumes
- Only scroll on actual content changes (skip no-op updates)
- Use overflow-y: auto for proper scrollable containers
- Add break-words to prevent horizontal overflow on long lines
Closes#17
Add gorilla/csrf middleware to protect all HTML-serving routes against
cross-site request forgery attacks. The webhook endpoint is excluded
since it uses secret-based authentication.
Changes:
- Add gorilla/csrf v1.7.3 dependency
- Add CSRF() middleware method using session secret as key
- Apply CSRF middleware to all HTML route groups in routes.go
- Pass CSRF token to all templates via addGlobals helper
- Add {{ .CSRFField }} / {{ $.CSRFField }} hidden inputs to all forms
Closes#11
Replaced manual DOM manipulation with a deploymentCard Alpine component
that uses x-text bindings and x-ref for proper scrolling, matching the
working container logs implementation.
- Remove details/summary element that may have caused layout issues
- Use simpler layout with header row and logs block below
- Change overflow-auto to overflow-y-scroll to force scrollbar
- Add break-all to handle long lines
Move bg-gray-900, rounded-lg, and p-4 from the pre element to the
wrapper div. This matches the working structure in app_detail.html
and allows overflow-auto to work correctly.
- Write deployment logs to files when deployment finishes (success or failure)
- Log files stored in DataDir/logs/<hostname>/<appname>/<appname>_<sha>_<timestamp>.log.txt
- Capture commit SHA for manual deploys by parsing git rev-parse HEAD after clone
- Add download endpoint for log files at /apps/{id}/deployments/{deploymentID}/download
- Add download link in deployment history view for finished deployments
- Add Alpine.js (self-hosted, embedded in static/)
- Refactor app.js to use Alpine.js stores and components
- Update templates to use x-data, x-bind, x-show, x-text directives
- Add reactive deploy button state, live logs, status badges
- Add auto-dismiss alerts with close button and transitions
- Add copy-to-clipboard component with feedback
- Add confirm dialog component for destructive actions
- Add relative time component with auto-update
- Add prettier to make fmt target for JS formatting
- Add deploy stats (last deploy time, total count) to dashboard
- Add recent-deployments API endpoint for real-time updates
- Add live build logs to deployments history page
- Fix git clone regression (preserve entrypoint for simple clones)
- Refactor JavaScript into shared app.js with page init functions
- Deploy button disables immediately on click
- Auto-refresh deployment list and logs during builds
- Format JavaScript with Prettier (4-space indent)
- Clone specific commit SHA from webhook instead of just branch HEAD
- Log webhook payload in deployment logs
- Add build/deploy timing to ntfy and Slack notifications
- Implement container rollback on deploy failure
- Remove old container only after successful deployment
- Show relative times in deployment history (hover for full date)
- Update port mappings UI with labeled text inputs
- Add footer with version info, license, and repo link
- Format deploy key comment as upaas_DATE_appname
- Add app_ports table for storing port mappings per app
- Add Port model with CRUD operations
- Add handlers for adding/deleting port mappings
- Add ports section to app detail template
- Update Docker client to configure port bindings when creating containers
- Support both TCP and UDP protocols
- Replace UUID with ULID for app ID generation (lexicographically sortable)
- Remove container_id column from apps table (migration 002)
- Add upaas.id Docker label to identify containers by app ID
- Implement FindContainerByAppID in Docker client to query by label
- Update handlers and deploy service to use label-based container lookup
- Show system-managed upaas.id label in UI with editing disabled
Container association is now determined dynamically via Docker label
rather than stored in the database, making the system more resilient
to container recreation or external changes.