docker: alpine base with openssh-client, mount SSH key + NET_RAW for scheduler
- Switch Dockerfile from distroless/static to alpine:3.21 - Install openssh-client-default in runtime image - Mount SSH key in scheduler service (docker-compose) - Add NET_RAW capability for ping checks - Wire OIKOS_SSH_KEY_PATH and OIKOS_SSH_USER env vars in scheduler - sshExec uses configured key path with StrictHostKeyChecking=no
This commit is contained in:
@@ -23,8 +23,10 @@ COPY --from=ui-builder /web/dist ./web/dist
|
|||||||
|
|
||||||
RUN CGO_ENABLED=0 go build -o /oikos -tags timetzdata -ldflags="-s -w" ./cmd/oikos
|
RUN CGO_ENABLED=0 go build -o /oikos -tags timetzdata -ldflags="-s -w" ./cmd/oikos
|
||||||
|
|
||||||
# --- Runtime: distroless static ---
|
# --- Runtime: alpine with SSH + ping for scheduler checks ---
|
||||||
FROM gcr.io/distroless/static:nonroot
|
FROM alpine:3.21
|
||||||
|
|
||||||
|
RUN apk add --no-cache ca-certificates openssh-client-default
|
||||||
|
|
||||||
COPY --from=builder /oikos /oikos
|
COPY --from=builder /oikos /oikos
|
||||||
COPY --from=builder /build/seeds /seeds
|
COPY --from=builder /build/seeds /seeds
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ services:
|
|||||||
OIKOS_DATABASE_URL: postgres://oikos:${OIKOS_DB_PASSWORD:-oikos_dev}@postgres:5432/oikos?sslmode=disable
|
OIKOS_DATABASE_URL: postgres://oikos:${OIKOS_DB_PASSWORD:-oikos_dev}@postgres:5432/oikos?sslmode=disable
|
||||||
OIKOS_DEBUG: "true"
|
OIKOS_DEBUG: "true"
|
||||||
OIKOS_SCHEDULER_INTERVAL: "30s"
|
OIKOS_SCHEDULER_INTERVAL: "30s"
|
||||||
|
OIKOS_SSH_KEY_PATH: /etc/oikos/ssh_key
|
||||||
|
volumes:
|
||||||
|
- ${OIKOS_SSH_KEY_PATH:-~/.ssh/id_ed25519}:/etc/oikos/ssh_key:ro
|
||||||
|
cap_add:
|
||||||
|
- NET_RAW
|
||||||
command: ["scheduler"]
|
command: ["scheduler"]
|
||||||
stop_signal: SIGTERM
|
stop_signal: SIGTERM
|
||||||
stop_grace_period: 30s
|
stop_grace_period: 30s
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ import (
|
|||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
sshKeyPath string
|
||||||
|
sshUser string
|
||||||
|
)
|
||||||
|
|
||||||
// Run starts the scheduler loop. Blocks until ctx is cancelled.
|
// Run starts the scheduler loop. Blocks until ctx is cancelled.
|
||||||
func Run(ctx context.Context, pool *db.Pool, cfg config.Config) {
|
func Run(ctx context.Context, pool *db.Pool, cfg config.Config) {
|
||||||
slog.Info("scheduler: starting", "interval", cfg.SchedulerInterval)
|
slog.Info("scheduler: starting", "interval", cfg.SchedulerInterval)
|
||||||
@@ -34,6 +39,12 @@ func Run(ctx context.Context, pool *db.Pool, cfg config.Config) {
|
|||||||
interval = 30 * time.Second
|
interval = 30 * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sshKeyPath = cfg.SSHKeyPath
|
||||||
|
sshUser = cfg.SSHUser
|
||||||
|
if sshUser == "" {
|
||||||
|
sshUser = "root"
|
||||||
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@@ -537,7 +548,7 @@ func checkSSHScript(ctx context.Context, cd sqlcgen.ListEnabledCheckDefsRow) che
|
|||||||
cfg.Port = 22
|
cfg.Port = 22
|
||||||
}
|
}
|
||||||
if cfg.User == "" {
|
if cfg.User == "" {
|
||||||
cfg.User = "root"
|
cfg.User = sshUser
|
||||||
}
|
}
|
||||||
|
|
||||||
if !allowlistedScript(cfg.Script) {
|
if !allowlistedScript(cfg.Script) {
|
||||||
@@ -609,12 +620,14 @@ func allowlistedScript(name string) bool {
|
|||||||
func sshExec(ctx context.Context, addr, user, cmd string, timeout time.Duration) ([]byte, error) {
|
func sshExec(ctx context.Context, addr, user, cmd string, timeout time.Duration) ([]byte, error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
"-o", "ConnectTimeout=" + strconv.Itoa(int(timeout.Seconds())),
|
"-o", "ConnectTimeout=" + strconv.Itoa(int(timeout.Seconds())),
|
||||||
"-o", "StrictHostKeyChecking=yes",
|
"-o", "StrictHostKeyChecking=no",
|
||||||
"-o", "BatchMode=yes",
|
"-o", "BatchMode=yes",
|
||||||
"-l", user,
|
"-o", "UserKnownHostsFile=/dev/null",
|
||||||
addr,
|
|
||||||
cmd,
|
|
||||||
}
|
}
|
||||||
|
if sshKeyPath != "" {
|
||||||
|
args = append(args, "-i", sshKeyPath)
|
||||||
|
}
|
||||||
|
args = append(args, "-l", user, addr, cmd)
|
||||||
c := exec.CommandContext(ctx, "ssh", args...)
|
c := exec.CommandContext(ctx, "ssh", args...)
|
||||||
return c.Output()
|
return c.Output()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user