simplifying docker workflow

This commit is contained in:
2025-10-14 21:54:28 +03:00
parent 7c4c4fd620
commit 758a22f964
5 changed files with 49 additions and 10 deletions

View File

@@ -3,6 +3,9 @@ ADMIN_TOKEN=devadmintoken
# Docker host binding (used by docker compose for port mapping)
HOST=127.0.0.1
PORT=8080
# User and group for file ownership (should match system user on host)
UID=1000
GID=1000
# Optional: Service configuration (defaults shown)
DEPLOY_ROOT=/var/www/docs

View File

@@ -1,11 +1,16 @@
# Docker Compose Variables (used for port mapping)
# Copy this file to .env for docker-compose to use
# Copy this file to .env for docker compose to use
# The Go service always binds to 0.0.0.0:8080 inside the container
HOST=0.0.0.0
PORT=8080
# User and group for file ownership (MUST match system user on host)
UID=1000
GID=1000
# Required: Admin bearer token for API access
ADMIN_TOKEN=your-secure-admin-token-here # TODO: generate a secure token
ADMIN_TOKEN=your-secure-admin-token-here
# Optional: Service configuration (defaults shown)
DEPLOY_ROOT=/var/www/tingz-docs
RELEASE_ROOT=/var/www/tingz-deploys

View File

@@ -17,12 +17,16 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
FROM alpine:latest
RUN adduser -D -u 1000 deployer && \
chown -R deployer:deployer /tmp
ARG UID
ARG GID
RUN addgroup -g ${GID} -S tingz && \
adduser -u ${UID} -S -G tingz -s /sbin/nologin tingz && \
chown -R tingz:tingz /tmp
COPY --from=builder /bin/deployer /deployer
USER deployer
USER tingz
EXPOSE 8080

View File

@@ -1,14 +1,17 @@
services:
server:
build: .
container_name: tingz-server
restart: unless-stopped
env_file: .env.development
env_file: .env
build:
context: .
args:
UID: ${UID}
GID: ${GID}
volumes:
- ./data:/data
- ./docs:/var/www/docs
- ./deploys:/var/www/deploys
ports:
- "${HOST}:${PORT}:8080"
user: "1000:1000"
user: "${UID}:${GID}"
restart: unless-stopped

View File

@@ -68,6 +68,10 @@ func (m *Manager) Deploy(ctx context.Context, username, project string, r io.Rea
return "", fmt.Errorf("failed to extract tarball: %w", err)
}
if err := m.lockdownPermissions(releasePath); err != nil {
return "", fmt.Errorf("failed to set read-only permissions: %w", err)
}
deployPath := filepath.Join(m.deployRoot, username, project)
deployParentDir := filepath.Dir(deployPath)
if err := os.MkdirAll(deployParentDir, 0755); err != nil {
@@ -178,6 +182,26 @@ func validateTarPath(path string) error {
return nil
}
func (m *Manager) lockdownPermissions(root string) error {
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
if err := os.Chmod(path, 0550); err != nil {
return fmt.Errorf("failed to chmod directory %s: %w", path, err)
}
} else {
if err := os.Chmod(path, 0440); err != nil {
return fmt.Errorf("failed to chmod file %s: %w", path, err)
}
}
return nil
})
}
func (m *Manager) cleanupOldReleases(username, project string) error {
releasesDir := filepath.Join(m.releaseRoot, username, project)