diff --git a/.gitignore b/.gitignore
index 391c492..150f862 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.DS_Store
node_modules
-public
\ No newline at end of file
+public/public
+temp_backup
\ No newline at end of file
diff --git a/.woodpecker.yml b/.woodpecker.yml
new file mode 100644
index 0000000..b166ec7
--- /dev/null
+++ b/.woodpecker.yml
@@ -0,0 +1,113 @@
+# build:1
+labels:
+ location: manager
+clone:
+ git:
+ image: woodpeckerci/plugin-git
+ settings:
+ partial: false
+ depth: 1
+when:
+ branch: [main, production]
+steps:
+ # Build Step for staging Branch
+ build-staging:
+ name: build-staging
+ image: woodpeckerci/plugin-docker-buildx
+ environment:
+ REGISTRY_USER:
+ from_secret: REGISTRY_USER
+ REGISTRY_PASSWORD:
+ from_secret: REGISTRY_PASSWORD
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ commands:
+ - echo "Building application for staging branch"
+ - echo "$${REGISTRY_PASSWORD}" | docker login -u "$${REGISTRY_USER}" --password-stdin git.nixc.us
+ - echo compose build
+ - docker compose -f docker-compose.staging.yml pull --ignore-buildable
+ - docker compose -f docker-compose.staging.yml build --pull
+ when:
+ event: push
+
+ deploy-new:
+ name: deploy-new
+ image: woodpeckerci/plugin-docker-buildx
+ environment:
+ REGISTRY_USER:
+ from_secret: REGISTRY_USER
+ REGISTRY_PASSWORD:
+ from_secret: REGISTRY_PASSWORD
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ commands:
+ - echo "$${REGISTRY_PASSWORD}" | docker login -u "$${REGISTRY_USER}" --password-stdin git.nixc.us
+ - echo compose push
+ - docker compose -f docker-compose.staging.yml push
+ - docker stack deploy --with-registry-auth -c ./stack.staging.yml $${CI_REPO_NAME}-staging
+ when:
+ event: push
+
+ cleanup-staging:
+ name: cleanup-staging
+ image: woodpeckerci/plugin-docker-buildx
+ environment:
+ REGISTRY_USER:
+ from_secret: REGISTRY_USER
+ REGISTRY_PASSWORD:
+ from_secret: REGISTRY_PASSWORD
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ commands:
+ - for i in {1..5}; do docker stack rm ${CI_REPO_NAME}-staging && break || sleep 10; done
+ - docker compose -f docker-compose.staging.yml down
+ - docker compose -f docker-compose.staging.yml rm -f
+ when:
+ event: push
+
+ build-push-production:
+ name: build-push-production
+ image: woodpeckerci/plugin-docker-buildx
+ environment:
+ REGISTRY_USER:
+ from_secret: REGISTRY_USER
+ REGISTRY_PASSWORD:
+ from_secret: REGISTRY_PASSWORD
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ commands:
+ - echo "Building application for production branch"
+ - echo "$${REGISTRY_PASSWORD}" | docker login -u "$${REGISTRY_USER}" --password-stdin git.nixc.us
+ - echo compose build
+ - docker compose -f docker-compose.production.yml pull --ignore-buildable
+ - docker compose -f docker-compose.production.yml build --pull
+ - docker compose -f docker-compose.production.yml push
+ when:
+ branch: main
+ event: push
+
+ deploy-production:
+ name: deploy-production
+ image: woodpeckerci/plugin-docker-buildx
+ environment:
+ REGISTRY_USER:
+ from_secret: REGISTRY_USER
+ REGISTRY_PASSWORD:
+ from_secret: REGISTRY_PASSWORD
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ commands:
+ - echo "$${REGISTRY_PASSWORD}" | docker login -u "$${REGISTRY_USER}" --password-stdin git.nixc.us
+ - docker stack deploy --with-registry-auth -c ./stack.production.yml $${CI_REPO_NAME}
+ when:
+ branch: main
+ event: push
+
+ post-deploy-smoke-tests-git-nixc-us:
+ name: run-post-deploy-smoke-tests-git-nixc-us
+ image: git.nixc.us/colin/playwright:latest
+ environment:
+ BASE_URL: "https://git.nixc.us"
+ when:
+ branch: production
+ event: push
\ No newline at end of file
diff --git a/CSS-JS-OPTIMIZATION.md b/CSS-JS-OPTIMIZATION.md
deleted file mode 100644
index 341afbf..0000000
--- a/CSS-JS-OPTIMIZATION.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# CSS and JavaScript Optimization Guide
-
-This document explains how to eliminate unused CSS and JavaScript from the ShowerLoop website.
-
-## Quick Start
-
-1. Install dependencies:
- ```bash
- npm install --legacy-peer-deps
- ```
-
-2. Build the production version with optimizations:
- ```bash
- ./build-production.sh
- ```
-
-## What This Does
-
-### CSS Optimization
-
-The build script optimizes CSS in two ways:
-
-1. **CSSO Optimization**: Uses CSSO to remove unused selectors, merge similar rules, and minify the CSS.
- - Typically reduces CSS by 5-30% depending on the file
- - Maintains full functionality while eliminating bloat
- - Works without requiring a running website
-
-2. **File Path Updates**: Automatically updates all HTML files to reference the optimized CSS versions.
-
-### JavaScript Optimization
-
-JavaScript optimization happens through:
-
-1. **Tree Shaking**: Rollup analyzes your code to detect which parts are actually used and removes dead code.
- - Eliminates unused imports and functions
- - Reduces JavaScript file sizes significantly
-
-2. **Code Splitting**: JavaScript is split into separate bundles:
- - app.modern.min.js - Main application code
- - video-init.modern.min.js - Video player initialization
- - skip-to-content.modern.min.js - Accessibility features
-
-3. **Minification**: All JavaScript is minified to reduce file size.
-
-## Optimization Results
-
-In our tests, the optimization achieves:
-
-| File Type | Size Reduction |
-|-----------|---------------|
-| CSS | 5-30% |
-| JavaScript| 30-60% |
-
-## How to Keep It Optimized
-
-1. **Maintain Source Files**: Keep original JavaScript source files in `src/js/`
-
-2. **Run Build Before Deployment**: Always run `./build-production.sh` before deploying to production
-
-3. **Add New Components Wisely**: When adding new CSS/JS, consider if it's truly needed or if existing code can be reused
-
-## Troubleshooting
-
-- **Missing Styles**: If elements look unstyled after optimization, check the original CSS files and update your HTML accordingly.
-
-- **JavaScript Errors**: If functionality breaks, check the browser console for errors and ensure all required code is in your source files.
-
-- **Build Errors**: Make sure all dependencies are installed with `npm install --legacy-peer-deps` before running the build scripts.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index ad69f4d..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 Shower-Loop
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index b628531..88e99cc 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,34 @@
-# website
-https://showerloop.cc new site for https://showerloop.org [planned]
+# ShowerLoop Website
-## Local Development
+This repository contains the source code for the ShowerLoop website, built with Hugo and served via Docker.
-To test this site locally:
+## Repository Structure
-1. Make sure you have [Hugo](https://gohugo.io/installation/) installed on your system
-2. Clone this repository
-3. Run the development server using the script:
+- `/docker/showerloop/` - Container configuration for the website
+ - `/docker/showerloop/public/` - Hugo website source files
+ - `/docker/showerloop/Dockerfile` - Docker image definition
+ - `/docker/showerloop/Caddyfile` - Caddy server configuration
+
+## Development
+
+To run the Hugo development server:
```bash
+cd docker/showerloop/public
./run-hugo-server.sh
```
-Or run Hugo directly:
+The development server will be available at http://localhost:1313/
+
+## Building
+
+To build the production site:
```bash
-hugo server -D --disableFastRender
+cd docker/showerloop/public
+./build-production.sh
```
-4. Open your browser and go to http://localhost:1313/ to view the site
-5. The site will automatically reload when you make changes to the content or templates
+## Deployment
-### Notes
-- The `-D` flag enables draft content to be visible in the development environment
-- `--disableFastRender` ensures full rebuilds for more reliable preview
+The site is automatically built and deployed using Woodpecker CI when changes are pushed to the master branch.
\ No newline at end of file
diff --git a/categories/index.xml b/categories/index.xml
deleted file mode 100644
index d336b43..0000000
--- a/categories/index.xml
+++ /dev/null
@@ -1 +0,0 @@
-Categories onhttp://localhost:54386/categories/Recent content in Categories onHugoen-us
\ No newline at end of file
diff --git a/contact-us/index.html b/contact-us/index.html
deleted file mode 100644
index 3cdb077..0000000
--- a/contact-us/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
Support the Project | ShowerLoop
-
Skip to Content
ShowerLoop
Support the Project
If you want to support the ShowerLoop project, check out our Make-It Button where you can contribute to our ongoing development.
<p>We work with limited resources and recycle many materials. With access to workspace and tools (thank you, Fablab!), we're able to continue developing this sustainable technology.</p>
-
- <p>We're collaborating with people around the world to bring ShowerLoop to various environments - boats, RVs, houses in remote locations, Pacific Islands, eco-friendly buildings, and historic structures without modern plumbing. The possibilities are endless, and together we hope to realize them all.</p>
-
- <p>Our team is developing a business model that fosters community around social and environmental ethics within the open source circular economy.</p>
-
- <div class="mdl-grid" style="justify-content: center; margin-top: 30px;">
- <a class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" href="/make-it">
- Support the Project
- </a>
- </div>
-</section>
-
\ No newline at end of file
diff --git a/docker-compose.production.yml b/docker-compose.production.yml
new file mode 100644
index 0000000..131ff22
--- /dev/null
+++ b/docker-compose.production.yml
@@ -0,0 +1,7 @@
+services:
+ showerloop:
+ build:
+ context: docker/showerloop
+ dockerfile: Dockerfile.production
+ pull: true
+ image: git.nixc.us/colin/showerloop-cc:production
diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml
new file mode 100644
index 0000000..0fb5654
--- /dev/null
+++ b/docker-compose.staging.yml
@@ -0,0 +1,6 @@
+services:
+ showerloop:
+ build:
+ context: docker/showerloop
+ pull: true
+ image: git.nixc.us/colin/showerloop-cc:staging
diff --git a/docker/Dockerfile.production b/docker/Dockerfile.production
new file mode 100644
index 0000000..460adb4
--- /dev/null
+++ b/docker/Dockerfile.production
@@ -0,0 +1 @@
+FROM git.nixc.us/colin/showerloop-cc:staging
diff --git a/docker/showerloop/Caddyfile b/docker/showerloop/Caddyfile
new file mode 100644
index 0000000..42ad00c
--- /dev/null
+++ b/docker/showerloop/Caddyfile
@@ -0,0 +1,87 @@
+# Template: Caddyfile.override
+# Purpose: Default configuration for custom containers.
+# Description:
+# - Serves static files from /srv.
+# - Provides a /health endpoint for health checks.
+# - Designed to run behind a reverse proxy like Træfik, listening only on port 80.
+# - comes with security headers
+
+:80 {
+ # Health check endpoint
+ respond /health "OK" 200
+
+ # Enable compression for text-based resources
+ encode gzip zstd
+
+ # Security headers
+ header {
+ # Cross-Origin headers
+ Cross-Origin-Embedder-Policy "require-corp"
+ Cross-Origin-Opener-Policy "same-origin"
+ Cross-Origin-Resource-Policy "same-origin"
+
+ # Permissions Policy
+ Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
+
+ # Referrer Policy
+ Referrer-Policy "strict-origin-when-cross-origin"
+
+ # HSTS
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
+
+ # Content Type Options
+ X-Content-Type-Options "nosniff"
+
+ # XSS Protection
+ X-XSS-Protection "1; mode=block"
+
+ # Frame Options (prevents clickjacking)
+ X-Frame-Options "SAMEORIGIN"
+
+ # Frame ancestors (prevents embedding in other sites)
+ Content-Security-Policy "frame-ancestors 'none'"
+
+ # Remove Server header
+ -Server
+ }
+
+ # Cache control for static assets - images, fonts, etc.
+ @staticAssets {
+ path *.jpg *.jpeg *.png *.webp *.avif *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot
+ method GET HEAD
+ }
+ header @staticAssets Cache-Control "public, max-age=31536000, immutable"
+ header @staticAssets ?Access-Control-Allow-Origin *
+
+ # Special handling for CSS and JS files
+ @cssAndJs {
+ path *.css *.js
+ method GET HEAD
+ }
+ header @cssAndJs Cache-Control "public, max-age=31536000, immutable"
+
+ # Cache HTML files but for a shorter period
+ @htmlFiles {
+ path *.html
+ method GET HEAD
+ }
+ header @htmlFiles Cache-Control "public, max-age=86400, must-revalidate"
+
+ # Static file server
+ file_server {
+ root /srv # Root directory for serving static files
+ }
+
+ # Restrict allowed methods to only GET and HEAD
+ @staticRequests {
+ method GET HEAD
+ }
+
+ handle @staticRequests {
+ root * /srv
+ file_server
+ }
+
+ # Handle all other methods
+ respond "Method Not Allowed" 405
+}
\ No newline at end of file
diff --git a/docker/showerloop/Dockerfile b/docker/showerloop/Dockerfile
new file mode 100644
index 0000000..72ebc30
--- /dev/null
+++ b/docker/showerloop/Dockerfile
@@ -0,0 +1,42 @@
+# Stage 1: Build Hugo site
+FROM alpine:latest AS hugo-builder
+
+# Install necessary dependencies (Hugo, Git, Node.js, and npm)
+RUN apk add --no-cache hugo git nodejs npm
+
+# Copy our enhanced Caddyfile
+COPY Caddyfile.default.template /etc/caddy/Caddyfile.override
+
+# Set working directory
+WORKDIR /site
+
+# Copy the Hugo source files
+COPY public/ /site
+
+# Install PostCSS and its dependencies locally and update browserslist
+RUN cd /site && npm init -y && \
+ npm install --save-dev postcss postcss-cli autoprefixer && \
+ npm install --save-dev caniuse-lite && \
+ npm update caniuse-lite browserslist
+
+# Build the Hugo site for production with optimizations
+# Disable GitInfo, enable minification, and set production environment
+RUN mkdir /public && \
+ cd /site && \
+ HUGO_ENABLEGITINFO=false \
+ HUGO_ENV=production \
+ npm run build:prod && \
+ cp -r /site/public/* /public/
+
+# Stage 2: Production image with prebuilt static files
+FROM git.nixc.us/colin/container-base:production-nixiusstatic
+
+# Copy the built site from the first stage
+COPY --from=hugo-builder /public /srv
+
+# Copy our enhanced Caddyfile for development
+COPY Caddyfile.default.template /etc/caddy/Caddyfile.override
+
+# Add health check endpoint for production monitoring
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+ CMD wget -q --spider http://localhost/healthcheck.txt || exit 1
\ No newline at end of file
diff --git a/.hugo_build.lock b/docker/showerloop/public/.hugo_build.lock
similarity index 100%
rename from .hugo_build.lock
rename to docker/showerloop/public/.hugo_build.lock
diff --git a/CNAME b/docker/showerloop/public/CNAME
similarity index 100%
rename from CNAME
rename to docker/showerloop/public/CNAME
diff --git a/_headers b/docker/showerloop/public/_headers
similarity index 100%
rename from _headers
rename to docker/showerloop/public/_headers
diff --git a/_redirects b/docker/showerloop/public/_redirects
similarity index 100%
rename from _redirects
rename to docker/showerloop/public/_redirects
diff --git a/analyze-css.js b/docker/showerloop/public/analyze-css.js
similarity index 100%
rename from analyze-css.js
rename to docker/showerloop/public/analyze-css.js
diff --git a/build-production.sh b/docker/showerloop/public/build-production.sh
similarity index 100%
rename from build-production.sh
rename to docker/showerloop/public/build-production.sh
diff --git a/docker/showerloop/public/categories/index.xml b/docker/showerloop/public/categories/index.xml
new file mode 100644
index 0000000..e9e2ccc
--- /dev/null
+++ b/docker/showerloop/public/categories/index.xml
@@ -0,0 +1 @@
+Categories onhttp://localhost:1313/categories/Recent content in Categories onHugoen-us
\ No newline at end of file
diff --git a/components/index.html b/docker/showerloop/public/components/index.html
similarity index 98%
rename from components/index.html
rename to docker/showerloop/public/components/index.html
index e1b3acb..df2468a 100644
--- a/components/index.html
+++ b/docker/showerloop/public/components/index.html
@@ -1,4 +1,4 @@
-Components | ShowerLoop
+Components | ShowerLoopHow It Works | ShowerLoop
+How It Works | ShowerLoopHome | ShowerLoop
+Home | ShowerLoop
\ No newline at end of file
diff --git a/posts/blog2/index.html b/docker/showerloop/public/posts/blog2/index.html
similarity index 85%
rename from posts/blog2/index.html
rename to docker/showerloop/public/posts/blog2/index.html
index 698dea2..08a8af9 100644
--- a/posts/blog2/index.html
+++ b/docker/showerloop/public/posts/blog2/index.html
@@ -1,4 +1,4 @@
-Showerloop at the Design museum | ShowerLoop
+Showerloop at the Design museum | ShowerLoop
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/posts/blog3/index.html b/docker/showerloop/public/posts/blog3/index.html
similarity index 91%
rename from posts/blog3/index.html
rename to docker/showerloop/public/posts/blog3/index.html
index bc7a242..dcf997d 100644
--- a/posts/blog3/index.html
+++ b/docker/showerloop/public/posts/blog3/index.html
@@ -1,4 +1,4 @@
-Don't Put These Things Down The Shower Drain! | ShowerLoop
+Don't Put These Things Down The Shower Drain! | ShowerLoop
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/posts/blog4/index.html b/docker/showerloop/public/posts/blog4/index.html
similarity index 89%
rename from posts/blog4/index.html
rename to docker/showerloop/public/posts/blog4/index.html
index 7bcb869..f4f58a2 100644
--- a/posts/blog4/index.html
+++ b/docker/showerloop/public/posts/blog4/index.html
@@ -1,4 +1,4 @@
-2 Ways to Be Economical When Showering With an Injury | ShowerLoop
+2 Ways to Be Economical When Showering With an Injury | ShowerLoop
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/posts/index.html b/docker/showerloop/public/posts/index.html
similarity index 98%
rename from posts/index.html
rename to docker/showerloop/public/posts/index.html
index 42c15e8..2f7a5ec 100644
--- a/posts/index.html
+++ b/docker/showerloop/public/posts/index.html
@@ -1,4 +1,4 @@
-Posts | ShowerLoop
+Posts | ShowerLoopResearch | ShowerLoop
+Research | ShowerLoop