1 Commits

Author SHA1 Message Date
7df8934786 v0.1.2
All checks were successful
Gitea Actions Demo / lint (push) Successful in 2m1s
Gitea Actions Demo / test (push) Successful in 14s
Gitea Actions Demo / docker (push) Successful in 2m12s
2025-04-01 21:06:55 -05:00
25 changed files with 265 additions and 365 deletions

View File

@@ -1,2 +1,2 @@
ARG VARIANT="3.4.4" ARG VARIANT="3.4.2"
FROM ghcr.io/rails/devcontainer/images/ruby:${VARIANT} FROM ghcr.io/rails/devcontainer/images/ruby:${VARIANT}

View File

@@ -6,7 +6,7 @@
"vscode": { "vscode": {
"extensions": [ "extensions": [
"Shopify.ruby-lsp", "Shopify.ruby-lsp",
"docker.docker" "ms-azuretools.vscode-docker"
] ]
} }
}, },

View File

@@ -1,7 +0,0 @@
**/.git
**/.gitignore
/.devcontainer
/.gitea
/.github
/.vscode
/charts

View File

@@ -1,27 +1,74 @@
--- ---
name: Release name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: on:
schedule: schedule:
- cron: "0 0 * * *" - cron: "0 10 * * *"
push: push:
branches: branches:
- main - "**"
tags: tags:
- "v*.*.*" - "v*.*.*"
pull_request:
jobs: jobs:
docker: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
checks: write
contents: write
steps:
- name: Login to Docker
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v4
- name: Ruby Setup
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true
- run: bundle install
- name: Standard Ruby
run: bundle exec standardrb
test:
needs: lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true
- run: bundle exec rake
docker:
needs: test
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
env: env:
DOCKER_ORG: ryanc DOCKER_ORG: ryanc
DOCKER_LATEST: latest DOCKER_LATEST: latest
defaults: defaults:
run: run:
shell: bash shell: bash
outputs:
metadata: ${{ steps.output.outputs.metadata }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@v4
with: with:
fetch-depth: 0 # all history for all branches and tags fetch-depth: 0 # all history for all branches and tags
@@ -36,69 +83,40 @@ jobs:
printf "GITHUB_SHA=%s\n" "$GITHUB_SHA" printf "GITHUB_SHA=%s\n" "$GITHUB_SHA"
printf "VERSION=%s\n" "$VERSION" | tee -a "$GITHUB_OUTPUT" printf "VERSION=%s\n" "$VERSION" | tee -a "$GITHUB_OUTPUT"
- name: Set up QEMU - name: Docker meta
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 id: meta
uses: docker/metadata-action@v5
with:
images: |
git.kill0.net/ryanc/kubernaut
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 uses: docker/setup-buildx-action@v3
- name: Login to Gitea registry - name: Login to Gitea registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 uses: docker/login-action@v3
with: with:
registry: git.kill0.net registry: git.kill0.net
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Docker meta (debian)
id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
git.kill0.net/ryanc/kubernaut
flavor: |
latest=auto
bake-target: docker-metadata-action
tags: |
type=schedule,pattern=nightly
type=edge
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Docker meta (alpine)
id: meta-alpine
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
git.kill0.net/ryanc/kubernaut
bake-target: docker-metadata-action-alpine
flavor: |
latest=auto
suffix=-alpine,onlatest=true
tags: |
type=schedule,pattern=nightly
type=edge
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Docker build and push - name: Docker build and push
uses: docker/bake-action@76f9fa3a758507623da19f6092dc4089a7e61592 # v6.6.0 uses: docker/build-push-action@v5
with: with:
push: ${{ github.event_name != 'pull_request' }} push: ${{ github.event_name != 'pull_request' }}
files: | tags: ${{ steps.meta.outputs.tags }}
./docker-bake.hcl labels: ${{ steps.meta.outputs.labels }}
cwd://${{ steps.meta.outputs.bake-file }}
cwd://${{ steps.meta-alpine.outputs.bake-file }}
- name: Setup Helm - name: Setup Helm
uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4.3.0 uses: azure/setup-helm@v4.3.0
- name: Publish Helm chart - name: Publish Helm chart
if: ${{ contains(github.ref, 'refs/tags/') }} if: ${{ contains(github.ref, 'refs/tags/') }}

View File

@@ -1,23 +0,0 @@
---
name: Ruby Lint
on:
push:
branches:
- "**"
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Ruby Setup
uses: ruby/setup-ruby@dffc446db9ba5a0c4446edb5bca1c5c473a806c5 # v1.235.0
with:
ruby-version: '3.4'
bundler-cache: true
- name: Standard Ruby
run: bundle exec standardrb

View File

@@ -1,22 +0,0 @@
---
name: Ruby Test
on:
push:
branches:
- "**"
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Test
uses: ruby/setup-ruby@dffc446db9ba5a0c4446edb5bca1c5c473a806c5 # v1.235.0
with:
ruby-version: '3.4'
bundler-cache: true
- run: bundle exec rake

40
Dockerfile Normal file
View File

@@ -0,0 +1,40 @@
FROM ruby:alpine AS base
WORKDIR /app
RUN <<EOT
gem update --system --no-document
gem install -N bundler
apk update
apk upgrade --no-cache
EOT
FROM base AS build
RUN <<EOT
apk add gcc musl-dev ruby-dev make
EOT
COPY Gemfile* .
RUN <<EOT
bundle config set --local without development
bundle install
EOT
FROM base
# RUN useradd ruby --home /app --shell /bin/sh
RUN adduser ruby -h /app -D
USER ruby:ruby
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=ruby:ruby /app /app
COPY --chown=ruby:ruby . .
EXPOSE 4567
CMD [ "bundle", "exec", "rackup", "--host", "0.0.0.0", "--port", "4567" ]

View File

@@ -3,13 +3,13 @@ source "https://rubygems.org"
gem "sinatra" gem "sinatra"
gem "sinatra-contrib" gem "sinatra-contrib"
gem "puma" gem "puma"
gem "rackup"
gem "anyflake" gem "anyflake"
gem "ksuid" gem "ksuid"
gem "nanoid" gem "nanoid"
gem "ulid" gem "ulid"
gem "uuid7" gem "uuid7"
gem "cuid2"
gem "jwt" gem "jwt"
gem "httparty" gem "httparty"

View File

@@ -3,68 +3,69 @@ GEM
specs: specs:
anyflake (0.0.1) anyflake (0.0.1)
ast (2.4.3) ast (2.4.3)
base64 (0.3.0) base64 (0.2.0)
bigdecimal (3.2.2) bigdecimal (3.1.9)
csv (3.3.5) csv (3.3.3)
cuid2 (1.0.1) diff-lcs (1.6.1)
diff-lcs (1.6.2)
httparty (0.23.1) httparty (0.23.1)
csv csv
mini_mime (>= 1.0.0) mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
json (2.12.2) json (2.10.2)
jwt (3.1.1) jwt (2.10.1)
base64 base64
ksuid (1.0.0) ksuid (1.0.0)
language_server-protocol (3.17.0.5) language_server-protocol (3.17.0.4)
lint_roller (1.1.0) lint_roller (1.1.0)
logger (1.7.0) logger (1.7.0)
mini_mime (1.1.5) mini_mime (1.1.5)
minitest (5.25.5) minitest (5.25.5)
multi_json (1.15.0) multi_json (1.15.0)
multi_xml (0.7.2) multi_xml (0.7.1)
bigdecimal (~> 3.1) bigdecimal (~> 3.1)
mustermann (3.0.3) mustermann (3.0.3)
ruby2_keywords (~> 0.0.1) ruby2_keywords (~> 0.0.1)
nanoid (2.0.0) nanoid (2.0.0)
nio4r (2.7.4) nio4r (2.7.4)
parallel (1.27.0) parallel (1.26.3)
parser (3.3.8.0) parser (3.3.7.4)
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
prism (1.4.0) prism (1.4.0)
puma (6.6.0) puma (6.6.0)
nio4r (~> 2.0) nio4r (~> 2.0)
racc (1.8.1) racc (1.8.1)
rack (3.1.16) rack (3.1.12)
rack-protection (4.1.1) rack-protection (4.1.1)
base64 (>= 0.1.0) base64 (>= 0.1.0)
logger (>= 1.6.0) logger (>= 1.6.0)
rack (>= 3.0.0, < 4) rack (>= 3.0.0, < 4)
rack-session (2.1.1) rack-session (2.1.0)
base64 (>= 0.1.0) base64 (>= 0.1.0)
rack (>= 3.0.0) rack (>= 3.0.0)
rack-test (2.2.0) rack-test (2.2.0)
rack (>= 1.3) rack (>= 1.3)
rackup (2.2.1)
rack (>= 3)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.3.0) rake (13.2.1)
rbs (3.9.4) rbs (3.9.2)
logger logger
regexp_parser (2.10.0) regexp_parser (2.10.0)
rspec (3.13.1) rspec (3.13.0)
rspec-core (~> 3.13.0) rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0) rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0) rspec-mocks (~> 3.13.0)
rspec-core (3.13.5) rspec-core (3.13.3)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-expectations (3.13.5) rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-mocks (3.13.5) rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-support (3.13.4) rspec-support (3.13.2)
rubocop (1.75.8) rubocop (1.73.2)
json (~> 2.3) json (~> 2.3)
language_server-protocol (~> 3.17.0.2) language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0) lint_roller (~> 1.1.0)
@@ -72,20 +73,20 @@ GEM
parser (>= 3.3.0.2) parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0) regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.44.0, < 2.0) rubocop-ast (>= 1.38.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0) unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.45.1) rubocop-ast (1.43.0)
parser (>= 3.3.7.2) parser (>= 3.3.7.2)
prism (~> 1.4) prism (~> 1.4)
rubocop-performance (1.25.0) rubocop-performance (1.24.0)
lint_roller (~> 1.1) lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0) rubocop (>= 1.72.1, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0) rubocop-ast (>= 1.38.0, < 2.0)
ruby-lsp (0.24.2) ruby-lsp (0.23.13)
language_server-protocol (~> 3.17.0) language_server-protocol (~> 3.17.0)
prism (>= 1.2, < 2.0) prism (>= 1.2, < 2.0)
rbs (>= 3, < 5) rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782) sorbet-runtime (>= 0.5.10782)
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
@@ -102,19 +103,19 @@ GEM
rack-protection (= 4.1.1) rack-protection (= 4.1.1)
sinatra (= 4.1.1) sinatra (= 4.1.1)
tilt (~> 2.0) tilt (~> 2.0)
sorbet-runtime (0.5.12204) sorbet-runtime (0.5.11971)
standard (1.50.0) standard (1.47.0)
language_server-protocol (~> 3.17.0.2) language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0) lint_roller (~> 1.0)
rubocop (~> 1.75.5) rubocop (~> 1.73.0)
standard-custom (~> 1.0.0) standard-custom (~> 1.0.0)
standard-performance (~> 1.8) standard-performance (~> 1.7)
standard-custom (1.0.2) standard-custom (1.0.2)
lint_roller (~> 1.0) lint_roller (~> 1.0)
rubocop (~> 1.50) rubocop (~> 1.50)
standard-performance (1.8.0) standard-performance (1.7.0)
lint_roller (~> 1.1) lint_roller (~> 1.1)
rubocop-performance (~> 1.25.0) rubocop-performance (~> 1.24.0)
tilt (2.6.0) tilt (2.6.0)
ulid (1.4.0) ulid (1.4.0)
unicode-display_width (3.1.4) unicode-display_width (3.1.4)
@@ -122,7 +123,7 @@ GEM
unicode-emoji (4.0.4) unicode-emoji (4.0.4)
uuid7 (0.2.0) uuid7 (0.2.0)
zeitwerk (~> 2.4) zeitwerk (~> 2.4)
zeitwerk (2.7.3) zeitwerk (2.7.2)
PLATFORMS PLATFORMS
ruby ruby
@@ -130,7 +131,6 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
anyflake anyflake
cuid2
httparty httparty
jwt jwt
ksuid ksuid
@@ -138,6 +138,7 @@ DEPENDENCIES
nanoid nanoid
puma puma
rack-test rack-test
rackup
rake rake
rspec rspec
ruby-lsp ruby-lsp
@@ -148,4 +149,4 @@ DEPENDENCIES
uuid7 uuid7
BUNDLED WITH BUNDLED WITH
2.6.9 2.6.6

