Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alt-dima committed Apr 28, 2024
1 parent 26dead3 commit d00bd6d
Show file tree
Hide file tree
Showing 19 changed files with 873 additions and 1 deletion.
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: goreleaser

on:
push:
branches:
- 'master'
tags:
- 'v*'
pull_request:

permissions:
contents: write
# packages: write
# issues: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22.2'
# More assembly might be required: Docker logins, GPG, etc.
# It all depends on your needs.
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
# 'latest', 'nightly', or a semver
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
21 changes: 21 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
before:
hooks:
- go mod tidy

builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
goarm:
- "7"
mod_timestamp: "{{ .CommitTimestamp }}"
flags:
- -trimpath
ldflags:
- -s -w -X main.version={{.Version}}
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ARG NODE_VERSION_IMAGE
FROM golang:1.22.2 as build
ARG VERSION_STRING="unknown"

COPY . /go

RUN cd /go && set -x; CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X main.version=$VERSION_STRING" -o run

FROM ${NODE_VERSION_IMAGE}
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssl ca-certificates curl && apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /app

RUN chown -R node:node /app

COPY --from=build /go/run /app/run
RUN chmod +x /app/run

USER node

RUN sh -c 'whoami && /app/run true'

ENTRYPOINT ["/app/run"]
15 changes: 15 additions & 0 deletions Dockerfile.windows
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ARG NODE_VERSION_IMAGE
FROM golang:1.22.2-windowsservercore-ltsc2022 as build
ARG VERSION_STRING="unknown"

COPY . /go

RUN cd /go && set -x; CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X main.version=$VERSION_STRING" -o entrypoint.exe

FROM ${DOTNET_VERSION_IMAGE}
ADD https://aka.ms/vs/17/release/vc_redist.x64.exe /vc_redist.x64.exe
RUN c:\vc_redist.x64.exe /install /quiet /norestart

COPY --from=build /go/entrypoint.exe /entrypoint/entrypoint.exe

ENTRYPOINT ["/entrypoint/entrypoint.exe"]
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
ifeq ($(strip $(VERSION_STRING)),)
VERSION_STRING := $(shell git rev-parse --short HEAD)
endif

BINDIR := $(CURDIR)/bin
PLATFORMS := linux/amd64/entrypoint/osusergo*netgo*static_build windows/amd64/entrypoint.exe/osusergo*static_build
BUILDCOMMAND := go build -trimpath -ldflags "-s -w -X main.version=${VERSION_STRING}"
temp = $(subst /, ,$@)
os = $(word 1, $(temp))
arch = $(word 2, $(temp))
label = $(word 3, $(temp))
tags = $(subst *, ,$(word 4, $(temp)))

UNAME := $(shell uname)
ifeq ($(UNAME), Darwin)
SHACOMMAND := shasum -a 256
else
SHACOMMAND := sha256sum
endif

.DEFAULT_GOAL := build

.PHONY: release
release: $(PLATFORMS)
$(PLATFORMS):
GOOS=$(os) GOARCH=$(arch) CGO_ENABLED=0 $(BUILDCOMMAND) -tags "$(tags)" -o "bin/$(label)"
$(SHACOMMAND) "bin/$(label)" > "bin/$(label).sha256"

.PHONY: build
build:
$(BUILDCOMMAND) -o bin/entrypoint

.PHONY: dep
dep:
go mod tidy
87 changes: 86 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,86 @@
# go-entrypoint
# Entrypoint for docker containers

Entrypoint for running apps in containers with:
1. Optional generation env variables (only for child process) from Vault secrets. Windows version also set env variables in Registry system-wide
2. SIGTERM and SIGINT propagation to child process
3. Wait for child process for finish and exit with child's exit code

## Entrypoint binaries delivery

### With built-in base image

You could use next Dockerfiles as example to build your base image:
- [Dockerfile for Linux for Node.JS apps](Dockerfile)
- [Dockerfile for Windows for Dot.Net apps](Dockerfile.windows)

