security: remove hardcoded credentials and add envsubst for go-zero configs
- Clear default passwords in all service configs and local dev YAMLs
- Add entrypoint.sh with envsubst to resolve ${ENV} vars in go-zero YAML
- Update Dockerfiles to install gettext and use entrypoint
- Update docker-compose to pass secrets via environment and require via ${VAR:?...}
- Add .gitignore rules for .env files, add .env.example template
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ec8ae6a73b
commit
a5b1b406ea
5
.gitignore
vendored
5
.gitignore
vendored
@ -99,3 +99,8 @@ Temporary Items
|
|||||||
# Local runtime data and certificates
|
# Local runtime data and certificates
|
||||||
data/
|
data/
|
||||||
deploy/bin/
|
deploy/bin/
|
||||||
|
|
||||||
|
# Environment secrets
|
||||||
|
.env
|
||||||
|
deploy/.env
|
||||||
|
!deploy/.env.example
|
||||||
|
|||||||
13
deploy/.env.example
Normal file
13
deploy/.env.example
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Copy this file to .env and fill in real values
|
||||||
|
# NEVER commit .env to git
|
||||||
|
|
||||||
|
# Database passwords (REQUIRED)
|
||||||
|
MYSQL_ROOT_PASSWORD=your_mysql_password_here
|
||||||
|
POSTGRES_PASSWORD=your_postgres_password_here
|
||||||
|
|
||||||
|
# JWT secret for gateway auth (REQUIRED)
|
||||||
|
ACCESS_SECRET=your_jwt_secret_here
|
||||||
|
|
||||||
|
# Neo4j (only needed for graph stack: docker-compose.graph.yaml)
|
||||||
|
NEO4J_AUTH=neo4j/your_neo4j_password_here
|
||||||
|
NEO4J_PASS=your_neo4j_password_here
|
||||||
@ -11,10 +11,12 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./gateway/gateway.
|
|||||||
|
|
||||||
FROM ${BASE_REGISTRY}/alpine:3.20
|
FROM ${BASE_REGISTRY}/alpine:3.20
|
||||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /server ./gateway
|
COPY --from=builder /server ./gateway
|
||||||
COPY deploy/etc/gateway.yaml etc/gateway.yaml
|
COPY deploy/etc/gateway.yaml etc/gateway.yaml
|
||||||
COPY deploy/tools/ tools/
|
COPY deploy/tools/ tools/
|
||||||
|
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||||
EXPOSE 8888
|
EXPOSE 8888
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
CMD ["./gateway", "-f", "etc/gateway.yaml"]
|
CMD ["./gateway", "-f", "etc/gateway.yaml"]
|
||||||
|
|||||||
@ -11,9 +11,11 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/inventory/in
|
|||||||
|
|
||||||
FROM ${BASE_REGISTRY}/alpine:3.20
|
FROM ${BASE_REGISTRY}/alpine:3.20
|
||||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /server ./inventory
|
COPY --from=builder /server ./inventory
|
||||||
COPY deploy/etc/inventory.yaml etc/inventory.yaml
|
COPY deploy/etc/inventory.yaml etc/inventory.yaml
|
||||||
|
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||||
EXPOSE 9002
|
EXPOSE 9002
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
CMD ["./inventory", "-f", "etc/inventory.yaml"]
|
CMD ["./inventory", "-f", "etc/inventory.yaml"]
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
FROM alpine:3.19
|
FROM alpine:3.19
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY deploy/bin/purchase .
|
COPY deploy/bin/purchase .
|
||||||
COPY deploy/etc/purchase.yaml etc/purchase.yaml
|
COPY deploy/etc/purchase.yaml etc/purchase.yaml
|
||||||
|
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||||
EXPOSE 9003
|
EXPOSE 9003
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
CMD ["./purchase", "-f", "etc/purchase.yaml"]
|
CMD ["./purchase", "-f", "etc/purchase.yaml"]
|
||||||
|
|||||||
@ -11,9 +11,11 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/system/syste
|
|||||||
|
|
||||||
FROM ${BASE_REGISTRY}/alpine:3.20
|
FROM ${BASE_REGISTRY}/alpine:3.20
|
||||||
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apk add --no-cache ca-certificates tzdata gettext
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /server ./system
|
COPY --from=builder /server ./system
|
||||||
COPY deploy/etc/system.yaml etc/system.yaml
|
COPY deploy/etc/system.yaml etc/system.yaml
|
||||||
|
COPY deploy/entrypoint.sh /entrypoint.sh
|
||||||
EXPOSE 9001
|
EXPOSE 9001
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
CMD ["./system", "-f", "etc/system.yaml"]
|
CMD ["./system", "-f", "etc/system.yaml"]
|
||||||
|
|||||||
@ -5,7 +5,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: muyu
|
POSTGRES_USER: muyu
|
||||||
POSTGRES_PASSWORD: muyu2026
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
||||||
POSTGRES_DB: muyu_crm
|
POSTGRES_DB: muyu_crm
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
ports:
|
ports:
|
||||||
@ -70,7 +70,7 @@ services:
|
|||||||
container_name: muyu-neo4j
|
container_name: muyu-neo4j
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
NEO4J_AUTH: neo4j/muyu2026
|
NEO4J_AUTH: ${NEO4J_AUTH:?Set NEO4J_AUTH in .env (e.g. neo4j/yourpassword)}
|
||||||
NEO4J_server_memory_heap_initial__size: 512m
|
NEO4J_server_memory_heap_initial__size: 512m
|
||||||
NEO4J_server_memory_heap_max__size: 1024m
|
NEO4J_server_memory_heap_max__size: 1024m
|
||||||
NEO4J_server_default__listen__address: 0.0.0.0
|
NEO4J_server_default__listen__address: 0.0.0.0
|
||||||
@ -103,7 +103,7 @@ services:
|
|||||||
KAFKA_GROUP: graphsync
|
KAFKA_GROUP: graphsync
|
||||||
NEO4J_URI: bolt://neo4j:7687
|
NEO4J_URI: bolt://neo4j:7687
|
||||||
NEO4J_USER: neo4j
|
NEO4J_USER: neo4j
|
||||||
NEO4J_PASS: muyu2026
|
NEO4J_PASS: ${NEO4J_PASS:?Set NEO4J_PASS in .env}
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
|
||||||
kafka-ui:
|
kafka-ui:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ services:
|
|||||||
container_name: muyu-mysql
|
container_name: muyu-mysql
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: muyu2026
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD in .env}
|
||||||
MYSQL_DATABASE: muyu_wms
|
MYSQL_DATABASE: muyu_wms
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
ports:
|
ports:
|
||||||
@ -39,7 +39,7 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: muyu
|
POSTGRES_USER: muyu
|
||||||
POSTGRES_PASSWORD: muyu2026
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
||||||
POSTGRES_DB: muyu_crm
|
POSTGRES_DB: muyu_crm
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
ports:
|
ports:
|
||||||
@ -90,6 +90,7 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||||
|
|
||||||
inventory-rpc:
|
inventory-rpc:
|
||||||
build:
|
build:
|
||||||
@ -106,6 +107,7 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||||
|
|
||||||
purchase-rpc:
|
purchase-rpc:
|
||||||
build:
|
build:
|
||||||
@ -122,6 +124,7 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||||
|
|
||||||
gateway:
|
gateway:
|
||||||
build:
|
build:
|
||||||
@ -142,6 +145,9 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
|
||||||
|
POSTGRES_DSN: "postgres://muyu:${POSTGRES_PASSWORD}@postgres:5432/muyu_crm?sslmode=disable"
|
||||||
|
ACCESS_SECRET: ${ACCESS_SECRET:?Set ACCESS_SECRET in .env}
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
|
|||||||
27
deploy/entrypoint.sh
Executable file
27
deploy/entrypoint.sh
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Substitute environment variables in YAML config templates before starting the service.
|
||||||
|
# Usage: entrypoint.sh <binary> -f <config.yaml>
|
||||||
|
#
|
||||||
|
# The YAML file is treated as a template with ${VAR} placeholders.
|
||||||
|
# envsubst replaces them with actual environment variable values at container start time.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BINARY="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
CONFIG_FILE=""
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$prev" in
|
||||||
|
-f) CONFIG_FILE="$arg" ;;
|
||||||
|
esac
|
||||||
|
prev="$arg"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$CONFIG_FILE" ] && [ -f "$CONFIG_FILE" ]; then
|
||||||
|
# Replace ${VAR} placeholders with environment variable values
|
||||||
|
envsubst < "$CONFIG_FILE" > "${CONFIG_FILE}.tmp"
|
||||||
|
mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$BINARY" "$@"
|
||||||
@ -4,12 +4,12 @@ Port: 8888
|
|||||||
Timeout: 120000
|
Timeout: 120000
|
||||||
|
|
||||||
Auth:
|
Auth:
|
||||||
AccessSecret: muyu-wms-jwt-secret-key-2026
|
AccessSecret: ${ACCESS_SECRET}
|
||||||
AccessExpire: 7200
|
AccessExpire: 7200
|
||||||
DefaultTenantId: t_default_001
|
DefaultTenantId: t_default_001
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: ${MYSQL_DSN}
|
||||||
PostgresDataSource: "postgres://muyu:muyu2026@postgres:5432/muyu_crm?sslmode=disable"
|
PostgresDataSource: ${POSTGRES_DSN}
|
||||||
|
|
||||||
SystemRpc:
|
SystemRpc:
|
||||||
Etcd:
|
Etcd:
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Etcd:
|
|||||||
- etcd:2379
|
- etcd:2379
|
||||||
Key: inventory.rpc
|
Key: inventory.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: ${MYSQL_DSN}
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: redis:6379
|
- Host: redis:6379
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Etcd:
|
|||||||
- etcd:2379
|
- etcd:2379
|
||||||
Key: purchase.rpc
|
Key: purchase.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: ${MYSQL_DSN}
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: redis:6379
|
- Host: redis:6379
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Etcd:
|
|||||||
- etcd:2379
|
- etcd:2379
|
||||||
Key: system.rpc
|
Key: system.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: ${MYSQL_DSN}
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: redis:6379
|
- Host: redis:6379
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
|
# Local development config — fill in credentials before running locally.
|
||||||
Name: gateway-api
|
Name: gateway-api
|
||||||
Host: 0.0.0.0
|
Host: 0.0.0.0
|
||||||
Port: 8888
|
Port: 8888
|
||||||
|
|
||||||
Auth:
|
Auth:
|
||||||
AccessSecret: muyu-wms-jwt-secret-key-2026
|
AccessSecret: your_jwt_secret_here
|
||||||
AccessExpire: 7200
|
AccessExpire: 7200
|
||||||
DefaultTenantId: t_default_001
|
DefaultTenantId: t_default_001
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||||
PostgresDataSource: "postgres://muyu:muyu2026@127.0.0.1:5432/muyu_crm?sslmode=disable"
|
PostgresDataSource: "postgres://muyu:your_password@127.0.0.1:5432/muyu_crm?sslmode=disable"
|
||||||
|
|
||||||
SystemRpc:
|
SystemRpc:
|
||||||
Etcd:
|
Etcd:
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
# Local development config — fill in DataSource before running locally.
|
||||||
Name: inventory.rpc
|
Name: inventory.rpc
|
||||||
ListenOn: 0.0.0.0:9002
|
ListenOn: 0.0.0.0:9002
|
||||||
|
|
||||||
@ -6,7 +7,7 @@ Etcd:
|
|||||||
- 127.0.0.1:2379
|
- 127.0.0.1:2379
|
||||||
Key: inventory.rpc
|
Key: inventory.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: 127.0.0.1:6379
|
- Host: 127.0.0.1:6379
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
# Local development config — fill in DataSource before running locally.
|
||||||
Name: purchase.rpc
|
Name: purchase.rpc
|
||||||
ListenOn: 0.0.0.0:9003
|
ListenOn: 0.0.0.0:9003
|
||||||
|
|
||||||
@ -6,7 +7,7 @@ Etcd:
|
|||||||
- 127.0.0.1:2379
|
- 127.0.0.1:2379
|
||||||
Key: purchase.rpc
|
Key: purchase.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: 127.0.0.1:6379
|
- Host: 127.0.0.1:6379
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
# Local development config — fill in DataSource before running locally.
|
||||||
|
# For Docker deployment, see deploy/etc/system.yaml (uses envsubst).
|
||||||
Name: system.rpc
|
Name: system.rpc
|
||||||
ListenOn: 0.0.0.0:9001
|
ListenOn: 0.0.0.0:9001
|
||||||
|
|
||||||
@ -6,7 +8,7 @@ Etcd:
|
|||||||
- 127.0.0.1:2379
|
- 127.0.0.1:2379
|
||||||
Key: system.rpc
|
Key: system.rpc
|
||||||
|
|
||||||
DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||||
|
|
||||||
Cache:
|
Cache:
|
||||||
- Host: 127.0.0.1:6379
|
- Host: 127.0.0.1:6379
|
||||||
|
|||||||
@ -32,7 +32,7 @@ func main() {
|
|||||||
flag.StringVar(&cfg.KafkaGroup, "kafka-group", envOr("KAFKA_GROUP", "graphsync"), "consumer group")
|
flag.StringVar(&cfg.KafkaGroup, "kafka-group", envOr("KAFKA_GROUP", "graphsync"), "consumer group")
|
||||||
flag.StringVar(&cfg.Neo4jURI, "neo4j-uri", envOr("NEO4J_URI", "bolt://localhost:7687"), "Neo4j bolt URI")
|
flag.StringVar(&cfg.Neo4jURI, "neo4j-uri", envOr("NEO4J_URI", "bolt://localhost:7687"), "Neo4j bolt URI")
|
||||||
flag.StringVar(&cfg.Neo4jUser, "neo4j-user", envOr("NEO4J_USER", "neo4j"), "Neo4j user")
|
flag.StringVar(&cfg.Neo4jUser, "neo4j-user", envOr("NEO4J_USER", "neo4j"), "Neo4j user")
|
||||||
flag.StringVar(&cfg.Neo4jPass, "neo4j-pass", envOr("NEO4J_PASS", "muyu2026"), "Neo4j password")
|
flag.StringVar(&cfg.Neo4jPass, "neo4j-pass", envOr("NEO4J_PASS", ""), "Neo4j password")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user