88
app.rb
View File

@@ -2,7 +2,6 @@ require "bundler/setup"
require "sinatra" require "sinatra"
require "sinatra/cookies" require "sinatra/cookies"
require "sinatra/multi_route" require "sinatra/multi_route"
require "sinatra/quiet_logger"
require "time" require "time"
require "fileutils" require "fileutils"
require "json" require "json"
@@ -21,9 +20,11 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + "/lib"
require "config" require "config"
VERSION = "0.2.3" VERSION = "0.1.1"
CHUNK_SIZE = 1024**2 CHUNK_SIZE = 1024**2
SESSION_SECRET_HEX_LENGTH = 64
JWT_SECRET_HEX_LENGTH = 64
DEFAULT_FLAKEY = 50 DEFAULT_FLAKEY = 50
NAME = "kubernaut".freeze NAME = "kubernaut".freeze
@@ -51,12 +52,9 @@ DURATION_PARTS = [
config = Config.new config = Config.new
set :quiet_logger_prefixes, %w[livez readyz]
set :session_secret, config.session_secret.unwrap set :session_secret, config.session_secret.unwrap
set :public_folder, __dir__ + "/static" set :public_folder, __dir__ + "/static"
register Sinatra::QuietLogger
module Sinatra module Sinatra
module RequestHeadersHelper module RequestHeadersHelper
def req_headers def req_headers
@@ -115,6 +113,7 @@ class TickTock
def initialize def initialize
@pid = ppid @pid = ppid
@procfs_f = format "/proc/%s/stat", @pid @procfs_f = format "/proc/%s/stat", @pid
puts @pid
end end
def uptime def uptime
@@ -165,7 +164,7 @@ class Sleep
include State include State
def initialize def initialize
@file = "/dev/shm/sleepy" @file = "/dev/shm/sleep"
end end
def asleep? def asleep?
@@ -182,11 +181,20 @@ class Sleep
end end
def ppid def ppid
pid = ENV.fetch "PUMA_PID", Process.pid pid = Process.pid
begin # self
Integer pid ps = File.open "/proc/#{pid}/stat", &:readline
rescue ArgumentError ps = ps.split(" ")
-1 ppid = Integer(ps[3])
# ppid
ps = File.open "/proc/#{ppid}/stat", &:readline
ps = ps.split(" ")
if ps[1].include? "ruby"
ppid
else
pid
end end
end end
@@ -224,7 +232,9 @@ end
enable :sessions enable :sessions
puts "#{NAME} #{VERSION} staring, per aspera ad astra" on_start do
puts "#{NAME} #{VERSION} staring, per aspera ad astra"
end
configure do configure do
mime_type :json, "application/json" mime_type :json, "application/json"
@@ -299,23 +309,6 @@ get "/headers", provides: "json" do
jsonify h, pretty: jsonify h, pretty:
end end
get "/uptime", provides: "json" do
tt = TickTock.new
x = {started_at: tt.started_at, seconds: tt.uptime.to_i, human: human_time(tt.uptime.to_i)}
jsonify x
end
post "/api/livez/toggle" do
Health.instance.toggle
"ok\n"
end
post "/api/livez/sleep" do
Sleep.instance.toggle
"ok\n"
end
get "/livez" do get "/livez" do
error 503 unless Health.instance.healthy? error 503 unless Health.instance.healthy?
@@ -324,6 +317,23 @@ get "/livez" do
Health.instance.to_s Health.instance.to_s
end end
get "/livez/uptime" do
tt = TickTock.new
x = {started_at: tt.started_at, seconds: tt.uptime.to_i, human: human_time(tt.uptime.to_i)}
jsonify x
end
post "/livez/toggle" do
Health.instance.toggle
"ok\n"
end
post "/livez/sleep" do
Sleep.instance.toggle
"ok\n"
end
get "/readyz" do get "/readyz" do
error 503 unless Ready.instance.ready? error 503 unless Ready.instance.ready?
@@ -372,27 +382,25 @@ post "/halt" do
nil nil
end end
get "/pid", provides: "json" do get "/pid" do
pretty = params.key? :pretty pretty = params.key? :pretty
jsonify({ppid: ppid, pid: Process.pid}, pretty:) jsonify({ppid: ppid, pid: Process.pid}, pretty:)
end end
get "/token", provides: "json" do get "/token" do
pretty = params.key? :pretty
exp = Time.now.to_i + SECONDS_PER_MINUTE * 2 exp = Time.now.to_i + SECONDS_PER_MINUTE * 2
payload = {name: "anonymous", exp: exp, jti: Random.uuid} payload = {name: "anonymous", exp: exp, jti: Random.uuid}
expires_at = Time.at(exp).to_datetime expires_at = Time.at(exp).to_datetime
token = JWT.encode payload, config.jwt_secret.unwrap, "HS256" token = JWT.encode payload, JWT_SECRET, "HS256"
x = {token: token, expires_at: expires_at} x = {token: token, expires_at: expires_at}
jsonify x, pretty: jsonify x
end end
get "/token/validate" do get "/token/validate" do
token = req_headers["authorization"].split[1] token = req_headers["authorization"].split[1]
payload = JWT.decode token, config.jwt_secret.unwrap, true, algorithm: "HS256" payload = JWT.decode token, JWT_SECRET, true, algorithm: "HS256"
jsonify payload jsonify payload
end end
@@ -444,13 +452,7 @@ end
get "/_cat/env" do get "/_cat/env" do
stream do |out| stream do |out|
e = if params.key? :rack ENV.sort.each do |k, v|
env
else
ENV
end
e.sort.each do |k, v|
out << "#{k}=#{v}\n" out << "#{k}=#{v}\n"
end end
end end

View File

@@ -15,10 +15,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.2.3 version: 0.1.2
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using. # follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes. # It is recommended to use it with quotes.
appVersion: "0.2.3" appVersion: "0.1.2"

View File

@@ -97,7 +97,7 @@ readinessProbe:
# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
autoscaling: autoscaling:
enabled: true enabled: false
minReplicas: 2 minReplicas: 2
maxReplicas: 100 maxReplicas: 100
targetCPUUtilizationPercentage: 80 targetCPUUtilizationPercentage: 80

View File

@@ -1,5 +0,0 @@
ENV["PUMA_PID"] = Process.pid.to_s
port ENV.fetch("PORT", 4567)
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]

