Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use minimum distroless base image #261

Merged
merged 2 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ jobs:
- name: Vet
run: make vet
docker:
name: Docker
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v4
- name: Docker
run: make docker_build
name: Docker
needs: [build, test, vet]
uses: ./.github/workflows/docker.yaml
secrets: inherit
43 changes: 43 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Docker
on:
workflow_call:
workflow_dispatch:
jobs:
docker_build:
name: Build Docker image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Docker QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/owenthereal/upterm/uptermd
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=,suffix=,format=long
- name: Docker build and push
uses: docker/build-push-action@v5
with:
push: ${{ startsWith(github.ref, 'refs/tags/v') }}
pull: true
file: Dockerfile.uptermd
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha
cache-to: |
type=gha,mode=max
15 changes: 7 additions & 8 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ on:
push:
tags: 'v*'
jobs:
release:
docker:
name: Docker
uses: ./.github/workflows/docker.yaml
secrets: inherit
gorelease:
name: Upload releases
runs-on: ubuntu-latest
needs: [docker]
steps:
- uses: actions/checkout@v4
- name: Set up Go
Expand All @@ -20,16 +25,10 @@ jobs:
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Docker push on master
run: |
# Build & publish on master
echo "${{ secrets.GH_TOKEN }}" | docker login ghcr.io -u USERNAME --password-stdin
TAG=${GITHUB_REF_NAME} make docker_push
TAG=latest make docker_push
deploy:
name: Deploy app
runs-on: ubuntu-latest
needs: [release]
needs: [gorelease]
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
Expand Down
37 changes: 25 additions & 12 deletions Dockerfile.uptermd
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
FROM golang:alpine as builder
# syntax=docker/dockerfile:1

WORKDIR $GOPATH/src/github.com/owenthereal/upterm
COPY . .
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
RUN go install ./cmd/uptermd/...
FROM golang:latest as builder

# Prepare for image
FROM alpine:latest
ARG TARGETOS TARGETARCH

MAINTAINER Owen Ou
LABEL org.opencontainers.image.source https://github.com/owenthereal/upterm
WORKDIR /src
ENV CGO_ENABLED=0
RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
GOOS=$TARGETOS GOARCH=$TARGETARCH go install \
./cmd/...

RUN adduser -D uptermd
USER uptermd
FROM gcr.io/distroless/static

USER nonroot:nonroot

WORKDIR /app
ENV PATH="/app:${PATH}"

