diff --git a/config-example/docker/.env b/config-example/docker/.env index dc52d679..6fd5e03a 100644 --- a/config-example/docker/.env +++ b/config-example/docker/.env @@ -16,7 +16,7 @@ MAIN_NODE_IP=192.168.1.20 SECOND_NODE=hive SECOND_NODE_IP=192.168.1.243 -# Local accounts +### Local accounts ADMIN_USER=admin ADMIN_PASSWORD="use-some-very-secure-value-here" @@ -25,3 +25,8 @@ ADMIN_DISPLAYNAME=AdminUser ADMIN_HOME=/home/buba INFRA_CONFIG_PATH=${ADMIN_HOME}/repos/infra/config + +### Cloud accounts + +# Genetate at: https://github.com/settings/tokens/new +GITHUB_API_TOKEN="use-some-very-secure-value-here" diff --git a/config-example/docker/myhost/.env b/config-example/docker/myhost/.env index b17ad541..7d313159 100644 --- a/config-example/docker/myhost/.env +++ b/config-example/docker/myhost/.env @@ -108,6 +108,19 @@ MSSQL_SA_PASSWORD="use-some-very-secure-value-here" # Optional: Custom collation (default: SQL_Latin1_General_CP1_CI_AS) # MSSQL_COLLATION="SQL_Latin1_General_CP1_CI_AS" +### PostgreSQL configuration +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="use-some-very-secure-value-here" +POSTGRES_DB="postgres" + +### Adminer configuration +# Optional: Default database server to connect to (leave empty for manual selection) +ADMINER_DEFAULT_SERVER="" +# Optional: Custom design theme name (leave empty for default) +ADMINER_DESIGN="" +# Optional: Space-separated list of plugins to enable (e.g., "tables-filter tinymce") +ADMINER_PLUGINS="" + ### ScanServJS configuration SCANSERVJS_SANED_NET_HOSTS="" # Example: "192.168.1.x;192.168.1.y" SCANSERVJS_AIRSCAN_DEVICES="" diff --git a/config-example/docker/myhost/.env.supabase b/config-example/docker/myhost/.env.supabase index 9d248621..804f05b0 100644 --- a/config-example/docker/myhost/.env.supabase +++ b/config-example/docker/myhost/.env.supabase @@ -50,7 +50,7 @@ SUPABASE_PG_META_CRYPTO_KEY="use-some-very-secure-value-here" SUPABASE_POSTGRES_HOST=db SUPABASE_POSTGRES_DB=postgres -SUPABASE_POSTGRES_PORT=5432 +SUPABASE_POSTGRES_PORT=5434 # Default: 5432 # default user is postgres diff --git a/config-example/docker/myhost/services.yaml b/config-example/docker/myhost/services.yaml index bdfc9aca..ed728ce1 100644 --- a/config-example/docker/myhost/services.yaml +++ b/config-example/docker/myhost/services.yaml @@ -90,10 +90,16 @@ services: state: up - name: bees state: up + + - database: + - name: adminer + state: up - name: couchdb state: up - name: mssql-server state: up + - name: postgresql + state: up - backup: - name: kopia-nas diff --git a/docker/database/adminer.yaml b/docker/database/adminer.yaml new file mode 100644 index 00000000..86aa8e53 --- /dev/null +++ b/docker/database/adminer.yaml @@ -0,0 +1,40 @@ +# Adminer is a full-featured database management tool written in PHP that consists +# of a single file ready to deploy to the target server. It supports MySQL, MariaDB, +# PostgreSQL, CockroachDB, SQLite, MS SQL, Oracle, and through plugins: Elasticsearch, +# SimpleDB, MongoDB, Firebird, ClickHouse, and IMAP systems. +# +# Links: +# - Home: https://www.adminer.org +# - Source: https://github.com/vrana/adminer +# - Docs: https://hub.docker.com/_/adminer/ +# +# TODO: Enable custom plugins via ADMINER_PLUGINS environment variable +# TODO: Consider mounting custom CSS themes for UI customization +# TODO: Create dedicated database network for secure database connections +--- +name: adminer +services: + adminer: + image: adminer:5.4.1-standalone + container_name: adminer + restart: unless-stopped + environment: + TZ: ${TIMEZONE} + ADMINER_DEFAULT_SERVER: ${ADMINER_DEFAULT_SERVER:-} + ADMINER_DESIGN: ${ADMINER_DESIGN:-} + ADMINER_PLUGINS: ${ADMINER_PLUGINS:-} + networks: + - proxy + labels: + traefik.enable: true + traefik.http.routers.adminer.middlewares: localaccess-sso@file + traefik.http.services.adminer.loadbalancer.server.port: 8080 + homepage.group: Storage + homepage.name: Adminer + homepage.icon: adminer.png + homepage.href: https://adminer.${MYDOMAIN}/ + homepage.description: "Full-featured database management tool" + +networks: + proxy: + external: true diff --git a/docker/storage/couchdb.yaml b/docker/database/couchdb.yaml similarity index 100% rename from docker/storage/couchdb.yaml rename to docker/database/couchdb.yaml diff --git a/docker/storage/mssql-server.yaml b/docker/database/mssql-server.yaml similarity index 100% rename from docker/storage/mssql-server.yaml rename to docker/database/mssql-server.yaml diff --git a/docker/database/postgresql.yaml b/docker/database/postgresql.yaml new file mode 100644 index 00000000..ce6d8b53 --- /dev/null +++ b/docker/database/postgresql.yaml @@ -0,0 +1,53 @@ +# PostgreSQL is a powerful, open source object-relational database system with over +# 35 years of active development that has earned it a strong reputation for +# reliability, feature robustness, and performance. +# +# Links: +# - Home: https://www.postgresql.org/ +# - Source: https://github.com/docker-library/postgres +# - Docs: https://hub.docker.com/_/postgres +# +# TODO: Add PgBouncer container for connection pooling +# TODO: Add PostgreSQL exporter for Prometheus monitoring +# TODO: Implement automated backup solution (pg_dump or pgBackRest) +# TODO: Consider enabling SSL/TLS for encrypted connections +# TODO: Set up streaming replication for high availability +--- +name: postgresql +services: + postgresql: + image: postgres:18.1-trixie + container_name: postgresql + restart: unless-stopped + shm_size: 128mb + environment: + TZ: ${TIMEZONE} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB:-postgres} + POSTGRES_INITDB_ARGS: --data-checksums + volumes: + - postgres-data:/var/lib/postgresql + - ./postgresql/initdb:/docker-entrypoint-initdb.d + ports: + - 5432:5432 + networks: + - proxy + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] + interval: 10s + timeout: 5s + retries: 5 + labels: + traefik.enable: false + homepage.group: Storage + homepage.name: PostgreSQL + homepage.icon: postgresql.png + homepage.description: "Powerful open source object-relational database system" + +volumes: + postgres-data: + +networks: + proxy: + external: true diff --git a/docker/database/postgresql/initdb/.gitkeep b/docker/database/postgresql/initdb/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/PRPs/containers/adminer.md b/docs/PRPs/containers/adminer.md new file mode 100644 index 00000000..fdcaefbf --- /dev/null +++ b/docs/PRPs/containers/adminer.md @@ -0,0 +1,135 @@ +## Base information for Adminer application + +Application name: Adminer +Homepage: https://www.adminer.org +GitHub page: https://github.com/vrana/adminer +Install instructions URL: https://hub.docker.com/_/adminer/ +Category: storage +Dashboard Icon: adminer.png +Dashboard Group: Storage +Short description: Full-featured database management tool in a single PHP file +Long description: Adminer is a full-featured database management tool written in PHP that consists of a single file ready to deploy to the target server. It supports MySQL, MariaDB, PostgreSQL, CockroachDB, SQLite, MS SQL, Oracle, and through plugins: Elasticsearch, SimpleDB, MongoDB, Firebird, ClickHouse, and IMAP systems. Adminer offers a tidier user interface, better support for database features, higher performance and more security compared to phpMyAdmin. + +## Container deployment + +### Docker Compose Configuration + +Basic deployment example: + +```yaml +services: + adminer: + image: adminer + restart: always + ports: + - 8080:8080 +``` + +Example with database: + +```yaml +services: + adminer: + image: adminer + restart: always + ports: + - 8080:8080 + + db: + image: mysql:5.6 + restart: always + environment: + MYSQL_ROOT_PASSWORD: example +``` + +### Docker Run Command + +Standalone mode with database link: +```bash +docker run --link some_database:db -p 8080:8080 adminer +``` + +Access the interface at `http://localhost:8080` or `http://host-ip:8080`. + +### FastCGI Variant + +For FastCGI-capable web servers: +```bash +docker run --link some_database:db -p 9000:9000 adminer:fastcgi +``` + +**Security Note:** The FastCGI socket exposes to port 9000. Implement firewall rules or use private Docker networks to prevent unauthorized access. + +### Environment Variables + +**ADMINER_PLUGINS:** Load official plugins by passing a space-separated filename list. + +Example: +```yaml +environment: + ADMINER_PLUGINS: 'tables-filter tinymce' +``` + +**Plugin Configuration:** Some plugins require parameters and need custom configuration files mounted in `/var/www/html/plugins-enabled/`. + +Available plugins: https://github.com/vrana/adminer/tree/master/plugins + +### Security Considerations + +1. **Access Control:** Adminer provides direct database access, so it should be placed behind authentication (e.g., Traefik with Authelia) +2. **Network Isolation:** Use private Docker networks instead of exposing ports publicly +3. **Database Credentials:** Never hardcode credentials in compose files; use environment variables or Docker secrets +4. **FastCGI Exposure:** When using the FastCGI variant, ensure port 9000 is not exposed to untrusted networks +5. **Regular Updates:** Keep the Adminer image updated for security patches + +### Supported Architectures + +The official image supports: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, riscv64, and s390x. + +### Database Support + +Adminer can manage the following database systems: +- MySQL / MariaDB +- PostgreSQL / CockroachDB +- SQLite +- MS SQL +- Oracle +- Firebird +- SimpleDB (via plugins) +- Elasticsearch (via plugins) +- MongoDB (via plugins) + +### Recommended Improvements + +1. **Reverse Proxy Integration:** Deploy behind Traefik with authentication middleware +2. **Custom Plugins:** Mount custom plugin configuration for enhanced functionality +3. **Theme Customization:** Adminer supports custom CSS themes that can be mounted +4. **Database Network:** Create a dedicated Docker network for database connections +5. **Read-Only Mode:** For production databases, consider using database user accounts with read-only permissions + +### Example Production-Ready Deployment + +```yaml +services: + adminer: + image: adminer + container_name: adminer + restart: unless-stopped + networks: + - database_network + - proxy_network + environment: + ADMINER_PLUGINS: 'tables-filter tinymce' + labels: + - "traefik.enable=true" + - "traefik.http.routers.adminer.rule=Host(`adminer.example.com`)" + - "traefik.http.routers.adminer.entrypoints=websecure" + - "traefik.http.routers.adminer.tls.certresolver=letsencrypt" + - "traefik.http.routers.adminer.middlewares=authelia@docker" + +networks: + database_network: + external: true + proxy_network: + external: true +``` diff --git a/docs/PRPs/containers/postgresql.md b/docs/PRPs/containers/postgresql.md new file mode 100644 index 00000000..7ac42464 --- /dev/null +++ b/docs/PRPs/containers/postgresql.md @@ -0,0 +1,230 @@ +## Base information for PostgreSQL application + +Application name: PostgreSQL +Homepage: https://www.postgresql.org/ +GitHub page: https://github.com/docker-library/postgres (Docker official image repository) +Install instructions URL: https://hub.docker.com/_/postgres +Category: storage +Dashboard Icon: postgresql.png +Dashboard Group: Storage +Short description: Powerful open source object-relational database system +Long description: PostgreSQL is a powerful, open source object-relational database system with over 35 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. It is positioned as "The world's most advanced open source database". + +## Container deployment + +### Docker Compose Example + +The official documentation provides this basic example with Adminer as a database management interface: + +```yaml +services: + db: + image: postgres + restart: always + shm_size: 128mb + environment: + POSTGRES_PASSWORD: example + + adminer: + image: adminer + restart: always + ports: + - 8080:8080 +``` + +**Important**: Set `shm_size: 128mb` to optimize performance and avoid shared memory issues. + +### Docker Run Command + +Basic startup command: +```bash +docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres +``` + +### Essential Environment Variables + +| Variable | Required | Purpose | +|----------|----------|---------| +| `POSTGRES_PASSWORD` | **Yes** | Sets superuser password; must not be empty | +| `POSTGRES_USER` | No | Creates named superuser (defaults to `postgres`) | +| `POSTGRES_DB` | No | Specifies initial database name | +| `POSTGRES_INITDB_ARGS` | No | Passes arguments to `initdb` (e.g., `--data-checksums`) | +| `POSTGRES_INITDB_WALDIR` | No | Designates transaction log directory | +| `POSTGRES_HOST_AUTH_METHOD` | No | Controls authentication method (default: `scram-sha-256`) | +| `PGDATA` | No | PostgreSQL 18+: `/var/lib/postgresql/18/docker` | + +### Volume Configuration + +**Critical for data persistence:** + +- **PostgreSQL 17 and below**: Mount volumes at `/var/lib/postgresql/data` (not at `/var/lib/postgresql`) +- **PostgreSQL 18+**: Mount at `/var/lib/postgresql` + +The documentation emphasizes: "Mount the data volume at `/var/lib/postgresql/data` and not at `/var/lib/postgresql` because mounts at the latter path will not persist database data when the container is re-created." + +Example with named volume: +```yaml +services: + db: + image: postgres:17 + volumes: + - postgres-data:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: example + +volumes: + postgres-data: +``` + +### Docker Secrets Support + +For secure password handling in production: + +```bash +docker run --name some-postgres \ + -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd \ + -d postgres +``` + +Supported variables with `_FILE` suffix: +- `POSTGRES_PASSWORD_FILE` +- `POSTGRES_USER_FILE` +- `POSTGRES_DB_FILE` +- `POSTGRES_INITDB_ARGS_FILE` + +### Initialization Scripts + +PostgreSQL supports automatic database initialization through scripts placed in `/docker-entrypoint-initdb.d/`: + +- `*.sql` files execute as the PostgreSQL superuser +- `*.sh` executable scripts run with superuser privileges +- Non-executable `*.sh` scripts are sourced + +**Important limitation**: Scripts only run if you start the container with an empty data directory. + +Example initialization script: +```bash +#!/usr/bin/env bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" \ + --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER docker; + CREATE DATABASE docker; + GRANT ALL PRIVILEGES ON DATABASE docker TO docker; +EOSQL +``` + +### Database Configuration + +#### Via Configuration File + +```bash +docker run -d --name some-postgres \ + -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf \ + -e POSTGRES_PASSWORD=mysecretpassword \ + postgres -c 'config_file=/etc/postgresql/postgresql.conf' +``` + +#### Via Command-Line Arguments + +```bash +docker run -d --name some-postgres \ + -e POSTGRES_PASSWORD=mysecretpassword \ + postgres -c shared_buffers=256MB -c max_connections=200 +``` + +In Docker Compose: +```yaml +services: + db: + image: postgres + command: -c shared_buffers=256MB -c max_connections=200 + environment: + POSTGRES_PASSWORD: example +``` + +**Essential for network access**: You must set `listen_addresses = '*'` so that other containers can access PostgreSQL. + +### Networking + +To connect from another container using psql: + +```bash +docker run -it --rm --network some-network postgres \ + psql -h some-postgres -U postgres +``` + +The system uses Unix socket connections internally for initialization scripts. + +### Security Considerations + +1. **Authentication**: + - Local connections use `trust` authentication (no password required from localhost) + - Remote connections require password authentication + - **Not recommended**: Using `trust` for all connections, as it allows anyone to connect without a password + +2. **Password Management**: + - Always set `POSTGRES_PASSWORD` (required) + - Use Docker Secrets for production deployments + - Never commit passwords to version control + +3. **Network Exposure**: + - Don't expose PostgreSQL port (5432) to the public internet without proper firewall rules + - Use reverse proxy or VPN for remote access + - Consider using connection pooling (e.g., PgBouncer) for better resource management + +4. **Data Protection**: + - Enable data checksums with `POSTGRES_INITDB_ARGS=--data-checksums` + - Use named volumes for data persistence + - Implement regular backup strategies + +### Supported Versions + +Current stable releases: +- PostgreSQL 18.1 (latest) +- PostgreSQL 17.7 +- PostgreSQL 16.11 +- PostgreSQL 15.15 +- PostgreSQL 14.20 + +Available as: +- Standard Debian-based images +- Alpine variants (smaller size) +- Version-specific base OS tags (Trixie, Bookworm, Alpine 3.21/3.22) + +### Best Practices + +1. **Data Persistence**: Always use named volumes instead of anonymous volumes +2. **Initialization Timing**: Account for database initialization delay on first startup +3. **Password Management**: Use Docker Secrets for production deployments +4. **Locale Support**: Alpine 15+ supports ICU locales via `POSTGRES_INITDB_ARGS` +5. **Script Safety**: Include `set -e` in shell scripts; use `ON_ERROR_STOP=1` in SQL scripts +6. **Health Checks**: Implement health checks to ensure database availability +7. **Resource Limits**: Set appropriate `shm_size` (at least 128MB recommended) + +### Example Health Check + +```yaml +services: + db: + image: postgres:17 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + environment: + POSTGRES_PASSWORD: example +``` + +### Possible Improvements + +1. **Connection Pooling**: Add PgBouncer container for better connection management +2. **Backup Solution**: Implement automated backups using pg_dump or continuous archiving (WAL-E, pgBackRest) +3. **Monitoring**: Add PostgreSQL exporter for Prometheus monitoring +4. **Replication**: Set up streaming replication for high availability +5. **Performance Tuning**: Optimize postgresql.conf settings based on workload +6. **SSL/TLS**: Enable encrypted connections for security +7. **Extension Management**: Pre-install commonly used extensions (PostGIS, pg_stat_statements, etc.) +8. **Log Management**: Configure log collection and rotation