Add devpi auto-initialization with startup script

- Startup script checks for initialization and runs devpi-init if needed
- Root password passed via DEVPI_ROOT_PASSWORD env var from secret
- Secret template references 1Password vault item
- Updated README with setup instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-01-20 11:19:37 -08:00
commit 8e9ab46335
5 changed files with 78 additions and 35 deletions

View file

@ -6,14 +6,14 @@ RUN pip install --no-cache-dir devpi-server devpi-web
# Create non-root user
RUN useradd -r -u 1000 devpi && mkdir -p /devpi && chown devpi:devpi /devpi
# Add startup script
COPY --chown=devpi:devpi start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
USER devpi
WORKDIR /devpi
# Expose default port
EXPOSE 3141
# Use ENTRYPOINT for flexibility
ENTRYPOINT ["devpi-server"]
# Default args (can be overridden)
CMD ["--serverdir", "/devpi", "--host", "0.0.0.0", "--port", "3141"]
ENTRYPOINT ["/usr/local/bin/start.sh"]

View file

@ -6,36 +6,33 @@ devpi-server running in Kubernetes, providing:
## Setup
### 1. Deploy via ArgoCD
### 1. Create the root password secret
```bash
```fish
kubectl create namespace devpi
op inject -i argocd/manifests/devpi/secret-root.yaml.tpl | kubectl apply -f -
```
### 2. Deploy via ArgoCD
```fish
argocd app sync apps
argocd app sync devpi
```
### 2. Initialize devpi (first time only)
The container will auto-initialize on first startup using the root password from the secret.
After the StatefulSet is running, initialize devpi with a root password:
### 3. Create user and index (first time only)
```bash
# Get the root password from 1Password
ROOT_PASSWORD=$(op --vault blumeops item get <item-id> --fields password --reveal)
After the pod is running:
# Initialize devpi
kubectl -n devpi exec -it devpi-0 -- devpi-init --serverdir /devpi --root-passwd "$ROOT_PASSWORD"
# Restart the pod to pick up the initialized state
kubectl -n devpi rollout restart statefulset devpi
```
### 3. Create user and index
```bash
# Login to devpi
```fish
# Login to devpi as root
uvx devpi use https://pypi.tail8d86e.ts.net
uvx devpi login root
# Enter root password when prompted
# Create user
# Create eblume user (prompts for password - use the one from 1Password)
uvx devpi user -c eblume email=blume.erich@gmail.com
# Create private index inheriting from PyPI
@ -56,8 +53,7 @@ trusted-host = pypi.tail8d86e.ts.net
### Upload private packages
```bash
# Build and publish
```fish
cd ~/code/personal/your-package
uv build
uv publish --publish-url https://pypi.tail8d86e.ts.net/eblume/dev/
@ -68,3 +64,9 @@ uv publish --publish-url https://pypi.tail8d86e.ts.net/eblume/dev/
- Web UI: https://pypi.tail8d86e.ts.net
- PyPI cache: https://pypi.tail8d86e.ts.net/root/pypi/+simple/
- Private index: https://pypi.tail8d86e.ts.net/eblume/dev/+simple/
## Credentials
Stored in 1Password vault `blumeops`, item `kyhzfifryqnuk7jeyibmmjvxxm`:
- `root password` - devpi root user
- `password` - eblume user password

View file

@ -0,0 +1,12 @@
# Template for devpi root password secret
# Create the secret before deploying:
# kubectl create namespace devpi
# op inject -i argocd/manifests/devpi/secret-root.yaml.tpl | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: devpi-root
namespace: devpi
type: Opaque
stringData:
password: "{{ op://vg6xf6vvfmoh5hqjjhlhbeoaie/kyhzfifryqnuk7jeyibmmjvxxm/root password }}"

View file

@ -0,0 +1,30 @@
#!/bin/bash
set -e
SERVERDIR="${DEVPI_SERVERDIR:-/devpi}"
HOST="${DEVPI_HOST:-0.0.0.0}"
PORT="${DEVPI_PORT:-3141}"
OUTSIDE_URL="${DEVPI_OUTSIDE_URL:-}"
# Check if devpi is initialized
if [ ! -f "$SERVERDIR/.serverversion" ]; then
echo "Initializing devpi server..."
if [ -z "$DEVPI_ROOT_PASSWORD" ]; then
echo "ERROR: DEVPI_ROOT_PASSWORD environment variable must be set for initialization"
exit 1
fi
devpi-init --serverdir "$SERVERDIR" --root-passwd "$DEVPI_ROOT_PASSWORD"
echo "Devpi initialized successfully"
fi
# Build command
CMD="devpi-server --serverdir $SERVERDIR --host $HOST --port $PORT"
if [ -n "$OUTSIDE_URL" ]; then
CMD="$CMD --outside-url $OUTSIDE_URL"
fi
echo "Starting devpi-server..."
exec $CMD

View file

@ -19,15 +19,14 @@ spec:
containers:
- name: devpi
image: registry.tail8d86e.ts.net/blumeops/devpi:latest
args:
- "--serverdir"
- "/devpi"
- "--host"
- "0.0.0.0"
- "--port"
- "3141"
- "--outside-url"
- "https://pypi.tail8d86e.ts.net"
env:
- name: DEVPI_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: devpi-root
key: password
- name: DEVPI_OUTSIDE_URL
value: "https://pypi.tail8d86e.ts.net"
ports:
- containerPort: 3141
name: http