COPY --from=builder /go/bin/* /app
COPY --from=builder /go/bin/uptermd /app/

# sshd
EXPOSE 2222
Expand All @@ -27,3 +29,14 @@ EXPOSE 8080
EXPOSE 9090

ENTRYPOINT ["uptermd"]

FROM gcr.io/distroless/static as uptermd-fly

USER nonroot:nonroot

WORKDIR /app
ENV PATH="/app:${PATH}"

COPY --from=builder /go/bin/uptermd /go/bin/uptermd-fly /app/

ENTRYPOINT ["uptermd-fly"]
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@ install:
go install ./cmd/...

TAG ?= latest
REPO ?= ghcr.io/owenthereal/upterm/uptermd
DOCKER_BUILD_FLAGS ?= --load
.PHONY: docker_build
docker_build:
docker build -t ghcr.io/owenthereal/upterm/uptermd:$(TAG) -f Dockerfile.uptermd .

.PHONY: docker_push
docker_push: docker_build
docker push ghcr.io/owenthereal/upterm/uptermd:$(TAG)
docker buildx build -t $(REPO):$(TAG) -f Dockerfile.uptermd $(DOCKER_BUILD_FLAGS) .

GO_TEST_FLAGS ?= ""
.PHONY: test
Expand Down
32 changes: 32 additions & 0 deletions cmd/uptermd-fly/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"os"

"github.com/owenthereal/upterm/cmd/uptermd/command"
log "github.com/sirupsen/logrus"
)

func main() {
logger := log.New()

flyAppName := os.Getenv("FLY_APP_NAME")
if flyAppName == "" {
logger.Fatal("FLY_APP_NAME is not set")
}

flyMachineID := os.Getenv("FLY_MACHINE_ID")
if flyMachineID == "" {
logger.Fatal("FLY_MACHINE_ID is not set")
}

os.Setenv("UPTERMD_NODE_ADDR", fmt.Sprintf("%s.vm.%s.internal:2222", flyMachineID, flyAppName))
os.Setenv("UPTERMD_SSH_ADDR", "0.0.0.0:2222")
os.Setenv("UPTERMD_WS_ADDR", "0.0.0.0:8080")
os.Setenv("UPTERMD_HOSTNAME", "uptermd.upterm.dev")

if err := command.Root(logger).Execute(); err != nil {
logger.Fatal(err)
}
}
85 changes: 85 additions & 0 deletions cmd/uptermd/command/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package command

import (
"fmt"
"os"
"strings"

"github.com/owenthereal/upterm/server"
"github.com/owenthereal/upterm/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)

func Root(logger log.FieldLogger) *cobra.Command {
rootCmd := &rootCmd{}
cmd := &cobra.Command{
Use: "uptermd",
Short: "Upterm Daemon",
RunE: rootCmd.Run,
}

cmd.PersistentFlags().String("config", "", "server config")

cmd.PersistentFlags().StringP("ssh-addr", "", utils.DefaultLocalhost("2222"), "ssh server address")
cmd.PersistentFlags().StringP("ws-addr", "", "", "websocket server address")
cmd.PersistentFlags().StringP("node-addr", "", "", "node address")
cmd.PersistentFlags().StringSliceP("private-key", "", nil, "server private key")
cmd.PersistentFlags().StringSliceP("hostname", "", nil, "server hostname for public-key authentication certificate principals. If empty, public-key authentication is used instead.")

cmd.PersistentFlags().StringP("network", "", "mem", "network provider")
cmd.PersistentFlags().StringSliceP("network-opt", "", nil, "network provider option")

cmd.PersistentFlags().StringP("metric-addr", "", "", "metric server address")
cmd.PersistentFlags().BoolP("debug", "", os.Getenv("DEBUG") != "", "debug")

return cmd
}

type rootCmd struct {
}

func (cmd *rootCmd) Run(c *cobra.Command, args []string) error {
var opt server.Opt
if err := unmarshalFlags(c, &opt); err != nil {
return err
}

return server.Start(opt)
}

func unmarshalFlags(cmd *cobra.Command, opts interface{}) error {
v := viper.New()

cmd.Flags().VisitAll(func(flag *pflag.Flag) {
flagName := flag.Name
if flagName != "config" && flagName != "help" {
if err := v.BindPFlag(flagName, flag); err != nil {
panic(fmt.Errorf("error binding flag '%s': %w", flagName, err).Error())
}
}
})

v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
v.SetEnvPrefix("UPTERMD")

cfgFile, err := cmd.Flags().GetString("config")
if err != nil {
return err
}

if _, err := os.Stat(cfgFile); err == nil {
v.SetConfigFile(cfgFile)
}

if err := v.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return fmt.Errorf("error loading config file %s: %w", cfgFile, err)
}
}

return v.Unmarshal(opts)
}
64 changes: 0 additions & 64 deletions cmd/uptermd/internal/command/root.go

This file was deleted.

2 changes: 1 addition & 1 deletion cmd/uptermd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"os"

"github.com/heroku/rollrus"
"github.com/owenthereal/upterm/cmd/uptermd/internal/command"
"github.com/owenthereal/upterm/cmd/uptermd/command"
log "github.com/sirupsen/logrus"
)

Expand Down
8 changes: 1 addition & 7 deletions fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,9 @@ app = "upterm"
kill_signal = "SIGINT"
kill_timeout = "5s"

[experimental]
cmd = [
"uptermd --ssh-addr 0.0.0.0:2222 --ws-addr 0.0.0.0:8080 --node-addr $(echo ${FLY_ALLOC_ID} | cut -f1 -d '-').vm.${FLY_APP_NAME}.internal:2222 --hostname uptermd.upterm.dev",
]
entrypoint = ["/bin/sh", "-c"]
auto_rollback = true

[build]
dockerfile = "Dockerfile.uptermd"
build-target = "uptermd-fly"

[[services]]
protocol = "tcp"
Expand Down
Loading