-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDockerfile
More file actions
160 lines (129 loc) · 4.94 KB
/
Dockerfile
File metadata and controls
160 lines (129 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Stage 1: Build frontend with Vite
FROM --platform=$BUILDPLATFORM node:20-bookworm-slim AS frontend-builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
WORKDIR /app/frontend
# Copy frontend package files
COPY frontend/package*.json ./
# Install frontend dependencies
RUN npm install --no-audit
# Copy frontend source
COPY frontend/ ./
# Build frontend
RUN npm run build
# Stage 2: Build backend TypeScript
FROM --platform=$BUILDPLATFORM node:20-bookworm-slim AS backend-builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
WORKDIR /app/backend
# Copy backend package files
COPY backend/package*.json ./
# Install backend dependencies
RUN npm install --no-audit
# Copy backend source
COPY backend/ ./
# Build backend
RUN npm run build
# Stage 2.5: Install backend production dependencies
# This runs on the target platform to ensure native modules (like sqlite3) are built correctly
FROM node:20-bookworm-slim AS backend-deps
WORKDIR /app/backend
COPY backend/package*.json ./
RUN npm install --omit=dev --no-audit
# Stage 3: Production image with Node.js and Bolt CLI
FROM ubuntu:24.04
ARG TARGETPLATFORM
ARG BUILDPLATFORM
# Add metadata labels
LABEL org.opencontainers.image.title="Pabawi"
LABEL org.opencontainers.image.description="Puppet Ansible Bolt Awesome Web Interface"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.vendor="example42"
LABEL org.opencontainers.image.source="https://github.com/example42/pabawi"
# Prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
# Set shell to bash with pipefail option
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Install Node.js, Puppet, and Bolt from upstream packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gnupg \
&& mkdir -p /etc/apt/keyrings \
# Add NodeSource repository for Node.js 20
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
# Add Puppet repository
&& curl -fsSL -o openvox8-release-ubuntu24.04.deb https://apt.voxpupuli.org/openvox8-release-ubuntu24.04.deb \
&& dpkg -i openvox8-release-ubuntu24.04.deb \
&& rm openvox8-release-ubuntu24.04.deb \
&& apt-get update && \
apt-get install -y --no-install-recommends \
nodejs \
openvox-agent \
bash \
openssh-client \
git \
coreutils \
ruby \
ruby-dev \
build-essential \
ansible \
openbolt \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Create non-root user
RUN groupadd -g 1001 pabawi && \
useradd -u 1001 -g pabawi -m -s /bin/bash pabawi
# Create application directory
WORKDIR /app
# Copy built backend
COPY --from=backend-builder --chown=pabawi:pabawi /app/backend/dist ./dist
COPY --from=backend-deps --chown=pabawi:pabawi /app/backend/node_modules ./node_modules
COPY --from=backend-builder --chown=pabawi:pabawi /app/backend/package*.json ./
# Copy only database migrations (not copied by TypeScript compiler)
# This avoids copying TypeScript sources into the runtime image
COPY --from=backend-builder --chown=pabawi:pabawi /app/backend/src/database/migrations ./dist/database/migrations
# Copy built frontend to public directory
COPY --from=frontend-builder --chown=pabawi:pabawi /app/frontend/dist ./public
# Create /opt/pabawi directory tree for all runtime data
RUN mkdir -p /opt/pabawi/data \
/opt/pabawi/bolt-project \
/opt/pabawi/control-repo \
/opt/pabawi/ansible \
/opt/pabawi/certs \
/opt/pabawi/ssh \
&& chown -R pabawi:pabawi /opt/pabawi
# Create entrypoint script to handle permissions
# Copy entrypoint script
COPY scripts/docker-entrypoint.sh /app/docker-entrypoint.sh
RUN sed -i 's/\r$//' /app/docker-entrypoint.sh && chmod +x /app/docker-entrypoint.sh
# Switch to non-root user
USER pabawi
ENTRYPOINT ["/app/docker-entrypoint.sh"]
# Expose port
EXPOSE 3000
# Set environment variables
ENV NODE_ENV=production \
PORT=3000 \
HOST=0.0.0.0 \
DATABASE_PATH=/opt/pabawi/data/pabawi.db \
BOLT_PROJECT_PATH=/opt/pabawi/bolt-project \
HIERA_CONTROL_REPO_PATH=/opt/pabawi/control-repo \
ANSIBLE_PROJECT_PATH=/opt/pabawi/ansible \
SSH_CONFIG_PATH=/opt/pabawi/ssh/config \
SSH_DEFAULT_KEY=/opt/pabawi/ssh/id_rsa \
# Integration settings (disabled by default)
PUPPETDB_ENABLED=false \
PUPPETSERVER_ENABLED=false \
HIERA_ENABLED=false \
ANSIBLE_ENABLED=false \
PROXMOX_ENABLED=false \
AWS_ENABLED=false \
SSH_ENABLED=false
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Start the application
CMD ["node", "dist/server.js"]