Security improvements for prod #1
Some checks failed
CI/CD Pipeline with Secure Ephemeral PiP / test-backend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / test-frontend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / build-backend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / build-frontend (push) Has been cancelled
Some checks failed
CI/CD Pipeline with Secure Ephemeral PiP / test-backend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / test-frontend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / build-backend (push) Has been cancelled
CI/CD Pipeline with Secure Ephemeral PiP / build-frontend (push) Has been cancelled
This commit is contained in:
parent
411d9f3f35
commit
18b88d6128
2 changed files with 33 additions and 11 deletions
|
@ -2010,6 +2010,13 @@ The `prod-pod.yml` file is specifically designed for production deployment and u
|
||||||
- **Persistent storage**: PostgreSQL data is stored in a named volume for persistence
|
- **Persistent storage**: PostgreSQL data is stored in a named volume for persistence
|
||||||
- **Environment variables**: Uses environment variables for configuration (set by the CI/CD workflow)
|
- **Environment variables**: Uses environment variables for configuration (set by the CI/CD workflow)
|
||||||
|
|
||||||
|
**Security Enhancements**:
|
||||||
|
- **Rootless operation**: All containers run as non-root user (UID/GID 1000)
|
||||||
|
- **Read-only filesystems**: Containers have read-only root filesystems with writable volumes only for data
|
||||||
|
- **Dropped capabilities**: All Linux capabilities are dropped for maximum security
|
||||||
|
- **No privilege escalation**: Containers cannot escalate privileges
|
||||||
|
- **Simplified configuration**: No external configmaps - all configuration is inline for easier management
|
||||||
|
|
||||||
**Service Architecture**:
|
**Service Architecture**:
|
||||||
1. **PostgreSQL**: Database with health checks and persistent storage
|
1. **PostgreSQL**: Database with health checks and persistent storage
|
||||||
2. **Backend**: Rust API service that waits for PostgreSQL to be healthy
|
2. **Backend**: Rust API service that waits for PostgreSQL to be healthy
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: prod-pod
|
name: sharenet-production-pod
|
||||||
labels:
|
labels:
|
||||||
app: sharenet-production
|
app: sharenet-production
|
||||||
annotations:
|
annotations:
|
||||||
io.containers.no-new-privileges: "true"
|
io.containers.no-new-privileges: "true"
|
||||||
spec:
|
spec:
|
||||||
hostname: prod-pod
|
hostname: sharenet-production-pod
|
||||||
# Security: run as non-root user with specific UID/GID
|
# Security: run as non-root user with specific UID/GID (matches PROD_SERVICE_USER)
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
runAsUser: 1000
|
runAsUser: 1000
|
||||||
|
@ -17,13 +17,20 @@ spec:
|
||||||
|
|
||||||
containers:
|
containers:
|
||||||
- name: postgres
|
- name: postgres
|
||||||
image: localhost/postgres:deployed
|
image: ${REGISTRY_HOST}/${APP_NAME}/postgres:${IMAGE_TAG}
|
||||||
# Security: drop all capabilities, read-only root filesystem except data volume
|
# Security: drop all capabilities, read-only root filesystem except data volume
|
||||||
securityContext:
|
securityContext:
|
||||||
readOnlyRootFilesystem: true
|
readOnlyRootFilesystem: true
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
capabilities:
|
capabilities:
|
||||||
drop: ["ALL"]
|
drop: ["ALL"]
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: sharenet
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: sharenet
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
envFrom:
|
envFrom:
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: postgres-secrets
|
name: postgres-secrets
|
||||||
|
@ -58,13 +65,18 @@ spec:
|
||||||
cpu: "500m"
|
cpu: "500m"
|
||||||
|
|
||||||
- name: backend
|
- name: backend
|
||||||
image: localhost/backend:deployed
|
image: ${REGISTRY_HOST}/${APP_NAME}/backend:${IMAGE_TAG}
|
||||||
# Security: drop all capabilities, read-only root filesystem
|
# Security: drop all capabilities, read-only root filesystem
|
||||||
securityContext:
|
securityContext:
|
||||||
readOnlyRootFilesystem: true
|
readOnlyRootFilesystem: true
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
capabilities:
|
capabilities:
|
||||||
drop: ["ALL"]
|
drop: ["ALL"]
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
value: postgres://sharenet:${POSTGRES_PASSWORD}@localhost:5432/sharenet
|
||||||
|
- name: PORT
|
||||||
|
value: "3001"
|
||||||
envFrom:
|
envFrom:
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: backend-secrets
|
name: backend-secrets
|
||||||
|
@ -99,13 +111,18 @@ spec:
|
||||||
cpu: "250m"
|
cpu: "250m"
|
||||||
|
|
||||||
- name: frontend
|
- name: frontend
|
||||||
image: localhost/frontend:deployed
|
image: ${REGISTRY_HOST}/${APP_NAME}/frontend:${IMAGE_TAG}
|
||||||
# Security: drop all capabilities, read-only root filesystem
|
# Security: drop all capabilities, read-only root filesystem
|
||||||
securityContext:
|
securityContext:
|
||||||
readOnlyRootFilesystem: true
|
readOnlyRootFilesystem: true
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
capabilities:
|
capabilities:
|
||||||
drop: ["ALL"]
|
drop: ["ALL"]
|
||||||
|
env:
|
||||||
|
- name: NEXT_PUBLIC_API_URL
|
||||||
|
value: http://localhost:3001
|
||||||
|
- name: PORT
|
||||||
|
value: "3000"
|
||||||
envFrom:
|
envFrom:
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: frontend-secrets
|
name: frontend-secrets
|
||||||
|
@ -122,7 +139,7 @@ spec:
|
||||||
cpu: "250m"
|
cpu: "250m"
|
||||||
|
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: localhost/nginx:deployed
|
image: ${REGISTRY_HOST}/${APP_NAME}/nginx:${IMAGE_TAG}
|
||||||
# Security: drop all capabilities, read-only root filesystem
|
# Security: drop all capabilities, read-only root filesystem
|
||||||
securityContext:
|
securityContext:
|
||||||
readOnlyRootFilesystem: true
|
readOnlyRootFilesystem: true
|
||||||
|
@ -132,10 +149,8 @@ spec:
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
hostPort: 80
|
|
||||||
- containerPort: 443
|
- containerPort: 443
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
hostPort: 443
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: nginx-conf
|
- name: nginx-conf
|
||||||
mountPath: /etc/nginx/nginx.conf
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
@ -170,7 +185,7 @@ spec:
|
||||||
- name: pgdata
|
- name: pgdata
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /opt/sharenet/volumes/pgdata
|
path: /opt/sharenet/volumes/pgdata
|
||||||
type: Directory
|
type: DirectoryOrCreate
|
||||||
- name: nginx-conf
|
- name: nginx-conf
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /opt/sharenet/nginx
|
path: /opt/sharenet/nginx
|
||||||
|
@ -178,7 +193,7 @@ spec:
|
||||||
- name: nginx-cache
|
- name: nginx-cache
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /opt/sharenet/volumes/nginx-cache
|
path: /opt/sharenet/volumes/nginx-cache
|
||||||
type: Directory
|
type: DirectoryOrCreate
|
||||||
- name: letsencrypt
|
- name: letsencrypt
|
||||||
hostPath:
|
hostPath:
|
||||||
path: /etc/letsencrypt
|
path: /etc/letsencrypt
|
||||||
|
|
Loading…
Add table
Reference in a new issue