DockerでMySQL、Caddyが利用されるよう変更したほか不具合を修正
This commit is contained in:
33
Caddyfile
Normal file
33
Caddyfile
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Caddyfile - Reverse Proxy Configuration
|
||||||
|
#
|
||||||
|
# 使用方法:
|
||||||
|
# 1. example.com を実際のドメインに置き換えてください
|
||||||
|
# 2. DNS の A レコードをこのサーバーの IP アドレスに向けてください
|
||||||
|
# 3. docker compose up -d で起動すると、自動的に HTTPS 証明書が取得されます
|
||||||
|
#
|
||||||
|
# ローカル開発用の場合は、以下のように変更してください
|
||||||
|
# :80 {
|
||||||
|
# reverse_proxy app:8080
|
||||||
|
# }
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
reverse_proxy app:8080
|
||||||
|
|
||||||
|
# ログ設定
|
||||||
|
log {
|
||||||
|
output file /data/access.log
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
|
||||||
|
# セキュリティヘッダー
|
||||||
|
header {
|
||||||
|
X-Content-Type-Options nosniff
|
||||||
|
X-Frame-Options DENY
|
||||||
|
X-XSS-Protection "1; mode=block"
|
||||||
|
Referrer-Policy strict-origin-when-cross-origin
|
||||||
|
-Server
|
||||||
|
}
|
||||||
|
|
||||||
|
# gzip 圧縮
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
33
Dockerfile
33
Dockerfile
@@ -1,12 +1,8 @@
|
|||||||
# Builder stage
|
# Builder stage
|
||||||
FROM golang:1.24-alpine AS builder
|
FROM golang:1.24-trixie AS builder
|
||||||
|
|
||||||
# Set working directory
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install git if needed for fetching dependencies (sometimes needed even with go modules)
|
|
||||||
# RUN apk add --no-cache git
|
|
||||||
|
|
||||||
# Copy go mod and sum files
|
# Copy go mod and sum files
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
@@ -21,12 +17,18 @@ COPY . .
|
|||||||
RUN CGO_ENABLED=0 go build -o server ./cmd/server/main.go
|
RUN CGO_ENABLED=0 go build -o server ./cmd/server/main.go
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM alpine:latest
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
# Install runtime dependencies
|
# Install runtime dependencies
|
||||||
RUN apk add --no-cache ca-certificates tzdata
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
tzdata \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN useradd -r -u 1000 -s /bin/false appuser
|
||||||
|
|
||||||
# Set working directory
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy binary from builder
|
# Copy binary from builder
|
||||||
@@ -35,8 +37,21 @@ COPY --from=builder /app/server .
|
|||||||
# Copy web assets (templates, static files)
|
# Copy web assets (templates, static files)
|
||||||
COPY --from=builder /app/web ./web
|
COPY --from=builder /app/web ./web
|
||||||
|
|
||||||
# Expose port (adjust if your app uses a different port)
|
# Create data directory for SQLite
|
||||||
|
RUN mkdir -p /app/data && chown -R appuser:appuser /app
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Expose port
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Volume for persistent data
|
||||||
|
VOLUME ["/app/data"]
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8080/ || exit 1
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
ENTRYPOINT ["./server"]
|
ENTRYPOINT ["./server"]
|
||||||
|
|||||||
34
config.ini.docker.example
Normal file
34
config.ini.docker.example
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
; Homework Manager 設定ファイル (Docker用)
|
||||||
|
; docker-compose.yml と一緒に使用してください
|
||||||
|
; ローカル実行する場合securityセクションのhttpsをfalseに変更するのを忘れないでください!!
|
||||||
|
|
||||||
|
[server]
|
||||||
|
port = 8080
|
||||||
|
debug = false
|
||||||
|
|
||||||
|
[database]
|
||||||
|
driver = mysql
|
||||||
|
host = db
|
||||||
|
port = 3306
|
||||||
|
user = homework
|
||||||
|
password = homework_password
|
||||||
|
name = homework_manager
|
||||||
|
|
||||||
|
[session]
|
||||||
|
; 本番環境では必ず変更してください
|
||||||
|
secret = CHANGE_THIS_TO_A_SECURE_RANDOM_STRING
|
||||||
|
|
||||||
|
[auth]
|
||||||
|
allow_registration = true
|
||||||
|
|
||||||
|
[security]
|
||||||
|
https = true
|
||||||
|
; こちらも本番環境では必ず変更してください
|
||||||
|
csrf_secret = CHANGE_THIS_TO_A_SECURE_RANDOM_STRING
|
||||||
|
rate_limit_enabled = true
|
||||||
|
rate_limit_requests = 100
|
||||||
|
rate_limit_window = 60
|
||||||
|
trusted_proxies = 172.16.0.0/12
|
||||||
|
|
||||||
|
[notification]
|
||||||
|
telegram_bot_token =
|
||||||
@@ -1,11 +1,64 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build: .
|
build: .
|
||||||
ports:
|
container_name: homework-manager
|
||||||
- "8080:8080"
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./homework.db:/app/homework.db
|
- ./config.ini:/app/config.ini:ro
|
||||||
- ./config.ini:/app/config.ini
|
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Tokyo
|
- TZ=Asia/Tokyo
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
expose:
|
||||||
|
- "8080"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: homework-db
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
|
||||||
|
MYSQL_DATABASE: ${MYSQL_DATABASE:-homework_manager}
|
||||||
|
MYSQL_USER: ${MYSQL_USER:-homework}
|
||||||
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-homework_password}
|
||||||
|
TZ: Asia/Tokyo
|
||||||
|
volumes:
|
||||||
|
- db-data:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-rootpassword}" ]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: caddy:2-alpine
|
||||||
|
container_name: homework-caddy
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
- caddy-data:/data
|
||||||
|
- caddy-config:/config
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Tokyo
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db-data:
|
||||||
|
caddy-data:
|
||||||
|
caddy-config:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type APIKey struct {
|
|||||||
ID uint `gorm:"primarykey" json:"id"`
|
ID uint `gorm:"primarykey" json:"id"`
|
||||||
UserID uint `gorm:"not null;index" json:"user_id"`
|
UserID uint `gorm:"not null;index" json:"user_id"`
|
||||||
Name string `gorm:"not null" json:"name"`
|
Name string `gorm:"not null" json:"name"`
|
||||||
KeyHash string `gorm:"not null;uniqueIndex" json:"-"`
|
KeyHash string `gorm:"not null;uniqueIndex;size:255" json:"-"`
|
||||||
LastUsed *time.Time `json:"last_used,omitempty"`
|
LastUsed *time.Time `json:"last_used,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
ID uint `gorm:"primarykey" json:"id"`
|
||||||
Email string `gorm:"uniqueIndex;not null" json:"email"`
|
Email string `gorm:"uniqueIndex;not null;size:255" json:"email"`
|
||||||
PasswordHash string `gorm:"not null" json:"-"`
|
PasswordHash string `gorm:"not null" json:"-"`
|
||||||
Name string `gorm:"not null" json:"name"`
|
Name string `gorm:"not null" json:"name"`
|
||||||
Role string `gorm:"not null;default:user" json:"role"` // "admin" or "user"
|
Role string `gorm:"not null;default:user" json:"role"` // "admin" or "user"
|
||||||
|
|||||||
Reference in New Issue
Block a user