This commit is contained in:
Mikan
2026-03-12 23:17:50 +03:00
parent 60204db3d2
commit 95716a6506
7 changed files with 125 additions and 174 deletions

View File

@@ -1,2 +1,9 @@
# Этот файл будет перезаписан при запуске ./scripts/02-apply-config.sh address=/.mikan/10.0.0.3
# Не редактируйте вручную address=/.mikan.local/10.0.0.3
local=/.mikan/
local=/.mikan.local/
no-resolv
server=1.1.1.1
server=8.8.8.8
log-queries
log-facility=/dev/stdout

View File

@@ -1,70 +1,87 @@
version: '3.8' version: '3.8'
services: services:
nginx-proxy: nginx-proxy:
image: nginxproxy/nginx-proxy:alpine image: nginxproxy/nginx-proxy:alpine
container_name: nginx-proxy container_name: nginx-proxy
restart: unless-stopped restart: unless-stopped
ports: ports:
- "80:80" - "80:80"
- "443:443" - "443:443"
volumes: volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro - /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx/certs:/etc/nginx/certs:ro - ./nginx/certs:/etc/nginx/certs:ro
- ./nginx/vhost.d:/etc/nginx/vhost.d:ro - ./nginx/vhost.d:/etc/nginx/vhost.d:ro
- ./nginx/html:/usr/share/nginx/html:rw - ./nginx/html:/usr/share/nginx/html:rw
networks: networks:
devnet: devnet:
ipv4_address: ${NGINX_IP} ipv4_address: ${NGINX_IP}
environment: environment:
- DEFAULT_HOST=welcome.${LOCAL_DOMAIN} - DEFAULT_HOST=welcome.${LOCAL_DOMAIN}
- HTTPS_METHOD=redirect - HTTPS_METHOD=redirect
- SSL_POLICY=Mozilla-Modern - SSL_POLICY=Mozilla-Modern
- DEFAULT_SSL_CERT=/etc/nginx/certs/default.crt - DEFAULT_SSL_CERT=/etc/nginx/certs/default.crt
- DEFAULT_SSL_KEY=/etc/nginx/certs/default.key - DEFAULT_SSL_KEY=/etc/nginx/certs/default.key
labels: labels:
- "com.github.nginx-proxy.nginx-proxy=true" - "com.github.nginx-proxy.nginx-proxy=true"
nginx-proxy-companion: nginx-proxy-companion:
image: nginxproxy/acme-companion image: nginxproxy/acme-companion
container_name: nginx-proxy-companion container_name: nginx-proxy-companion
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- ./nginx/certs:/etc/nginx/certs:rw - ./nginx/certs:/etc/nginx/certs:rw
- ./acme:/etc/acme.sh - ./acme:/etc/acme.sh
- ./nginx/vhost.d:/etc/nginx/vhost.d:rw - ./nginx/vhost.d:/etc/nginx/vhost.d:rw
networks: networks:
- devnet - devnet
environment: environment:
- DEFAULT_EMAIL=${LETSENCRYPT_EMAIL} - DEFAULT_EMAIL=${LETSENCRYPT_EMAIL}
- NGINX_PROXY_CONTAINER=nginx-proxy - NGINX_PROXY_CONTAINER=nginx-proxy
- ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory - ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
depends_on: depends_on:
- nginx-proxy - nginx-proxy
welcome: welcome:
image: nginx:alpine image: nginx:alpine
container_name: welcome container_name: welcome
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- ./nginx/html:/usr/share/nginx/html:ro - ./nginx/html:/usr/share/nginx/html:ro
environment: environment:
- VIRTUAL_HOST=welcome.${LOCAL_DOMAIN},welcome.${LOCAL_DOMAIN}.local - VIRTUAL_HOST=welcome.${LOCAL_DOMAIN},welcome.${LOCAL_DOMAIN}.local
networks: networks:
- devnet - devnet
depends_on: depends_on:
- nginx-proxy - nginx-proxy
networks: dnsmasq:
devnet: image: jpillora/dnsmasq
driver: bridge container_name: dnsmasq
ipam: restart: unless-stopped
config: ports:
- subnet: ${SUBNET} - "53:53/udp"
gateway: ${GATEWAY} - "53:53/tcp"
volumes:
volumes: - ./dnsmasq/dnsmasq.conf:/etc/dnsmasq.conf:ro
acme: cap_add:
vhost.d: - NET_ADMIN
networks:
devnet:
ipv4_address: ${DNSMASQ_IP}
healthcheck:
test: ["CMD", "nslookup", "localhost", "127.0.0.1"]
interval: 30s
timeout: 5s
retries: 3
networks:
devnet:
external: true
name: devnet
volumes:
acme:
vhost.d:
html: html:

View File

@@ -1,7 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head><title>Placeholder</title></head> <head><title>Добро пожаловать!</title></head>
<body> <body>
<p>Run ./scripts/00-init.sh to generate content</p> <h1>Сервисы .mikan</h1>
<p>Добавьте свои сервисы в папку <code>services/</code></p>
</body> </body>
</html> </html>

1
scripts/00-init.sh Normal file → Executable file
View File

