Harden app and registry workloads
This commit is contained in:
parent
f7e3065cda
commit
16069b7950
|
|
@ -24,9 +24,21 @@ spec:
|
|||
operator: In
|
||||
values:
|
||||
- debian
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
containers:
|
||||
- name: registry
|
||||
image: registry:2
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
name: http
|
||||
|
|
@ -51,10 +63,14 @@ spec:
|
|||
volumeMounts:
|
||||
- name: registry-vol
|
||||
mountPath: /var/lib/registry
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: registry-vol
|
||||
persistentVolumeClaim:
|
||||
claimName: registry-pvc
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ FROM nginx:1.27-alpine
|
|||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY public/ /usr/share/nginx/html/
|
||||
|
||||
EXPOSE 80
|
||||
USER nginx
|
||||
|
||||
EXPOSE 8080
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen 8080;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
|
|
|||
|
|
@ -17,12 +17,24 @@ spec:
|
|||
spec:
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: raspberry
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
fsGroup: 101
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
containers:
|
||||
- name: demos-static
|
||||
image: 192.168.100.68:30500/demos-static:latest
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
|
|
@ -42,6 +54,20 @@ spec:
|
|||
memory: 32Mi
|
||||
limits:
|
||||
memory: 128Mi
|
||||
volumeMounts:
|
||||
- name: nginx-cache
|
||||
mountPath: /var/cache/nginx
|
||||
- name: nginx-run
|
||||
mountPath: /var/run
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: nginx-cache
|
||||
emptyDir: {}
|
||||
- name: nginx-run
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
@ -53,7 +79,7 @@ spec:
|
|||
externalTrafficPolicy: Local
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
targetPort: http
|
||||
nodePort: 30081
|
||||
selector:
|
||||
app: demos-static
|
||||
|
|
|
|||
|
|
@ -17,7 +17,15 @@ RUN ln -sf /usr/bin/php82 /usr/bin/php
|
|||
# Alpine keeps Apache site configs here instead of a2enmod
|
||||
RUN sed -i 's/#LoadModule rewrite_module/LoadModule rewrite_module/' /etc/apache2/httpd.conf && \
|
||||
sed -i 's/#LoadModule headers_module/LoadModule headers_module/' /etc/apache2/httpd.conf && \
|
||||
sed -i 's/DirectoryIndex index.html/DirectoryIndex index.php index.html/' /etc/apache2/httpd.conf
|
||||
sed -i 's/DirectoryIndex index.html/DirectoryIndex index.php index.html/' /etc/apache2/httpd.conf && \
|
||||
sed -i 's/^Listen 80$/Listen 8080/' /etc/apache2/httpd.conf && \
|
||||
sed -i 's#^ErrorLog .*#ErrorLog /proc/self/fd/2#' /etc/apache2/httpd.conf && \
|
||||
sed -i 's#^CustomLog .*#CustomLog /proc/self/fd/1 combined#' /etc/apache2/httpd.conf && \
|
||||
if grep -q '^PidFile ' /etc/apache2/httpd.conf; then \
|
||||
sed -i 's#^PidFile .*#PidFile /tmp/httpd.pid#' /etc/apache2/httpd.conf; \
|
||||
else \
|
||||
printf '\nPidFile /tmp/httpd.pid\n' >> /etc/apache2/httpd.conf; \
|
||||
fi
|
||||
|
||||
# Copy files directly into Alpine's default web root
|
||||
COPY . /var/www/localhost/htdocs/
|
||||
|
|
@ -31,9 +39,15 @@ RUN mkdir -p /var/www/localhost/htdocs/db && \
|
|||
|
||||
# Match local user permissions for the runtime user (Alpine uses 'apache' instead of 'www-data')
|
||||
RUN usermod -u 1000 apache && \
|
||||
groupmod -g 1000 apache
|
||||
groupmod -g 1000 apache && \
|
||||
mkdir -p /run/apache2 /var/log/apache2 /tmp/website-lang && \
|
||||
chown -R apache:apache /run/apache2 /var/log/apache2 /tmp/website-lang /var/www/localhost/htdocs/db
|
||||
|
||||
EXPOSE 80
|
||||
ENV WEBSITE_LANG_WRITE_DIR=/tmp/website-lang
|
||||
|
||||
USER apache
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Start Apache in the foreground
|
||||
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
|
||||
|
|
|
|||
|
|
@ -3,10 +3,17 @@
|
|||
// Include this at the top of every page.
|
||||
// Provides: $lang, $text, $en, $availableLangs
|
||||
|
||||
$availableLangs = array_map(
|
||||
$staticLangDir = __DIR__ . '/lang';
|
||||
$runtimeLangDir = getenv('WEBSITE_LANG_WRITE_DIR') ?: null;
|
||||
$langFiles = glob($staticLangDir . '/*.php') ?: [];
|
||||
if ($runtimeLangDir && is_dir($runtimeLangDir)) {
|
||||
$langFiles = array_merge($langFiles, glob($runtimeLangDir . '/*.php') ?: []);
|
||||
}
|
||||
|
||||
$availableLangs = array_values(array_unique(array_map(
|
||||
fn($f) => basename($f, '.php'),
|
||||
glob(__DIR__ . '/lang/*.php')
|
||||
);
|
||||
$langFiles
|
||||
)));
|
||||
|
||||
function getLang($supported) {
|
||||
if (isset($_GET['lang']) && in_array($_GET['lang'], $supported)) {
|
||||
|
|
@ -18,12 +25,15 @@ function getLang($supported) {
|
|||
|
||||
$lang = getLang($availableLangs);
|
||||
|
||||
$file = __DIR__ . "/lang/$lang.php";
|
||||
$file = $runtimeLangDir ? "$runtimeLangDir/$lang.php" : '';
|
||||
if (!$file || !file_exists($file)) {
|
||||
$file = "$staticLangDir/$lang.php";
|
||||
}
|
||||
if (!file_exists($file)) {
|
||||
$lang = 'nah';
|
||||
$file = __DIR__ . "/lang/nah.php";
|
||||
$file = "$staticLangDir/nah.php";
|
||||
}
|
||||
|
||||
// Always load English as translation source
|
||||
$en = include __DIR__ . '/lang/en.php';
|
||||
$en = include "$staticLangDir/en.php";
|
||||
$text = array_replace($en, include $file);
|
||||
|
|
|
|||
|
|
@ -48,11 +48,18 @@ foreach ($base as $key => $value) {
|
|||
$lines[] = "];";
|
||||
$content = implode("\n", $lines) . "\n";
|
||||
|
||||
$path = __DIR__ . "/lang/$lang.php";
|
||||
if (file_put_contents($path, $content) === false) {
|
||||
$langDir = getenv('WEBSITE_LANG_WRITE_DIR') ?: (__DIR__ . '/lang');
|
||||
if (!is_dir($langDir) && !mkdir($langDir, 0755, true)) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Could not write file — check permissions on lang/']);
|
||||
echo json_encode(['error' => 'Could not create language directory']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'lang' => $lang, 'path' => "lang/$lang.php"]);
|
||||
$path = "$langDir/$lang.php";
|
||||
if (file_put_contents($path, $content) === false) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Could not write language file']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'lang' => $lang]);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ spec:
|
|||
spec:
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: raspberry
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution: # requiredDuringSchedulingIgnoredDuringExecution:
|
||||
|
|
@ -38,8 +44,17 @@ spec:
|
|||
- name: php-app
|
||||
image: 192.168.100.68:30500/php-website:latest
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
env:
|
||||
- name: WEBSITE_LANG_WRITE_DIR
|
||||
value: /tmp/website-lang
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
|
|
@ -59,6 +74,24 @@ spec:
|
|||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
volumeMounts:
|
||||
- name: apache-run
|
||||
mountPath: /run/apache2
|
||||
- name: apache-logs
|
||||
mountPath: /var/log/apache2
|
||||
- name: website-db
|
||||
mountPath: /var/www/localhost/htdocs/db
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: apache-run
|
||||
emptyDir: {}
|
||||
- name: apache-logs
|
||||
emptyDir: {}
|
||||
- name: website-db
|
||||
emptyDir: {}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
@ -70,7 +103,7 @@ spec:
|
|||
externalTrafficPolicy: Local
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
targetPort: http
|
||||
nodePort: 30080
|
||||
selector:
|
||||
app: php-website
|
||||
|
|
|
|||
Loading…
Reference in New Issue