Compare commits

...

4 Commits

Author SHA1 Message Date
Paul Payne
351f58b80d Update docs for adding apps. 2025-10-22 22:36:53 +00:00
Paul Payne
458e70b7be mysql connection improvement. 2025-10-18 19:01:37 +00:00
Paul Payne
f68ff43879 Updates documentation. 2025-10-18 18:57:35 +00:00
Paul Payne
47c23d3f1b Updates mysql to not use bitnami. 2025-10-18 18:57:22 +00:00
7 changed files with 535 additions and 488 deletions

View File

@@ -1,16 +1,22 @@
# Adding custom apps # Adding Wild Cloud Apps
Custom apps can be added to your Wild Cloud apps directory. This guide is for contributors and maintainers who want to create or modify Wild Cloud apps. If you're looking to use existing apps, see [README.md](README.md).
Custom apps can be deployed using Wild Cloud scripts. Wild Cloud apps follow a specific structure and naming convention to ensure compatibility with the Wild Cloud ecosystem. ## Overview
## App Structure Wild Cloud apps are Kubernetes applications packaged as Kustomize configurations with standardized conventions for configuration management, secrets handling, and deployment.
Each subdirectory in this directory represents a Wild Cloud app. Each app directory contains an "app manifest" (`manifest.yaml`), a "kustomization" (`kustomization.yaml`), and one or more "configurations" (yaml files containing definitions/configurations of Kubernetes objects/resources). ## Required Files
### App Manifest Each app directory must contain:
The required `manifest.yaml` file contains metadata about the app. 1. **`manifest.yaml`** - App metadata and configuration schema
2. **`kustomization.yaml`** - Kustomize configuration with Wild Cloud labels
3. **Resource files** - Kubernetes manifests (deployments, services, ingresses, etc.)
### App Manifest (`manifest.yaml`)
The manifest defines the app's metadata, dependencies, configuration schema, and secret requirements.
This is the contents of an example `manifest.yaml` file for an app named "immich": This is the contents of an example `manifest.yaml` file for an app named "immich":
@@ -39,21 +45,23 @@ requiredSecrets:
- apps.postgres.password - apps.postgres.password
``` ```
Explanation of the fields: #### Manifest Fields
- `name`: The name of the app, used for identification. | Field | Required | Description |
- `description`: A brief description of the app. |-------|----------|-------------|
- `version`: The version of the app. This should generally follow the versioning scheme of the app itself. | `name` | Yes | App identifier (must match directory name) |
- `icon`: A URL to an icon representing the app. | `description` | Yes | Brief app description shown in listings |
- `requires`: A list of other apps that this app depends on. Each entry should be the name of another app. | `version` | Yes | App version (follow upstream versioning) |
- `defaultConfig`: A set of default configuration values for the app. When an app is added using `wild-app-add`, these values will be added to the Wild Cloud `config.yaml` file. | `icon` | No | URL to app icon for UI display |
- `requiredSecrets`: A list of secrets that must be set in the Wild Cloud `secrets.yaml` file for the app to function properly. These secrets are typically sensitive information like database passwords or API keys. Keys with random values will be generated automatically when the app is added. | `requires` | No | List of dependency apps (e.g., `postgres`, `redis`) |
| `defaultConfig` | Yes | Default configuration values merged into operator's `config.yaml` |
| `requiredSecrets` | No | List of secrets in dotted-path format (e.g., `apps.appname.dbPassword`) |
### Kustomization **Important:** All configuration keys referenced in templates (via `{{ .apps.appname.key }}`) must be defined in `defaultConfig` or be standard Wild Cloud variables.
Each app directory should also contain a `kustomization.yaml` file. This file defines how the app's Kubernetes resources are built and deployed. It can include references to other Kustomize files, patches, and configurations. ### Kustomization (`kustomization.yaml`)
Here is an example `kustomization.yaml` file for the "immich" app: The kustomization file defines how Kubernetes resources are built and applies Wild Cloud's standard labels.
```yaml ```yaml
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
@@ -74,105 +82,108 @@ resources:
- pvc.yaml - pvc.yaml
- service.yaml - service.yaml
- db-init-job.yaml - db-init-job.yaml
``` ```
Kustomization requirements: #### Kustomization Requirements
- Every Wild Cloud kustomization should include the Wild Cloud labels in its `kustomization.yaml` file. This allows the Wild Cloud to identify and manage the app correctly. The labels should be defined under the `labels` key, as shown in the example above. - **Namespace**: Must match the app name
- The `app` label and `namespace` keys should the app's name/directory. - **Labels**: Must include standard Wild Cloud labels with `includeSelectors: true`
- **Resources**: List all Kubernetes manifest files
#### Standard Wild Cloud Labels #### Labeling Strategy
Wild Cloud uses a consistent labeling strategy across all apps: Wild Cloud uses Kustomize's `includeSelectors: true` feature to automatically apply standard labels to all resources AND their selectors:
```yaml ```yaml
labels: labels:
- includeSelectors: true - includeSelectors: true
pairs: pairs:
app: myapp # The app name (matches directory) app: myapp # App name (matches directory)
managedBy: kustomize # Managed by Kustomize
partOf: wild-cloud # Part of Wild Cloud ecosystem
```
The `includeSelectors: true` setting automatically applies these labels to all resources AND their selectors, which means:
1. **Resource labels** - All resources get the standard Wild Cloud labels
2. **Selector labels** - All selectors automatically include these labels for robust selection
This allows individual resources to use simple, component-specific selectors:
```yaml
selector:
matchLabels:
component: web
```
Which Kustomize automatically expands to:
```yaml
selector:
matchLabels:
app: myapp
component: web
managedBy: kustomize managedBy: kustomize
partOf: wild-cloud partOf: wild-cloud
``` ```
### Configuration Files This means individual resources can use simple, component-specific selectors like `component: web`, and Kustomize will automatically expand them to include all Wild Cloud labels.
Wild Cloud apps use Kustomize as kustomize files are simple, transparent, and easier to manage in a Git repository. **Do NOT use Helm-style labels** (`app.kubernetes.io/name`, `app.kubernetes.io/instance`). Use simple component labels (`component: web`, `component: worker`, etc.) instead.
#### Templates ## Configuration Templates
For operators, Wild Cloud apps use standard configuration files. This makes modifying the app's configuration straightforward, as operators can customize their app files as needed. They can choose to manage modifications and updates directly on the configuration files using `git` tools, or they can use Kustomize patches or overlays. As a convenience for operators, when adding an app (using `wild-app-add`), the app's configurations will be compiled with the operator's Wild Cloud configuration and secrets. This results in standard Kustomize files being placed in the Wild Cloud home directory, which can then be modified as needed. This means the configuration files in this repository are actually templates, but they will be compiled into standard Kustomize files when the app is added to an operator's Wild Cloud home directory. ### Gomplate Templating
To reference operator configuration in the configuration files, use gomplate variables, such as `{{ .cloud.domain }}` for the domain name. All configuration variables you use need to exist in the operator's `config.yaml`, so they should be either standard Wild Cloud operator variables, or be defined in the app's `manifest.yaml` under `defaultConfig`. Resource files in this repository are **templates** that get compiled when users add apps via the web app, CLI, or API. Use gomplate syntax to reference configuration:
When `wild-app-add` is run, the app's Kustomize files will be compiled with the operator's Wild Cloud configuration and secrets resulting in standard Kustomize files being placed in the Wild Cloud home directory.
#### External DNS Configuration
Wild Cloud apps use external-dns annotations in their ingress resources to automatically manage DNS records:
- `external-dns.alpha.kubernetes.io/target: {{ .cloud.domain }}` - Creates a CNAME record pointing the app subdomain to the main cluster domain (e.g., `ghost.cloud.payne.io``cloud.payne.io`)
- `external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"` - Disables Cloudflare proxy for direct DNS resolution
#### Database Initialization Jobs
Apps that rely on PostgreSQL or MySQL databases typically need a database initialization job to create the required database and user before the main application starts. These jobs:
- Run as Kubernetes Jobs that execute once and complete
- Create the application database if it doesn't exist
- Create the application user with appropriate permissions
- Should be included in the app's `kustomization.yaml` resources list
- Use the same database connection settings as the main application
Examples of apps with db-init jobs: `gitea`, `codimd`, `immich`, `openproject`
##### Database URL Configuration
**Important:** When apps require database URLs with embedded credentials, always use a separate `dbUrl` secret instead of trying to construct the URL with environment variable substitution in Kustomize templates.
**Wrong** (Kustomize cannot process runtime env var substitution):
```yaml ```yaml
- name: DB_URL # Common template variables
value: "postgresql://user:$(DB_PASSWORD)@host/db" domain: {{ .cloud.domain }} # Operator's domain
email: {{ .operator.email }} # Operator's email
image: {{ .apps.myapp.serverImage }} # App-specific config
dbHost: {{ .apps.myapp.dbHostname }} # App-specific config
``` ```
**Correct** (Use a dedicated secret): **Template variable sources:**
1. Standard Wild Cloud variables (`{{ .cloud.* }}`, `{{ .operator.* }}`)
2. App-specific variables defined in your manifest's `defaultConfig`
All template variables must be defined in one of these locations. The compiled files are placed in the instance's directory as standard Kubernetes manifests.
### External DNS
Ingress resources should include external-dns annotations for automatic DNS management:
```yaml
annotations:
external-dns.alpha.kubernetes.io/target: {{ .cloud.domain }}
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
```
This creates a CNAME from the app subdomain to the cluster domain (e.g., `myapp.cloud.example.com``cloud.example.com`).
## Database Patterns
### Database Initialization Jobs
Apps requiring PostgreSQL or MySQL should include a database initialization job (`db-init-job.yaml`):
**Purpose:**
- Creates the application database (if it doesn't exist)
- Creates/updates the application user with proper credentials
- Grants necessary permissions
- Installs required database extensions (e.g., PostgreSQL's `vector`, `cube`, `earthdistance`)
**Implementation requirements:**
- Use `restartPolicy: OnFailure`
- Include in `kustomization.yaml` resources
- Use appropriate security context (e.g., `runAsUser: 999` for PostgreSQL)
**Example apps:** `immich`, `gitea`, `openproject`, `discourse`
### Database URL Configuration
When apps need database URLs with embedded credentials, **always use a dedicated `dbUrl` secret**.
**Wrong** - Kustomize cannot process runtime env var substitution:
```yaml
- name: DB_URL
value: "postgresql://user:$(DB_PASSWORD)@host/db" # This won't work!
```
**Correct** - Use a dedicated secret:
```yaml ```yaml
- name: DB_URL - name: DB_URL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: app-secrets name: myapp-secrets
key: apps.appname.dbUrl key: apps.myapp.dbUrl
``` ```
Add `apps.appname.dbUrl` to the manifest's `requiredSecrets` and the `wild-app-add` script will generate the complete URL with embedded credentials. Add `apps.myapp.dbUrl` to your manifest's `requiredSecrets`, and the system will generate the complete URL with embedded credentials automatically when the app is added.
##### Security Context Requirements ## Security Requirements
Pods must comply with Pod Security Standards. All pods should include proper security contexts to avoid deployment warnings: ### Security Contexts
**All pods must comply with Pod Security Standards.** Include security contexts at both pod and container levels:
```yaml ```yaml
spec: spec:
@@ -180,8 +191,8 @@ spec:
spec: spec:
securityContext: securityContext:
runAsNonRoot: true runAsNonRoot: true
runAsUser: 999 # Use appropriate non-root user ID runAsUser: 999 # Use appropriate non-root UID
runAsGroup: 999 # Use appropriate group ID runAsGroup: 999 # Use appropriate GID
seccompProfile: seccompProfile:
type: RuntimeDefault type: RuntimeDefault
containers: containers:
@@ -189,77 +200,147 @@ spec:
securityContext: securityContext:
allowPrivilegeEscalation: false allowPrivilegeEscalation: false
capabilities: capabilities:
drop: drop: [ALL]
- ALL
readOnlyRootFilesystem: false # Set to true when possible readOnlyRootFilesystem: false # Set to true when possible
``` ```
For PostgreSQL init jobs, use `runAsUser: 999` (postgres user). For other database types, use the appropriate non-root user ID for that database container. **Common user IDs:**
- PostgreSQL: `runAsUser: 999`
- Redis: `runAsUser: 999`
- MySQL: Consult the container image documentation
#### Secrets ### Secrets Management
Secrets are managed in the `secrets.yaml` file in the Wild Cloud home directory. The app's `manifest.yaml` should list any required secrets under `requiredSecrets`. When the app is added, default secret values will be generated and stored in the `secrets.yaml` file. Secrets are always stored and referenced in the `apps.<app-name>.<secret-name>` yaml path. When `wild-app-deploy` is run, a Secret resource will be created in the Kubernetes cluster with the name `<app-name>-secrets`, containing all secrets defined in the manifest's `requiredSecrets` key. These secrets can then be referenced in the app's Kustomize files using a `secretKeyRef`. Secrets use a **full dotted-path naming convention** to prevent naming conflicts:
**Important:** Always use the full dotted path from the manifest as the secret key, not just the last segment. For example, to mount a secret in an environment variable, you would use: **In manifest:**
```yaml
requiredSecrets:
- apps.myapp.dbPassword
- apps.postgres.password
```
**In resources:**
```yaml ```yaml
env: env:
- name: DB_PASSWORD - name: DB_PASSWORD
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: immich-secrets name: myapp-secrets
key: apps.immich.dbPassword # Use full dotted path, not just "dbPassword" key: apps.myapp.dbPassword # Full dotted path, not just "dbPassword"
``` ```
This approach prevents naming conflicts between apps and makes secret keys more descriptive and consistent with the `secrets.yaml` structure. **Secret workflow:**
1. List secrets in manifest's `requiredSecrets`
2. When adding an app, the system generates random values in the instance's `secrets.yaml`
3. When deploying, the system creates a Kubernetes Secret named `<app-name>-secrets`
4. Resources reference secrets using full dotted paths
`secrets.yaml` files should not be checked in to a git repository and are ignored by default in Wild Cloud home directories. Checked in kustomize files should only reference secrets, not compile them. **Important:** Never commit `secrets.yaml` to Git. Templates should only reference secrets, never contain actual secret values.
## App Lifecycle ## Converting from Helm Charts
Apps in Wild Cloud are managed by operators using a set of commands run from their Wild Cloud home directory. Wild Cloud prefers Kustomize over Helm for simplicity and Git-friendliness. When an official Helm chart exists, convert it rather than creating manifests from scratch.
- `wild-apps-list`: Lists all available apps. ### Conversion Process
- `wild-app-add <app-name>`: Reads the app from the Wild Cloud repository, adds the app manifest to your Wild Cloud home `apps` directory, updates missing values in `config.yaml` and `secrets.yaml` with the app's default configurations, and compiles the app's Kustomize files.
- `wild-app-deploy <app-name>`: Deploys the app to your Wild Cloud.
## Contributing
If you would like to contribute an app to the Wild Cloud, issue a pull request with the app's directory containing the `manifest.yaml` file and any necessary Kustomize files. Ensure that your app follows the structure outlined above.
## Tips for App Packagers
### Converting from Helm Charts
Wild Cloud apps use Kustomize as kustomize files are simpler, more transparent, and easier to manage in a Git repository than Helm charts.
IMPORTANT! If an official Helm chart is available for an app, it is recommended to convert that chart to a Wild Cloud app rather than creating a new app from scratch.
If you have a Helm chart that you want to convert to a Wild Cloud app, the following example steps can simplify the process for you:
1. **Extract and render the Helm chart:**
```bash ```bash
helm fetch --untar --untardir charts nginx-stable/nginx-ingress helm fetch --untar --untardir charts repo/chart-name
helm template --output-dir base --namespace ingress --values values.yaml ingress-controller charts/nginx-ingress helm template --output-dir base --namespace myapp --values values.yaml myapp charts/chart-name
cat <<EOF > base/nginx-ingress/namespace.yaml cd base/chart-name
```
2. **Add namespace manifest:**
```bash
cat <<EOF > namespace.yaml
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
metadata: metadata:
name: ingress name: myapp
EOF EOF
cd base/nginx-ingress ```
3. **Create kustomization:**
```bash
kustomize create --autodetect kustomize create --autodetect
``` ```
After running these commands against your own Helm chart, you will have a Kustomize directory structure that can be used as a Wild Cloud app. All you need to do then, usually, is: 4. **Convert to Wild Cloud format:**
- Create `manifest.yaml` with app metadata
- Replace hardcoded values with gomplate variables (e.g., `{{ .cloud.domain }}`)
- Update secrets to use dotted-path convention
- Replace Helm labels with Wild Cloud standard labels
- Add `includeSelectors: true` to kustomization
- Use simple component labels (`component: web`, not `app.kubernetes.io/name`)
- Add security contexts to all pods
- Add external-dns annotations to ingresses
- add an app manifest (a `manifest.yaml` file). ### Example Label Migration
- replace any hardcoded operator values with Wild Cloud operator variables, such as `{{ .cloud.domain }}` for the domain name.
- modify how secrets are referenced in the Kustomize files (see above) **Helm style:**
- update labels and selectors to use the Wild Cloud standard: ```yaml
- Replace complex Helm labels (like `app.kubernetes.io/name`, `app.kubernetes.io/instance`) with simple component labels labels:
- Use `component: web`, `component: worker`, etc. in selectors and pod template labels app.kubernetes.io/name: myapp
- Let Kustomize handle the common labels (`app`, `managedBy`, `partOf`) automatically app.kubernetes.io/instance: release-name
- remove any Helm-specific labels from the Kustomize files, as Wild Cloud apps do not use Helm labels. app.kubernetes.io/component: server
```
**Wild Cloud style:**
```yaml
# In kustomization.yaml (applied automatically)
labels:
- includeSelectors: true
pairs:
app: myapp
managedBy: kustomize
partOf: wild-cloud
# In individual resources
labels:
component: server # Simple component label
```
## Validation Checklist
Before submitting a new or modified app, verify:
- [ ] **Manifest**
- [ ] `name` matches directory name
- [ ] All required fields present (`name`, `description`, `version`, `defaultConfig`)
- [ ] All template variables defined in `defaultConfig` or are standard Wild Cloud variables
- [ ] Secrets use dotted-path format (e.g., `apps.appname.secretname`)
- [ ] Dependencies listed in `requires` (if any)
- [ ] **Kustomization**
- [ ] Includes standard Wild Cloud labels with `includeSelectors: true`
- [ ] Namespace matches app name
- [ ] All resource files listed under `resources:`
- [ ] **Resources**
- [ ] All hardcoded values replaced with gomplate variables
- [ ] Secrets reference full dotted paths
- [ ] Security contexts on all pods (both pod-level and container-level)
- [ ] Simple component labels, no Helm-style labels
- [ ] Ingresses include external-dns annotations
- [ ] Database apps include init jobs (if applicable)
- [ ] **Testing**
- [ ] Templates compile successfully with sample config
- [ ] App deploys without errors in test cluster
- [ ] All dependencies work correctly
## Contributing
Contributions are welcome! To contribute:
1. Fork the repository
2. Create a new app directory following the structure above
3. Test your app thoroughly
4. Submit a pull request with:
- Description of the app and its purpose
- Any special configuration notes
- Dependencies required
## Notice: Third-Party Software ## Notice: Third-Party Software

171
CLAUDE.md Normal file
View File

@@ -0,0 +1,171 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This repository contains the Wild Cloud apps directory - a collection of Kubernetes applications packaged as Kustomize configurations. Each app is a self-contained directory with standardized manifests that can be deployed to Wild Cloud clusters using Wild Cloud CLI tools.
## Repository Architecture
### App Structure
Each app follows a strict structure:
- **`manifest.yaml`** - App metadata, dependencies, default configuration, and secret requirements
- **`kustomization.yaml`** - Kustomize configuration with standard Wild Cloud labels
- **Resource files** - Kubernetes objects (deployments, services, ingresses, PVCs, jobs, etc.)
### Templating System
Configuration files use **gomplate templating** to reference operator configuration:
- Use `{{ .cloud.domain }}` for the operator's domain
- Use `{{ .apps.appname.configKey }}` for app-specific configuration
- Use `{{ .operator.email }}` for operator email
- All template variables must be defined in either the app's `manifest.yaml` under `defaultConfig` or be standard Wild Cloud operator variables
Templates are compiled when users add apps to their Wild Cloud instance via the web app, CLI, or API.
### Label Strategy
Wild Cloud uses a consistent labeling approach powered by Kustomize's `includeSelectors: true` feature:
```yaml
labels:
- includeSelectors: true
pairs:
app: appname # App name (matches directory)
managedBy: kustomize
partOf: wild-cloud
```
This automatically applies labels to all resources AND their selectors. Individual resources can use simple component-specific selectors like `component: web` or `component: worker`, and Kustomize will expand them to include the standard Wild Cloud labels.
**Important:** Do NOT use Helm-style labels (`app.kubernetes.io/name`, `app.kubernetes.io/instance`). Use simple component labels instead.
## Working with Apps
### Creating/Modifying Apps
1. **Manifest fields:**
- `name` - Must match directory name
- `description` - Brief app description
- `version` - App version (follow upstream versioning)
- `icon` - URL to app icon
- `requires` - List of dependency apps (e.g., `postgres`, `redis`, `memcached`)
- `defaultConfig` - Default configuration values (will be added to operator's `config.yaml`)
- `requiredSecrets` - List of secrets in dotted path format (e.g., `apps.appname.dbPassword`)
2. **Kustomization requirements:**
- Must include standard Wild Cloud labels with `includeSelectors: true`
- Namespace must match app name
- List all resource files under `resources:`
3. **Security contexts:**
All pods must comply with Pod Security Standards:
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 999 # Use appropriate non-root UID
runAsGroup: 999
seccompProfile:
type: RuntimeDefault
containers:
- securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: false # Set to true when possible
```
### Secrets Management
Secrets use **full dotted paths** as keys:
```yaml
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: appname-secrets
key: apps.appname.dbPassword # Full path, not just "dbPassword"
```
**Database URL secrets:** When apps need database URLs with embedded credentials, always use a dedicated `dbUrl` secret in `requiredSecrets`. Do NOT try to construct URLs with env var substitution in templates - Kustomize cannot process runtime environment variables.
### Database Initialization Jobs
Apps requiring PostgreSQL/MySQL databases should include a `db-init-job.yaml`:
- Creates the app database if it doesn't exist
- Creates/updates the app user with proper password
- Grants appropriate permissions
- For PostgreSQL jobs: use `runAsUser: 999` (postgres user)
- Include any required database extensions (e.g., Immich requires `vector`, `cube`, `earthdistance`)
Examples: [immich/db-init-job.yaml](immich/db-init-job.yaml), [gitea/db-init-job.yaml](gitea/db-init-job.yaml)
### External DNS Configuration
Ingress resources should include external-dns annotations:
```yaml
annotations:
external-dns.alpha.kubernetes.io/target: {{ .cloud.domain }}
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
```
This creates CNAME records pointing app subdomains to the main cluster domain.
### Converting Helm Charts
Wild Cloud prefers Kustomize over Helm for transparency and Git-friendliness. To convert a Helm chart:
```bash
helm fetch --untar --untardir charts repo/chart-name
helm template --output-dir base --namespace namespace --values values.yaml release-name charts/chart-name
cd base/chart-name
kustomize create --autodetect
```
Then:
1. Add `manifest.yaml`
2. Replace hardcoded values with gomplate variables
3. Update secrets to use Wild Cloud's dotted-path approach
4. Replace Helm labels with simple component labels
5. Add standard Wild Cloud labels to `kustomization.yaml`
6. Add security contexts to all pods
## Managing Wild Cloud Apps
Users can manage apps through:
1. **Web App**: Navigate to the Apps page in your instance to browse, add, configure, and deploy apps
2. **CLI**: Use the Wild CLI for terminal-based workflows:
- `wild app list` - List all available apps
- `wild app add <app-name>` - Add an app (compiles templates, updates config/secrets)
- `wild app deploy <app-name>` - Deploy an app to the cluster
- `wild app list-deployed` - List deployed apps
- `wild app status <app-name>` - Get app status
- `wild app delete <app-name>` - Delete an app
3. **API**: Use the Wild Central API endpoints for automation:
- `GET /api/v1/apps/available` - List all available apps
- `GET /api/v1/apps/available/{app-name}` - Get app details
- `POST /api/v1/instances/{instance-name}/apps` - Add an app (compiles templates, updates config/secrets)
- `POST /api/v1/instances/{instance-name}/apps/{app-name}/deploy` - Deploy an app to the cluster
- `GET /api/v1/instances/{instance-name}/apps` - List deployed apps
- `GET /api/v1/instances/{instance-name}/apps/{app-name}/status` - Get app status
## Validation
Before submitting changes:
1. Ensure `manifest.yaml` has all required fields
2. Verify `kustomization.yaml` includes standard Wild Cloud labels
3. Check all templates use valid configuration paths defined in `defaultConfig`
4. Confirm secrets use full dotted-path keys
5. Verify all pods have proper security contexts
6. Test template compilation works with sample operator config
## Examples of Well-Structured Apps
- **immich** - Multi-deployment app with database init, multiple services, PostgreSQL extensions
- **openproject** - App with multiple dependencies (postgres, memcached), configmap-based configuration
- **gitea** - Standard app with database init, PVC for storage

318
README.md
View File

@@ -1,265 +1,121 @@
# Wild Cloud-maintained apps # Wild Cloud Apps Directory
This is the Wild Cloud apps repository. This is the official Wild Cloud apps repository containing a curated collection of self-hosted applications that can be deployed to your Wild Cloud cluster.
This repository contains a collection of apps that can be deployed using Wild Cloud scripts. Wild Cloud apps follow a specific structure and naming convention to ensure compatibility with the Wild Cloud ecosystem. ## What are Wild Cloud Apps?
## App Structure Wild Cloud apps are pre-packaged Kubernetes applications using Kustomize that follow standardized conventions for configuration, secrets management, and deployment. Each app includes:
Each subdirectory in this directory represents a Wild Cloud app. Each app directory contains an "app manifest" (`manifest.yaml`), a "kustomization" (`kustomization.yaml`), and one or more "configurations" (yaml files containing definitions/configurations of Kubernetes objects/resources). - **App manifest** (`manifest.yaml`) - Metadata, dependencies, and default configuration
- **Kustomization** (`kustomization.yaml`) - Kubernetes resource definitions
- **Configuration templates** - Deployments, services, ingresses, and other resources
### App Manifest Apps use gomplate templates that compile with your Wild Cloud configuration when added, making them easy to customize while maintaining a consistent deployment experience.
The required `manifest.yaml` file contains metadata about the app. ## Using Wild Cloud Apps
This is the contents of an example `manifest.yaml` file for an app named "immich": ### Web App (Recommended)
```yaml The easiest way to manage apps is through the Wild Cloud web app:
name: immich
description: Immich is a self-hosted photo and video backup solution that allows you to store, manage, and share your media files securely. 1. **Navigate to Apps**: Access your instance in the web app and go to the Apps page
version: 1.0.0 2. **Browse Available Apps**: View all available apps from the Wild Directory with descriptions and icons
icon: https://immich.app/assets/images/logo.png 3. **Add an App**: Click on an app to view details and click "Add" to:
requires: - Copy the app manifest to your instance's `apps` directory
- name: redis - Add default configuration to your `config.yaml`
- name: postgres - Generate required secrets in your `secrets.yaml`
defaultConfig: - Compile templates with your configuration
serverImage: ghcr.io/immich-app/immich-server:release 4. **Configure** (optional): Modify app settings before deployment
mlImage: ghcr.io/immich-app/immich-machine-learning:release 5. **Deploy**: Click "Deploy" to apply the app to your cluster
timezone: UTC 6. **Monitor**: View app status, logs, and manage deployments
serverPort: 2283
mlPort: 3003 ### CLI
storage: 250Gi
cacheStorage: 10Gi For terminal-based workflows, use the Wild CLI:
redisHostname: redis.redis.svc.cluster.local
dbHostname: postgres.postgres.svc.cluster.local ```bash
dbUsername: immich # List available apps
domain: immich.{{ .cloud.domain }} wild app list
requiredSecrets:
- apps.immich.dbPassword # Add app to instance
- apps.postgres.password wild app add <app-name>
# Deploy app
wild app deploy <app-name>
# List deployed apps
wild app list-deployed
# Get app status
wild app status <app-name>
# Delete app
wild app delete <app-name>
``` ```
Explanation of the fields: The CLI connects to the Wild Central API (default: `http://localhost:5055`). You can override with `--daemon-url` or set `WILD_API_URI` environment variable.
- `name`: The name of the app, used for identification. ### API
- `description`: A brief description of the app.
- `version`: The version of the app. This should generally follow the versioning scheme of the app itself.
- `icon`: A URL to an icon representing the app.
- `requires`: A list of other apps that this app depends on. Each entry should be the name of another app.
- `defaultConfig`: A set of default configuration values for the app. When an app is added using `wild-app-add`, these values will be added to the Wild Cloud `config.yaml` file.
- `requiredSecrets`: A list of secrets that must be set in the Wild Cloud `secrets.yaml` file for the app to function properly. These secrets are typically sensitive information like database passwords or API keys. Keys with random values will be generated automatically when the app is added.
### Kustomization For automation or advanced workflows, use the Wild Central API:
Each app directory should also contain a `kustomization.yaml` file. This file defines how the app's Kubernetes resources are built and deployed. It can include references to other Kustomize files, patches, and configurations. ```bash
# List available apps
curl http://localhost:5055/api/v1/apps/available
Here is an example `kustomization.yaml` file for the "immich" app: # Get app details
curl http://localhost:5055/api/v1/apps/available/{app-name}
```yaml # List deployed apps for an instance
apiVersion: kustomize.config.k8s.io/v1beta1 curl http://localhost:5055/api/v1/instances/{instance-name}/apps
kind: Kustomization
namespace: immich
labels:
- includeSelectors: true
pairs:
app: immich
managedBy: kustomize
partOf: wild-cloud
resources:
- deployment-server.yaml
- deployment-machine-learning.yaml
- deployment-microservices.yaml
- ingress.yaml
- namespace.yaml
- pvc.yaml
- service.yaml
- db-init-job.yaml
```
Kustomization requirements: # Add app to configuration
curl -X POST http://localhost:5055/api/v1/instances/{instance-name}/apps \
-H "Content-Type: application/json" \
-d '{"name": "app-name", "config": {}}'
- Every Wild Cloud kustomization should include the Wild Cloud labels in its `kustomization.yaml` file. This allows the Wild Cloud to identify and manage the app correctly. The labels should be defined under the `labels` key, as shown in the example above. # Deploy app
- The `app` label and `namespace` keys should the app's name/directory. curl -X POST http://localhost:5055/api/v1/instances/{instance-name}/apps/{app-name}/deploy
#### Standard Wild Cloud Labels # Get app status
curl http://localhost:5055/api/v1/instances/{instance-name}/apps/{app-name}/status
Wild Cloud uses a consistent labeling strategy across all apps:
```yaml
labels:
- includeSelectors: true
pairs:
app: myapp # The app name (matches directory)
managedBy: kustomize # Managed by Kustomize
partOf: wild-cloud # Part of Wild Cloud ecosystem
``` ```
The `includeSelectors: true` setting automatically applies these labels to all resources AND their selectors, which means: ### How It Works
1. **Resource labels** - All resources get the standard Wild Cloud labels 1. **Add an app**: The system compiles the app's templates using your Wild Cloud configuration (domain, email, etc.) and creates standard Kustomize files in your instance directory
2. **Selector labels** - All selectors automatically include these labels for robust selection 2. **Customize** (optional): Modify app configuration through the web app, CLI, or by editing files directly
3. **Deploy**: The system applies the Kustomize configuration to your cluster
4. **Manage**: Track changes with Git, update configurations, and monitor app health
This allows individual resources to use simple, component-specific selectors: ### Dependencies
```yaml Some apps require other apps to function. For example:
selector: - **Immich** requires PostgreSQL and Redis
matchLabels: - **OpenProject** requires PostgreSQL and Memcached
component: web - **Gitea** requires PostgreSQL
```
Which Kustomize automatically expands to: When you add an app, check its `requires` field in the manifest and ensure dependencies are added first.
```yaml ## Available Apps
selector:
matchLabels:
app: myapp
component: web
managedBy: kustomize
partOf: wild-cloud
```
### Configuration Files This repository includes apps for:
- Content management (Ghost, Discourse)
- Project management (OpenProject)
- Photo management (Immich)
- Code hosting (Gitea)
- Email marketing (Listmonk, Keila)
- AI interfaces (Open WebUI, vLLM)
- Databases (PostgreSQL, MySQL, Redis, Memcached)
- And more...
Wild Cloud apps use Kustomize as kustomize files are simple, transparent, and easier to manage in a Git repository. Browse the full catalog with descriptions through the web app, CLI, or via the API endpoint `/api/v1/apps/available`.
#### Templates
For operators, Wild Cloud apps use standard configuration files. This makes modifying the app's configuration straightforward, as operators can customize their app files as needed. They can choose to manage modifications and updates directly on the configuration files using `git` tools, or they can use Kustomize patches or overlays. As a convenience for operators, when adding an app (using `wild-app-add`), the app's configurations will be compiled with the operator's Wild Cloud configuration and secrets. This results in standard Kustomize files being placed in the Wild Cloud home directory, which can then be modified as needed. This means the configuration files in this repository are actually templates, but they will be compiled into standard Kustomize files when the app is added to an operator's Wild Cloud home directory.
To reference operator configuration in the configuration files, use gomplate variables, such as `{{ .cloud.domain }}` for the domain name. All configuration variables you use need to exist in the operator's `config.yaml`, so they should be either standard Wild Cloud operator variables, or be defined in the app's `manifest.yaml` under `defaultConfig`.
When `wild-app-add` is run, the app's Kustomize files will be compiled with the operator's Wild Cloud configuration and secrets resulting in standard Kustomize files being placed in the Wild Cloud home directory.
#### External DNS Configuration
Wild Cloud apps use external-dns annotations in their ingress resources to automatically manage DNS records:
- `external-dns.alpha.kubernetes.io/target: {{ .cloud.domain }}` - Creates a CNAME record pointing the app subdomain to the main cluster domain (e.g., `ghost.cloud.payne.io``cloud.payne.io`)
- `external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"` - Disables Cloudflare proxy for direct DNS resolution
#### Database Initialization Jobs
Apps that rely on PostgreSQL or MySQL databases typically need a database initialization job to create the required database and user before the main application starts. These jobs:
- Run as Kubernetes Jobs that execute once and complete
- Create the application database if it doesn't exist
- Create the application user with appropriate permissions
- Should be included in the app's `kustomization.yaml` resources list
- Use the same database connection settings as the main application
Examples of apps with db-init jobs: `gitea`, `codimd`, `immich`, `openproject`
##### Database URL Configuration
**Important:** When apps require database URLs with embedded credentials, always use a separate `dbUrl` secret instead of trying to construct the URL with environment variable substitution in Kustomize templates.
**Wrong** (Kustomize cannot process runtime env var substitution):
```yaml
- name: DB_URL
value: "postgresql://user:$(DB_PASSWORD)@host/db"
```
**Correct** (Use a dedicated secret):
```yaml
- name: DB_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: apps.appname.dbUrl
```
Add `apps.appname.dbUrl` to the manifest's `requiredSecrets` and the `wild-app-add` script will generate the complete URL with embedded credentials.
##### Security Context Requirements
Pods must comply with Pod Security Standards. All pods should include proper security contexts to avoid deployment warnings:
```yaml
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 999 # Use appropriate non-root user ID
runAsGroup: 999 # Use appropriate group ID
seccompProfile:
type: RuntimeDefault
containers:
- name: container-name
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false # Set to true when possible
```
For PostgreSQL init jobs, use `runAsUser: 999` (postgres user). For other database types, use the appropriate non-root user ID for that database container.
#### Secrets
Secrets are managed in the `secrets.yaml` file in the Wild Cloud home directory. The app's `manifest.yaml` should list any required secrets under `requiredSecrets`. When the app is added, default secret values will be generated and stored in the `secrets.yaml` file. Secrets are always stored and referenced in the `apps.<app-name>.<secret-name>` yaml path. When `wild-app-deploy` is run, a Secret resource will be created in the Kubernetes cluster with the name `<app-name>-secrets`, containing all secrets defined in the manifest's `requiredSecrets` key. These secrets can then be referenced in the app's Kustomize files using a `secretKeyRef`.
**Important:** Always use the full dotted path from the manifest as the secret key, not just the last segment. For example, to mount a secret in an environment variable, you would use:
```yaml
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: immich-secrets
key: apps.immich.dbPassword # Use full dotted path, not just "dbPassword"
```
This approach prevents naming conflicts between apps and makes secret keys more descriptive and consistent with the `secrets.yaml` structure.
`secrets.yaml` files should not be checked in to a git repository and are ignored by default in Wild Cloud home directories. Checked in kustomize files should only reference secrets, not compile them.
## App Lifecycle
Apps in Wild Cloud are managed by operators using a set of commands run from their Wild Cloud home directory.
- `wild-apps-list`: Lists all available apps.
- `wild-app-add <app-name>`: Reads the app from the Wild Cloud repository, adds the app manifest to your Wild Cloud home `apps` directory, updates missing values in `config.yaml` and `secrets.yaml` with the app's default configurations, and compiles the app's Kustomize files.
- `wild-app-deploy <app-name>`: Deploys the app to your Wild Cloud.
## Contributing ## Contributing
If you would like to contribute an app to the Wild Cloud, issue a pull request with the app's directory containing the `manifest.yaml` file and any necessary Kustomize files. Ensure that your app follows the structure outlined above. Want to add a new app or improve an existing one? See [ADDING-APPS.md](ADDING-APPS.md) for detailed guidance on creating Wild Cloud apps.
## Tips for App Packagers Contributions are welcome via pull requests. Ensure your app follows the Wild Cloud conventions and includes all required files.
### Converting from Helm Charts
Wild Cloud apps use Kustomize as kustomize files are simpler, more transparent, and easier to manage in a Git repository than Helm charts.
IMPORTANT! If an official Helm chart is available for an app, it is recommended to convert that chart to a Wild Cloud app rather than creating a new app from scratch.
If you have a Helm chart that you want to convert to a Wild Cloud app, the following example steps can simplify the process for you:
```bash
helm fetch --untar --untardir charts nginx-stable/nginx-ingress
helm template --output-dir base --namespace ingress --values values.yaml ingress-controller charts/nginx-ingress
cat <<EOF > base/nginx-ingress/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ingress
EOF
cd base/nginx-ingress
kustomize create --autodetect
```
After running these commands against your own Helm chart, you will have a Kustomize directory structure that can be used as a Wild Cloud app. All you need to do then, usually, is:
- add an app manifest (a `manifest.yaml` file).
- replace any hardcoded operator values with Wild Cloud operator variables, such as `{{ .cloud.domain }}` for the domain name.
- modify how secrets are referenced in the Kustomize files (see above)
- update labels and selectors to use the Wild Cloud standard:
- Replace complex Helm labels (like `app.kubernetes.io/name`, `app.kubernetes.io/instance`) with simple component labels
- Use `component: web`, `component: worker`, etc. in selectors and pod template labels
- Let Kustomize handle the common labels (`app`, `managedBy`, `partOf`) automatically
- remove any Helm-specific labels from the Kustomize files, as Wild Cloud apps do not use Helm labels.
## Notice: Third-Party Software ## Notice: Third-Party Software

View File

@@ -20,7 +20,7 @@ Sensitive configuration is stored in the `gitea-secrets` secret and managed by t
- `dbPassword` - Database password - `dbPassword` - Database password
- `smtpPassword` - SMTP authentication password - `smtpPassword` - SMTP authentication password
Secrets are defined in `secrets.yaml` and listed in `manifest.yaml` under `requiredSecrets`. The `wild-app-deploy` command automatically ensures all required secrets exist in the `gitea-secrets` secret before deployment. Secrets are defined in `secrets.yaml` and listed in `manifest.yaml` under `requiredSecrets`. When deploying, the system automatically ensures all required secrets exist in the `gitea-secrets` secret before deployment.
### Persistent Configuration (app.ini) ### Persistent Configuration (app.ini)
Gitea manages its own `app.ini` file on persistent storage for: Gitea manages its own `app.ini` file on persistent storage for:
@@ -41,13 +41,13 @@ Gitea manages its own `app.ini` file on persistent storage for:
### Non-Secret Settings ### Non-Secret Settings
1. Edit `gitea.env` with your changes 1. Edit `gitea.env` with your changes
2. Run `wild-app-deploy gitea` to apply changes 2. Deploy the app via the web app, CLI, or API to apply changes
3. Pod will restart and pick up new configuration 3. Pod will restart and pick up new configuration
### Secret Settings ### Secret Settings
1. Edit `secrets.yaml` with your secret values 1. Edit `secrets.yaml` with your secret values
2. Ensure the secret key is listed in `manifest.yaml` under `requiredSecrets` 2. Ensure the secret key is listed in `manifest.yaml` under `requiredSecrets`
3. Run `wild-app-deploy gitea` - this will automatically update the `gitea-secrets` secret and restart the pod 3. Deploy the app via the web app, CLI, or API - this will automatically update the `gitea-secrets` secret and restart the pod
### Web UI Changes ### Web UI Changes
Configuration changes made through Gitea's admin web interface are automatically persisted to the `app.ini` file on persistent storage and will survive pod restarts. Configuration changes made through Gitea's admin web interface are automatically persisted to the `app.ini` file on persistent storage and will survive pod restarts.

View File

@@ -4,34 +4,37 @@ metadata:
name: mysql name: mysql
namespace: mysql namespace: mysql
data: data:
my.cnf: | custom.cnf: |
[mysqld] [mysqld]
authentication_policy='* ,,' # Connection settings
bind-address=0.0.0.0
skip-name-resolve skip-name-resolve
explicit_defaults_for_timestamp max_connections=200
basedir=/opt/bitnami/mysql max_allowed_packet=64M
plugin_dir=/opt/bitnami/mysql/lib/plugin
port={{ .apps.mysql.port }} # Character set
mysqlx=0 character-set-server=utf8mb4
mysqlx_port=33060 collation-server=utf8mb4_unicode_ci
socket=/opt/bitnami/mysql/tmp/mysql.sock
datadir=/bitnami/mysql/data # Performance tuning
tmpdir=/opt/bitnami/mysql/tmp innodb_buffer_pool_size=512M
max_allowed_packet=16M innodb_log_file_size=128M
bind-address=* innodb_flush_log_at_trx_commit=2
pid-file=/opt/bitnami/mysql/tmp/mysqld.pid innodb_flush_method=O_DIRECT
log-error=/opt/bitnami/mysql/logs/mysqld.log
character-set-server=UTF8 # Query optimization
slow_query_log=0 slow_query_log=1
long_query_time=10.0 long_query_time=2
slow_query_log_file=/var/lib/mysql/slow-query.log
# Timeout settings
wait_timeout=600
interactive_timeout=600
# Binary logging (optional, for replication)
# server-id=1
# log_bin=/var/lib/mysql/mysql-bin
# binlog_format=ROW
[client] [client]
port={{ .apps.mysql.port }} default-character-set=utf8mb4
socket=/opt/bitnami/mysql/tmp/mysql.sock
default-character-set=UTF8
plugin_dir=/opt/bitnami/mysql/lib/plugin
[manager]
port={{ .apps.mysql.port }}
socket=/opt/bitnami/mysql/tmp/mysql.sock
pid-file=/opt/bitnami/mysql/tmp/mysqld.pid

View File

@@ -1,10 +1,10 @@
name: mysql name: mysql
description: MySQL is an open-source relational database management system description: MySQL is an open-source relational database management system
version: 8.4.5 version: 9.1.0
icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
requires: [] requires: []
defaultConfig: defaultConfig:
image: docker.io/bitnami/mysql:8.4.5-debian-12-r0 image: mysql:9.1.0
port: 3306 port: 3306
storage: 20Gi storage: 20Gi
dbName: mysql dbName: mysql

View File

@@ -20,46 +20,13 @@ spec:
serviceAccountName: default serviceAccountName: default
automountServiceAccountToken: false automountServiceAccountToken: false
securityContext: securityContext:
fsGroup: 1001
fsGroupChangePolicy: Always
initContainers:
- name: preserve-logs-symlinks
image: {{ .apps.mysql.image }}
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 1001
runAsNonRoot: true runAsNonRoot: true
runAsUser: 1001 runAsUser: 999
runAsGroup: 999
fsGroup: 999
fsGroupChangePolicy: Always
seccompProfile: seccompProfile:
type: RuntimeDefault type: RuntimeDefault
resources:
limits:
cpu: 250m
ephemeral-storage: 1Gi
memory: 256Mi
requests:
cpu: 100m
ephemeral-storage: 50Mi
memory: 128Mi
command:
- /bin/bash
args:
- -ec
- |
#!/bin/bash
. /opt/bitnami/scripts/libfs.sh
# We copy the logs folder because it has symlinks to stdout and stderr
if ! is_dir_empty /opt/bitnami/mysql/logs; then
cp -r /opt/bitnami/mysql/logs /emptydir/app-logs-dir
fi
volumeMounts:
- name: empty-dir
mountPath: /emptydir
containers: containers:
- name: mysql - name: mysql
image: {{ .apps.mysql.image }} image: {{ .apps.mysql.image }}
@@ -69,15 +36,8 @@ spec:
capabilities: capabilities:
drop: drop:
- ALL - ALL
readOnlyRootFilesystem: true readOnlyRootFilesystem: false
runAsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
seccompProfile:
type: RuntimeDefault
env: env:
- name: BITNAMI_DEBUG
value: "false"
- name: MYSQL_ROOT_PASSWORD - name: MYSQL_ROOT_PASSWORD
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
@@ -92,83 +52,59 @@ spec:
key: apps.mysql.password key: apps.mysql.password
- name: MYSQL_DATABASE - name: MYSQL_DATABASE
value: {{ .apps.mysql.dbName }} value: {{ .apps.mysql.dbName }}
- name: MYSQL_PORT - name: TZ
value: "{{ .apps.mysql.port }}" value: {{ .apps.mysql.timezone }}
ports: ports:
- name: mysql - name: mysql
containerPort: {{ .apps.mysql.port }} containerPort: {{ .apps.mysql.port }}
protocol: TCP
livenessProbe: livenessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
exec: exec:
command: command:
- /bin/bash - /bin/sh
- -ec - -c
- | - mysqladmin ping -h localhost --silent
password_aux="${MYSQL_ROOT_PASSWORD:-}" initialDelaySeconds: 30
mysqladmin status -uroot -p"${password_aux}" periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe: readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
exec: exec:
command: command:
- /bin/bash - /bin/sh
- -ec - -c
- | - mysql -h localhost -u root -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"
password_aux="${MYSQL_ROOT_PASSWORD:-}" initialDelaySeconds: 10
mysqladmin ping -uroot -p"${password_aux}" | grep "mysqld is alive" periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
startupProbe: startupProbe:
failureThreshold: 10 exec:
command:
- /bin/sh
- -c
- mysqladmin ping -h localhost --silent
initialDelaySeconds: 15 initialDelaySeconds: 15
periodSeconds: 10 periodSeconds: 10
successThreshold: 1 timeoutSeconds: 5
timeoutSeconds: 1 failureThreshold: 40
exec:
command:
- /bin/bash
- -ec
- |
password_aux="${MYSQL_ROOT_PASSWORD:-}"
mysqladmin ping -uroot -p"${password_aux}" | grep "mysqld is alive"
resources: resources:
limits: limits:
cpu: 750m cpu: 1000m
ephemeral-storage: 2Gi memory: 1Gi
memory: 768Mi
requests: requests:
cpu: 500m cpu: 500m
ephemeral-storage: 50Mi
memory: 512Mi memory: 512Mi
volumeMounts: volumeMounts:
- name: data - name: data
mountPath: /bitnami/mysql mountPath: /var/lib/mysql
- name: empty-dir
mountPath: /tmp
subPath: tmp-dir
- name: empty-dir
mountPath: /opt/bitnami/mysql/conf
subPath: app-conf-dir
- name: empty-dir
mountPath: /opt/bitnami/mysql/tmp
subPath: app-tmp-dir
- name: empty-dir
mountPath: /opt/bitnami/mysql/logs
subPath: app-logs-dir
- name: config - name: config
mountPath: /opt/bitnami/mysql/conf/my.cnf mountPath: /etc/mysql/conf.d/custom.cnf
subPath: my.cnf subPath: custom.cnf
volumes: volumes:
- name: config - name: config
configMap: configMap:
name: mysql name: mysql
- name: empty-dir
emptyDir: {}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: data name: data