View File

@@ -1,22 +0,0 @@
group "default" {
targets = [ "bookworm", "alpine" ]
}
target "docker-metadata-action" {}
target "docker-metadata-action-alpine" {}
target "_common" {
args = {
RUBY_VERSION = "3.4.4"
}
}
target "bookworm" {
dockerfile = "./dockerfiles/bookworm.Dockerfile"
inherits = [ "_common", "docker-metadata-action" ]
}
target "alpine" {
dockerfile = "./dockerfiles/alpine.Dockerfile"
inherits = [ "_common", "docker-metadata-action-alpine" ]
}

View File

@@ -1,54 +0,0 @@
ARG RUBY_VERSION="3.4.4"
ARG BASE_REGISTRY="docker.io"
FROM ${BASE_REGISTRY}/ruby:${RUBY_VERSION}-alpine AS base
ENV RACK_ENV="production" \
BUNDLE_DEPLOYMENT=true \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development test" \
RUBY_YJIT_ENABLE=true
WORKDIR /kubernaut
RUN \
--mount=type=cache,id=var-cache-apk,target=/var/cache/apk,sharing=locked \
apk update -q; \
apk add bash jemalloc
RUN \
--mount=type=cache,id=usr-local-bundle-cache,target=${BUNDLE_PATH},sharing=locked \
gem update --system --no-document; \
gem install -N bundler
FROM base AS build
RUN \
--mount=type=cache,id=var-cache-apk,target=/var/cache/apk,sharing=locked \
apk update -q; \
apk add musl-dev gcc make; \
apk add bash jemalloc
COPY Gemfile Gemfile.lock ./
RUN \
--mount=type=cache,id=usr-local-bundle-ruby-cache,target=${BUNDLE_PATH}/ruby/3.4.0/cache,sharing=locked \
bundle install
COPY . .
FROM base
ENV PORT=4567
RUN \
addgroup --system --gid 666 kubernaut; \
adduser --system --uid 666 --ingroup kubernaut --shell /bin/bash --disabled-password kubernaut
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /kubernaut /kubernaut
USER kubernaut:kubernaut
EXPOSE $PORT
ENTRYPOINT [ "/kubernaut/dockerfiles/entrypoint.sh" ]
CMD [ "bundle", "exec", "puma" ]

