Taguette
Free and open-source qualitative research tool (which works on all operating systems!)
Check it out here
- Set an A record for all three subdomains (taguette, mailhog, traefik) pointing to the server ip. Wait a bit for it to propagate.
- Install docker + docker compose
- Go to your desired folder and create docker-compose.yaml, .env, and ./data/config.py with the content below
- Set email, domain, and basic auth in .env
Note: For user:password pair, you can use this command:
echo $(htpasswd -nB testuser) | sed -e s/\\$/\\$\\$/g
- Set cookie secret in config.py (and any other desired settings)
To generate a cookie secreet you can use this command:
openssl rand -base64 48
- Run
docker compose up traefik
- Ensure that traefik.${DOMAIN} works
- In a different terminal, run
docker compose run --rm -it taguette
to set password - Ensure taguette.${DOMAIN} works and you can log in with admin user
- Shut down both containers
- Comment out the letsencrypt staging urls and debug and auth logging for traefik
- Run
docker compose up -d
- Enjoy / debug
docker-compose.yaml
version: "3"
services:
traefik:
image: "traefik:v2.3.4"
container_name: traefik
command:
- --log.level=DEBUG
- --accesslog=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --api.dashboard=true
- --certificatesresolvers.myresolver.acme.email=${LE_EMAIL}
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.${DOMAIN}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.dashboard.tls=true"
- "traefik.http.routers.dashboard.tls.certresolver=myresolver"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=${BASIC_AUTH}"
taguette:
image: "quay.io/remram44/taguette:1.4.1"
command: ["server", "/data/config.py"]
labels:
- traefik.enable=true
- traefik.http.routers.echo.rule=Host(`taguette.${DOMAIN}`)
- traefik.http.routers.echo.service=taguette-service
- traefik.http.routers.echo.entrypoints=websecure
- traefik.http.routers.echo.tls.certresolver=myresolver
- traefik.http.routers.echo.tls=true
- traefik.http.services.taguette-service.loadbalancer.server.port=7465
volumes:
- "./data:/data"
mailhog:
image: mailhog/mailhog:v1.0.1
labels:
- traefik.enable=true
- traefik.http.routers.mailhog.rule=Host(`mailhog.${DOMAIN}`)
- traefik.http.routers.mailhog.service=mailhog-service
- traefik.http.routers.mailhog.entrypoints=websecure
- traefik.http.routers.mailhog.tls.certresolver=myresolver
- traefik.http.routers.mailhog.tls=true
- traefik.http.services.mailhog-service.loadbalancer.server.port=8025
- traefik.http.routers.mailhog.middlewares=auth
- "traefik.http.middlewares.auth.basicauth.users=${BASIC_AUTH}"
config.py
# This is the configuration file for Taguette
# It is a Python file, so you can use the full Python syntax
# Name of this server
NAME = "Misconfigured Taguette Server"
# Address and port to listen on
BIND_ADDRESS = "0.0.0.0"
PORT = 7465
# Base path of the application
BASE_PATH = "/"
# A unique secret key that will be used to sign cookies
# set this to something secure and uncomment
# you can e.g. use the command 'openssl rand -base64 48'
SECRET_KEY = "<insert secret key here>"
# Database to use
# This is a SQLAlchemy connection URL; refer to their documentation for info
# https://docs.sqlalchemy.org/en/latest/core/engines.html
# If using SQLite3 on Unix, note the 4 slashes for an absolute path
# (keep 3 before a relative path)
DATABASE = "sqlite:////data/database.sqlite3"
# Redis instance for live collaboration
# This is not required if using a single server, collaboration will still work
#REDIS_SERVER = 'redis://localhost:6379'
# Address to send system emails from
EMAIL = "Misconfigured Taguette Server <taguette@example.com>"
# Terms of service (HTML file)
TOS_FILE = None #'tos.html'
# If set to None, no terms of service link will be displayed anywhere
#TOS_FILE = None
# Extra footer at the bottom of every page
#EXTRA_FOOTER = """
# | This instance of Taguette is managed by Example University.
# Please <a href="mailto:it@example.org">email IT</a> with any questions.
#"""
# Default language
DEFAULT_LANGUAGE = 'en_US'
# SMTP server to use to send emails
MAIL_SERVER = {
"ssl": False,
"host": "mailhog",
"port": 1025,
}
# Whether users must explicitly accept cookies before using the website
COOKIES_PROMPT = False
# Whether new users can create an account
REGISTRATION_ENABLED = True
# Whether users can import projects from SQLite3 files
SQLITE3_IMPORT_ENABLED = True
# Set this to true if you are behind a reverse proxy that sets the
# X-Forwarded-For header.
# Leave this at False if users are connecting to Taguette directly
X_HEADERS = True
# Time limits for converting documents
CONVERT_TO_HTML_TIMEOUT = 3 * 60 # 3min for importing document into Taguette
CONVERT_FROM_HTML_TIMEOUT = 3 * 60 # 3min for exporting from Taguette
# If you want to export metrics using Prometheus, set a port number here
#PROMETHEUS_LISTEN = "0.0.0.0:9101"
# If you want to report errors to Sentry, set your DSN here
#SENTRY_DSN = "https://<key>@sentry.io/<project>"
.env
LE_EMAIL=your@email.here
DOMAIN=yourdomain.com
BASIC_AUTH=testuser:$$2y$$05$$ZWEu/Xe2Xw9uAXpHKKefnudGbzKLLr/c7mnc1cL/UYXTr/k/dotgq