mirror of
https://github.com/usetrmnl/inker.git
synced 2026-04-29 13:45:07 -07:00
v0.2.0 — BYOD support, canvas zoom, CORS hardening, local network data sources
- BYOD: Register any e-ink device manually with custom resolution - Canvas zoom: Auto-fit, +/-/fit controls, Ctrl+scroll - Alternative device types: /api/setup HTTP_MODEL header → dimensions lookup - Local network data sources: Settings toggle with SSRF safety guardrails - CORS: Same-origin default, opt-in via CORS_ORIGINS env - Models tab removed (devices have width/height, designer has presets) - Dashboard Connect Device buttons redirect to /devices/new - Version bumped to 0.2.0 across all packages and Swagger
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
**/node_modules
|
||||
npm-debug.log
|
||||
.git
|
||||
.gitignore
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
.vscode
|
||||
.idea
|
||||
coverage
|
||||
*.log
|
||||
.DS_Store
|
||||
|
||||
# Dev files
|
||||
backend/Dockerfile.dev
|
||||
frontend/Dockerfile.dev
|
||||
docker-compose.dev.yml
|
||||
|
||||
# Private/CI files
|
||||
.drone.yml
|
||||
start.sh
|
||||
backend/start.sh
|
||||
|
||||
# Test output
|
||||
.nyc_output
|
||||
|
||||
# Upload data (mounted as volume)
|
||||
backend/uploads/*
|
||||
!backend/uploads/.gitkeep
|
||||
|
||||
# Build artifacts (rebuilt in Docker)
|
||||
backend/dist
|
||||
frontend/dist
|
||||
@@ -0,0 +1,15 @@
|
||||
# Inker Configuration
|
||||
# Copy this file to .env and modify as needed:
|
||||
# cp .env.example .env
|
||||
|
||||
# Admin PIN for login (change this!)
|
||||
ADMIN_PIN="1111"
|
||||
|
||||
# Database password (change for production!)
|
||||
POSTGRES_PASSWORD=inker_password
|
||||
|
||||
# Timezone for clock/date widgets
|
||||
TZ=UTC
|
||||
|
||||
# Frontend port (default: 80)
|
||||
INKER_PORT=80
|
||||
@@ -0,0 +1,18 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- name: Test backend
|
||||
run: cd backend && bun install --frozen-lockfile && bun test
|
||||
- name: Test frontend
|
||||
run: cd frontend && bun install --frozen-lockfile && bun run test
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*.*.*'
|
||||
- '*.*.*-*'
|
||||
|
||||
env:
|
||||
IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/inker
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Test backend
|
||||
run: cd backend && bun install --frozen-lockfile && bun test
|
||||
|
||||
- name: Test frontend
|
||||
run: cd frontend && bun install --frozen-lockfile && bun run test
|
||||
|
||||
build-and-push:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.IMAGE }}:${{ github.ref_name }}
|
||||
${{ env.IMAGE }}:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Build
|
||||
dist/
|
||||
build/
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
logs.txt
|
||||
npm-debug.log*
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Docker volumes (local data)
|
||||
postgres_data/
|
||||
redis_data/
|
||||
|
||||
# Docker local overrides
|
||||
docker-compose.override.yml
|
||||
|
||||
# Uploads (user generated)
|
||||
uploads/*
|
||||
!uploads/.gitkeep
|
||||
|
||||
# Package locks (optional - keep if you want reproducible builds)
|
||||
# package-lock.json
|
||||
# bun.lockb
|
||||
|
||||
# Test coverage
|
||||
coverage/
|
||||
.nyc_output/
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
# All-in-one Dockerfile for Inker
|
||||
# Bundles: frontend (nginx), backend (bun/nestjs), PostgreSQL 17, Redis 8
|
||||
|
||||
# =============================================================================
|
||||
# Stage 1: Build frontend
|
||||
# =============================================================================
|
||||
FROM oven/bun:1-alpine AS frontend-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY frontend/package.json frontend/bun.lock* ./
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
COPY frontend/ .
|
||||
RUN bun run build
|
||||
|
||||
# =============================================================================
|
||||
# Stage 2: Install backend production dependencies
|
||||
# =============================================================================
|
||||
FROM oven/bun:1-slim AS backend-install
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Node.js binary for Prisma generate (bun segfaults with Prisma CLI)
|
||||
COPY --from=node:22-slim /usr/local/bin/node /usr/local/bin/node
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends openssl && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY backend/package.json backend/bun.lock* ./
|
||||
COPY backend/prisma ./prisma/
|
||||
|
||||
# Install all deps → generate prisma → reinstall production-only → prune
|
||||
RUN bun install --frozen-lockfile && \
|
||||
node ./node_modules/prisma/build/index.js generate && \
|
||||
cp -r node_modules/.prisma /tmp/.prisma && \
|
||||
rm -rf node_modules && \
|
||||
bun install --production --frozen-lockfile && \
|
||||
cp -r /tmp/.prisma node_modules/.prisma && \
|
||||
rm -rf /tmp/.prisma \
|
||||
node_modules/typescript \
|
||||
node_modules/@types && \
|
||||
# Prune unnecessary files from production node_modules
|
||||
find node_modules \( \
|
||||
-name "*.md" -o -name "*.map" -o -name "CHANGELOG*" -o \
|
||||
-name "README*" -o -name "LICENSE*" -o -name "*.d.ts" -o \
|
||||
-name "*.test.*" -o -name "*.spec.*" -o \
|
||||
-name "__tests__" -o -name "docs" -o -name ".github" -o \
|
||||
-name "example" -o -name "examples" -o -name ".npmignore" -o \
|
||||
-name "tsconfig.json" -o -name ".eslintrc*" -o -name ".prettierrc*" \
|
||||
\) -exec rm -rf {} + 2>/dev/null || true && \
|
||||
# Remove swagger UI (not needed in production)
|
||||
rm -rf node_modules/swagger-ui-dist && \
|
||||
# Remove musl variants of sharp (only glibc needed on Debian)
|
||||
rm -rf node_modules/@img/sharp-libvips-linuxmusl-x64 \
|
||||
node_modules/@img/sharp-linuxmusl-x64
|
||||
|
||||
# =============================================================================
|
||||
# Stage 3: Build backend
|
||||
# =============================================================================
|
||||
FROM oven/bun:1-slim AS backend-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=node:22-slim /usr/local/bin/node /usr/local/bin/node
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends openssl && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY backend/package.json backend/bun.lock* ./
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
COPY backend/prisma ./prisma/
|
||||
RUN node ./node_modules/prisma/build/index.js generate
|
||||
|
||||
COPY backend/ .
|
||||
RUN bun run build
|
||||
|
||||
# =============================================================================
|
||||
# Stage 4: Production (all-in-one)
|
||||
# =============================================================================
|
||||
FROM debian:trixie-slim AS production
|
||||
|
||||
ARG S6_OVERLAY_VERSION=3.2.1.0
|
||||
|
||||
# Install all system packages in one layer
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# PostgreSQL
|
||||
postgresql-17 \
|
||||
# Redis
|
||||
redis-server \
|
||||
# Nginx
|
||||
nginx \
|
||||
# Chrome headless shell dependencies
|
||||
wget ca-certificates openssl unzip \
|
||||
fonts-liberation fontconfig \
|
||||
libnss3 libatk-bridge2.0-0t64 libdrm2 libxkbcommon0 \
|
||||
libgbm1 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
|
||||
libasound2t64 libcups2t64 libatk1.0-0t64 libnspr4 libdbus-1-3 \
|
||||
# s6-overlay dependencies
|
||||
xz-utils \
|
||||
&& \
|
||||
# Install Chrome Headless Shell
|
||||
CHROME_VERSION=$(wget -qO- "https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE") && \
|
||||
wget -q "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chrome-headless-shell-linux64.zip" -O /tmp/chrome.zip && \
|
||||
unzip /tmp/chrome.zip -d /opt/ && \
|
||||
chmod +x /opt/chrome-headless-shell-linux64/chrome-headless-shell && \
|
||||
rm /tmp/chrome.zip && \
|
||||
# Strip Chrome: remove GPU libs (--disable-gpu), keep only en-US locale, remove hyphen data
|
||||
rm -f /opt/chrome-headless-shell-linux64/libEGL.so \
|
||||
/opt/chrome-headless-shell-linux64/libGLESv2.so \
|
||||
/opt/chrome-headless-shell-linux64/libvk_swiftshader.so \
|
||||
/opt/chrome-headless-shell-linux64/libvulkan.so.1 \
|
||||
/opt/chrome-headless-shell-linux64/vk_swiftshader_icd.json \
|
||||
/opt/chrome-headless-shell-linux64/LICENSE.headless_shell && \
|
||||
find /opt/chrome-headless-shell-linux64/locales -type f ! -name 'en-US.pak' -delete && \
|
||||
rm -rf /opt/chrome-headless-shell-linux64/hyphen-data && \
|
||||
# Install s6-overlay
|
||||
wget -q "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" -O /tmp/s6-noarch.tar.xz && \
|
||||
tar -C / -Jxpf /tmp/s6-noarch.tar.xz && \
|
||||
wget -q "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz" -O /tmp/s6-x86_64.tar.xz && \
|
||||
tar -C / -Jxpf /tmp/s6-x86_64.tar.xz && \
|
||||
rm /tmp/s6-noarch.tar.xz /tmp/s6-x86_64.tar.xz && \
|
||||
# Install PostgreSQL 15 from PGDG for data migration (15→17) support
|
||||
# Existing users upgrading from bookworm need PG 15 binaries to dump their data
|
||||
echo "deb http://apt.postgresql.org/pub/repos/apt trixie-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \
|
||||
wget -qO /etc/apt/trusted.gpg.d/pgdg.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc && \
|
||||
apt-get update -qq && \
|
||||
apt-get install -y -qq --no-install-recommends postgresql-15 >/dev/null 2>&1 && \
|
||||
rm -rf /var/lib/postgresql/15 /etc/apt/sources.list.d/pgdg.list && \
|
||||
# Remove build-only tools normally
|
||||
apt-get purge -y unzip xz-utils wget && apt-get autoremove -y && \
|
||||
# Force-remove transitive deps not needed at runtime
|
||||
# (bypass dependency checks to avoid cascading removal of postgresql/chrome)
|
||||
dpkg --purge --force-depends \
|
||||
libllvm19 libz3-4 libperl5.40 perl perl-modules-5.40 \
|
||||
libavahi-client3 libavahi-common-data libavahi-common3 \
|
||||
libelf1t64 libc-l10n locales \
|
||||
2>/dev/null || true && \
|
||||
rm -rf /var/lib/apt/lists/* /var/log/dpkg.log /var/log/apt && \
|
||||
# Remove system locales and unused data (keep only C/POSIX and en_US)
|
||||
rm -rf /usr/share/locale /usr/share/i18n /usr/share/doc /usr/share/man \
|
||||
/usr/share/info /usr/share/lintian /usr/share/X11/xkb \
|
||||
/var/cache/debconf/*-old && \
|
||||
# Remove auto-created PostgreSQL cluster (will be initialized on first run)
|
||||
rm -rf /var/lib/postgresql/17/main/*
|
||||
|
||||
# Install Bun runtime (copy from build image)
|
||||
COPY --from=oven/bun:1-slim /usr/local/bin/bun /usr/local/bin/bun
|
||||
RUN ln -s /usr/local/bin/bun /usr/local/bin/bunx
|
||||
|
||||
# Puppeteer configuration
|
||||
ENV PUPPETEER_EXECUTABLE_PATH=/opt/chrome-headless-shell-linux64/chrome-headless-shell
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||
|
||||
# Application environment defaults
|
||||
ENV NODE_ENV=production \
|
||||
PORT=3002 \
|
||||
DATABASE_URL=postgresql://inker_user:inker_password@localhost:5432/inker_db \
|
||||
REDIS_HOST=localhost \
|
||||
REDIS_PORT=6379 \
|
||||
REDIS_PASSWORD=inker_redis \
|
||||
REDIS_URL=redis://:inker_redis@localhost:6379 \
|
||||
ADMIN_PIN="1111" \
|
||||
CORS_ORIGINS=* \
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Set up application directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy backend production dependencies
|
||||
COPY --from=backend-install /app/node_modules ./node_modules
|
||||
|
||||
# Copy Prisma schema and generated client
|
||||
COPY backend/prisma ./prisma/
|
||||
COPY --from=backend-install /app/node_modules/.prisma ./node_modules/.prisma
|
||||
COPY --from=backend-install /app/node_modules/@prisma ./node_modules/@prisma
|
||||
|
||||
# Copy backend build
|
||||
COPY --from=backend-builder /app/dist ./dist
|
||||
COPY backend/package.json ./
|
||||
|
||||
# Copy backend font assets
|
||||
COPY backend/assets/fonts /app/assets/fonts
|
||||
|
||||
# Copy frontend build to nginx html directory
|
||||
COPY --from=frontend-builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy frontend font files
|
||||
COPY frontend/public/fonts /usr/share/nginx/html/fonts
|
||||
|
||||
# Copy nginx config
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
RUN rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Copy s6-overlay service definitions
|
||||
COPY docker/cont-init.d/ /etc/cont-init.d/
|
||||
COPY docker/services.d/ /etc/services.d/
|
||||
RUN chmod +x /etc/cont-init.d/* && \
|
||||
chmod +x /etc/services.d/*/run
|
||||
|
||||
# Create required directories
|
||||
RUN mkdir -p /app/uploads/screens /app/uploads/firmware /app/uploads/widgets \
|
||||
/app/uploads/captures /app/uploads/drawings /app/logs \
|
||||
/data /var/lib/postgresql/17/main /run/postgresql && \
|
||||
chown -R postgres:postgres /var/lib/postgresql /run/postgresql
|
||||
|
||||
# Create non-root user for backend process
|
||||
RUN useradd --system --no-create-home --shell /usr/sbin/nologin inker && \
|
||||
chown -R inker:inker /app
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
# Health check via nginx
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
|
||||
CMD bun -e "const r=await fetch('http://127.0.0.1/health');process.exit(r.ok?0:1)" || exit 1
|
||||
|
||||
# s6-overlay entrypoint
|
||||
ENTRYPOINT ["/init"]
|
||||
@@ -0,0 +1,172 @@
|
||||
Inker - Source Available License
|
||||
License Version 1.1
|
||||
|
||||
Copyright (c) 2025-2026 Wojtek (wojo)
|
||||
All rights reserved.
|
||||
|
||||
|
||||
DEFINITIONS
|
||||
|
||||
"Software" means the Inker source code, documentation, assets, and any
|
||||
associated files in this repository.
|
||||
|
||||
"Personal Use" means use by an individual for private, non-commercial
|
||||
purposes where the Software does not directly or indirectly generate
|
||||
revenue.
|
||||
|
||||
"Internal Organizational Use" means use within an organization solely for
|
||||
that organization's own operational purposes, provided the Software is not
|
||||
offered to third parties and does not form a component of any product or
|
||||
service provided to third parties, whether for a fee or otherwise.
|
||||
|
||||
"Contribution" means any modification, addition, or improvement submitted
|
||||
to the original repository via pull request, patch, or other mechanism.
|
||||
|
||||
"Original Repository" means the official Inker repository maintained by the
|
||||
copyright holder at its designated hosting location.
|
||||
|
||||
|
||||
1. GRANT OF LICENSE
|
||||
|
||||
Subject to the terms and conditions of this license, the copyright holder
|
||||
grants you a limited, non-exclusive, non-transferable, non-sublicensable,
|
||||
revocable license to:
|
||||
|
||||
(a) View, download, and run the Software for Personal Use.
|
||||
(b) Run the Software for Internal Organizational Use.
|
||||
(c) Submit Contributions to the Original Repository.
|
||||
|
||||
No other rights are granted, whether express or implied. All rights not
|
||||
explicitly granted herein are reserved by the copyright holder.
|
||||
|
||||
|
||||
2. RESTRICTIONS
|
||||
|
||||
You may NOT, and you may not permit any third party to:
|
||||
|
||||
(a) Sell, resell, sublicense, rent, lease, loan, or otherwise transfer
|
||||
the Software or any rights in the Software to any third party.
|
||||
|
||||
(b) Redistribute, publish, or make the Software available to third
|
||||
parties in any form, whether modified or unmodified, in whole or
|
||||
in part.
|
||||
|
||||
(c) Modify, adapt, translate, reverse engineer, decompile, disassemble,
|
||||
or create derivative works based on the Software, except for
|
||||
Contributions submitted to the Original Repository in accordance
|
||||
with Section 3.
|
||||
|
||||
(d) Use the Software, in whole or in part, as a component of, or
|
||||
foundation for, any product or service offered to third parties,
|
||||
whether for a fee or free of charge. This includes, without
|
||||
limitation, offering the Software as a hosted service, a managed
|
||||
service, or embedding it within another product.
|
||||
|
||||
(e) Use the Software to develop any software or service that provides
|
||||
substantially similar functionality to the Software.
|
||||
|
||||
(f) Remove, alter, or obscure this license notice, any copyright
|
||||
notices, or any other proprietary notices contained in the
|
||||
Software.
|
||||
|
||||
(g) Use the name, trademarks, or branding of the Software or its
|
||||
author to endorse or promote products or services without prior
|
||||
written permission.
|
||||
|
||||
(h) Circumvent or attempt to circumvent any of the restrictions in
|
||||
this license, including by using the Software's design, structure,
|
||||
or logic to create a substantially similar work in any programming
|
||||
language or framework.
|
||||
|
||||
|
||||
3. CONTRIBUTIONS
|
||||
|
||||
By submitting a Contribution to the Original Repository, you:
|
||||
|
||||
(a) Grant the copyright holder a perpetual, worldwide, irrevocable,
|
||||
non-exclusive, royalty-free, fully sublicensable license to use,
|
||||
reproduce, modify, display, distribute, and create derivative works
|
||||
from your Contribution as part of the Software, under any license
|
||||
terms the copyright holder chooses.
|
||||
|
||||
(b) Represent that you have the legal right to grant the above license
|
||||
and that your Contribution does not infringe on any third-party
|
||||
rights.
|
||||
|
||||
(c) Acknowledge that the creation of a Contribution for submission to
|
||||
the Original Repository is the sole exception to the restriction
|
||||
on derivative works in Section 2(c).
|
||||
|
||||
|
||||
4. TERMINATION
|
||||
|
||||
(a) This license is effective until terminated. Your rights under this
|
||||
license will terminate automatically and immediately, without notice,
|
||||
if you fail to comply with any term of this license.
|
||||
|
||||
(b) Upon termination, you must cease all use of the Software and destroy
|
||||
all copies in your possession or control.
|
||||
|
||||
(c) The copyright holder reserves the right to revoke this license at
|
||||
any time, for any reason, upon thirty (30) days written notice.
|
||||
|
||||
(d) Sections 5, 6, 7, and 8 survive termination of this license.
|
||||
|
||||
|
||||
5. DISCLAIMER OF WARRANTIES
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE," WITHOUT WARRANTY
|
||||
OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
NON-INFRINGEMENT, AND ACCURACY. THE COPYRIGHT HOLDER DOES NOT WARRANT
|
||||
THAT THE SOFTWARE WILL BE ERROR-FREE, UNINTERRUPTED, OR FREE OF
|
||||
HARMFUL COMPONENTS.
|
||||
|
||||
|
||||
6. LIMITATION OF LIABILITY
|
||||
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
THE COPYRIGHT HOLDER BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING BUT NOT LIMITED TO LOSS
|
||||
OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION, OR LOSS OF GOODWILL,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR INABILITY TO USE THE
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
THE COPYRIGHT HOLDER'S TOTAL AGGREGATE LIABILITY ARISING OUT OF OR
|
||||
RELATED TO THIS LICENSE SHALL NOT EXCEED THE AMOUNT YOU PAID FOR THE
|
||||
SOFTWARE (WHICH IS ZERO).
|
||||
|
||||
SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN
|
||||
DAMAGES. IN SUCH JURISDICTIONS, THE ABOVE LIMITATIONS SHALL APPLY TO
|
||||
THE MAXIMUM EXTENT PERMITTED BY LAW.
|
||||
|
||||
|
||||
7. GOVERNING LAW AND DISPUTE RESOLUTION
|
||||
|
||||
(a) This license shall be governed by and construed in accordance with
|
||||
the laws of the Republic of Poland, without regard to its conflict
|
||||
of law provisions.
|
||||
|
||||
(b) Any dispute arising out of or in connection with this license shall
|
||||
be subject to the exclusive jurisdiction of the courts of Poland.
|
||||
|
||||
(c) Nothing in this section shall prevent the copyright holder from
|
||||
seeking injunctive or other equitable relief in any jurisdiction
|
||||
to protect intellectual property rights.
|
||||
|
||||
|
||||
8. GENERAL PROVISIONS
|
||||
|
||||
(a) This license constitutes the entire agreement between you and the
|
||||
copyright holder regarding the Software and supersedes all prior
|
||||
agreements and understandings.
|
||||
|
||||
(b) If any provision of this license is held to be unenforceable, the
|
||||
remaining provisions shall remain in full force and effect.
|
||||
|
||||
(c) The failure of the copyright holder to enforce any right or
|
||||
provision of this license shall not constitute a waiver of such
|
||||
right or provision.
|
||||
|
||||
(d) This license may not be assigned or transferred by you without the
|
||||
prior written consent of the copyright holder.
|
||||
@@ -0,0 +1,124 @@
|
||||
[](https://buymeacoffee.com/wojo_o)
|
||||
|
||||
# Inker v0.2.0
|
||||
|
||||
Self-hosted e-ink device management system for [TRMNL](https://usetrmnl.com/) devices and BYOD e-ink displays. Design screens, create custom widgets, and manage your displays from a modern web interface.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- **Screen Designer** — Drag & drop widget placement, snap guides, freehand drawing, auto-fit zoom for any resolution
|
||||
- **Built-in Widgets** — Clock, date, text, weather, countdown, days until, QR code, image, GitHub stars, battery, WiFi, device info
|
||||
- **Custom Widgets** — Connect to any JSON API or RSS feed (including local network sources), JavaScript transformations, grid layouts
|
||||
- **Playlists** — Rotate multiple screens on devices automatically
|
||||
- **Device Management** — Auto-provisioning, BYOD support with custom resolutions, real-time status, logs
|
||||
- **BYOD Support** — Register any e-ink device manually with custom screen resolution
|
||||
|
||||
## Screenshots
|
||||
|
||||
| Screen Designer | Devices | Screens |
|
||||
|:-:|:-:|:-:|
|
||||
|  |  |  |
|
||||
|
||||
| List of sources | Custom Data Sources | Custom Widgets |
|
||||
|:-:|:-:|:-:|
|
||||
|  |  |  |
|
||||
|
||||
## Quick start
|
||||
|
||||
### Docker Run
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name inker \
|
||||
--restart unless-stopped \
|
||||
-p 80:80 \
|
||||
-v inker_postgres:/var/lib/postgresql/17/main \
|
||||
-v inker_redis:/data \
|
||||
-v inker_uploads:/app/uploads \
|
||||
wojooo/inker:latest
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
inker:
|
||||
image: wojooo/inker:latest
|
||||
container_name: inker
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/17/main
|
||||
- redis_data:/data
|
||||
- uploads_data:/app/uploads
|
||||
environment:
|
||||
TZ: UTC
|
||||
ADMIN_PIN: "1111" # Quotes required — YAML strips leading zeros without them
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
uploads_data:
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Open **http://your-server-ip** and log in with PIN `1111`.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `ADMIN_PIN` | Login PIN | `1111` |
|
||||
| `TZ` | Timezone for widgets | `UTC` |
|
||||
| `CORS_ORIGINS` | Allowed CORS origins (comma-separated, or `*` for all) | same-origin |
|
||||
|
||||
Pass with `-e`:
|
||||
```bash
|
||||
docker run -d \
|
||||
--name inker \
|
||||
--restart unless-stopped \
|
||||
-p 80:80 \
|
||||
-e ADMIN_PIN="1111" \
|
||||
-e TZ=Europe/Warsaw \
|
||||
-v inker_postgres:/var/lib/postgresql/17/main \
|
||||
-v inker_redis:/data \
|
||||
-v inker_uploads:/app/uploads \
|
||||
wojooo/inker:latest
|
||||
```
|
||||
|
||||
### Build from source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wojo-o/inker.git
|
||||
cd inker
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If something isn't working after an update or on first run, reset the volumes and start fresh:
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> **Note:** This removes all data (database, uploads). Only use on a fresh install or when you don't mind losing data.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
cd backend && bun test # 375 tests
|
||||
cd frontend && bun run test # 19 tests
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Source Available — see [LICENSE](LICENSE) for details.
|
||||
@@ -0,0 +1,6 @@
|
||||
dist
|
||||
node_modules
|
||||
coverage
|
||||
*.js
|
||||
.env
|
||||
uploads
|
||||
@@ -0,0 +1,48 @@
|
||||
# Dependencies
|
||||
node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# Testing
|
||||
/coverage
|
||||
*.log
|
||||
|
||||
# Production
|
||||
/dist
|
||||
/build
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Uploads
|
||||
uploads/*
|
||||
!uploads/.gitkeep
|
||||
|
||||
# Prisma
|
||||
prisma/*.db
|
||||
prisma/*.db-journal
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Misc
|
||||
.eslintcache
|
||||
.nyc_output
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user