diff --git a/.github/workflows/build-and-push-images.yml b/.github/workflows/build-and-push-images.yml new file mode 100644 index 0000000..ff7a5dc --- /dev/null +++ b/.github/workflows/build-and-push-images.yml @@ -0,0 +1,45 @@ +name: Build and Push Images + +on: + push: + tags: + - "*" + branches: + - master + pull_request: + branches: + - master + +env: + REGISTRY: ghcr.io + IMAGE_NAME: start-portainer-stack + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Log in to the Container registry + uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@69f6fc9d46f2f8bf0d5491e4aabe0bb8c6a4678a + with: + images: ${{ env.REGISTRY }}/chatton/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@e551b19e49efd4e98792db7592c17c09b89db8d8 + with: + context: scripts/portainer + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/scripts/portainer/Dockerfile b/scripts/portainer/Dockerfile new file mode 100644 index 0000000..bd89af0 --- /dev/null +++ b/scripts/portainer/Dockerfile @@ -0,0 +1,29 @@ + +# Dockerfile References: https://docs.docker.com/engine/reference/builder/ + +# Start from the latest golang base image +FROM golang:latest as builder + + +# Set the Current Working Directory inside the container +WORKDIR /app + +# Copy the source from the current directory to the Working Directory inside the container +COPY . . + +# Build the Go app +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . + + +######## Start a new stage from scratch ####### +FROM alpine:latest + +RUN apk --no-cache add ca-certificates + +WORKDIR /root/ + +# Copy the Pre-built binary file from the previous stage +COPY --from=builder /app/main . + +# Command to run the executable +ENTRYPOINT ["./main"] \ No newline at end of file diff --git a/scripts/portainer/client/client.go b/scripts/portainer/client/client.go index 26cc8c2..cd21b96 100644 --- a/scripts/portainer/client/client.go +++ b/scripts/portainer/client/client.go @@ -26,6 +26,10 @@ type Credentials struct { BaseUrl string `json:"baseUrl"` } +func (c Credentials) IsValid() bool { + return c.Username != "" && c.Password != "" && c.BaseUrl != "" +} + func NewPortainerClient(creds Credentials) (*PortainerClient, error) { c := &PortainerClient{ baseUrl: creds.BaseUrl, diff --git a/scripts/portainer/main.go b/scripts/portainer/main.go index a81a38e..57dda14 100644 --- a/scripts/portainer/main.go +++ b/scripts/portainer/main.go @@ -12,7 +12,34 @@ import ( "github.com/chatton/portainer/client" ) +const ( + portainerUserNameEnv = "PORTAINER_USER_NAME" + portainerPasswordEnv = "PORTAINER_PASSWORD" + portainerBaseUrlEnv = "PORTAINER_BASE_URL" +) + +func loadCredsFromEnv() client.Credentials { + userName, _ := os.LookupEnv(portainerUserNameEnv) + password, _ := os.LookupEnv(portainerPasswordEnv) + baseUrl, _ := os.LookupEnv(portainerBaseUrlEnv) + return client.Credentials{ + Username: userName, + Password: password, + BaseUrl: baseUrl, + } +} + func loadCreds() client.Credentials { + // look for env vars first + creds := loadCredsFromEnv() + if creds.IsValid() { + return creds + } + // fallback to file + return loadCredsFromFile() +} + +func loadCredsFromFile() client.Credentials { usr, _ := user.Current() credPath := fmt.Sprintf("%s/.homelab/portainer-creds.json", usr.HomeDir)