diff --git a/.dockerignore b/.dockerignore
index 325bfc0..a4f8385 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -13,6 +13,7 @@
 # Ignore all default key files.
 /config/master.key
 /config/credentials/*.key
+/registry_password.key
 
 # Ignore all logfiles and tempfiles.
 /log/*
diff --git a/.gitignore b/.gitignore
index 595d2ac..624d98f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@
 
 # Ignore master key for decrypting credentials and more.
 /config/master.key
+/registry_password.key
 
 # Vite Ruby
 /public/vite*
diff --git a/.kamal/secrets b/.kamal/secrets
index 9a771a3..82ecbcc 100644
--- a/.kamal/secrets
+++ b/.kamal/secrets
@@ -10,8 +10,9 @@
 # Use a GITHUB_TOKEN if private repositories are needed for the image
 # GITHUB_TOKEN=$(gh config get -h github.com oauth_token)
 
-# Grab the registry password from ENV
-KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
+# Set the Docker registry password directly
+# Replace 'your-docker-password' with your actual Docker Hub password
+KAMAL_REGISTRY_PASSWORD=$(cat registry_password.key)
 
 # Improve security by using a password manager. Never check config/master.key into git!
 RAILS_MASTER_KEY=$(cat config/master.key)
diff --git a/Dockerfile b/Dockerfile
index eab450a..fa630b0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,23 +1,30 @@
 # syntax=docker/dockerfile:1
 # check=error=true
 
-# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
-# docker build -t img_manager .
-# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name img_manager img_manager
-
-# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html
+# This Dockerfile is designed for Git-based deployment with Kamal
+# It pulls code from Git during deployment and uses external volumes for code, build artifacts, and data
 
 # Make sure RUBY_VERSION matches the Ruby version in .ruby-version
 ARG RUBY_VERSION=3.2.2
-FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
+FROM docker.io/library/ruby:$RUBY_VERSION-slim
 
 # Rails app lives here
 WORKDIR /rails
 
-# Install base packages
+# Install base packages including Git for code pulling
 RUN apt-get update -qq && \
-    apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \
-    rm -rf /var/lib/apt/lists /var/cache/apt/archives
+    apt-get install --no-install-recommends -y \
+    curl \
+    libjemalloc2 \
+    libvips \
+    sqlite3 \
+    nodejs \
+    npm \
+    netcat-openbsd \
+    git \
+    build-essential \
+    pkg-config \
+    && rm -rf /var/lib/apt/lists /var/cache/apt/archives
 
 # Set production environment
 ENV RAILS_ENV="production" \
@@ -25,43 +32,35 @@ ENV RAILS_ENV="production" \
     BUNDLE_PATH="/usr/local/bundle" \
     BUNDLE_WITHOUT="development"
 
-# Throw-away build stage to reduce size of final image
-FROM base AS build
-
-# Install packages needed to build gems
-RUN apt-get update -qq && \
-    apt-get install --no-install-recommends -y build-essential git pkg-config && \
-    rm -rf /var/lib/apt/lists /var/cache/apt/archives
-
-# Install application gems
-COPY Gemfile Gemfile.lock ./
-RUN bundle install && \
-    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
-    bundle exec bootsnap precompile --gemfile
-
-# Copy application code
-COPY . .
-
-# Precompile bootsnap code for faster boot times
-RUN bundle exec bootsnap precompile app/ lib/
-
-
-
-
-# Final stage for app image
-FROM base
-
-# Copy built artifacts: gems, application
-COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
-COPY --from=build /rails /rails
+# Create directories for mounted volumes
+RUN mkdir -p \
+    /rails/code \
+    /rails/storage \
+    /rails/public/uploads \
+    /rails/public/assets \
+    /rails/public/vite \
+    /rails/node_modules \
+    /rails/tmp \
+    /rails/log \
+    /rails/tmp/pids \
+    /rails/tmp/cache \
+    /rails/tmp/sockets
+
+# Declare volumes for persistent storage
+VOLUME ["/rails/code", "/rails/storage", "/rails/public/uploads", "/rails/public/vite", "/rails/node_modules", "/rails/log", "/rails/tmp"]
+
+# Copy entrypoint script
+COPY bin/docker-entrypoint /rails/bin/
+RUN chmod +x /rails/bin/docker-entrypoint
 
 # Run and own only the runtime files as a non-root user for security
 RUN groupadd --system --gid 1000 rails && \
     useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
-    chown -R rails:rails db log storage tmp
+    chown -R rails:rails /rails
+
 USER 1000:1000
 
-# Entrypoint prepares the database.
+# Entrypoint pulls code, installs dependencies, and prepares the application
 ENTRYPOINT ["/rails/bin/docker-entrypoint"]
 
 # Start server via Thruster by default, this can be overwritten at runtime
diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb
index ec3a79c..271e0c9 100644
--- a/app/controllers/concerns/authentication.rb
+++ b/app/controllers/concerns/authentication.rb
@@ -35,7 +35,7 @@ module Authentication
 
     def request_authentication
       session[:return_to_after_authenticating] = request.url
-      redirect_to new_sessions_path
+      redirect_to new_session_path
     end
 
     def after_authentication_url
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index 4f2c8fe..0c4b4a8 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -10,7 +10,7 @@ class PasswordsController < ApplicationController
       PasswordsMailer.reset(user).deliver_later
     end
 
-    redirect_to new_sessions_path, notice: "Password reset instructions sent (if user with that email address exists)."
+    redirect_to new_session_path, notice: "Password reset instructions sent (if user with that email address exists)."
   end
 
   def edit
@@ -18,7 +18,7 @@ class PasswordsController < ApplicationController
 
   def update
     if @user.update(params.permit(:password, :password_confirmation))
-      redirect_to new_sessions_path, notice: "Password has been reset."
+      redirect_to new_session_path, notice: "Password has been reset."
     else
       redirect_to edit_password_path(params[:token]), alert: "Passwords did not match."
     end
diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint
index 57567d6..cb0fcd6 100755
--- a/bin/docker-entrypoint
+++ b/bin/docker-entrypoint
@@ -1,14 +1,260 @@
 #!/bin/bash -e
+echo "Starting deployment process..."
 
-# Enable jemalloc for reduced memory usage and latency.
+# Enable jemalloc for reduced memory usage and latency
 if [ -z "${LD_PRELOAD+x}" ]; then
     LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit)
     export LD_PRELOAD
 fi
 
-# If running the rails server then create or migrate existing database
+# Ensure all required directories exist with proper permissions
+echo "Setting up directories..."
+mkdir -p /rails/code /rails/storage /rails/public/uploads /rails/public/assets /rails/public/vite /rails/node_modules /rails/log /rails/tmp/pids /rails/tmp/cache /rails/tmp/sockets
+
+# Set very permissive permissions for all directories
+chmod -R 777 /rails/storage /rails/public/uploads /rails/public/assets /rails/public/vite /rails/node_modules /rails/log /rails/tmp
+chown -R rails:rails /rails/storage /rails/public/uploads /rails/public/assets /rails/public/vite /rails/node_modules /rails/log /rails/tmp
+
+# Verify the storage directory exists and has proper permissions
+echo "Verifying storage directory permissions:"
+ls -la /rails | grep storage
+
+# Test if storage directory is writable
+echo "Testing storage directory write access..."
+if touch /rails/storage/test_write_access; then
+  echo "✅ Storage directory is writable"
+  rm /rails/storage/test_write_access
+else
+  echo "❌ ERROR: Cannot write to storage directory. Check volume mount and permissions."
+  # Continue anyway, but log the error
+fi
+
+# Wait for external volumes to be properly mounted
+sleep 5
+
+# Check if code directory is empty or if we need to clone/pull the repository
+if [ -z "${GIT_REPOSITORY}" ]; then
+  echo "⚠️ GIT_REPOSITORY environment variable not set. Using mounted code directory."
+else
+  echo "🔄 Setting up code from Git repository: ${GIT_REPOSITORY}"
+  
+  # Check if we already have the repository
+  if [ -d "/rails/code/.git" ]; then
+    echo "Git repository exists, pulling latest changes..."
+    cd /rails/code
+    git fetch
+    
+    # Check if we need to checkout a specific branch or tag
+    if [ -n "${GIT_BRANCH}" ]; then
+      echo "Checking out branch/tag: ${GIT_BRANCH}"
+      git checkout ${GIT_BRANCH}
+      git pull origin ${GIT_BRANCH}
+    else
+      echo "No branch specified, pulling latest from current branch"
+      git pull
+    fi
+  else
+    echo "Cloning repository..."
+    # Clone the repository
+    if [ -n "${GIT_BRANCH}" ]; then
+      git clone --branch ${GIT_BRANCH} ${GIT_REPOSITORY} /rails/code
+    else
+      git clone ${GIT_REPOSITORY} /rails/code
+    fi
+  fi
+  
+  echo "✅ Code updated from Git repository"
+fi
+
+# Create symbolic links from code directory to Rails app directory
+echo "Setting up symbolic links..."
+cd /rails/code
+
+# Link important directories and files to maintain Rails structure
+for dir in app bin config db lib public vendor; do
+  if [ -d "/rails/code/$dir" ]; then
+    ln -sfn /rails/code/$dir /rails/$dir
+  fi
+done
+
+# Link important files
+for file in Gemfile Gemfile.lock Rakefile config.ru; do
+  if [ -f "/rails/code/$file" ]; then
+    ln -sf /rails/code/$file /rails/$file
+  fi
+done
+
+# Link node_modules if it exists in the mounted volume
+if [ -d "/rails/node_modules" ]; then
+  ln -sfn /rails/node_modules /rails/code/node_modules
+fi
+
+# If running the rails server then install dependencies and prepare the database
 if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then
-  ./bin/rails db:prepare
+  cd /rails
+  
+  # Install Ruby dependencies if needed
+  echo "Installing Ruby dependencies..."
+  if [ ! -d "${BUNDLE_PATH}/ruby" ] || [ "$FORCE_BUNDLE_INSTALL" = "true" ]; then
+    bundle install
+    echo "✅ Ruby dependencies installed"
+  else
+    echo "✅ Ruby dependencies already installed"
+  fi
+  
+  # Install Node.js dependencies if needed
+  echo "Installing Node.js dependencies..."
+  if [ ! -d "/rails/node_modules/node_modules" ] || [ "$FORCE_NPM_INSTALL" = "true" ]; then
+    npm install
+    echo "✅ Node.js dependencies installed"
+  else
+    echo "✅ Node.js dependencies already installed"
+  fi
+  
+  # Prepare database files with proper permissions
+  echo "Ensuring database files exist with proper permissions..."
+  
+  # Create database directory with proper permissions
+  mkdir -p /rails/storage
+  chmod -R 777 /rails/storage
+  chown -R rails:rails /rails/storage
+  
+  echo "Creating database files if they don't exist..."
+  # Create database files if they don't exist
+  for db_file in production.sqlite3 production_cache.sqlite3 production_queue.sqlite3 production_cable.sqlite3; do
+    if [ ! -f "/rails/storage/$db_file" ]; then
+      echo "Creating /rails/storage/$db_file"
+      touch "/rails/storage/$db_file"
+      chmod 666 "/rails/storage/$db_file"
+      chown rails:rails "/rails/storage/$db_file"
+    else
+      echo "Database file /rails/storage/$db_file already exists"
+      # Make sure existing file has correct permissions
+      chmod 666 "/rails/storage/$db_file"
+      chown rails:rails "/rails/storage/$db_file"
+    fi
+  done
+  
+  # Double-check permissions and ownership
+  echo "Database directory permissions:"
+  ls -la /rails/storage
+  
+  # Test if we can write to the database file
+  echo "Testing database file write access..."
+  if sqlite3 /rails/storage/production.sqlite3 "PRAGMA user_version;" > /dev/null 2>&1; then
+    echo "✅ Database file is writable"
+  else
+    echo "❌ ERROR: Cannot write to database file. Check volume mount and permissions."
+    # Try to fix permissions again with more aggressive approach
+    echo "Attempting more aggressive permission fix..."
+    chown -R rails:rails /rails/storage
+    chmod -R 777 /rails/storage
+    chmod 666 /rails/storage/*.sqlite3
+    
+    # Try to create an empty database structure
+    echo "Attempting to initialize empty database..."
+    sqlite3 /rails/storage/production.sqlite3 "CREATE TABLE IF NOT EXISTS schema_migrations (version varchar(255) NOT NULL); CREATE UNIQUE INDEX unique_schema_migrations ON schema_migrations (version);" || true
+  fi
+  
+  # Prepare the database with retry logic
+  echo "Preparing database..."
+  
+  # First try to manually create schema_migrations table to avoid common issues
+  echo "Attempting to create schema_migrations table manually..."
+  for db_file in /rails/storage/production.sqlite3 /rails/storage/production_cache.sqlite3 /rails/storage/production_queue.sqlite3 /rails/storage/production_cable.sqlite3; do
+    echo "Initializing $db_file..."
+    sqlite3 "$db_file" "CREATE TABLE IF NOT EXISTS schema_migrations (version varchar(255) NOT NULL); CREATE UNIQUE INDEX IF NOT EXISTS unique_schema_migrations ON schema_migrations (version);" || true
+  done
+  
+  # Create empty schema.rb file to help Rails recognize the database state
+  mkdir -p /rails/db
+  if [ ! -f "/rails/db/schema.rb" ]; then
+    echo "Creating empty schema.rb file..."
+    cat > /rails/db/schema.rb << 'EOL'
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema[7.1].define(version: 0) do
+  # These are extensions that must be enabled in order to support this database
+
+end
+EOL
+  fi
+  
+  # Check if we should skip database preparation
+  if [ "${SKIP_DB_PREPARATION}" = "true" ]; then
+    echo "⚠️ SKIP_DB_PREPARATION is set to true, skipping database preparation"
+    echo "✅ Using existing database files without migrations"
+    SUCCESS=true
+  else
+    # Now try to run db:prepare with multiple attempts
+    for i in {1..3}; do
+      echo "Database preparation attempt $i..."
+      
+      # Print current environment for debugging
+      echo "Current environment:"
+      echo "- Working directory: $(pwd)"
+      echo "- User: $(whoami)"
+      echo "- Storage directory contents:"
+      ls -la /rails/storage
+      echo "- Database config:"
+      cat /rails/config/database.yml | grep -A 10 production
+      
+      # Try different database commands with increasing aggressiveness
+      if [ $i -eq 1 ]; then
+        echo "Trying db:prepare..."
+        RAILS_ENV=production ./bin/rails db:prepare --trace && SUCCESS=true && break
+      elif [ $i -eq 2 ]; then
+        echo "Trying db:migrate:status..."
+        RAILS_ENV=production ./bin/rails db:migrate:status --trace || true
+        echo "Trying db:schema:load..."
+        RAILS_ENV=production ./bin/rails db:schema:load --trace && SUCCESS=true && break
+      else
+        echo "Trying db:setup..."
+        RAILS_ENV=production ./bin/rails db:setup --trace && SUCCESS=true && break
+      fi
+      
+      echo "⚠️ Database preparation attempt $i failed, retrying..."
+      
+      # Try to fix permissions again
+      echo "Fixing permissions again..."
+      chmod -R 777 /rails/storage
+      chmod 666 /rails/storage/*.sqlite3
+      chown -R rails:rails /rails/storage
+      
+      sleep 5
+    done
+  fi
+  
+  if [ "$SUCCESS" = "true" ]; then
+    echo "✅ Database prepared successfully"
+  else
+    echo "⚠️ WARNING: Database preparation failed after 3 attempts, but continuing startup"
+    echo "The application may not function correctly until database issues are resolved"
+  fi
+  
+  # Build Vite assets if needed
+  if [ ! -d "/rails/public/vite" ] || [ -z "$(ls -A /rails/public/vite)" ] || [ "$FORCE_VITE_BUILD" = "true" ]; then
+    echo "Building Vite assets..."
+    bundle exec vite build
+    echo "✅ Vite assets built"
+  else
+    echo "✅ Vite assets already exist"
+  fi
+  
+  # Create health check file
+  touch /rails/tmp/healthy
+  echo "✅ Application ready to start"
 fi
 
+echo "🚀 Starting application..."
 exec "${@}"
diff --git a/bin/setup_volumes.sh b/bin/setup_volumes.sh
new file mode 100755
index 0000000..bdfad2d
--- /dev/null
+++ b/bin/setup_volumes.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# This script sets up the required directories and permissions on the server
+# Run this script on the server before deploying
+
+echo "Setting up directories and permissions for img-manager..."
+
+# Create all required directories
+mkdir -p /root/img_manager/code
+mkdir -p /root/img_manager/storage
+mkdir -p /root/img_manager/uploads
+mkdir -p /root/img_manager/public/vite
+mkdir -p /root/img_manager/node_modules
+mkdir -p /root/img_manager/logs
+mkdir -p /root/img_manager/tmp
+
+# Set very permissive permissions
+chmod -R 777 /root/img_manager
+
+# Create empty database files with proper permissions
+touch /root/img_manager/storage/production.sqlite3
+touch /root/img_manager/storage/production_cache.sqlite3
+touch /root/img_manager/storage/production_queue.sqlite3
+touch /root/img_manager/storage/production_cable.sqlite3
+chmod 666 /root/img_manager/storage/*.sqlite3
+
+# Initialize the database files with schema_migrations tables
+echo "Initializing database files with schema_migrations tables..."
+for db_file in /root/img_manager/storage/production.sqlite3 /root/img_manager/storage/production_cache.sqlite3 /root/img_manager/storage/production_queue.sqlite3 /root/img_manager/storage/production_cable.sqlite3; do
+  sqlite3 "$db_file" "CREATE TABLE IF NOT EXISTS schema_migrations (version varchar(255) NOT NULL); CREATE UNIQUE INDEX IF NOT EXISTS unique_schema_migrations ON schema_migrations (version);" || echo "Failed to initialize $db_file"
+done
+
+echo "Checking SELinux status..."
+if command -v getenforce &> /dev/null; then
+  selinux_status=$(getenforce)
+  echo "SELinux status: $selinux_status"
+  
+  if [ "$selinux_status" == "Enforcing" ]; then
+    echo "SELinux is enforcing. Setting proper contexts..."
+    # Set SELinux context for the directories
+    if command -v chcon &> /dev/null; then
+      chcon -Rt svirt_sandbox_file_t /root/img_manager
+    else
+      echo "chcon command not found. Unable to set SELinux context."
+    fi
+  fi
+else
+  echo "getenforce command not found. Unable to check SELinux status."
+fi
+
+echo "Directory permissions:"
+ls -la /root/img_manager
+
+echo "Storage directory permissions:"
+ls -la /root/img_manager/storage
+
+echo "Setup complete!"
diff --git a/config/database.yml b/config/database.yml
index 2640cb5..f573dab 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -21,21 +21,21 @@ test:
   database: storage/test.sqlite3
 
 
-# Store production database in the storage/ directory, which by default
-# is mounted as a persistent Docker volume in config/deploy.yml.
+# Store production database in the /rails/storage/ directory with absolute paths
+# This ensures the database files are found regardless of current directory
 production:
   primary:
     <<: *default
-    database: storage/production.sqlite3
+    database: /rails/storage/production.sqlite3
   cache:
     <<: *default
-    database: storage/production_cache.sqlite3
+    database: /rails/storage/production_cache.sqlite3
     migrations_paths: db/cache_migrate
   queue:
     <<: *default
-    database: storage/production_queue.sqlite3
+    database: /rails/storage/production_queue.sqlite3
     migrations_paths: db/queue_migrate
   cable:
     <<: *default
-    database: storage/production_cable.sqlite3
+    database: /rails/storage/production_cable.sqlite3
     migrations_paths: db/cable_migrate
diff --git a/config/deploy.yml b/config/deploy.yml
index 26f4793..ea9aef9 100644
--- a/config/deploy.yml
+++ b/config/deploy.yml
@@ -2,12 +2,12 @@
 service: img_manager
 
 # Name of the container image.
-image: your-user/img_manager
+image: mumumumushu/img_manager
 
 # Deploy to these servers.
 servers:
   web:
-    - 192.168.0.1
+    - 45.78.59.154
   # job:
   #   hosts:
   #     - 192.168.0.1
@@ -18,14 +18,16 @@ servers:
 #
 # Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
 proxy:
-  ssl: true
-  host: app.example.com
+  # ssl: true
+  host: 45.78.59.154
+  # If you have a domain name, use it instead of the IP address
+  # host: your-domain.com
 
 # Credentials for your image host.
 registry:
   # Specify the registry server, if you're not using Docker Hub
   # server: registry.digitalocean.com / ghcr.io / ...
-  username: your-user
+  username: mumumumushu
 
   # Always use an access token rather than real password when possible.
   password:
@@ -35,9 +37,26 @@ registry:
 env:
   secret:
     - RAILS_MASTER_KEY
+    # Add Git credentials if needed for private repositories
+    # - GIT_CREDENTIALS
   clear:
+    # Git repository configuration
+    GIT_REPOSITORY: http://git.tallty.com/mumumumushu/img-manager.git
+    GIT_BRANCH: main
+    
+    # Force rebuild flags (set to true when you want to force rebuild)
+    FORCE_BUNDLE_INSTALL: true
+    FORCE_NPM_INSTALL: true
+    FORCE_VITE_BUILD: true
+    
+    # Database configuration
+    RAILS_ENV: production
+    DATABASE_URL: sqlite3:///rails/storage/production.sqlite3
+    
+    # Disable database migrations during startup to avoid SQLite issues
+    SKIP_DB_PREPARATION: true
+    
     # Run the Solid Queue Supervisor inside the web server's Puma process to do jobs.
-    # When you start using multiple servers, you should split out job processing to a dedicated machine.
     SOLID_QUEUE_IN_PUMA: true
 
     # Set number of processes dedicated to Solid Queue (default: 1)
@@ -47,11 +66,10 @@ env:
     # WEB_CONCURRENCY: 2
 
     # Match this to any external database server to configure Active Record correctly
-    # Use img_manager-db for a db accessory server on same machine via local kamal docker network.
     # DB_HOST: 192.168.0.2
 
     # Log everything from Rails
-    # RAILS_LOG_LEVEL: debug
+    RAILS_LOG_LEVEL: debug
 
 # Aliases are triggered with "bin/kamal <alias>". You can overwrite arguments on invocation:
 # "bin/kamal logs -r job" will tail logs from the first server in the job section.
@@ -60,18 +78,47 @@ aliases:
   shell: app exec --interactive --reuse "bash"
   logs: app logs -f
   dbc: app exec --interactive --reuse "bin/rails dbconsole"
+  assets: app exec --interactive --reuse "bundle exec vite build"
+  migrate: app exec --interactive --reuse "bin/rails db:migrate"
 
-
-# Use a persistent storage volume for sqlite database files and local Active Storage files.
-# Recommended to change this to a mounted volume path that is backed up off server.
+# Use persistent storage volumes for external storage of code, files, and database
+# These volumes will be mounted to the container and persist between deployments
 volumes:
-  - "img_manager_storage:/rails/storage"
+  # Git code repository storage
+  - "/root/img_manager/code:/rails/code"
+  # Database storage with simpler configuration (no Z flag to avoid SELinux issues)
+  - "/root/img_manager/storage:/rails/storage"
+  # Uploaded files storage
+  - "/root/img_manager/uploads:/rails/public/uploads"
+  # Vite assets storage
+  - "/root/img_manager/public/vite:/rails/public/vite"
+  # Node modules storage
+  - "/root/img_manager/node_modules:/rails/node_modules"
+  # Logs storage
+  - "/root/img_manager/logs:/rails/log"
+  # Tmp directory for pids and other temporary files
+  - "/root/img_manager/tmp:/rails/tmp"
 
 
 # Bridge fingerprinted assets, like JS and CSS, between versions to avoid
 # hitting 404 on in-flight requests. Combines all files from new and old
 # version inside the asset_path.
-asset_path: /rails/public/assets
+# Disable asset bridging for now to fix deployment issues
+asset_path: false
+
+# Deployment configuration for better reliability
+# Increase the time to wait for a container to become ready
+# deploy_timeout: 180
+
+# # Increase the time to wait for a container to drain
+# drain_timeout: 60
+
+# # Increase the time to wait for a container to boot after it is running
+# readiness_delay: 30
+
+# Note: Run the setup script manually before deployment:
+# scp ./bin/setup_volumes.sh root@45.78.59.154:/root/setup_volumes.sh
+# ssh root@45.78.59.154 'chmod +x /root/setup_volumes.sh && /root/setup_volumes.sh'
 
 # Configure the image builder.
 builder:
diff --git a/registry_password.key.sample b/registry_password.key.sample
new file mode 100644
index 0000000..7a26ef0
--- /dev/null
+++ b/registry_password.key.sample
@@ -0,0 +1 @@
+dckr_pat_3-xxxx
\ No newline at end of file