From 8e9a456d0874a50959438fd76cd4334a4c7a311c Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 14 Mar 2025 11:34:37 -0700 Subject: [PATCH 01/10] spec fixes --- spec/spec_helper.rb | 1 - stack_car.gemspec | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index af93ca5..09d5bcf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,4 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) -require 'pry' require "stack_car" require 'yaml' diff --git a/stack_car.gemspec b/stack_car.gemspec index d5d7ea1..63cd7ec 100644 --- a/stack_car.gemspec +++ b/stack_car.gemspec @@ -27,5 +27,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "pry" spec.add_runtime_dependency "dotenv" spec.add_runtime_dependency "json", "~> 2.3" - spec.add_runtime_dependency "thor", "~> 0.19" + spec.add_runtime_dependency "thor", "~> 0.20" end From 7a9abea0d12b7f3349865222a09e0815b6adb319 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 24 Mar 2025 14:50:05 -0700 Subject: [PATCH 02/10] add traefik proxy to stack car --- .gitignore | 4 ++- bin/test_sc | 5 ++++ lib/stack_car.rb | 8 +++--- lib/stack_car/cli.rb | 6 +++++ lib/stack_car/os.rb | 54 ++++++++++++++++++++++++++++++++++++++ lib/stack_car/proxy.rb | 42 ++++++++++++++++++++++++++++++ proxy/compose.yaml | 59 ++++++++++++++++++++++++++++++++++++++++++ proxy/traefik.yml | 49 +++++++++++++++++++++++++++++++++++ 8 files changed, 223 insertions(+), 4 deletions(-) create mode 100755 bin/test_sc create mode 100644 lib/stack_car/os.rb create mode 100644 lib/stack_car/proxy.rb create mode 100644 proxy/compose.yaml create mode 100644 proxy/traefik.yml diff --git a/.gitignore b/.gitignore index 19ec067..e7e5bc9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ /spec/reports/ /tmp/ **/.#* -/public/* \ No newline at end of file +/public/* +/proxy/localhost* +.tool-versions diff --git a/bin/test_sc b/bin/test_sc new file mode 100755 index 0000000..82ed502 --- /dev/null +++ b/bin/test_sc @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +ENV['STACK_CAR_DEBUG'] = 'true' +load "#{File.dirname(__FILE__)}/../lib/stack_car.rb" + +StackCar::HammerOfTheGods.start(ARGV) diff --git a/lib/stack_car.rb b/lib/stack_car.rb index 62fbcda..9368159 100644 --- a/lib/stack_car.rb +++ b/lib/stack_car.rb @@ -1,6 +1,8 @@ -require "stack_car/version" -require "stack_car/cli" -require "stack_car/dot_rc" +require_relative './stack_car/version' +require_relative './stack_car/os' +require_relative './stack_car/proxy' +require_relative './stack_car/cli' +require_relative './stack_car/dot_rc' ## # Ruby 3.x removed {File.exists?} in favor of {File.exist?}. This shim ensures that we can run diff --git a/lib/stack_car/cli.rb b/lib/stack_car/cli.rb index 837cff6..34ecef9 100644 --- a/lib/stack_car/cli.rb +++ b/lib/stack_car/cli.rb @@ -2,6 +2,7 @@ require 'erb' require 'dotenv' require 'json' +require 'byebug' if ENV['STACK_CAR_DEBUG'] module StackCar class HammerOfTheGods < Thor @@ -15,6 +16,9 @@ def self.exit_on_failure? true end + desc 'proxy COMMAND', 'Manage the traefik proxy for local development' + subcommand 'proxy', Proxy + method_option :service, default: 'web', type: :string, aliases: '-s' method_option :build, default: false, type: :boolean, aliases: '-b' method_option :logs, default: true, type: :boolean @@ -330,6 +334,7 @@ def dockerize(dir=".") end protected + def compose_depends(*excludes) @compose_depends = [] services = [:fcrepo, :postgres, :mysql, :elasticsearch, :sidekiq, :solr, :redis, :mongodb, :memcached] - excludes @@ -370,6 +375,7 @@ def run_with_exit(*args) if !result exit(1) end + result end def file_config diff --git a/lib/stack_car/os.rb b/lib/stack_car/os.rb new file mode 100644 index 0000000..29686d5 --- /dev/null +++ b/lib/stack_car/os.rb @@ -0,0 +1,54 @@ +# From Dory https://github.com/FreedomBen/dory/blob/master/lib/dory/os.rb +module StackCar + module Os + def self.bash(command) + system("bash -c '#{command}'") + end + + def self.ubuntu? + self.bash(self.ubuntu_cmd) + end + + def self.fedora? + self.bash(self.fedora_cmd) + end + + def self.arch? + self.bash(self.arch_cmd) + end + + def self.macos? + self.bash('uname -a | grep "Darwin" > /dev/null') + end + + def self.ubuntu_cmd + %q( + if $(which lsb_release >/dev/null 2>&1); then + lsb_release -d | grep --color=auto "Ubuntu" > /dev/null + else + uname -a | grep --color=auto "Ubuntu" > /dev/null + fi + ) + end + + def self.fedora_cmd + %q( + if $(which lsb_release >/dev/null 2>&1); then + lsb_release -d | grep --color=auto "Fedora" > /dev/null + else + uname -r | grep --color=auto "fc" > /dev/null + fi + ) + end + + def self.arch_cmd + %q( + if $(which lsb_release >/dev/null 2>&1); then + lsb_release -d | grep --color=auto "Arch" > /dev/null + else + uname -a | grep --color=auto "ARCH" > /dev/null + fi + ) + end + end +end diff --git a/lib/stack_car/proxy.rb b/lib/stack_car/proxy.rb new file mode 100644 index 0000000..3bf0934 --- /dev/null +++ b/lib/stack_car/proxy.rb @@ -0,0 +1,42 @@ +require 'thor' + +module StackCar + class Proxy < Thor + include Thor::Actions + + desc 'up', 'Launch traefik proxy for local development, assumes localhost.direct is the domain' + def up + #find the socket + set_proxy_env + run("docker compose -f proxy/compose.yaml up -d") + end + + desc 'down', 'Stop traefik proxy for local development' + def down + set_proxy_env + run("docker compose -f proxy/compose.yaml down") + end + + desc 'cert', 'Add a self-signed certificate for localhost.direct to the system' + def cert + run("pushd proxy && wget https://aka.re/localhost-ss && popd") + say("\n\n\nEnter the password found https://github.com/Upinel/localhost.direct?tab=readme-ov-file#a-non-public-ca-certificate-if-you-have-admin-right-on-your-development-environment-you-can-use-the-following-10-years-long-pre-generated-self-signed-certificate\n\n\n") + system("unzip -d proxy proxy/localhost-ss") + if Os.macos? + run("sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain proxy/localhost.direct.SS.crt") + elsif Os.ubuntu? + run("sudo cp proxy/localhost.direct.SS.crt /usr/local/share/ca-certificates/localhost.direct.SS.crt") + run("sudo update-ca-certificates") + else + say("\n\n\nPlease figure out how to add a certificate to your system, then open a PR for your OS/Distro") + say("Files are located #{ENV['PWD']}/proxy/localhost.direct.SS.crt and #{ENV['PWD']}/proxy/localhost.direct.SS.key\n\n\n") + exit(1) + end + end + + protected + def set_proxy_env + ENV['DOCKER_SOCKET'] ||= "/var/run/docker.sock" + end + end +end diff --git a/proxy/compose.yaml b/proxy/compose.yaml new file mode 100644 index 0000000..90578f2 --- /dev/null +++ b/proxy/compose.yaml @@ -0,0 +1,59 @@ +services: + traefik: + image: "traefik" + ports: + - "80:80" + - "443:443" + - "3333:3333" + volumes: + - "${DOCKER_SOCKET}:/var/run/docker.sock:ro" + - ./traefik.yml:/etc/traefik/traefik.yml + - ./localhost.direct.SS.crt:/etc/traefik/cert.pem + - ./localhost.direct.SS.key:/etc/traefik/key.pem + labels: + - traefik.enable=true + - traefik.http.routers.router.rule=Host(`traefik.localhost.direct`) + - traefik.http.routers.router.entrypoints=websecure + - traefik.http.services.router.loadbalancer.server.port=8080 + - traefik.http.routers.router.tls=true + healthcheck: + test: ["CMD-SHELL", "traefik healthcheck --ping"] + interval: 4s + timeout: 4s + retries: 8 + start_period: 4s + + whoami: + image: traefik/whoami + ports: + - "80" + labels: + - "traefik.enable=true" + - "traefik.http.routers.whoami.tls=true" + - "traefik.http.routers.whoami.entrypoints=websecure" + - "traefik.http.routers.whoami.rule=Host(`whoami.localhost.direct`)" + - "traefik.http.services.whoami.loadbalancer.server.port=80" + + # dnsmasq: + # image: joweisberg/dnsmasq + # restart: always + # ports: + # - ${DNSMASQ_PORT}:53 + # - 5380:8080 + # environment: + # HTTP_USER: ${DNSMASQ_USER} + # HTTP_PASS: ${DNSMASQ_PASSWORD} + # labels: + # - "traefik.enable=true" + # - "traefik.http.routers.dnsmasq.rule=Host(`dnsmasq.${DOMAIN}`)" + # - "traefik.http.services.dnsmasq.loadbalancer.server.port=8080" + # - "traefik.http.routers.dnsmasq.entrypoints=web" + # volumes: + # - ./dnsmasq/dnsmasq.conf:/etc/dnsmasq.conf + # - ./dnsmasq/dnsmasq.d/:/etc/dnsmasq.d +networks: + default: + name: network.direct + ipam: + config: + - subnet: 172.100.61.0/24 diff --git a/proxy/traefik.yml b/proxy/traefik.yml new file mode 100644 index 0000000..7920129 --- /dev/null +++ b/proxy/traefik.yml @@ -0,0 +1,49 @@ +--- +global: + sendAnonymousUsage: false + +providers: + docker: + exposedByDefault: false + endpoint: "unix:///var/run/docker.sock" + file: + directory: /etc/traefik + watch: true + +api: + insecure: true + dashboard: true + +serversTransport: + insecureSkipVerify: true + +entryPoints: + web: + address: ":80" + http: + redirections: + entryPoint: + to: websecure + scheme: https + + websecure: + address: ":443" + + tcp: + address: ":3333" + +tls: + certificates: + - certFile: /etc/traefik/cert.pem + keyFile: /etc/traefik/key.pem + stores: + default: + defaultCertificate: + certFile: /etc/traefik/cert.pem + keyFile: /etc/traefik/key.pem + +ping: + entryPoint: "web" + +log: + level: DEBUG From 2d2771563609738ac598530c1d89bf26e6755aac Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 24 Mar 2025 14:52:34 -0700 Subject: [PATCH 03/10] bump version --- lib/stack_car/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stack_car/version.rb b/lib/stack_car/version.rb index 2480e8a..1be400d 100644 --- a/lib/stack_car/version.rb +++ b/lib/stack_car/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module StackCar - VERSION = '0.18.0' + VERSION = '0.19.0' end From 7dd7a55655627b0a4edaefb07ba49fc163d56aac Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 24 Mar 2025 15:08:39 -0700 Subject: [PATCH 04/10] deal with proxy paths --- lib/stack_car/cli.rb | 4 ++++ lib/stack_car/proxy.rb | 18 +++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/stack_car/cli.rb b/lib/stack_car/cli.rb index 34ecef9..5a4aafb 100644 --- a/lib/stack_car/cli.rb +++ b/lib/stack_car/cli.rb @@ -12,6 +12,10 @@ def self.source_root File.join(File.dirname(__FILE__), '..', '..', 'templates') end + def self.gem_root + File.join(File.dirname(__FILE__), '..', '..') + end + def self.exit_on_failure? true end diff --git a/lib/stack_car/proxy.rb b/lib/stack_car/proxy.rb index 3bf0934..b740943 100644 --- a/lib/stack_car/proxy.rb +++ b/lib/stack_car/proxy.rb @@ -8,24 +8,25 @@ class Proxy < Thor def up #find the socket set_proxy_env - run("docker compose -f proxy/compose.yaml up -d") + run("docker compose -f #{HammerOfTheGods.gem_root}/proxy/compose.yaml up -d") end desc 'down', 'Stop traefik proxy for local development' def down set_proxy_env - run("docker compose -f proxy/compose.yaml down") + run("docker compose -f #{HammerOfTheGods.gem_root}/proxy/compose.yaml down") end desc 'cert', 'Add a self-signed certificate for localhost.direct to the system' def cert - run("pushd proxy && wget https://aka.re/localhost-ss && popd") + proxy_dir = "#{HammerOfTheGods.gem_root}/proxy" + run("pushd #{proxy_dir} && wget https://aka.re/localhost-ss && popd") say("\n\n\nEnter the password found https://github.com/Upinel/localhost.direct?tab=readme-ov-file#a-non-public-ca-certificate-if-you-have-admin-right-on-your-development-environment-you-can-use-the-following-10-years-long-pre-generated-self-signed-certificate\n\n\n") - system("unzip -d proxy proxy/localhost-ss") + system("unzip -d #{proxy_dir} #{proxy_dir}/localhost-ss") if Os.macos? - run("sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain proxy/localhost.direct.SS.crt") + run("sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain #{proxy_dir}/localhost.direct.SS.crt") elsif Os.ubuntu? - run("sudo cp proxy/localhost.direct.SS.crt /usr/local/share/ca-certificates/localhost.direct.SS.crt") + run("sudo cp #{proxy_dir}/localhost.direct.SS.crt /usr/local/share/ca-certificates/localhost.direct.SS.crt") run("sudo update-ca-certificates") else say("\n\n\nPlease figure out how to add a certificate to your system, then open a PR for your OS/Distro") @@ -37,6 +38,9 @@ def cert protected def set_proxy_env ENV['DOCKER_SOCKET'] ||= "/var/run/docker.sock" - end + unless File.exist?("#{HammerOfTheGods.gem_root}/proxy/localhost.direct.SS.crt") + say("you must run proxy cert once after installing this gem before using the proxy") + exit(1) + end end end From 63c3a74aadb8034e9e1b987544d8c2720a2a0523 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 24 Mar 2025 15:12:57 -0700 Subject: [PATCH 05/10] readme updates --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ff20c38..0a666a5 100644 --- a/README.md +++ b/README.md @@ -17,23 +17,26 @@ Stack Car is an opinionated set of tools around Docker and Rails. It provides c Because stack_car will be used to run your application in side of Docker, you want to install stack car in to your system Ruby instead of putting in your applications Gemfile ```bash -gem install stack_car +gem install stack_car ``` ## Usage -Commands are accesible via the "sc" short cut. Note: this will need to be in your command path in front of the spreadsheet command (sc), which is a fairly archaiac unix spreadsheet tool. We're guessing you don't edit a lot of spreadsheets in your terminal, but if you do, we also figure you can override your path order pretty easily. Many of these commands have short versions or alias to make remembering them easier. If there are obvious aliases missing, PRs are welcome. +Commands are accessible via the "sc" short cut. Note: this will need to be in your command path in front of the spreadsheet command (sc), which is a fairly archaiac unix spreadsheet tool. We're guessing you don't edit a lot of spreadsheets in your terminal, but if you do, we also figure you can override your path order pretty easily. Many of these commands have short versions or alias to make remembering them easier. If there are obvious aliases missing, PRs are welcome. ```ruby Commands: stack_car bundle_exec ARGS # wraps docker compose exec web bundle exec unless --service is used to specify (sc be ARGS) stack_car console ARGS # shortcut to start rails console - stack_car dockerize DIR # Will copy the docker tempates in to your project, see options for supported dependencies + stack_car dockerize DIR # Will copy the docker templates in to your project, see options for supported dependencies stack_car exec ARGS # wraps docker compose exec web unless --service is used to specify stack_car help [COMMAND] # Describe available commands or one specific command stack_car stop # starts docker compose with rebuild and orphan removal, defaults to all stack_car up # starts docker compose with rebuild and orphan removal, defaults to web stack_car walk ARGS # wraps docker compose run web unless --service is used to specify + stack_car proxy up # starts proxy container for SSL termination + stack_car proxy down # stops running proxy container + stack_car proxy cert # generates SSL certificates for local development, uses *.localhost.direct ``` ## Development @@ -79,7 +82,7 @@ Alternatively, set it in your shell's `rc` file (`~/.bashrc`, `~/.zshrc`, etc.) With `THOR_MERGE` set, you can enter `m` at the command prompt when there is a conflict between app and `sc` template files. -*Note*: For best experience, set `THOR_MERGE` to **GUI text editor** (ie. `code` or `atom`). +*Note*: For best experience, set `THOR_MERGE` to **GUI text editor** (ie. `code` or `atom`). Initiating a merge pulls 2 versions of the file to the editor. One is what is proposed by stack_car, the other is the original. **Add what you need from the template version to the original file and save the changes**. @@ -107,7 +110,7 @@ stack_car will have provided sensible defaults for your services but customizati - Do a text search to find and replace any instances `CHANGEME` in the generated files - Add any **general environment variables** to `.env` - This sets defaults for all docker compose environments -- Add any **development environment variables** to `.env.development` +- Add any **development environment variables** to `.env.development` - These set up any new values or overrides specific to your development env - Run `sc build` to build your image - On failed build, browse the terminal output to track down and squash any misconfigurations. Rebuild From e67557c996a9a451667d0eeba0f43ea8d4241f9f Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 24 Mar 2025 15:26:18 -0700 Subject: [PATCH 06/10] the end --- lib/stack_car/proxy.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/stack_car/proxy.rb b/lib/stack_car/proxy.rb index b740943..c07623e 100644 --- a/lib/stack_car/proxy.rb +++ b/lib/stack_car/proxy.rb @@ -42,5 +42,6 @@ def set_proxy_env say("you must run proxy cert once after installing this gem before using the proxy") exit(1) end + end end end From afc91b858ab412870629e188dc67798a5b85a661 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Tue, 25 Mar 2025 12:57:13 -0700 Subject: [PATCH 07/10] fix network naming --- proxy/compose.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proxy/compose.yaml b/proxy/compose.yaml index 90578f2..83f64cd 100644 --- a/proxy/compose.yaml +++ b/proxy/compose.yaml @@ -53,7 +53,4 @@ services: # - ./dnsmasq/dnsmasq.d/:/etc/dnsmasq.d networks: default: - name: network.direct - ipam: - config: - - subnet: 172.100.61.0/24 + name: stackcar From fd688a24f1b7729a6cc7a1f7e5b4a9685bd3fa0e Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 31 Mar 2025 15:28:13 -0700 Subject: [PATCH 08/10] more robust, ruby like download and unzip of cert --- lib/stack_car/os.rb | 10 ++++++++++ lib/stack_car/proxy.rb | 44 ++++++++++++++++++++++++++++++++++++++---- stack_car.gemspec | 1 + 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/stack_car/os.rb b/lib/stack_car/os.rb index 29686d5..7986dbf 100644 --- a/lib/stack_car/os.rb +++ b/lib/stack_car/os.rb @@ -21,6 +21,16 @@ def self.macos? self.bash('uname -a | grep "Darwin" > /dev/null') end + def self.wsl? + self.bash(self.wsl_cmd) + end + + def self.wsl_cmd + %q( + grep -i "microsoft\|wsl" /proc/version > /dev/null 2>&1 + ) + end + def self.ubuntu_cmd %q( if $(which lsb_release >/dev/null 2>&1); then diff --git a/lib/stack_car/proxy.rb b/lib/stack_car/proxy.rb index c07623e..881a6c8 100644 --- a/lib/stack_car/proxy.rb +++ b/lib/stack_car/proxy.rb @@ -1,4 +1,7 @@ require 'thor' +require 'open-uri' +require 'fileutils' +require 'archive/zip' module StackCar class Proxy < Thor @@ -19,15 +22,24 @@ def down desc 'cert', 'Add a self-signed certificate for localhost.direct to the system' def cert - proxy_dir = "#{HammerOfTheGods.gem_root}/proxy" - run("pushd #{proxy_dir} && wget https://aka.re/localhost-ss && popd") - say("\n\n\nEnter the password found https://github.com/Upinel/localhost.direct?tab=readme-ov-file#a-non-public-ca-certificate-if-you-have-admin-right-on-your-development-environment-you-can-use-the-following-10-years-long-pre-generated-self-signed-certificate\n\n\n") - system("unzip -d #{proxy_dir} #{proxy_dir}/localhost-ss") + say("Downloading certificate package...") + + IO.copy_stream(URI.open(download_url), output_file) + say("Download complete.") + unzip_file + if Os.macos? run("sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain #{proxy_dir}/localhost.direct.SS.crt") elsif Os.ubuntu? run("sudo cp #{proxy_dir}/localhost.direct.SS.crt /usr/local/share/ca-certificates/localhost.direct.SS.crt") run("sudo update-ca-certificates") + elsif Os.wsl? + say("\n\n\nFor WSL, you need to add the certificate to Windows certificate store:\n") + say("1. Copy the certificate to a Windows-accessible location:\n") + run("cp #{proxy_dir}/localhost.direct.SS.crt /mnt/c/temp/localhost.direct.SS.crt") + say("\n2. Now run this Windows command to import the certificate (requires admin rights):\n") + run("powershell.exe -Command \"Start-Process powershell -Verb RunAs -ArgumentList '-Command Import-Certificate -FilePath C:\\temp\\localhost.direct.SS.crt -CertStoreLocation Cert:\\LocalMachine\\Root'\"") + say("\n3. Then restart your browser to apply the changes\n\n") else say("\n\n\nPlease figure out how to add a certificate to your system, then open a PR for your OS/Distro") say("Files are located #{ENV['PWD']}/proxy/localhost.direct.SS.crt and #{ENV['PWD']}/proxy/localhost.direct.SS.key\n\n\n") @@ -36,6 +48,18 @@ def cert end protected + + def unzip_file + say("\n\n\nEnter the password found https://github.com/Upinel/localhost.direct?tab=readme-ov-file#a-non-public-ca-certificate-if-you-have-admin-right-on-your-development-environment-you-can-use-the-following-10-years-long-pre-generated-self-signed-certificate\n\n\n") + password = ask('[Required] Enter the unzip password::') + zip_file = "#{proxy_dir}/localhost-ss" + Archive::Zip.extract(zip_file, proxy_dir, :password => password) + say("Successfully unzipped certificate files.") + rescue Zlib::DataError + say("Incorrect password. Please try again.") + exit(1) + end + def set_proxy_env ENV['DOCKER_SOCKET'] ||= "/var/run/docker.sock" unless File.exist?("#{HammerOfTheGods.gem_root}/proxy/localhost.direct.SS.crt") @@ -43,5 +67,17 @@ def set_proxy_env exit(1) end end + + def proxy_dir + @proxy_dir ||= "#{HammerOfTheGods.gem_root}/proxy" + end + + def download_url + @download_url ||= "https://aka.re/localhost-ss" + end + + def output_file + @output_file ||= File.join(proxy_dir, "localhost-ss") + end end end diff --git a/stack_car.gemspec b/stack_car.gemspec index 63cd7ec..3aa8a8d 100644 --- a/stack_car.gemspec +++ b/stack_car.gemspec @@ -25,6 +25,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "yard" spec.add_development_dependency "yard-thor" spec.add_development_dependency "pry" + spec.add_runtime_dependency "archive-zip" spec.add_runtime_dependency "dotenv" spec.add_runtime_dependency "json", "~> 2.3" spec.add_runtime_dependency "thor", "~> 0.20" From 2bbc2ac8e9610ac899bdd4ac111768dff4155073 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 31 Mar 2025 15:39:50 -0700 Subject: [PATCH 09/10] update github actions --- .github/workflows/rspec-action.yaml | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/rspec-action.yaml b/.github/workflows/rspec-action.yaml index 1ff3208..cec554a 100644 --- a/.github/workflows/rspec-action.yaml +++ b/.github/workflows/rspec-action.yaml @@ -1,35 +1,35 @@ name: Test -on: +on: push: branches: - main pull_request: branches: - main -jobs: +jobs: rspec: name: Run rspec with ruby runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Cache - uses: actions/cache@v2.1.3 - with: - path: vendor/bundle - key: '2.3' - - name: Setup Ruby - uses: ruby/setup-ruby@v1.59.1 - with: - ruby-version: '2.3' - - name: Dependencies - run: | - bundle config path vendor/bundle - bundle install - - name: Rspec - run: 'bundle exec rspec' - - name: Publish Test Report - uses: mikepenz/action-junit-report@v3 - if: always() # always run even if the previous step fails - with: - report_paths: '**/build/test-results/test/TEST-*.xml' + - name: Checkout code + uses: actions/checkout@v3 + - name: Cache + uses: actions/cache@v4.2.3 + with: + path: vendor/bundle + key: "2.3" + - name: Setup Ruby + uses: ruby/setup-ruby@v1.59.1 + with: + ruby-version: "2.3" + - name: Dependencies + run: | + bundle config path vendor/bundle + bundle install + - name: Rspec + run: "bundle exec rspec" + - name: Publish Test Report + uses: mikepenz/action-junit-report@v3 + if: always() # always run even if the previous step fails + with: + report_paths: "**/build/test-results/test/TEST-*.xml" From 1184fcd28dd8d192318036b29ff5745081673874 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Mon, 31 Mar 2025 15:49:16 -0700 Subject: [PATCH 10/10] update instructions --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a666a5..6c807e0 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,54 @@ Commands: stack_car proxy cert # generates SSL certificates for local development, uses *.localhost.direct ``` +## Proxy +StackCar has a built-in proxy designed to simplify local SSL development. The proxy provides SSL termination for your web services, allowing you to run your applications with HTTPS locally. + +### Getting Started with the Proxy + +To use the StackCar proxy: +1. **Download and Install the SSL certificates** for local development: + ```bash + sc proxy cert + ``` + This will download the SSL certificates for `*.localhost.direct`. This only needs to be done once per version of stack_car. + +2. **Start the proxy**: + ```bash + sc proxy up + ``` + +3. If you application is running in Docker, make sure you application has labels: + ```yaml + labels: + - "traefik.enable=true" + - "traefik.http.routers.my-app.tls=true" + - "traefik.http.routers.my-app.entrypoints=websecure" + - "traefik.http.routers.my-app.rule=HostRegexp(`my-app.localhost.direct`)" + - "traefik.http.services.my-app.loadbalancer.server.port=3000" + ``` + +4. **Access your application** using `https://my-app.localhost.direct` + +### Proxy Configuration + +The proxy configuration can be customized in your `docker-compose.yml` file. By default, it's configured to handle SSL termination on port 443 and forward traffic to your application services. + +### Stopping the Proxy + +When you're done working with SSL, you can stop the proxy: +```bash +sc proxy down +``` + +### Troubleshooting + +- **Certificate issues**: If your browser doesn't trust the certificate, you may need to add the generated certificate to your system's trust store. +- **Port conflicts**: Ensure port 443 is available on your local machine. + ## Development -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can run `bin/test_sc` to run the command but from your local check out. You can also run `bin/console` for an interactive prompt that will allow you to experiment. **To install this gem onto your local machine** - Run `bundle exec rake install`