🍦 Soft Serve Frontend

Browse your Git repositories

build-job.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: notes-app-source
  namespace: default
data:
  Dockerfile: |
    FROM python:3.11-slim
    
    WORKDIR /app
    
    # Copy requirements and install dependencies
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Copy application code
    COPY app.py .
    COPY templates/ templates/
    
    # Create data directory for persistent storage
    RUN mkdir -p /data
    
    # Expose port
    EXPOSE 5000
    
    # Set environment variable
    ENV NOTES_FILE=/data/notes.json
    
    # Run the application
    CMD ["python", "app.py"]
  
  requirements.txt: |
    Flask==3.0.0
    Werkzeug==3.0.1
  
  app.py: |
    from flask import Flask, render_template, request, redirect, url_for, jsonify
    import json
    import os
    from datetime import datetime

    app = Flask(__name__)

    # Store notes in a JSON file
    NOTES_FILE = os.environ.get('NOTES_FILE', '/data/notes.json')

    def load_notes():
        """Load notes from JSON file"""
        if os.path.exists(NOTES_FILE):
            try:
                with open(NOTES_FILE, 'r') as f:
                    return json.load(f)
            except:
                return []
        return []

    def save_notes(notes):
        """Save notes to JSON file"""
        os.makedirs(os.path.dirname(NOTES_FILE), exist_ok=True)
        with open(NOTES_FILE, 'w') as f:
            json.dump(notes, f, indent=2)

    @app.route('/')
    def index():
        """Display all notes"""
        notes = load_notes()
        return render_template('index.html', notes=notes)

    @app.route('/add', methods=['POST'])
    def add_note():
        """Add a new note"""
        title = request.form.get('title', '').strip()
        content = request.form.get('content', '').strip()
        
        if title and content:
            notes = load_notes()
            note = {
                'id': len(notes) + 1,
                'title': title,
                'content': content,
                'created_at': datetime.now().isoformat()
            }
            notes.append(note)
            save_notes(notes)
        
        return redirect(url_for('index'))

    @app.route('/delete/<int:note_id>', methods=['POST'])
    def delete_note(note_id):
        """Delete a note by ID"""
        notes = load_notes()
        notes = [n for n in notes if n['id'] != note_id]
        save_notes(notes)
        return redirect(url_for('index'))

    @app.route('/api/notes', methods=['GET'])
    def api_get_notes():
        """API endpoint to get all notes"""
        notes = load_notes()
        return jsonify(notes)

    @app.route('/api/notes', methods=['POST'])
    def api_add_note():
        """API endpoint to add a note"""
        data = request.get_json()
        title = data.get('title', '').strip()
        content = data.get('content', '').strip()
        
        if not title or not content:
            return jsonify({'error': 'Title and content are required'}), 400
        
        notes = load_notes()
        note = {
            'id': len(notes) + 1,
            'title': title,
            'content': content,
            'created_at': datetime.now().isoformat()
        }
        notes.append(note)
        save_notes(notes)
        
        return jsonify(note), 201

    @app.route('/health')
    def health():
        """Health check endpoint"""
        return jsonify({'status': 'healthy'}), 200

    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=False)

---
apiVersion: batch/v1
kind: Job
metadata:
  name: build-notes-app
  namespace: default
spec:
  template:
    spec:
      restartPolicy: Never
      dnsPolicy: Default
      dnsConfig:
        nameservers:
          - 8.8.8.8
          - 1.1.1.1
      nodeSelector:
        kubernetes.io/arch: arm64
      initContainers:
      - name: setup-source
        image: busybox:latest
        command:
        - sh
        - -c
        - |
          cp /source-config/* /workspace/
          mkdir -p /workspace/templates
          cp /source-config/index.html /workspace/templates/
        volumeMounts:
        - name: source
          mountPath: /source-config
        - name: workspace
          mountPath: /workspace
      containers:
      - name: kaniko
        image: gcr.io/kaniko-project/executor:latest
        args:
        - "--dockerfile=/workspace/Dockerfile"
        - "--context=/workspace"
        - "--destination=harbor.kratov.luiv.dev/luna_priv/notes:latest"
        - "--cache=true"
        volumeMounts:
        - name: workspace
          mountPath: /workspace
        - name: docker-config
          mountPath: /kaniko/.docker/
      volumes:
      - name: workspace
        emptyDir: {}
      - name: source
        configMap:
          name: notes-app-source
      - name: docker-config
        secret:
          secretName: harbor-registry-secret
          items:
          - key: .dockerconfigjson
            path: config.json