Add production deployment: Dockerfile, docker-compose, deploy script
- Dockerfile: multi-stage build (golang:1.25-alpine → alpine:3.21), linux/amd64 - infra/mariadb: docker-compose + init SQL for reanimator DB/user - infra/reanimator: docker-compose for reanimator-api (Gitea registry) - deploy.sh: local build → push to git.mchus.pro → SSH deploy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
FROM golang:1.25-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o reanimator-api ./cmd/reanimator-api
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine:3.21
|
||||||
|
|
||||||
|
RUN apk add --no-cache tzdata ca-certificates
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /build/reanimator-api ./reanimator-api
|
||||||
|
COPY --from=builder /build/migrations ./migrations
|
||||||
|
|
||||||
|
EXPOSE 9999
|
||||||
|
|
||||||
|
ENTRYPOINT ["./reanimator-api"]
|
||||||
55
deploy.sh
Executable file
55
deploy.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
IMAGE="git.mchus.pro/reanimator/core"
|
||||||
|
TAG="${1:-latest}"
|
||||||
|
DEPLOY_DIR="/appdata/reanimator"
|
||||||
|
|
||||||
|
echo "Deploy target:"
|
||||||
|
echo " 1) local"
|
||||||
|
echo " 2) remote (SSH)"
|
||||||
|
read -rp "Choice [1/2]: " choice
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1)
|
||||||
|
TARGET="local"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
read -rp "SSH target (login@hostname): " SSH_TARGET
|
||||||
|
TARGET="ssh"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid choice" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "==> Building and pushing $IMAGE:$TAG (linux/amd64)..."
|
||||||
|
docker buildx build --platform linux/amd64 -t "$IMAGE:$TAG" --push .
|
||||||
|
|
||||||
|
if [ "$TARGET" = "local" ]; then
|
||||||
|
echo "==> Deploying locally..."
|
||||||
|
docker pull "$IMAGE:$TAG"
|
||||||
|
cd "$DEPLOY_DIR"
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d --remove-orphans
|
||||||
|
echo "-- Status:"
|
||||||
|
docker compose ps
|
||||||
|
echo "==> Done."
|
||||||
|
else
|
||||||
|
echo "==> Deploying on $SSH_TARGET..."
|
||||||
|
ssh "$SSH_TARGET" "
|
||||||
|
set -euo pipefail
|
||||||
|
echo '-- Pulling image...'
|
||||||
|
docker pull $IMAGE:$TAG
|
||||||
|
|
||||||
|
echo '-- Restarting container...'
|
||||||
|
cd $DEPLOY_DIR
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d --remove-orphans
|
||||||
|
|
||||||
|
echo '-- Status:'
|
||||||
|
docker compose ps
|
||||||
|
"
|
||||||
|
echo "==> Done."
|
||||||
|
fi
|
||||||
17
infra/mariadb/docker-compose.yml
Normal file
17
infra/mariadb/docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
services:
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:11.4
|
||||||
|
container_name: mariadb
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: /appdata/mariadb/mariadb.env
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- /appdata/mariadb/data:/var/lib/mysql
|
||||||
|
- /appdata/mariadb/init:/docker-entrypoint-initdb.d:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
9
infra/mariadb/init/01_reanimator.sql
Normal file
9
infra/mariadb/init/01_reanimator.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
CREATE DATABASE IF NOT EXISTS reanimator
|
||||||
|
CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
CREATE USER IF NOT EXISTS 'reanimator'@'%' IDENTIFIED BY 'REANIMATOR_PASSWORD_PLACEHOLDER';
|
||||||
|
|
||||||
|
GRANT ALL PRIVILEGES ON reanimator.* TO 'reanimator'@'%';
|
||||||
|
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
9
infra/mariadb/mariadb.env.example
Normal file
9
infra/mariadb/mariadb.env.example
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Скопировать на сервер: /appdata/mariadb/mariadb.env
|
||||||
|
# Заменить все значения на реальные
|
||||||
|
|
||||||
|
MARIADB_ROOT_PASSWORD=changeme_root
|
||||||
|
|
||||||
|
# Пользователь для reanimator (должен совпадать с паролем в init/01_reanimator.sql)
|
||||||
|
MARIADB_USER=reanimator
|
||||||
|
MARIADB_PASSWORD=changeme_reanimator
|
||||||
|
MARIADB_DATABASE=reanimator
|
||||||
16
infra/reanimator/docker-compose.yml
Normal file
16
infra/reanimator/docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
services:
|
||||||
|
reanimator-api:
|
||||||
|
image: git.mchus.pro/reanimator/core:latest
|
||||||
|
container_name: reanimator-api
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: /appdata/reanimator/reanimator.env
|
||||||
|
ports:
|
||||||
|
- "9999:9999"
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget -qO- http://localhost:9999/health || exit 1"]
|
||||||
|
interval: 15s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 20s
|
||||||
5
infra/reanimator/reanimator.env.example
Normal file
5
infra/reanimator/reanimator.env.example
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Скопировать на сервер: /appdata/reanimator/reanimator.env
|
||||||
|
|
||||||
|
HTTP_ADDR=:9999
|
||||||
|
DATABASE_DSN=reanimator:PASSWORD@tcp(host.docker.internal:3306)/reanimator?parseTime=true
|
||||||
|
MIGRATIONS_DIR=/app/migrations
|
||||||
Reference in New Issue
Block a user