View File

@@ -1,62 +0,0 @@
ARG RUBY_VERSION="3.4.4"
ARG BASE_REGISTRY="docker.io"
ARG DEBIAN_VERSION="bookworm"
FROM ${BASE_REGISTRY}/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS base
ENV RACK_ENV="production" \
BUNDLE_DEPLOYMENT=true \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development test" \
RUBY_YJIT_ENABLE=true
WORKDIR /kubernaut
RUN rm -f /etc/apt/apt.conf.d/docker-clean
RUN \
--mount=type=cache,id=var-cache-apt,target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=var-lib-apt,target=/var/lib/apt,sharing=locked \
apt-get update -qq; \
apt-get install --yes --no-install-recommends \
libjemalloc2
RUN \
--mount=type=cache,id=usr-local-bundle-cache,target=${BUNDLE_PATH},sharing=locked \
gem update --system --no-document; \
gem install -N bundler
ENV DEBIAN_FRONTEND="noninteractive"
FROM base AS build
RUN \
--mount=type=cache,id=var-cache-apt,target=/var/cache/apt,sharing=locked \
--mount=type=cache,id=var-lib-apt,target=/var/lib/apt,sharing=locked \
apt-get update -qq; \
apt-get install --yes --no-install-recommends \
build-essential
COPY Gemfile Gemfile.lock ./
RUN \
--mount=type=cache,id=usr-local-bundle-ruby-cache,target=${BUNDLE_PATH}/ruby/3.4.0/cache,sharing=locked \
bundle install
COPY . .
FROM base
ENV PORT=4567
RUN \
groupadd --system --gid 666 kubernaut; \
useradd --system --uid 666 --gid kubernaut --create-home --shell /bin/bash kubernaut
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /kubernaut /kubernaut
USER kubernaut:kubernaut
EXPOSE $PORT
ENTRYPOINT [ "/kubernaut/dockerfiles/entrypoint.sh" ]
CMD [ "bundle", "exec", "puma" ]

