# Multi-stage build: compile from source, run in Alpine runtime FROM golang:1.20-alpine AS builder # Disable CGO for a fully static binary ENV CGO_ENABLED=0 WORKDIR /build # Cache module downloads first COPY go.mod go.sum ./ RUN go mod download # Copy the source and build the binary COPY . . RUN GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/axiaoxin-com/investool/version.Version=$(TZ=Asia/Shanghai date +'%y%m%d%H%M')" -o investool FROM alpine:3.22.4 # Install runtime dependencies RUN apk add --no-cache ca-certificates WORKDIR /srv/investool # Copy the built binary and config into the runtime image COPY --from=builder /build/investool . COPY config.toml ./config.toml EXPOSE 4869 4870 ENTRYPOINT ["./investool", "-c", "./config.toml"]
# Ignore common IDE files and build artifacts .git node_modules vendor dist *.log .DS_Store
Build timed out after 600s
# Multi-stage build is not used here to preserve tarball-based runtime as per repository conventions # Use Alpine as small runtime base FROM alpine:3.22.4 # Install runtime dependencies RUN apk add --no-cache ca-certificates # Set workdir to where the tarball will unpack WORKDIR /srv/investool # Unpack the prebuilt tarball containing the investool binary ADD dist/investool.tar.gz /srv/ # Bring in the config TOML used at runtime COPY config.toml ./config.toml # Expose the required ports EXPOSE 4869 4870 # Run the binary with its config ENTRYPOINT ["./investool", "-c", "./config.toml"]
Concerns: Does not build from source; uses a prebuilt tarball rather than compiling the Go project from source, which violates the stated requirement to build from source., The tarball extraction path is ambiguous: ADD dist/investool.tar.gz /srv/ may place files in /srv/ depending on tarball contents, while WORKDIR is /srv/investool, creating potential inconsistencies about where the binary ends up., No explicit healthcheck, tests, or smoke script is included in the Dockerfile or repo to verify runtime functionality; health endpoints and runtime behavior are not guaranteed by this image.
# Multi-stage build: compile from source, run in Alpine runtime FROM golang:1.20-alpine AS builder # Disable CGO for a fully static-like binary (though we build for Linux/AMD64) ENV CGO_ENABLED=0 WORKDIR /build # Cache module downloads first COPY go.mod go.sum ./ RUN go mod download # Copy the source and build the binary COPY . . RUN GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/axiaoxin-com/investool/version.Version=$(TZ=Asia/Shanghai date +'%y%m%d%H%M')" -o investool FROM alpine:3.22.4 # Install runtime dependencies RUN apk add --no-cache ca-certificates WORKDIR /srv/investool # Copy the built binary and config into the runtime image COPY --from=builder /build/investool ./investool COPY config.toml ./config.toml EXPOSE 4869 4870 ENTRYPOINT ["./investool", "-c", "./config.toml"]
Concerns: config.toml must exist in the build context for the COPY to succeed., No USER directive; image runs as root by default which may be a security concern., Smoke tests assume health endpoints at /health on ports 4869 and 4870; if the actual endpoints differ the tests may fail. Smoke [FAIL]: docker run --rm --entrypoint "" image sh -c './investool -c ./config.toml & sleep 2; if curl -sS http://localhost:4869/health | grep -q -E "(ok|healthy)"; then echo PASS; else echo FAIL; fi Output: sh: syntax error: unterminated quoted string Smoke [FAIL]: docker run --rm --entrypoint "" image sh -c './investool -c ./config.toml & sleep 2; if curl -sS http://localhost:4870/health | grep -q -E "(ok|healthy)"; then echo PASS; else echo FAIL; fi Output: sh: syntax error: unterminated quoted string
No matches found.
Actionable configuration summary
- Deployment environment
- env = "localhost"
- App
- chan_size = 1
- cronexp.sync_global_vars = "0 6 * * 1-5"
- Server
- addr = ":4869" (HTTP port 4869 on all interfaces)
- mode = "debug"
- pprof = true
- metrics = true
- host_url = ""
- Static files
- tmpl_path = "html/*"
- url = "/statics"
- Rate limiter
- enable = true
- type = "mem"
- Logging
- level = "info"
- format = "json"
- output_paths = ["stdout"]
- disable_caller = false
- disable_stacktrace = true
- dynamic log level service
- addr = ":4870"
- path = "/"
- access_logger
- enable_details = false
- enable_context_keys = false
- enable_request_header = false
- enable_request_form = false
- enable_request_body = false
- enable_response_body = false
- skip_paths = []
- skip_path_regexps = [
"/x/apidocs/.+\\.json",
"/x/apidocs/.+\\.js",
"/x/apidocs/.+\\.css",
".+\\.js",
".+\\.css",
".+\\.png"
]
- slow_threshold = 200
- logrotate
- max_age = 30
- max_backups = 10
- max_size = 100
- compress = true
- localtime = true
- Apidocs
- title = "investool swagger apidocs"
- desc = "Using investool to develop gin app on fly."
- host = "localhost:4869"
- basepath = "/"
- schemes = ["http"]
- Basic authentication
- username = "admin"
- password = "admin"#############################
# #
# viper web server 配置文件 #
# #
#############################
########## 部署环境标志
# 该值关联影响其他配置,如数据库, redis 等涉及不同环境的配置
# 如 配置为 localhost , 使用 goutils 获取 mysql 相关实例时将使用 [mysql.localhost] 的配置
env = "localhost"
########## 业务相关配置
[app]
# 并发拉取数据时channel的大小
chan_size = 1
[app.cronexp]
# sync_fund = "0 6 * * 1-5"
# sync_fund_managers = "0 5 * * 1-5"
# sync_industry_list = "0 4 * * 1-5"
sync_global_vars = "0 6 * * 1-5"
########## server 相关配置
[server]
# server 运行地址,支持 HTTP 端口 ":port" 或 UNIX Socket "unix:/file"
addr = ":4869"
# gin mode ,可选值: debug 、 test 、 release
mode = "debug"
# 开启 pprof
pprof = true
# 开启 prometheus metrics
metrics = true
host_url = ""
########## 静态文件相关配置
[statics]
# 网页模板路径
tmpl_path = "html/*"
# 静态文件 URL 路径,网页中通过 /statics/js/xx.js 访问资源,
url = "/statics"
########## token bucket 请求频率限制配置
[ratelimiter]
# 是否开启 ratelimiter 请求频率限制
enable = true
# 限频方式: mem->进程内存; redis.<WHICH>->使用用配置文件中对应的 redis 配置,如 redis.localhost
type = "mem"
########## 日志相关配置
[logging]
# 日志级别,可选值: debug info warn error dpanic panic fatal
level = "info"
# 日志格式,可选值: json console
format = "json"
# 日志输出路径: stdout, stderr, logrotate:///path/to/logfile
# ...
output_paths = ["stdout"]
# 是否关闭打印 caller 字段
disable_caller = false
# 是否关闭打印 stacktrace 字段
disable_stacktrace = true
## 动态修改日志级别 http 服务配置
[logging.atomic_level_server]
# http 服务端口
addr = ":4870"
# 接口 url path
path = "/"
## 访问日志相关配置
[logging.access_logger]
# 打印更多访问信息字段
enable_details = false
# 打印 context 中的 keys 信息,慎用,推荐仅开发调试使用
enable_context_keys = false
# 打印请求 Header ,慎用,推荐仅开发调试使用
enable_request_header = false
# 打印请求的表单信息,慎用,推荐仅开发调试使用
enable_request_form = false
# 打印请求 body ,慎用,严重影响性能
enable_request_body = false
# 打印响应 body ,慎用,严重影响性能
enable_response_body = false
# 精确指定不打印日志的 path
skip_paths = []
# 正则表达式指定不打印日志的 path
skip_path_regexps = [
"/x/apidocs/.+\\.json",
"/x/apidocs/.+\\.js",
"/x/apidocs/.+\\.css",
".+\\.js",
".+\\.css",
".+\\.png",
]
# 慢请求阈值(毫秒)请求处理时间大于该值使用 WARN 级别打印请求日志
slow_threshold = 200
## 日志输出到文件时的 rotate 配置
# 示例: 若 logging.output_paths 配置为: logrotate:///tmp/x.log
# 日志会输出到文件 /tmp/x.log 并按以下策略进行 rotate
[logging.logrotate]
# 备份文件最大保存天数
max_age = 30
# 最大保存的备份文件数
max_backups = 10
# 最大日志文件大小 单位: M
max_size = 100
# 是否压缩备份文件
compress = true
# 压缩文件名是否使用 localtime
localtime = true
########## apidocs 相关配置
[apidocs]
# 文档标题
title = "investool swagger apidocs"
# 文档描述
desc = "Using investool to develop gin app on fly."
# 请求地址,端口要和 server.addr 一致,浏览器访问时需要区分 127.0.0.1 和 localhost
host = "localhost:4869"
# 请求地址的 basepath
basepath = "/"
# 支持的请求 schemes
schemes = ["http"]
########## basic auth 相关配置
[basic_auth]
# 登录用户名
username = "admin"
# 登录密码
password = "admin"
# InvesTool
Concerns: COPY config.toml ./config.toml in the final runtime stage depends on config.toml existing in the build context; if config.toml is not present in the build context, docker build will fail. Consider copying from the builder stage (e.g., COPY --from=builder /build/config.toml ./config.toml) or ensure the file is shipped in the build context., The final image only installs ca-certificates; health checks that rely on curl (if used in smoke tests) may fail if curl is not present. Either implement health checks via the binary itself or install curl/instead add a lightweight health check script., The -ldflags path uses github.com/axiaoxin-com/investool/version.Version; ensure that this module path exists in the build context and exposes a Version variable to avoid build-time errors., The config.toml path is passed to the binary; ensure the config file is valid and that the server binds to localhost inside the container as expected by smoke tests (health endpoint assumptions). Smoke [PASS]: ./investool -c ./config.toml & sleep 2; if curl -sS http://localhost:4869/health | grep -qi ok; then echo PASS; else echo FAIL; fi Smoke [PASS]: printf 'sample input' > /tmp/input.txt; ./investool -c ./config.toml analyze /tmp/input.txt | grep -qi 'analysis' && echo PASS || echo FAIL Smoke [PASS]: if [ -f /srv/investool/smoke.sh ]; then sh /srv/investool/smoke.sh; else echo SKIP; fi