Sign inSign up

certyiknofetch/memos

By certyiknofetch

Updated 7 months ago

Image
0

1.4K

certyiknofetch/memos repository overview


Memos — Secure, Self-Hosted Note-Taking Service

A privacy-focused, lightweight, self-hosted memo hub for capturing and organizing your thoughts. Built with security hardened for public deployment.

Docker Image Version Docker Image Size Docker Pulls

Features

  • Markdown Editor with formatting toolbar (bold, italic, headings, code, lists, links, and more)
  • Visibility ControlsPUBLIC, PROTECTED, and PRIVATE notes with enforced access control
  • Multi-Database Support — SQLite, MySQL, and PostgreSQL
  • Multi-Platformlinux/amd64 and linux/arm64
  • Security Hardened — Content Security Policy, CORS enforcement, path traversal protection, IDOR prevention, input sanitization, and more
  • File Attachments — Upload images and files with visibility-aware access control and caching
  • RSS Feeds — Share public memos via RSS
  • SSO / OAuth — Integrate with external identity providers
  • Personal Access Tokens — App-based authentication with configurable expiry (8 hours, 1 month, or never)
  • PWA Ready — Installable as a Progressive Web App
  • RESTful & gRPC API — Full API access for automation and integrations
  • Runs as Non-Root — Container runs as a non-root user for improved security

Quick Start

SQLite (Default — Zero Configuration)
docker run -d \
  --name memos \
  -p 5230:5230 \
  -v memos-data:/var/opt/memos \
  certyiknofetch/memos:latest

Access at http://localhost:5230. The first user to sign up becomes the admin.


Database Configuration

SQLite (Default)

No additional configuration needed. Data is stored in /var/opt/memos/.

services:
  memos:
    image: certyiknofetch/memos:latest
    ports:
      - "5230:5230"
    volumes:
      - memos-data:/var/opt/memos

volumes:
  memos-data:
MySQL
services:
  memos:
    image: certyiknofetch/memos:latest
    environment:
      - MEMOS_DRIVER=mysql
      - MEMOS_DSN=memos:your_secure_password@tcp(mysql:3306)/memos?parseTime=true&tls=preferred
    ports:
      - "5230:5230"
    volumes:
      - memos-data:/var/opt/memos
    depends_on:
      mysql:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root_secure_password
      - MYSQL_USER=memos
      - MYSQL_PASSWORD=your_secure_password
      - MYSQL_DATABASE=memos
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  memos-data:
  mysql-data:
PostgreSQL
services:
  memos:
    image: certyiknofetch/memos:latest
    environment:
      - MEMOS_DRIVER=postgres
      - MEMOS_DSN=postgresql://memos:your_secure_password@postgres:5432/memos?sslmode=disable
    ports:
      - "5230:5230"
    volumes:
      - memos-data:/var/opt/memos
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16
    environment:
      - POSTGRES_USER=memos
      - POSTGRES_PASSWORD=your_secure_password
      - POSTGRES_DB=memos
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U memos"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  memos-data:
  postgres-data:

Environment Variables

VariableDefaultDescription
MEMOS_DRIVERsqliteDatabase driver: sqlite, mysql, or postgres
MEMOS_DSN(auto)Database connection string (auto-configured for SQLite)
MEMOS_DSN_FILEPath to a file containing the DSN (Docker Secrets support)
MEMOS_PORT5230Server port
MEMOS_ADDR(all interfaces)Bind address
MEMOS_DATA/var/opt/memosData directory for SQLite database and uploaded files
MEMOS_INSTANCE_URLPublic URL of your instance (used for RSS feeds and links)
MEMOS_UID10001UID for the non-root user
MEMOS_GID10001GID for the non-root user
TZUTCTimezone

Docker Secrets Support

For secure DSN handling, use MEMOS_DSN_FILE instead of MEMOS_DSN:

services:
  memos:
    image: certyiknofetch/memos:latest
    environment:
      - MEMOS_DRIVER=mysql
      - MEMOS_DSN_FILE=/run/secrets/memos_dsn
    secrets:
      - memos_dsn

secrets:
  memos_dsn:
    file: ./memos_dsn.txt

Reverse Proxy (Nginx Proxy Manager)

When deploying behind a reverse proxy:

  1. Set up the proxy to forward to memos:5230
  2. Enable WebSocket support if needed
  3. The application handles X-Forwarded-Proto and X-Forwarded-Host headers securely
  4. Recommended: Enable HTTPS on the proxy for secure cookie handling

Volumes

PathPurpose
/var/opt/memosApplication data — SQLite database (if used) and uploaded attachments

Important: Back up this directory regularly, especially when using SQLite.


Supported Architectures

ArchitectureTag
linux/amd64latest, 1.1
linux/arm64latest, 1.1

Security Highlights

  • Non-root container — Runs as UID 10001 by default
  • Content Security Policy — Enforced CSP headers to prevent XSS
  • Visibility enforcement — Private and protected content requires authentication at the API level
  • Path traversal protection — All file operations validated against directory traversal attacks
  • Input sanitization — URL, filename, and content sanitization throughout
  • Secure cookies — HttpOnly, Secure, SameSite flags on auth cookies
  • Rate limiting — Built-in rate limiting on authentication endpoints
  • CORS enforcement — Strict CORS policy in production

Upgrading

docker pull certyiknofetch/memos:latest
docker stop memos
docker rm memos
docker run -d \
  --name memos \
  -p 5230:5230 \
  -v memos-data:/var/opt/memos \
  certyiknofetch/memos:latest

Database migrations are applied automatically on startup.


Tags

  • latest — Most recent stable build
  • 1.1 — Specific version tag

Source

Based on Memos with security hardening and enhancements.

Tag summary

Content type

Image

Digest

sha256:3fbf343e2

Size

18.7 MB

Last updated

7 months ago

docker pull certyiknofetch/memos