mirror of
https://github.com/nickyeoman/docker-compose-cookbooks.git
synced 2026-09-03 18:36:22 +00:00
fix high-priority stacks: add missing sample.env+README for hedgedoc, memos, posthog, shlink
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
# HedgeDoc
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
HedgeDoc is a self-hosted collaborative markdown editor for creating and sharing real-time notes and documentation. This Docker Compose stack deploys HedgeDoc with SQLite storage and an external reverse proxy.
|
||||||
|
|
||||||
|
## Project Details
|
||||||
|
|
||||||
|
- **Project Repository:** [HedgeDoc](https://hedgedoc.org)
|
||||||
|
- **Container Image:** [GitHub Container Registry](https://github.com/orgs/hedgedoc/packages)
|
||||||
|
- **Compose Example:** [Official Docs](https://docs.hedgedoc.org)
|
||||||
|
- **Documentation:** [Docs](https://docs.hedgedoc.org)
|
||||||
|
- **Reverse Proxy Port:** `3000`
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Copy `sample.env` to `.env` and edit values as needed
|
||||||
|
2. Start the stack: `docker compose up -d`
|
||||||
|
3. Open http://localhost:3000 in your browser
|
||||||
|
|
||||||
|
## Environment Variable Notes
|
||||||
|
|
||||||
|
- `VOL_PATH` – base path for persistent data (default: `/data`)
|
||||||
|
- `HEDGEDOC_IMAGE` – image tag (default: `ghcr.io/hedgedoc/hedgedoc:latest`)
|
||||||
|
- `HEDGEDOC_RESTART` – restart policy (default: `unless-stopped`)
|
||||||
|
- `HEDGEDOC_PORT` – host port (default: `3000`)
|
||||||
|
- `HEDGEDOC_DOMAIN` – server domain (default: `localhost`)
|
||||||
|
- `HEDGEDOC_SSL` – enable HTTPS (default: `false`)
|
||||||
|
- `HEDGEDOC_ADDPORT` – append port to URL (default: `true`)
|
||||||
|
|
||||||
|
## Volume Notes
|
||||||
|
|
||||||
|
- `${VOL_PATH:-/data}/hedgedoc/data` – SQLite database and uploads
|
||||||
|
|
||||||
|
## Network Notes
|
||||||
|
|
||||||
|
Requires the external `proxy` network.
|
||||||
|
|
||||||
|
## Docker Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name hedgedoc \
|
||||||
|
-p 3000:3000 \
|
||||||
|
-e CMD_DB_URL=sqlite:///data/hedgedoc.db \
|
||||||
|
-e CMD_DOMAIN=localhost \
|
||||||
|
-v /data/hedgedoc/data:/hedgedoc/data \
|
||||||
|
ghcr.io/hedgedoc/hedgedoc:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Notes / Gotchas
|
||||||
|
|
||||||
|
- Uses SQLite by default. For PostgreSQL, add `CMD_DB_URL=postgres://...` and a `postgres` service.
|
||||||
|
- For production, set `CMD_DOMAIN` to your actual domain and `CMD_PROTOCOL_USESSL=true`.
|
||||||
|
|
||||||
|
## Dockhand Stack, Deploy from Git
|
||||||
|
|
||||||
|
Cookbooks Repository
|
||||||
|
stackname: hedgedoc
|
||||||
|
Compose file path: hedgedoc_dev/compose.yaml
|
||||||
|
Additional env file (optional): hedgedoc_dev/sample.env
|
||||||
|
|
||||||
|
Then "Load" hedgedoc_dev/sample.env into the Environmental variables in dockhand
|
||||||
|
|
||||||
|
Create the Stack
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
services:
|
||||||
|
hedgedoc:
|
||||||
|
image: ${HEDGEDOC_IMAGE:-ghcr.io/hedgedoc/hedgedoc:latest}
|
||||||
|
restart: ${HEDGEDOC_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/hedgedoc/data:/hedgedoc/data
|
||||||
|
environment:
|
||||||
|
- CMD_DB_URL=sqlite:///data/hedgedoc.db
|
||||||
|
- CMD_DOMAIN=${HEDGEDOC_DOMAIN:-localhost}
|
||||||
|
- CMD_PROTOCOL_USESSL=${HEDGEDOC_SSL:-false}
|
||||||
|
- CMD_URL_ADDPORT=${HEDGEDOC_ADDPORT:-true}
|
||||||
|
ports:
|
||||||
|
- "${HEDGEDOC_PORT:-3000}:3000"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
services:
|
|
||||||
hedgedoc:
|
|
||||||
image: ghcr.io/hedgedoc/hedgedoc:latest
|
|
||||||
container_name: hedgedoc
|
|
||||||
environment:
|
|
||||||
- CMD_DB_URL=sqlite://data/hedgedoc.db
|
|
||||||
volumes:
|
|
||||||
- ./data:/hedgedoc/data
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
data:
|
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Compose
|
||||||
|
VOL_PATH=/data
|
||||||
|
HEDGEDOC_IMAGE=ghcr.io/hedgedoc/hedgedoc:latest
|
||||||
|
HEDGEDOC_RESTART=unless-stopped
|
||||||
|
HEDGEDOC_PORT=3000
|
||||||
|
|
||||||
|
# HedgeDoc
|
||||||
|
HEDGEDOC_DOMAIN=localhost
|
||||||
|
HEDGEDOC_SSL=false
|
||||||
|
HEDGEDOC_ADDPORT=true
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Memos
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Memos is a self-hosted, lightweight note-taking and knowledge-base application with a focus on simplicity and privacy. This Docker Compose stack deploys Memos with persistent storage and an external reverse proxy.
|
||||||
|
|
||||||
|
## Project Details
|
||||||
|
|
||||||
|
- **Project Repository:** [Memos](https://www.usememos.com)
|
||||||
|
- **Container Image:** [Docker Hub](https://hub.docker.com/r/neosmemo/memos)
|
||||||
|
- **Compose Example:** [Official Docs](https://www.usememos.com/docs/install/self-hosting)
|
||||||
|
- **Documentation:** [Docs](https://www.usememos.com/docs)
|
||||||
|
- **Reverse Proxy Port:** `5230`
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Copy `sample.env` to `.env` and edit values as needed
|
||||||
|
2. Start the stack: `docker compose up -d`
|
||||||
|
3. Open http://localhost:5230 in your browser
|
||||||
|
4. Create your admin account on first visit
|
||||||
|
|
||||||
|
## Environment Variable Notes
|
||||||
|
|
||||||
|
- `VOL_PATH` – base path for persistent data (default: `/data`)
|
||||||
|
- `MEMOS_IMAGE` – image tag (default: `neosmemo/memos:stable`)
|
||||||
|
- `MEMOS_RESTART` – restart policy (default: `unless-stopped`)
|
||||||
|
- `MEMOS_PORT` – host port (default: `5230`)
|
||||||
|
|
||||||
|
## Volume Notes
|
||||||
|
|
||||||
|
- `${VOL_PATH:-/data}/memos` – SQLite database, uploads, and user data
|
||||||
|
|
||||||
|
## Network Notes
|
||||||
|
|
||||||
|
Requires the external `proxy` network.
|
||||||
|
|
||||||
|
## Docker Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name memos \
|
||||||
|
-p 5230:5230 \
|
||||||
|
-v /data/memos:/var/opt/memos \
|
||||||
|
neosmemo/memos:stable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Notes / Gotchas
|
||||||
|
|
||||||
|
- Memos uses SQLite by default — no external database needed.
|
||||||
|
- All data is stored in the mounted volume. Back up regularly.
|
||||||
|
|
||||||
|
## Dockhand Stack, Deploy from Git
|
||||||
|
|
||||||
|
Cookbooks Repository
|
||||||
|
stackname: memos
|
||||||
|
Compose file path: memos_dev/compose.yaml
|
||||||
|
Additional env file (optional): memos_dev/sample.env
|
||||||
|
|
||||||
|
Then "Load" memos_dev/sample.env into the Environmental variables in dockhand
|
||||||
|
|
||||||
|
Create the Stack
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
services:
|
||||||
|
memos:
|
||||||
|
image: ${MEMOS_IMAGE:-neosmemo/memos:stable}
|
||||||
|
restart: ${MEMOS_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/memos:/var/opt/memos
|
||||||
|
ports:
|
||||||
|
- "${MEMOS_PORT:-5230}:5230"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#####################################################################################################################################
|
|
||||||
# Memos
|
|
||||||
#
|
|
||||||
# https://www.usememos.com/docs/install/self-hosting
|
|
||||||
#####################################################################################################################################
|
|
||||||
|
|
||||||
services:
|
|
||||||
memos:
|
|
||||||
image: neosmemo/memos:stable
|
|
||||||
container_name: memos
|
|
||||||
volumes:
|
|
||||||
- ~/.memos/:/var/opt/memos
|
|
||||||
ports:
|
|
||||||
- 5230:5230
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Compose
|
||||||
|
VOL_PATH=/data
|
||||||
|
MEMOS_IMAGE=neosmemo/memos:stable
|
||||||
|
MEMOS_RESTART=unless-stopped
|
||||||
|
MEMOS_PORT=5230
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# PostHog
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
PostHog is a self-hosted product analytics platform offering event tracking, session recording, feature flags, and experimentation. This Docker Compose stack deploys PostHog with PostgreSQL, Redis, ClickHouse, and Kafka.
|
||||||
|
|
||||||
|
**Note:** PostHog is resource-intensive. Minimum 4GB RAM, 8GB+ recommended.
|
||||||
|
|
||||||
|
## Project Details
|
||||||
|
|
||||||
|
- **Project Repository:** [PostHog](https://posthog.com)
|
||||||
|
- **Container Image:** [Docker Hub](https://hub.docker.com/r/posthog/posthog)
|
||||||
|
- **Compose Example:** [Official Hobby Compose](https://github.com/PostHog/posthog/blob/master/docker-compose.hobby.yml)
|
||||||
|
- **Documentation:** [Self-Host Docs](https://posthog.com/docs/self-host)
|
||||||
|
- **Reverse Proxy Port:** `8000`
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Copy `sample.env` to `.env` and edit all values (especially `POSTHOG_SECRET_KEY`)
|
||||||
|
2. Start the stack: `docker compose up -d` (first startup will run migrations — this can take several minutes)
|
||||||
|
3. Open http://localhost:8000 in your browser
|
||||||
|
4. Create your admin account on first visit
|
||||||
|
|
||||||
|
## Environment Variable Notes
|
||||||
|
|
||||||
|
### Compose
|
||||||
|
- `VOL_PATH` – base path for persistent data (default: `/data`)
|
||||||
|
- `POSTHOG_IMAGE` – image tag (default: `posthog/posthog:latest`)
|
||||||
|
- `POSTHOG_RESTART` – restart policy (default: `unless-stopped`)
|
||||||
|
|
||||||
|
### Core
|
||||||
|
- `POSTHOG_SITE_URL` – public URL of your PostHog instance (required)
|
||||||
|
- `POSTHOG_SECRET_KEY` – Django secret key for session encryption (required, set to a long random string)
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- `POSTHOG_DB_NAME` – PostgreSQL database name (default: `posthog`)
|
||||||
|
- `POSTHOG_DB_USER` – PostgreSQL user (default: `posthog`)
|
||||||
|
- `POSTHOG_DB_PASSWORD` – PostgreSQL password (required)
|
||||||
|
|
||||||
|
### ClickHouse
|
||||||
|
- `POSTHOG_CLICKHOUSE_DB` – ClickHouse database name (default: `posthog`)
|
||||||
|
- `POSTHOG_CLICKHOUSE_USER` – ClickHouse user (default: `clickhouse`)
|
||||||
|
- `POSTHOG_CLICKHOUSE_PASSWORD` – ClickHouse password (required)
|
||||||
|
|
||||||
|
### Email (optional)
|
||||||
|
- `POSTHOG_EMAIL_HOST` – SMTP server host
|
||||||
|
- `POSTHOG_EMAIL_USER` – SMTP username
|
||||||
|
- `POSTHOG_EMAIL_PASSWORD` – SMTP password
|
||||||
|
- `POSTHOG_EMAIL_PORT` – SMTP port (default: `587`)
|
||||||
|
- `POSTHOG_EMAIL_TLS` – enable TLS (default: `true`)
|
||||||
|
|
||||||
|
## Volume Notes
|
||||||
|
|
||||||
|
- `${VOL_PATH:-/data}/posthog/postgres` – PostgreSQL data
|
||||||
|
- `${VOL_PATH:-/data}/posthog/redis` – Redis data
|
||||||
|
- `${VOL_PATH:-/data}/posthog/clickhouse` – ClickHouse analytics data
|
||||||
|
- `${VOL_PATH:-/data}/posthog/kafka` – Kafka message queue data
|
||||||
|
- `${VOL_PATH:-/data}/posthog/data` – PostHog app data (uploads, exports)
|
||||||
|
- `${VOL_PATH:-/data}/posthog/logs` – application logs
|
||||||
|
|
||||||
|
## Network Notes
|
||||||
|
|
||||||
|
- Requires the external `proxy` network for reverse proxy access.
|
||||||
|
- All backend services communicate over the internal network.
|
||||||
|
|
||||||
|
## Docker Run
|
||||||
|
|
||||||
|
PostHog requires multiple interdependent services. Use the Docker Compose stack rather than individual `docker run` commands.
|
||||||
|
|
||||||
|
## Additional Notes / Gotchas
|
||||||
|
|
||||||
|
- **Resource heavy.** PostHog needs at least 4GB RAM and 10GB disk. ClickHouse and Kafka are memory-intensive.
|
||||||
|
- **First startup is slow.** Migrations run on initial deploy and can take 5–10 minutes. Check logs with `docker compose logs -f posthog`.
|
||||||
|
- **SECRET_KEY must be set.** Generate one with `openssl rand -hex 32` and set it in `.env`.
|
||||||
|
- **Kafka** runs without authentication on the internal network only.
|
||||||
|
- This is a simplified dev deployment. For production, see the [official hobby compose](https://github.com/PostHog/posthog/blob/master/docker-compose.hobby.yml) which includes additional services (plugins, ingestion pipelines, object storage, etc.).
|
||||||
|
- Port 8000 is the internal web port. Proxy it through Nginx Proxy Manager on the `proxy` network.
|
||||||
|
|
||||||
|
## Dockhand Stack, Deploy from Git
|
||||||
|
|
||||||
|
Cookbooks Repository
|
||||||
|
stackname: posthog
|
||||||
|
Compose file path: posthog_dev/compose.yaml
|
||||||
|
Additional env file (optional): posthog_dev/sample.env
|
||||||
|
|
||||||
|
Then "Load" posthog_dev/sample.env into the Environmental variables in dockhand
|
||||||
|
|
||||||
|
Create the Stack
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: ${POSTHOG_POSTGRES_IMAGE:-postgres:15-alpine}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/postgres:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=${POSTHOG_DB_NAME:-posthog}
|
||||||
|
- POSTGRES_USER=${POSTHOG_DB_USER:-posthog}
|
||||||
|
- POSTGRES_PASSWORD=${POSTHOG_DB_PASSWORD:-posthog}
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTHOG_DB_USER:-posthog} -d ${POSTHOG_DB_NAME:-posthog}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: ${POSTHOG_REDIS_IMAGE:-redis:7-alpine}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/redis:/data
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
clickhouse:
|
||||||
|
image: ${POSTHOG_CLICKHOUSE_IMAGE:-clickhouse/clickhouse-server:24-alpine}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/clickhouse:/var/lib/clickhouse
|
||||||
|
environment:
|
||||||
|
- CLICKHOUSE_DB=${POSTHOG_CLICKHOUSE_DB:-posthog}
|
||||||
|
- CLICKHOUSE_USER=${POSTHOG_CLICKHOUSE_USER:-clickhouse}
|
||||||
|
- CLICKHOUSE_PASSWORD=${POSTHOG_CLICKHOUSE_PASSWORD:-clickhouse}
|
||||||
|
- CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
image: ${POSTHOG_KAFKA_IMAGE:-docker.io/bitnami/kafka:3.7}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/kafka:/bitnami/kafka
|
||||||
|
environment:
|
||||||
|
- KAFKA_CFG_NODE_ID=0
|
||||||
|
- KAFKA_CFG_PROCESS_ROLES=controller,broker
|
||||||
|
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
|
||||||
|
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
|
||||||
|
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
|
||||||
|
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092
|
||||||
|
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||||
|
- ALLOW_PLAINTEXT_LISTENER=yes
|
||||||
|
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
|
||||||
|
- KAFKA_CFG_LOG_RETENTION_MS=3600000
|
||||||
|
- KAFKA_CFG_LOG_RETENTION_CHECK_INTERVAL_MS=300000
|
||||||
|
- KAFKA_CFG_LOG_RETENTION_HOURS=1
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
posthog:
|
||||||
|
image: ${POSTHOG_IMAGE:-posthog/posthog:latest}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
command: /compose/start
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/data:/data
|
||||||
|
- ${VOL_PATH:-/data}/posthog/logs:/var/log
|
||||||
|
environment:
|
||||||
|
- SITE_URL=${POSTHOG_SITE_URL:-http://localhost:8000}
|
||||||
|
- SECRET_KEY=${POSTHOG_SECRET_KEY:?must_be_set}
|
||||||
|
- DATABASE_URL=postgres://${POSTHOG_DB_USER:-posthog}:${POSTHOG_DB_PASSWORD:-posthog}@postgres:5432/${POSTHOG_DB_NAME:-posthog}
|
||||||
|
- REDIS_URL=redis://redis:6379/
|
||||||
|
- CLICKHOUSE_HOST=clickhouse
|
||||||
|
- CLICKHOUSE_DATABASE=${POSTHOG_CLICKHOUSE_DB:-posthog}
|
||||||
|
- CLICKHOUSE_USER=${POSTHOG_CLICKHOUSE_USER:-clickhouse}
|
||||||
|
- CLICKHOUSE_PASSWORD=${POSTHOG_CLICKHOUSE_PASSWORD:-clickhouse}
|
||||||
|
- CLICKHOUSE_SECURE=false
|
||||||
|
- CLICKHOUSE_VERIFY=false
|
||||||
|
- KAFKA_HOSTS=kafka:9092
|
||||||
|
- DEPLOYMENT=hobby
|
||||||
|
- OPT_OUT_CAPTURE=true
|
||||||
|
- DISABLE_SECURITY=0
|
||||||
|
- EMAIL_HOST=${POSTHOG_EMAIL_HOST:-}
|
||||||
|
- EMAIL_HOST_USER=${POSTHOG_EMAIL_USER:-}
|
||||||
|
- EMAIL_HOST_PASSWORD=${POSTHOG_EMAIL_PASSWORD:-}
|
||||||
|
- EMAIL_PORT=${POSTHOG_EMAIL_PORT:-587}
|
||||||
|
- EMAIL_USE_TLS=${POSTHOG_EMAIL_TLS:-true}
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
|
- clickhouse
|
||||||
|
- kafka
|
||||||
|
|
||||||
|
worker:
|
||||||
|
image: ${POSTHOG_IMAGE:-posthog/posthog:latest}
|
||||||
|
restart: ${POSTHOG_RESTART:-unless-stopped}
|
||||||
|
command: /compose/worker
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/posthog/data:/data
|
||||||
|
environment:
|
||||||
|
- SITE_URL=${POSTHOG_SITE_URL:-http://localhost:8000}
|
||||||
|
- SECRET_KEY=${POSTHOG_SECRET_KEY:?must_be_set}
|
||||||
|
- DATABASE_URL=postgres://${POSTHOG_DB_USER:-posthog}:${POSTHOG_DB_PASSWORD:-posthog}@postgres:5432/${POSTHOG_DB_NAME:-posthog}
|
||||||
|
- REDIS_URL=redis://redis:6379/
|
||||||
|
- CLICKHOUSE_HOST=clickhouse
|
||||||
|
- CLICKHOUSE_DATABASE=${POSTHOG_CLICKHOUSE_DB:-posthog}
|
||||||
|
- CLICKHOUSE_USER=${POSTHOG_CLICKHOUSE_USER:-clickhouse}
|
||||||
|
- CLICKHOUSE_PASSWORD=${POSTHOG_CLICKHOUSE_PASSWORD:-clickhouse}
|
||||||
|
- CLICKHOUSE_SECURE=false
|
||||||
|
- CLICKHOUSE_VERIFY=false
|
||||||
|
- KAFKA_HOSTS=kafka:9092
|
||||||
|
- DEPLOYMENT=hobby
|
||||||
|
- OPT_OUT_CAPTURE=true
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- redis
|
||||||
|
- clickhouse
|
||||||
|
- kafka
|
||||||
|
- posthog
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
# https://hub.docker.com/r/posthog/posthog
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Compose
|
||||||
|
VOL_PATH=/data
|
||||||
|
POSTHOG_IMAGE=posthog/posthog:latest
|
||||||
|
POSTHOG_RESTART=unless-stopped
|
||||||
|
|
||||||
|
# Core
|
||||||
|
POSTHOG_SITE_URL=http://localhost:8000
|
||||||
|
POSTHOG_SECRET_KEY=ChangeMeToALongRandomStringHere
|
||||||
|
|
||||||
|
# Database
|
||||||
|
POSTHOG_DB_NAME=posthog
|
||||||
|
POSTHOG_DB_USER=posthog
|
||||||
|
POSTHOG_DB_PASSWORD=ChangeThisPassword
|
||||||
|
|
||||||
|
# ClickHouse
|
||||||
|
POSTHOG_CLICKHOUSE_DB=posthog
|
||||||
|
POSTHOG_CLICKHOUSE_USER=clickhouse
|
||||||
|
POSTHOG_CLICKHOUSE_PASSWORD=ChangeThisPassword
|
||||||
|
|
||||||
|
# Email (optional)
|
||||||
|
POSTHOG_EMAIL_HOST=
|
||||||
|
POSTHOG_EMAIL_USER=
|
||||||
|
POSTHOG_EMAIL_PASSWORD=
|
||||||
|
POSTHOG_EMAIL_PORT=587
|
||||||
|
POSTHOG_EMAIL_TLS=true
|
||||||
+102
-4
@@ -1,9 +1,107 @@
|
|||||||
# Shlink
|
# Shlink
|
||||||
|
|
||||||
Work in progress.
|
## Overview
|
||||||
|
|
||||||
|
Shlink is a self-hosted URL shortener with a REST API and web client for managing short links, tracking visits, and generating QR codes. This Docker Compose stack deploys Shlink with MariaDB, the web client, and an external reverse proxy.
|
||||||
|
|
||||||
## Gotcha
|
## Project Details
|
||||||
|
|
||||||
The web client doesn't have user authentication by default.
|
- **Project Repository:** [Shlink](https://shlink.io)
|
||||||
I used nginx proxy manager to block it.
|
- **Container Image:** [Docker Hub](https://hub.docker.com/r/shlinkio/shlink)
|
||||||
|
- **Compose Example:** [Official Docs](https://shlink.io/documentation/install-docker/)
|
||||||
|
- **Documentation:** [Docs](https://shlink.io/documentation)
|
||||||
|
- **Reverse Proxy Port:** `8080` (Shlink API), `8003` (web client)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Copy `sample.env` to `.env` and edit all values (especially `SHLINK_DOMAIN`, database passwords)
|
||||||
|
2. Start the stack: `docker compose up -d`
|
||||||
|
3. Access the Shlink REST API at http://localhost:8080
|
||||||
|
4. Access the web client at http://localhost:8003
|
||||||
|
5. Configure the web client with your Shlink server URL and API key (generate one via the CLI)
|
||||||
|
|
||||||
|
## Environment Variable Notes
|
||||||
|
|
||||||
|
### Compose
|
||||||
|
- `VOL_PATH` – base path for persistent data (default: `/data`)
|
||||||
|
- `SHLINK_IMAGE` – Shlink image tag (default: `shlinkio/shlink:latest`)
|
||||||
|
- `SHLINK_WEB_CLIENT_IMAGE` – web client image tag (default: `shlinkio/shlink-web-client:latest`)
|
||||||
|
- `SHLINK_RESTART` – restart policy (default: `unless-stopped`)
|
||||||
|
- `SHLINK_PORT` – Shlink API host port (default: `8080`)
|
||||||
|
- `SHLINK_WEB_CLIENT_PORT` – web client host port (default: `8003`)
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- `MARIADB_IMAGE` – MariaDB image tag (default: `mariadb:10.11`)
|
||||||
|
- `MARIADB_ROOT_PASSWORD` – MariaDB root password (required)
|
||||||
|
- `SHLINK_DB_NAME` – database name (default: `shlink`)
|
||||||
|
- `SHLINK_DB_USER` – database user (default: `shlink`)
|
||||||
|
- `SHLINK_DB_PASSWORD` – database password (required)
|
||||||
|
|
||||||
|
### Shlink
|
||||||
|
- `SHLINK_DOMAIN` – default short domain (default: `localhost`)
|
||||||
|
- `SHLINK_HTTPS` – whether HTTPS is enabled (default: `false`)
|
||||||
|
- `SHLINK_REDIRECT_URL` – base URL redirect for unknown short codes (default: `https://localhost`)
|
||||||
|
- `TZ` – timezone (default: `America/Vancouver`)
|
||||||
|
|
||||||
|
## Volume Notes
|
||||||
|
|
||||||
|
- `${VOL_PATH:-/data}/shlink/db` – MariaDB data files
|
||||||
|
- `${VOL_PATH:-/data}/shlink/web-client` – web client static config (servers.json)
|
||||||
|
|
||||||
|
## Network Notes
|
||||||
|
|
||||||
|
Requires the external `proxy` network for reverse proxy access.
|
||||||
|
|
||||||
|
## Docker Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name shlink-mariadb \
|
||||||
|
-e MARIADB_DATABASE=shlink \
|
||||||
|
-e MARIADB_USER=shlink \
|
||||||
|
-e MARIADB_PASSWORD=ChangeThisPassword \
|
||||||
|
-e MARIADB_ROOT_PASSWORD=ChangeThisRootPassword \
|
||||||
|
-v /data/shlink/db:/var/lib/mysql \
|
||||||
|
mariadb:10.11
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name shlink \
|
||||||
|
-p 8080:8080 \
|
||||||
|
-e DEFAULT_DOMAIN=localhost \
|
||||||
|
-e IS_HTTPS_ENABLED=false \
|
||||||
|
-e DB_DRIVER=maria \
|
||||||
|
-e DB_HOST=mariadb \
|
||||||
|
-e DB_NAME=shlink \
|
||||||
|
-e DB_USER=shlink \
|
||||||
|
-e DB_PASSWORD=ChangeThisPassword \
|
||||||
|
-e DEFAULT_BASE_URL_REDIRECT=https://localhost \
|
||||||
|
shlinkio/shlink:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name shlink-web-client \
|
||||||
|
-p 8003:80 \
|
||||||
|
-v /data/shlink/web-client:/usr/share/nginx/html \
|
||||||
|
shlinkio/shlink-web-client:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Notes / Gotchas
|
||||||
|
|
||||||
|
- The web client does **not** have built-in user authentication. Use Nginx Proxy Manager (or similar) to add basic auth or IP restrictions in front of it.
|
||||||
|
- Generate an API key after starting: `docker compose exec shlink shlink api-key:generate`
|
||||||
|
- Use the API key to configure the web client under "Settings > Manage Servers".
|
||||||
|
- After changing `SHLINK_DOMAIN`, you must update the domain in Shlink's config or via the API.
|
||||||
|
|
||||||
|
## Dockhand Stack, Deploy from Git
|
||||||
|
|
||||||
|
Cookbooks Repository
|
||||||
|
stackname: shlink
|
||||||
|
Compose file path: shlink_dev/compose.yaml
|
||||||
|
Additional env file (optional): shlink_dev/sample.env
|
||||||
|
|
||||||
|
Then "Load" shlink_dev/sample.env into the Environmental variables in dockhand
|
||||||
|
|
||||||
|
Create the Stack
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
services:
|
||||||
|
mariadb:
|
||||||
|
image: ${MARIADB_IMAGE:-mariadb:10.11}
|
||||||
|
restart: ${SHLINK_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/shlink/db:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MARIADB_DATABASE=${SHLINK_DB_NAME:-shlink}
|
||||||
|
- MARIADB_USER=${SHLINK_DB_USER:-shlink}
|
||||||
|
- MARIADB_PASSWORD=${SHLINK_DB_PASSWORD:-ChangeThisPassword}
|
||||||
|
- MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD:-ChangeThisRootPassword}
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
shlink:
|
||||||
|
image: ${SHLINK_IMAGE:-shlinkio/shlink:latest}
|
||||||
|
restart: ${SHLINK_RESTART:-unless-stopped}
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ:-America/Vancouver}
|
||||||
|
- DEFAULT_DOMAIN=${SHLINK_DOMAIN:-localhost}
|
||||||
|
- IS_HTTPS_ENABLED=${SHLINK_HTTPS:-false}
|
||||||
|
- DB_DRIVER=maria
|
||||||
|
- DB_HOST=mariadb
|
||||||
|
- DB_NAME=${SHLINK_DB_NAME:-shlink}
|
||||||
|
- DB_USER=${SHLINK_DB_USER:-shlink}
|
||||||
|
- DB_PASSWORD=${SHLINK_DB_PASSWORD:-ChangeThisPassword}
|
||||||
|
- DEFAULT_BASE_URL_REDIRECT=${SHLINK_REDIRECT_URL:-https://localhost}
|
||||||
|
ports:
|
||||||
|
- "${SHLINK_PORT:-8080}:8080"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
|
||||||
|
shlink-web-client:
|
||||||
|
image: ${SHLINK_WEB_CLIENT_IMAGE:-shlinkio/shlink-web-client:latest}
|
||||||
|
restart: ${SHLINK_RESTART:-unless-stopped}
|
||||||
|
volumes:
|
||||||
|
- ${VOL_PATH:-/data}/shlink/web-client:/usr/share/nginx/html
|
||||||
|
ports:
|
||||||
|
- "${SHLINK_WEB_CLIENT_PORT:-8003}:80"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
services:
|
|
||||||
|
|
||||||
mariadb-shlink:
|
|
||||||
image: mariadb:10.7.1 # https://hub.docker.com/_/mariadb
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
MYSQL_ROOT_PASSWORD: change
|
|
||||||
MYSQL_USER: shlink
|
|
||||||
MYSQL_PASSWORD: changea
|
|
||||||
MYSQL_DATABASE: shlinkdb
|
|
||||||
volumes:
|
|
||||||
- ./data/shlink-db:/var/lib/mysql
|
|
||||||
- "/etc/timezone:/etc/timezone:ro"
|
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
|
||||||
networks:
|
|
||||||
- 4lt_internal
|
|
||||||
|
|
||||||
shlink:
|
|
||||||
# proxy to port 8080
|
|
||||||
image: shlinkio/shlink:3.6.1
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- TZ=America/Vancouver
|
|
||||||
- DEFAULT_DOMAIN=4lt.ca
|
|
||||||
- IS_HTTPS_ENABLED=true
|
|
||||||
- DB_DRIVER=maria
|
|
||||||
- DB_USER=shlink
|
|
||||||
- DB_NAME=shlinkdb
|
|
||||||
- DB_PASSWORD=change
|
|
||||||
- DB_HOST=mariadb-shlink
|
|
||||||
- DEFAULT_BASE_URL_REDIRECT=https://www.domain.ca
|
|
||||||
|
|
||||||
shlink-web-client:
|
|
||||||
image: shlinkio/shlink-web-client
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- ./shlink/servers.json:/usr/share/nginx/html/servers.json
|
|
||||||
ports:
|
|
||||||
- 8003:80
|
|
||||||
|
|
||||||
networks:
|
|
||||||
- 4lt_internal
|
|
||||||
- admin_web
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Compose
|
||||||
|
VOL_PATH=/data
|
||||||
|
SHLINK_IMAGE=shlinkio/shlink:latest
|
||||||
|
SHLINK_WEB_CLIENT_IMAGE=shlinkio/shlink-web-client:latest
|
||||||
|
SHLINK_RESTART=unless-stopped
|
||||||
|
SHLINK_PORT=8080
|
||||||
|
SHLINK_WEB_CLIENT_PORT=8003
|
||||||
|
|
||||||
|
# MariaDB
|
||||||
|
MARIADB_IMAGE=mariadb:10.11
|
||||||
|
MARIADB_ROOT_PASSWORD=ChangeThisRootPassword
|
||||||
|
|
||||||
|
# Shlink Database
|
||||||
|
SHLINK_DB_NAME=shlink
|
||||||
|
SHLINK_DB_USER=shlink
|
||||||
|
SHLINK_DB_PASSWORD=ChangeThisPassword
|
||||||
|
|
||||||
|
# Shlink
|
||||||
|
SHLINK_DOMAIN=localhost
|
||||||
|
SHLINK_HTTPS=false
|
||||||
|
SHLINK_REDIRECT_URL=https://localhost
|
||||||
|
TZ=America/Vancouver
|
||||||
Reference in New Issue
Block a user