Applications CI will use those base images in `FROM`

### With S3 storage and Kubernetes host_mount

1. Create an S3 bucket (like `infra-binaries`)
2. Upload binaries (for linux and windows) to the S3 bucket
1. New binary should be uploaded to the temp name like `entrypoint.tmp`
2. Old binary should be renamed to the `entrypoint.old`
3. New binary should be renamed from temp name `entrypoint.tmp` to `entrypoint`
3. Every k8s node contains a bootstrap code to download relevant entrypoint binary
1. For linux nodes:
```
pre_bootstrap_user_data = <<-EOT
#!/bin/bash
mkdir -p /entrypoint
aws s3 cp s3://infra-binaries/entrypoint/entrypoint /entrypoint/entrypoint || aws s3 cp s3://infra-binaries/entrypoint/entrypoint.old /entrypoint/entrypoint
chmod +x /entrypoint/entrypoint
EOT
```
2. For windows nodes:
```
pre_bootstrap_user_data = <<-EOT
Read-S3Object -BucketName "infra-binaries" -Key "entrypoint/entrypoint.exe" -Region "eu-west-2" -File "/entrypoint/entrypoint.exe"; if (-not $?) { Read-S3Object -BucketName "infra-binaries" -Key "entrypoint/entrypoint.exe.old" -Region "eu-west-2" -File "/entrypoint/entrypoint.exe" }
EOT
```
4. Configure POD with host volume mount `/entrypoint/`
5. Configure POD's `command` (entrypoint) changed to `/entrypoint/entrypoint` for linix and `/entrypoint/entrypoint.exe` for windows
6. To update `entrypoint` on nodes, could use project [go-entrypoint-updater](https://github.com/alt-dima/go-entrypoint-updater)
## Entrypoint logic workflow
1. Check if `VAULT_ADDR` env var configured and Vault is reacheble and ready by endpoint `/v1/sys/health`
3. If list with required Vault secrets is not empty:
1. Read secrets list from `SECRETS_SOURCE_CONFIG` env var, by default: `./secrets_config.json#secrets_list` (`./secrets_config.json` - json file path, `secrets_list` - json path inside file)
2. Init Vault Client with credentials (env vars `VAULT_APPROLE_RID` and `VAULT_APPROLE_SID`)
3. Read required secrets from Vault and set env varibales with these values to the child
4. Run child app process with defined arguments
6. Wait until process will be terminated (with signals propagation) or exited by itself
### Vault secrets:
Regular `/secret/{secret_path}` will be used.
Required secrets configuration (`secrets_config.json` example):
```json
{
"secrets_list": [
"mongodb",
"rabbitmq",
{
"secretname": "mysql#local",
"envvarname": "env1"
},
]
}
```
## Usage:
```bash
export SECRETS_SOURCE_CONFIG=./secrets_config.json#secrets_list
export VAULT_APPROLE_SID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export VAULT_APPROLE_RID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export VAULT_ADDR=https://vault-api-address

entrypoint node app.js appparam1 appparam2 appparam3
```
Listed secrets from `secrets_config.json` file will be provided as a child's process env vars (and container-wide for windows) in the following format:
Non `[^a-zA-Z0-9_]` characters in the secret path will be replaced with `_` (like envconsul did)

```bash
echo $secret_mongodb_url1
secret_mongodb_url1="xxx"
```
if one of listed secret's path doesn't exist in Vault - entrypoint will fail.
35 changes: 35 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module github.com/alt-dima/go-entrypoint

go 1.22.2

require (
github.com/PaesslerAG/jsonpath v0.1.1
github.com/hashicorp/vault/api v1.13.0
github.com/hashicorp/vault/api/auth/approle v0.6.0
golang.org/x/sys v0.19.0
)

require (
github.com/PaesslerAG/gval v1.2.2 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.6 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/stretchr/testify v1.9.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
)
Loading

0 comments on commit d00bd6d

Please sign in to comment.