View File

@@ -1,15 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# output debugging info
ruby --version
printf "rubygems %s\n" "$(gem --version)"
bundle version
if [ -z "${LD_PRELOAD+x}" ]; then
LD_PRELOAD="$(find /usr/lib -name libjemalloc.so.2 -print -quit)"
export LD_PRELOAD
fi
exec "${@}"

View File

@@ -16,24 +16,18 @@ spec:
spec: spec:
containers: containers:
- name: kubernaut - name: kubernaut
image: git.kill0.net/ryanc/kubernaut:0.2.3 image: git.kill0.net/ryanc/kubernaut:0.1.2
imagePullPolicy: IfNotPresent imagePullPolicy: Always
ports: ports:
- name: sinatra-web - name: sinatra-web
containerPort: 4567 containerPort: 4567
env: env:
- name: KUBERNAUT_SESSION_SECRET - name: SESSION_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: kubernaut name: kubernaut-session-secret
key: session_secret key: session_secret
optional: true optional: true
- name: KUBERNAUT_JWT_SECRET
valueFrom:
secretKeyRef:
name: kubernaut
key: jwt_secret
optional: true
envFrom: envFrom:
- configMapRef: - configMapRef:
name: kubernaut-configmap name: kubernaut-configmap

View File

@@ -3,6 +3,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
namespace: kubernaut namespace: kubernaut
resources: resources:
- secret.yaml
- configmap.yaml - configmap.yaml
- deployment.yaml - deployment.yaml
- hpa.yaml - hpa.yaml

