simplifying docker workflow
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
10
Dockerfile
10
Dockerfile
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user