@@ -24,7 +24,6 @@ echo "Проверка сети devnet..."
if ! docker network inspect devnet &>/dev/null; then if ! docker network inspect devnet &>/dev/null; then
echo "Создаём сеть devnet..." echo "Создаём сеть devnet..."
docker network create \ docker network create \
--driver=bridge \
--subnet="${SUBNET}" \ --subnet="${SUBNET}" \
--gateway="${GATEWAY}" \ --gateway="${GATEWAY}" \
devnet devnet

View File

@@ -1,49 +0,0 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR/.."
if [ ! -f "$PROJECT_ROOT/.env" ]; then
echo "Файл .env не найден. Запустите сначала ./scripts/00-init.sh"
exit 1
fi
export $(grep -v '^#' "$PROJECT_ROOT/.env" | xargs)
CERTS_DIR="$PROJECT_ROOT/nginx/certs"
CA_DIR="$PROJECT_ROOT/ca"
if ! command -v mkcert &> /dev/null; then
echo "mkcert не установлен."
echo "Linux: sudo apt install mkcert"
echo "macOS: brew install mkcert nss"
exit 1
fi
mkdir -p "$CERTS_DIR" "$CA_DIR"
DOMAINS=(
"*.$LOCAL_DOMAIN"
"*.$LOCAL_DOMAIN.local"
"$LOCAL_DOMAIN"
"localhost"
"127.0.0.1"
"::1"
)
if [ -n "$PUBLIC_DOMAIN" ]; then
DOMAINS+=("*.$PUBLIC_DOMAIN" "$PUBLIC_DOMAIN")
fi
mkcert -install
mkcert \
-cert-file "$CERTS_DIR/default.crt" \
-key-file "$CERTS_DIR/default.key" \
"${DOMAINS[@]}"
cp "$(mkcert -CAROOT)/rootCA.pem" "$CA_DIR/rootCA.pem"
echo "Сертификаты созданы в $CERTS_DIR"
echo "Установите корневой сертификат на устройствах:"
echo " $CA_DIR/rootCA.pem"

0
scripts/02-apply-config.sh Normal file → Executable file
View File

76
scripts/add-service.sh Normal file → Executable file
View File

@@ -1,65 +1,41 @@
#!/bin/bash #!/bin/bash
set -e set -e
if [ $# -ne 2 ]; then
echo "Использование: $0 <название> <порт>"
echo "Пример: $0 gitea 3000"
exit 1
fi
NAME=$1
PORT=$2
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR/.." ROOT_DIR="$SCRIPT_DIR/.."
if [ ! -f "$PROJECT_ROOT/.env" ]; then if [ -f "$ROOT_DIR/.env" ]; then
echo "Файл .env не найден. Запустите сначала ./scripts/00-init.sh" export $(grep -v '^#' "$ROOT_DIR/.env" | xargs)
fi
LOCAL_DOMAIN=${LOCAL_DOMAIN:-mikan}
if [ $# -lt 1 ]; then
echo "Usage: $0 <service_name> [extra_domains...]"
exit 1 exit 1
fi fi
export $(grep -v '^#' "$PROJECT_ROOT/.env" | xargs) SERVICE_NAME=$1
shift
EXTRA_DOMAINS=("$@")
SERVICE_DIR="$PROJECT_ROOT/services/$NAME" DOMAINS_FILE="$ROOT_DIR/domains.txt"
if [ -d "$SERVICE_DIR" ]; then if [ ! -f "$DOMAINS_FILE" ]; then
echo "Сервис '$NAME' уже существует!" touch "$DOMAINS_FILE"
exit 1
fi fi
mkdir -p "$SERVICE_DIR/data" PRIMARY="${SERVICE_NAME}.${LOCAL_DOMAIN}"
ALIAS="${SERVICE_NAME}.local"
cat > "$SERVICE_DIR/docker-compose.yml" <<EOF {
version: '3.8' echo "$PRIMARY"
echo "$ALIAS"
for domain in "${EXTRA_DOMAINS[@]}"; do
echo "$domain"
done
} >> "$DOMAINS_FILE"
services: sort -u "$DOMAINS_FILE" | grep -v '^$' > "$DOMAINS_FILE.tmp" && mv "$DOMAINS_FILE.tmp" "$DOMAINS_FILE"
$NAME:
image: nginx:alpine
container_name: $NAME
restart: unless-stopped
environment:
- VIRTUAL_HOST=$NAME.$LOCAL_DOMAIN,$NAME.$LOCAL_DOMAIN.local
$(if [ -n "$PUBLIC_DOMAIN" ]; then
echo " - LETSENCRYPT_HOST=$NAME.$PUBLIC_DOMAIN"
echo " - LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL"
else
echo " # LETSENCRYPT_HOST="
echo " # LETSENCRYPT_EMAIL="
fi)
- VIRTUAL_PORT=$PORT
volumes:
- .//data
networks:
- devnet
depends_on:
- nginx-proxy
networks: exec "$SCRIPT_DIR/regenerate-cert.sh"
devnet:
external: true
EOF
echo "Сервис '$NAME' создан в $SERVICE_DIR"
echo "Запустите:"
echo " cd $PROJECT_ROOT"
echo " docker compose -f docker-compose.yml -f services/$NAME/docker-compose.yml up -d"