15
kustomize/app/secret.yaml Normal file
View File

@@ -0,0 +1,15 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: kubernaut-session-secret
namespace: kubernaut
spec:
encryptedData:
session_secret: AgCY08t0AU418znEZt5d252J+lH+fwYki2g6jdJpfdRfVQjnA+b52P0KWrs/x5pB0PKab6Z3JY/Tz0SQCaoIsCR4IzUO3a095aulRqb6Qr1Lz8udBVta4JJMZLmo26tuUfVHlpD1d6J8rkBSm8vzckFLkOA1Wfl/9rS3K4qwiDogA5pI0ULghFkeEx1yKdRwPq0k8PuvOvLUJ6oNq3e5n+B/BrVWdQ+7XQxUq/AMANJrDbe+RD33f99LArHYA7bFMbY8YRazXSTAkeunpTlxTjuGZKYvJKupo29LHz2OVbZVX/hI0nZkdVpcgqvbxF6Vw9CuCeAmtKYl7A3qsAWqDLUdP3hRLsk2P9RDNhEzYWh4ml8APzziWzihdJbGEjwLy7HsHgKslM0XbBnRQDlxp/JtvcWdjQp33A+QOON32zOKHi+qJjDYyGebS1+xkPbnyb1MPSJVAtFpj7dlLbFekLFDZEbXuJYUl1wKdFOIjJHmNK/MTEV2kOhtiVj/aeKgSXwor9hR7Uxzs5ZSawp9uWw+hpr58EX6I+RtfO4yjFC6FjnagiU6SlI1Q2F7/nv82g1UWTYMpNN5bduS1YFWmsnXvK+W7YQHpSForr5ndtCSHmclbXb5Fc33sywC5u6Bi2Gu5/MW6d73BOog5BC3QtOuEQ044Q+cuU3RIlKADBqKLzZmHlmukyyGuZfXJnGjlWGKp3J1KecucTo6XC9QHpUkjXEKdlE63mOI1VuOGyBIHl60v4bnWiBg+aDZVHipz4JLKsVB0HOgBBK7+tOX6tr1GDG/F7Nz/i9ebzUV6i8Ec1jHf+2ZcTtBkNXBIkHc84+4Qd33/gOuP+lizLfIhfQ3DFWbwyfYumpVbeapyYhB0CE=
template:
metadata:
creationTimestamp: null
name: kubernaut-session-secret
namespace: kubernaut

