Add Ubuntu deployment: scripts, SSL, systemd and setup.sh
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Env and secrets
|
||||
.env
|
||||
|
||||
# Build artifacts
|
||||
*.exe
|
||||
shop
|
||||
/vendor/
|
||||
|
||||
# Docs and dev
|
||||
README.md
|
||||
scripts/
|
||||
+10
-2
@@ -10,5 +10,13 @@ ADMIN_PASSWORD=change_me
|
||||
# Секрет для сессий (обязательно смените в продакшене)
|
||||
SESSION_SECRET=your_random_secret_key_here
|
||||
|
||||
# Domain for Caddy SSL (production)
|
||||
DOMAIN=shop.example.com
|
||||
# Часовой пояс сервера (Ubuntu)
|
||||
TZ=Europe/Moscow
|
||||
|
||||
# --- Продакшен на Ubuntu с доменом ---
|
||||
# DOMAIN=shop.example.com
|
||||
# CADDY_EMAIL=admin@example.com
|
||||
# CADDYFILE=./Caddyfile.prod
|
||||
|
||||
# Для доступа по IP без домена оставьте DOMAIN закомментированным
|
||||
# и используйте Caddyfile по умолчанию (HTTP на порту 80)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
* text=auto eol=lf
|
||||
*.sh text eol=lf
|
||||
@@ -1,14 +1,5 @@
|
||||
{
|
||||
admin localhost:2019
|
||||
}
|
||||
|
||||
# Локальная разработка — HTTP на порту 80
|
||||
# HTTP — доступ по IP или localhost (без домена)
|
||||
:80 {
|
||||
encode gzip
|
||||
reverse_proxy app:8080
|
||||
}
|
||||
|
||||
# Продакшен — автоматический SSL от Let's Encrypt
|
||||
# Раскомментируйте и закомментируйте блок :80 выше
|
||||
# {$DOMAIN} {
|
||||
# reverse_proxy app:8080
|
||||
# }
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
email {$CADDY_EMAIL}
|
||||
}
|
||||
|
||||
{$DOMAIN} {
|
||||
encode gzip
|
||||
reverse_proxy app:8080
|
||||
}
|
||||
@@ -16,6 +16,8 @@ FROM alpine:3.21
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
ENV TZ=UTC
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /shop /app/shop
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
.PHONY: help install deploy up down logs restart ssl update
|
||||
|
||||
help:
|
||||
@echo "Shop — команды для Ubuntu"
|
||||
@echo ""
|
||||
@echo " make install — установить Docker (sudo)"
|
||||
@echo " make deploy — первый запуск проекта"
|
||||
@echo " make up — поднять контейнеры"
|
||||
@echo " make down — остановить контейнеры"
|
||||
@echo " make logs — логи всех сервисов"
|
||||
@echo " make restart — перезапуск"
|
||||
@echo " make ssl — включить SSL (DOMAIN=... EMAIL=...)"
|
||||
@echo " make update — git pull + пересборка"
|
||||
|
||||
install:
|
||||
sudo ./scripts/install-ubuntu.sh
|
||||
|
||||
deploy:
|
||||
chmod +x scripts/*.sh
|
||||
./scripts/deploy.sh
|
||||
|
||||
up:
|
||||
docker compose up -d
|
||||
|
||||
down:
|
||||
docker compose down
|
||||
|
||||
logs:
|
||||
docker compose logs -f
|
||||
|
||||
restart:
|
||||
docker compose restart
|
||||
|
||||
ssl:
|
||||
@test -n "$(DOMAIN)" || (echo "Укажите DOMAIN=shop.example.com EMAIL=admin@example.com"; exit 1)
|
||||
./scripts/enable-ssl.sh "$(DOMAIN)" "$(EMAIL)"
|
||||
|
||||
update:
|
||||
./scripts/update.sh
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Главная страница интернет-магазина на **Go**, **PostgreSQL 17**, **Docker Compose** и **Caddy** (обратный прокси + SSL).
|
||||
|
||||
Проект настроен для развёртывания на **Ubuntu 22.04 / 24.04**.
|
||||
|
||||
## Стек
|
||||
|
||||
| Компонент | Технология |
|
||||
@@ -9,20 +11,74 @@
|
||||
| Backend | Go 1.23, `net/http`, `pgx/v5` |
|
||||
| База данных | PostgreSQL 17 |
|
||||
| Прокси / SSL | Caddy 2 |
|
||||
| ОС | Ubuntu 22.04 / 24.04 |
|
||||
| Контейнеризация | Docker Compose |
|
||||
|
||||
## Быстрый старт
|
||||
## Быстрый старт на Ubuntu
|
||||
|
||||
```bash
|
||||
# Скопировать переменные окружения
|
||||
cp .env.example .env
|
||||
# Клонировать репозиторий
|
||||
git clone https://git.evilfox.cc/test2/shop-go.git /opt/shop
|
||||
cd /opt/shop
|
||||
|
||||
# Запустить все сервисы
|
||||
docker compose up --build -d
|
||||
# 1. Установить Docker (один раз, с sudo)
|
||||
sudo ./scripts/install-ubuntu.sh
|
||||
|
||||
# Открыть в браузере
|
||||
# http://localhost
|
||||
# http://localhost/admin/login — админка
|
||||
# Перелогиниться или:
|
||||
newgrp docker
|
||||
|
||||
# 2. Запустить магазин
|
||||
chmod +x scripts/*.sh
|
||||
./scripts/deploy.sh
|
||||
```
|
||||
|
||||
Откройте в браузере:
|
||||
- `http://IP_СЕРВЕРА` — магазин
|
||||
- `http://IP_СЕРВЕРА/admin/login` — админка
|
||||
|
||||
Или через Make:
|
||||
|
||||
```bash
|
||||
make install # sudo, установка Docker
|
||||
make deploy # первый запуск
|
||||
make logs # просмотр логов
|
||||
```
|
||||
|
||||
## Продакшен с доменом и SSL
|
||||
|
||||
1. Настройте DNS: A-запись домена → IP сервера Ubuntu
|
||||
2. Откройте порты 80 и 443 (скрипт `install-ubuntu.sh` настраивает ufw)
|
||||
3. Включите SSL:
|
||||
|
||||
```bash
|
||||
./scripts/enable-ssl.sh shop.example.com admin@example.com
|
||||
```
|
||||
|
||||
Или:
|
||||
|
||||
```bash
|
||||
make ssl DOMAIN=shop.example.com EMAIL=admin@example.com
|
||||
```
|
||||
|
||||
Caddy автоматически получит сертификат Let's Encrypt.
|
||||
|
||||
Вручную через `.env`:
|
||||
|
||||
```env
|
||||
DOMAIN=shop.example.com
|
||||
CADDY_EMAIL=admin@example.com
|
||||
CADDYFILE=./Caddyfile.prod
|
||||
```
|
||||
|
||||
Затем: `docker compose up -d --force-recreate caddy`
|
||||
|
||||
## Автозапуск при загрузке Ubuntu
|
||||
|
||||
```bash
|
||||
sudo cp systemd/shop.service /etc/systemd/system/
|
||||
# Отредактируйте WorkingDirectory, если проект не в /opt/shop
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now shop
|
||||
```
|
||||
|
||||
## Админ
|
||||
@@ -35,7 +91,9 @@ ADMIN_PASSWORD=change_me
|
||||
SESSION_SECRET=your_random_secret_key_here
|
||||
```
|
||||
|
||||
Вход: **http://localhost/admin/login**
|
||||
Скрипт `deploy.sh` генерирует пароли автоматически при первом запуске.
|
||||
|
||||
Вход: `/admin/login`
|
||||
|
||||
При изменении `ADMIN_PASSWORD` пароль обновится в БД при следующем запуске.
|
||||
|
||||
@@ -46,29 +104,26 @@ SESSION_SECRET=your_random_secret_key_here
|
||||
| Caddy | 80, 443 | Обратный прокси, SSL |
|
||||
| App | 8080 (внутри) | Go-приложение |
|
||||
| PostgreSQL | 5432 (внутри) | База данных |
|
||||
| Caddy Admin | 2019 | Панель управления Caddy |
|
||||
|
||||
## SSL в продакшене
|
||||
|
||||
1. Укажите домен в `.env`:
|
||||
```
|
||||
DOMAIN=shop.example.com
|
||||
```
|
||||
|
||||
2. Обновите `Caddyfile` — раскомментируйте блок с `{$DOMAIN}` и закомментируйте `:80`.
|
||||
|
||||
3. Убедитесь, что порты 80 и 443 открыты. Caddy автоматически получит сертификат Let's Encrypt.
|
||||
|
||||
## Локальная разработка без Docker
|
||||
## Обновление на сервере
|
||||
|
||||
```bash
|
||||
# Запустить только PostgreSQL
|
||||
./scripts/update.sh
|
||||
# или
|
||||
make update
|
||||
```
|
||||
|
||||
## Локальная разработка (Ubuntu)
|
||||
|
||||
```bash
|
||||
# Только PostgreSQL в Docker
|
||||
docker compose up db -d
|
||||
|
||||
# Установить зависимости и запустить приложение
|
||||
export DB_HOST=localhost DB_USER=shop DB_PASSWORD=shop_secret DB_NAME=shop
|
||||
export ADMIN_EMAIL=admin@shop.local ADMIN_PASSWORD=change_me
|
||||
|
||||
go mod tidy
|
||||
go run ./cmd/shop
|
||||
|
||||
# http://localhost:8080
|
||||
```
|
||||
|
||||
@@ -76,15 +131,19 @@ go run ./cmd/shop
|
||||
|
||||
```
|
||||
shop/
|
||||
├── cmd/shop/main.go # Точка входа
|
||||
├── cmd/shop/main.go
|
||||
├── internal/
|
||||
│ ├── database/ # Подключение к PostgreSQL
|
||||
│ ├── handlers/ # HTTP-обработчики, шаблоны, статика
|
||||
│ ├── models/ # Модели данных
|
||||
│ └── repository/ # Запросы к БД
|
||||
├── migrations/ # SQL-миграции
|
||||
├── Caddyfile # Конфигурация Caddy
|
||||
├── migrations/
|
||||
├── scripts/
|
||||
│ ├── install-ubuntu.sh # установка Docker + ufw
|
||||
│ ├── deploy.sh # первый запуск
|
||||
│ ├── enable-ssl.sh # SSL для домена
|
||||
│ └── update.sh # обновление
|
||||
├── systemd/shop.service # автозапуск
|
||||
├── Caddyfile # HTTP (IP / localhost)
|
||||
├── Caddyfile.prod # HTTPS (домен)
|
||||
├── docker-compose.yml
|
||||
├── Makefile
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
@@ -108,3 +167,9 @@ docker compose down
|
||||
# С удалением данных БД
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
## Требования к серверу Ubuntu
|
||||
|
||||
- 1 CPU, 1 GB RAM (минимум)
|
||||
- Ubuntu 22.04 или 24.04 LTS
|
||||
- Открытые порты 22 (SSH), 80, 443
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ import (
|
||||
"shop/internal/config"
|
||||
"shop/internal/database"
|
||||
"shop/internal/handlers"
|
||||
"shop/internal/middleware"
|
||||
"shop/internal/repository"
|
||||
)
|
||||
|
||||
@@ -63,7 +64,7 @@ func main() {
|
||||
addr := ":" + getEnv("APP_PORT", "8080")
|
||||
srv := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: mux,
|
||||
Handler: middleware.TrustProxy(mux),
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
|
||||
+7
-8
@@ -7,6 +7,7 @@ services:
|
||||
POSTGRES_USER: ${DB_USER:-shop}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-shop_secret}
|
||||
POSTGRES_DB: ${DB_NAME:-shop}
|
||||
TZ: ${TZ:-UTC}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
- ./migrations/001_init.sql:/docker-entrypoint-initdb.d/001_init.sql:ro
|
||||
@@ -25,21 +26,17 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: shop-app
|
||||
restart: unless-stopped
|
||||
env_file: .env
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "5432"
|
||||
DB_USER: ${DB_USER:-shop}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-shop_secret}
|
||||
DB_NAME: ${DB_NAME:-shop}
|
||||
APP_PORT: "8080"
|
||||
ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@shop.local}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-change_me}
|
||||
SESSION_SECRET: ${SESSION_SECRET:-dev_session_secret}
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- shop-net
|
||||
init: true
|
||||
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
@@ -48,17 +45,19 @@ services:
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "2019:2019"
|
||||
env_file: .env
|
||||
environment:
|
||||
DOMAIN: ${DOMAIN:-localhost}
|
||||
CADDY_EMAIL: ${CADDY_EMAIL:-}
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ${CADDYFILE:-./Caddyfile}:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
depends_on:
|
||||
- app
|
||||
networks:
|
||||
- shop-net
|
||||
init: true
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
|
||||
@@ -58,27 +58,36 @@ func (s *Session) Validate(token string) (string, bool) {
|
||||
return email, true
|
||||
}
|
||||
|
||||
func (s *Session) SetCookie(w http.ResponseWriter, token string) {
|
||||
func (s *Session) SetCookie(w http.ResponseWriter, r *http.Request, token string) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: cookieName,
|
||||
Value: token,
|
||||
Path: "/admin",
|
||||
HttpOnly: true,
|
||||
Secure: s.isSecure(r),
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
MaxAge: int(sessionTTL.Seconds()),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Session) ClearCookie(w http.ResponseWriter) {
|
||||
func (s *Session) ClearCookie(w http.ResponseWriter, r *http.Request) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: cookieName,
|
||||
Value: "",
|
||||
Path: "/admin",
|
||||
HttpOnly: true,
|
||||
Secure: s.isSecure(r),
|
||||
MaxAge: -1,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Session) isSecure(r *http.Request) bool {
|
||||
if r.TLS != nil {
|
||||
return true
|
||||
}
|
||||
return strings.EqualFold(r.Header.Get("X-Forwarded-Proto"), "https")
|
||||
}
|
||||
|
||||
func (s *Session) FromRequest(r *http.Request) (string, bool) {
|
||||
c, err := r.Cookie(cookieName)
|
||||
if err != nil {
|
||||
|
||||
@@ -81,12 +81,12 @@ func (h *AdminHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
h.session.SetCookie(w, token)
|
||||
h.session.SetCookie(w, r, token)
|
||||
http.Redirect(w, r, "/admin/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (h *AdminHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
h.session.ClearCookie(w)
|
||||
h.session.ClearCookie(w, r)
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TrustProxy восстанавливает схему HTTPS за Caddy/nginx.
|
||||
func TrustProxy(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if proto := r.Header.Get("X-Forwarded-Proto"); strings.EqualFold(proto, "https") {
|
||||
r.URL.Scheme = "https"
|
||||
}
|
||||
if host := r.Header.Get("X-Forwarded-Host"); host != "" {
|
||||
r.Host = host
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
if ! command -v docker &>/dev/null; then
|
||||
echo "Docker не найден. Сначала: sudo ./scripts/install-ubuntu.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f .env ]]; then
|
||||
cp .env.example .env
|
||||
SECRET=$(openssl rand -hex 32)
|
||||
DB_PASS=$(openssl rand -hex 16)
|
||||
sed -i "s/your_random_secret_key_here/${SECRET}/" .env
|
||||
sed -i "s/DB_PASSWORD=shop_secret/DB_PASSWORD=${DB_PASS}/" .env
|
||||
sed -i "s/ADMIN_PASSWORD=change_me/ADMIN_PASSWORD=$(openssl rand -base64 18 | tr -d '/+=')/" .env
|
||||
echo "Создан .env с автоматически сгенерированными паролями."
|
||||
echo "Проверьте ADMIN_EMAIL и DOMAIN перед продакшеном."
|
||||
fi
|
||||
|
||||
docker compose pull --ignore-buildable 2>/dev/null || true
|
||||
docker compose up --build -d
|
||||
|
||||
echo ""
|
||||
echo "Сервисы запущены."
|
||||
echo " Магазин: http://$(hostname -I | awk '{print $1}')"
|
||||
echo " Админка: http://$(hostname -I | awk '{print $1}')/admin/login"
|
||||
echo ""
|
||||
echo "Логи: docker compose logs -f"
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# Переключение Caddy на продакшен-режим с SSL (Ubuntu + домен)
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
if [[ ! -f .env ]]; then
|
||||
echo "Сначала запустите: ./scripts/deploy.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DOMAIN="${1:-}"
|
||||
EMAIL="${2:-}"
|
||||
|
||||
if [[ -z "${DOMAIN}" || -z "${EMAIL}" ]]; then
|
||||
echo "Использование: ./scripts/enable-ssl.sh <домен> <email>"
|
||||
echo "Пример: ./scripts/enable-ssl.sh shop.example.com admin@example.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set_env() {
|
||||
local key="$1" val="$2"
|
||||
if grep -q "^${key}=" .env; then
|
||||
sed -i "s|^${key}=.*|${key}=${val}|" .env
|
||||
else
|
||||
echo "${key}=${val}" >> .env
|
||||
fi
|
||||
}
|
||||
|
||||
set_env DOMAIN "${DOMAIN}"
|
||||
set_env CADDY_EMAIL "${EMAIL}"
|
||||
set_env CADDYFILE "./Caddyfile.prod"
|
||||
|
||||
docker compose up -d --force-recreate caddy
|
||||
|
||||
echo "SSL включён для https://${DOMAIN}"
|
||||
echo "Убедитесь, что DNS A-запись указывает на этот сервер."
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Установка Docker и Docker Compose на Ubuntu 22.04 / 24.04
|
||||
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "Запустите с sudo: sudo ./scripts/install-ubuntu.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -qi ubuntu /etc/os-release 2>/dev/null; then
|
||||
echo "Скрипт предназначен для Ubuntu."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
apt-get update
|
||||
apt-get install -y ca-certificates curl gnupg ufw
|
||||
|
||||
# Docker official repo
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
if [[ ! -f /etc/apt/keyrings/docker.gpg ]]; then
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
fi
|
||||
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "${VERSION_CODENAME}") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list
|
||||
|
||||
apt-get update
|
||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
systemctl enable --now docker
|
||||
|
||||
# Firewall
|
||||
ufw allow OpenSSH
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw --force enable
|
||||
|
||||
SUDO_USER_NAME="${SUDO_USER:-$USER}"
|
||||
if id "${SUDO_USER_NAME}" &>/dev/null; then
|
||||
usermod -aG docker "${SUDO_USER_NAME}"
|
||||
echo "Пользователь ${SUDO_USER_NAME} добавлен в группу docker."
|
||||
echo "Перелогиньтесь или выполните: newgrp docker"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Docker установлен: $(docker --version)"
|
||||
echo "Compose: $(docker compose version)"
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
git pull origin main
|
||||
docker compose up --build -d
|
||||
docker image prune -f
|
||||
|
||||
echo "Обновление завершено."
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# Быстрая установка на Ubuntu — запуск: sudo bash setup.sh
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "Запустите: sudo bash setup.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bash scripts/install-ubuntu.sh
|
||||
|
||||
REAL_USER="${SUDO_USER:-ubuntu}"
|
||||
if id "${REAL_USER}" &>/dev/null; then
|
||||
sudo -u "${REAL_USER}" bash scripts/deploy.sh
|
||||
else
|
||||
bash scripts/deploy.sh
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Готово! Откройте http://$(hostname -I | awk '{print $1}')"
|
||||
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Shop internet store (Docker Compose)
|
||||
Requires=docker.service
|
||||
After=docker.service network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
WorkingDirectory=/opt/shop
|
||||
ExecStart=/usr/bin/docker compose up -d --remove-orphans
|
||||
ExecStop=/usr/bin/docker compose down
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user