mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 03:52:26 +08:00
feat(deploy): support optional Apple network subnet
This commit is contained in:
@@ -36,6 +36,11 @@ APPLE_CONTAINER_SUB2API_IMAGE=weishaw/sub2api:latest
|
||||
APPLE_CONTAINER_POSTGRES_IMAGE=postgres:18-alpine
|
||||
APPLE_CONTAINER_REDIS_IMAGE=redis:8-alpine
|
||||
|
||||
# Optional fixed IPv4 CIDR for the private Apple container network. Leave empty
|
||||
# to let Apple container select one. Set only when host tooling needs a stable
|
||||
# network gateway, and choose a CIDR that does not overlap your LAN or VPN.
|
||||
APPLE_CONTAINER_NETWORK_SUBNET=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Logging Configuration
|
||||
# 日志配置
|
||||
|
||||
@@ -105,6 +105,22 @@ APPLE_CONTAINER_POSTGRES_IMAGE=postgres:18-alpine
|
||||
APPLE_CONTAINER_REDIS_IMAGE=redis:8-alpine
|
||||
```
|
||||
|
||||
By default, Apple `container` selects the private IPv4 subnet for the managed
|
||||
network. Set `APPLE_CONTAINER_NETWORK_SUBNET` only when host-side tooling needs
|
||||
a stable network gateway:
|
||||
|
||||
```dotenv
|
||||
APPLE_CONTAINER_NETWORK_SUBNET=
|
||||
```
|
||||
|
||||
Leave the setting empty to keep automatic subnet allocation. When setting it,
|
||||
choose a CIDR that does not overlap the host LAN or VPN. The script applies the
|
||||
setting only when it creates `sub2api-apple`. If the existing managed network
|
||||
uses a different subnet, it stops without deleting any resources. To migrate
|
||||
intentionally, run `./apple-container.sh destroy --yes` to remove the managed
|
||||
containers and network while preserving named volumes, then run
|
||||
`./apple-container.sh up`.
|
||||
|
||||
The normal `up` command recreates the application container, so application environment changes are applied immediately. Use `up --recreate` when changing PostgreSQL or Redis container images or Redis runtime configuration. Persistent data remains in named volumes.
|
||||
|
||||
`POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB` are applied only when PostgreSQL initializes an empty data volume. Changing them in `.env` and recreating the container does not change an existing database. Rotate a password with `ALTER ROLE`, and plan explicit migrations for user or database changes. To intentionally initialize a new empty database, first back up the old one and use `destroy --volumes`.
|
||||
|
||||
@@ -31,6 +31,7 @@ POSTGRES_PASSWORD=""
|
||||
POSTGRES_DB=""
|
||||
REDIS_PASSWORD=""
|
||||
TZ_VALUE=""
|
||||
NETWORK_SUBNET=""
|
||||
POSTGRES_ADDRESS=""
|
||||
REDIS_ADDRESS=""
|
||||
APP_ENV_FILE=""
|
||||
@@ -210,15 +211,28 @@ preflight_stack_ownership() {
|
||||
}
|
||||
|
||||
ensure_network() {
|
||||
local existing_subnet
|
||||
local -a network_args
|
||||
|
||||
if resource_exists network "${NETWORK_NAME}"; then
|
||||
assert_resource_owned network "${NETWORK_NAME}"
|
||||
if [[ -n "${NETWORK_SUBNET}" ]]; then
|
||||
existing_subnet="$(inspect_resource network "${NETWORK_NAME}" | \
|
||||
plutil -extract 0.configuration.ipv4Subnet raw -o - -)" || \
|
||||
die "Unable to read the IPv4 subnet for ${NETWORK_NAME}."
|
||||
if [[ "${existing_subnet}" != "${NETWORK_SUBNET}" ]]; then
|
||||
die "Existing network '${NETWORK_NAME}' uses subnet '${existing_subnet}', but APPLE_CONTAINER_NETWORK_SUBNET is '${NETWORK_SUBNET}'. Run './apple-container.sh destroy --yes' to recreate the network while preserving volumes, then run 'up' again."
|
||||
fi
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
info "Creating network ${NETWORK_NAME}..."
|
||||
container network create \
|
||||
--label "${STACK_LABEL_KEY}=${STACK_LABEL_VALUE}" \
|
||||
"${NETWORK_NAME}" >/dev/null
|
||||
network_args=(--label "${STACK_LABEL_KEY}=${STACK_LABEL_VALUE}")
|
||||
if [[ -n "${NETWORK_SUBNET}" ]]; then
|
||||
network_args+=(--subnet "${NETWORK_SUBNET}")
|
||||
fi
|
||||
container network create "${network_args[@]}" "${NETWORK_NAME}" >/dev/null
|
||||
}
|
||||
|
||||
ensure_volume() {
|
||||
@@ -410,6 +424,7 @@ prepare_environment() {
|
||||
POSTGRES_DB="$(read_env_value POSTGRES_DB sub2api)"
|
||||
REDIS_PASSWORD="$(read_env_value REDIS_PASSWORD)"
|
||||
TZ_VALUE="$(read_env_value TZ Asia/Shanghai)"
|
||||
NETWORK_SUBNET="$(read_env_value APPLE_CONTAINER_NETWORK_SUBNET)"
|
||||
|
||||
[[ -n "${BIND_HOST}" ]] || die "BIND_HOST must not be empty."
|
||||
validate_ipv4_address "${BIND_HOST}"
|
||||
|
||||
@@ -48,6 +48,8 @@ assert_exists "${STATE_DIR}/containers/sub2api-apple"
|
||||
assert_exists "${STATE_DIR}/containers/sub2api-apple-postgres"
|
||||
assert_exists "${STATE_DIR}/containers/sub2api-apple-redis"
|
||||
assert_exists "${STATE_DIR}/running/sub2api-apple"
|
||||
[[ ! -s "${STATE_DIR}/network-subnets/sub2api-apple" ]] || \
|
||||
fail "up passed a subnet when APPLE_CONTAINER_NETWORK_SUBNET was unset"
|
||||
"${SCRIPT}" status >/dev/null
|
||||
|
||||
"${SCRIPT}" up --recreate
|
||||
@@ -62,6 +64,23 @@ assert_missing "${STATE_DIR}/containers/sub2api-apple"
|
||||
assert_missing "${STATE_DIR}/networks/sub2api-apple"
|
||||
assert_exists "${STATE_DIR}/volumes/sub2api-apple-data"
|
||||
|
||||
printf '\nAPPLE_CONTAINER_NETWORK_SUBNET=172.31.250.0/24\n' >>"${ENV_FILE}"
|
||||
"${SCRIPT}" up
|
||||
[[ "$(<"${STATE_DIR}/network-subnets/sub2api-apple")" == "172.31.250.0/24" ]] || \
|
||||
fail "up did not pass APPLE_CONTAINER_NETWORK_SUBNET to network creation"
|
||||
|
||||
printf 'APPLE_CONTAINER_NETWORK_SUBNET=172.31.251.0/24\n' >>"${ENV_FILE}"
|
||||
if mismatch_output="$("${SCRIPT}" up 2>&1)"; then
|
||||
fail "up accepted a configured subnet that differs from the existing network"
|
||||
fi
|
||||
[[ "${mismatch_output}" == *"Existing network 'sub2api-apple' uses subnet '172.31.250.0/24'"* ]] || \
|
||||
fail "up did not explain the existing network subnet mismatch"
|
||||
[[ "${mismatch_output}" == *"destroy --yes"* ]] || \
|
||||
fail "up did not provide the network migration command"
|
||||
assert_exists "${STATE_DIR}/networks/sub2api-apple"
|
||||
assert_exists "${STATE_DIR}/containers/sub2api-apple"
|
||||
|
||||
"${SCRIPT}" destroy --yes
|
||||
"${SCRIPT}" up
|
||||
"${SCRIPT}" destroy --volumes --yes
|
||||
assert_missing "${STATE_DIR}/volumes/sub2api-apple-data"
|
||||
|
||||
Vendored
+29
-2
@@ -7,6 +7,7 @@ mkdir -p \
|
||||
"${STATE_DIR}/containers" \
|
||||
"${STATE_DIR}/running" \
|
||||
"${STATE_DIR}/networks" \
|
||||
"${STATE_DIR}/network-subnets" \
|
||||
"${STATE_DIR}/volumes" \
|
||||
"${STATE_DIR}/unowned/container" \
|
||||
"${STATE_DIR}/unowned/network" \
|
||||
@@ -34,10 +35,19 @@ inspect_resource() {
|
||||
local resource_name=$2
|
||||
local label_value="apple-container"
|
||||
local address="192.168.65.4/24"
|
||||
local subnet="192.168.65.0/24"
|
||||
|
||||
if [[ -e "${STATE_DIR}/unowned/${resource_type}/${resource_name}" ]]; then
|
||||
label_value="other"
|
||||
fi
|
||||
if [[ "${resource_type}" == "network" ]]; then
|
||||
if [[ -s "${STATE_DIR}/network-subnets/${resource_name}" ]]; then
|
||||
subnet="$(<"${STATE_DIR}/network-subnets/${resource_name}")"
|
||||
fi
|
||||
printf '[{"configuration":{"ipv4Subnet":"%s","labels":{"org.sub2api.stack":"%s"}}}]\n' \
|
||||
"${subnet}" "${label_value}"
|
||||
return
|
||||
fi
|
||||
case "${resource_name}" in
|
||||
sub2api-apple-postgres) address="192.168.65.2/24" ;;
|
||||
sub2api-apple-redis) address="192.168.65.3/24" ;;
|
||||
@@ -82,9 +92,26 @@ case "${command}" in
|
||||
echo default
|
||||
list_names "${STATE_DIR}/networks"
|
||||
;;
|
||||
create) touch "${STATE_DIR}/networks/$(last_argument "$@")" ;;
|
||||
create)
|
||||
network_name="$(last_argument "$@")"
|
||||
subnet=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--subnet)
|
||||
subnet=$2
|
||||
shift 2
|
||||
;;
|
||||
*) shift ;;
|
||||
esac
|
||||
done
|
||||
touch "${STATE_DIR}/networks/${network_name}"
|
||||
printf '%s' "${subnet}" >"${STATE_DIR}/network-subnets/${network_name}"
|
||||
;;
|
||||
inspect) inspect_resource network "${1}" ;;
|
||||
delete) rm -f "${STATE_DIR}/networks/${1}" ;;
|
||||
delete)
|
||||
rm -f "${STATE_DIR}/networks/${1}"
|
||||
rm -f "${STATE_DIR}/network-subnets/${1}"
|
||||
;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user