View File

@@ -6,3 +6,4 @@ metadata:
resources: resources:
- namespace.yaml - namespace.yaml
- ./app - ./app
- ./memcached

View File

@@ -0,0 +1,21 @@
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: kubernaut-memcached
spec:
selector:
matchLabels:
app: kubernaut-memcached
template:
metadata:
labels:
app: kubernaut-memcached
spec:
containers:
- name: kubernaut-memcached
image: memcached:latest
ports:
- name: memcached
containerPort: 11211

View File

@@ -0,0 +1,7 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kubernaut
resources:
- deployment.yaml
- services.yaml

View File

@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: Service
metadata:
name: kubernaut-memcached
spec:
ports:
- name: memcached
port: 11211
targetPort: memcached
selector:
app: kubernaut-memcached

View File

@@ -1,8 +1,5 @@
require "sensitive" require "sensitive"
SESSION_SECRET_HEX_LENGTH = 64
JWT_SECRET_HEX_LENGTH = 64
class Config class Config
attr_accessor :cat attr_accessor :cat
@@ -12,7 +9,7 @@ class Config
@prefix = prefix @prefix = prefix
@cat = cat @cat = cat
session_secret ||= fetch_env "SESSION_SECRET" do session_secret ||= ENV.fetch "SESSION_SECRET" do
SecureRandom.hex SESSION_SECRET_HEX_LENGTH SecureRandom.hex SESSION_SECRET_HEX_LENGTH
end end