tabby-web testing
This commit is contained in:
196
modules/nixos/services/tabby-web/README.md
Normal file
196
modules/nixos/services/tabby-web/README.md
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
# Tabby Web Service Module
|
||||||
|
|
||||||
|
This module provides a NixOS service for running the Tabby Web terminal application server.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Systemd service with automatic startup
|
||||||
|
- User and group management
|
||||||
|
- Database migration on startup
|
||||||
|
- Configurable environment variables
|
||||||
|
- Security hardening
|
||||||
|
- Firewall integration
|
||||||
|
- Support for PostgreSQL and SQLite databases
|
||||||
|
- Social authentication configuration
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
mjallen.services.tabby-web = {
|
||||||
|
enable = true;
|
||||||
|
port = 9000;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Configuration
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
mjallen.services.tabby-web = {
|
||||||
|
enable = true;
|
||||||
|
port = 8080;
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
# Use PostgreSQL instead of SQLite
|
||||||
|
databaseUrl = "postgresql://tabby:password@localhost:5432/tabby";
|
||||||
|
|
||||||
|
# Use S3 for app distribution storage
|
||||||
|
appDistStorage = "s3://my-bucket/tabby-dist";
|
||||||
|
|
||||||
|
# Configure social authentication
|
||||||
|
socialAuth = {
|
||||||
|
github = {
|
||||||
|
key = "your-github-oauth-key";
|
||||||
|
secret = "your-github-oauth-secret";
|
||||||
|
};
|
||||||
|
gitlab = {
|
||||||
|
key = "your-gitlab-oauth-key";
|
||||||
|
secret = "your-gitlab-oauth-secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Performance tuning
|
||||||
|
workers = 8;
|
||||||
|
timeout = 300;
|
||||||
|
|
||||||
|
# Additional environment variables
|
||||||
|
extraEnvironment = {
|
||||||
|
DEBUG = "0";
|
||||||
|
LOG_LEVEL = "info";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### Basic Options
|
||||||
|
|
||||||
|
- `enable`: Enable the tabby-web service
|
||||||
|
- `port`: Port to run the server on (default: 9000)
|
||||||
|
- `openFirewall`: Whether to open the firewall port (default: false)
|
||||||
|
- `user`: User to run the service as (default: "tabby-web")
|
||||||
|
- `group`: Group to run the service as (default: "tabby-web")
|
||||||
|
- `dataDir`: Data directory (default: "/var/lib/tabby-web")
|
||||||
|
|
||||||
|
### Database Configuration
|
||||||
|
|
||||||
|
- `databaseUrl`: Database connection URL
|
||||||
|
- SQLite: `"sqlite:///var/lib/tabby-web/tabby.db"` (default)
|
||||||
|
- PostgreSQL: `"postgresql://user:password@host:port/database"`
|
||||||
|
|
||||||
|
### Storage Configuration
|
||||||
|
|
||||||
|
- `appDistStorage`: Storage URL for app distributions
|
||||||
|
- Local: `"file:///var/lib/tabby-web/dist"` (default)
|
||||||
|
- S3: `"s3://bucket-name/path"`
|
||||||
|
- GCS: `"gcs://bucket-name/path"`
|
||||||
|
|
||||||
|
### Social Authentication
|
||||||
|
|
||||||
|
Configure OAuth providers:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
socialAuth = {
|
||||||
|
github = {
|
||||||
|
key = "oauth-key";
|
||||||
|
secret = "oauth-secret";
|
||||||
|
};
|
||||||
|
gitlab = {
|
||||||
|
key = "oauth-key";
|
||||||
|
secret = "oauth-secret";
|
||||||
|
};
|
||||||
|
microsoftGraph = {
|
||||||
|
key = "oauth-key";
|
||||||
|
secret = "oauth-secret";
|
||||||
|
};
|
||||||
|
googleOauth2 = {
|
||||||
|
key = "oauth-key";
|
||||||
|
secret = "oauth-secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Options
|
||||||
|
|
||||||
|
- `workers`: Number of gunicorn worker processes (default: 4)
|
||||||
|
- `timeout`: Worker timeout in seconds (default: 120)
|
||||||
|
|
||||||
|
### Additional Configuration
|
||||||
|
|
||||||
|
- `extraEnvironment`: Additional environment variables as an attribute set
|
||||||
|
|
||||||
|
## Service Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start the service
|
||||||
|
sudo systemctl start tabby-web
|
||||||
|
|
||||||
|
# Enable automatic startup
|
||||||
|
sudo systemctl enable tabby-web
|
||||||
|
|
||||||
|
# Check service status
|
||||||
|
sudo systemctl status tabby-web
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
sudo journalctl -u tabby-web -f
|
||||||
|
|
||||||
|
# Run management commands
|
||||||
|
sudo -u tabby-web tabby-web-manage migrate
|
||||||
|
sudo -u tabby-web tabby-web-manage add_version 1.0.156-nightly.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
The service runs with extensive security hardening:
|
||||||
|
|
||||||
|
- Dedicated user and group
|
||||||
|
- Restricted filesystem access
|
||||||
|
- No new privileges
|
||||||
|
- Protected system directories
|
||||||
|
- Private temporary directory
|
||||||
|
- Memory execution protection
|
||||||
|
- Namespace restrictions
|
||||||
|
|
||||||
|
## Database Setup
|
||||||
|
|
||||||
|
### PostgreSQL
|
||||||
|
|
||||||
|
If using PostgreSQL, ensure the database and user exist:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE USER tabby WITH PASSWORD 'your-password';
|
||||||
|
CREATE DATABASE tabby OWNER tabby;
|
||||||
|
```
|
||||||
|
|
||||||
|
### SQLite
|
||||||
|
|
||||||
|
SQLite databases are created automatically in the data directory.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
1. **Service fails to start**: Check logs with `journalctl -u tabby-web`
|
||||||
|
2. **Database connection issues**: Verify database URL and credentials
|
||||||
|
3. **Permission errors**: Ensure data directory has correct ownership
|
||||||
|
4. **Port conflicts**: Check if another service is using the configured port
|
||||||
|
|
||||||
|
## Integration with Reverse Proxy
|
||||||
|
|
||||||
|
Example Nginx configuration:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name tabby.example.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:9000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
121
modules/nixos/services/tabby-web/default.nix
Normal file
121
modules/nixos/services/tabby-web/default.nix
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.${namespace}.services.tabby-web;
|
||||||
|
|
||||||
|
# Build environment variables from configuration
|
||||||
|
environmentVars = {
|
||||||
|
DATABASE_URL = cfg.databaseUrl;
|
||||||
|
APP_DIST_STORAGE = cfg.appDistStorage;
|
||||||
|
PORT = toString cfg.port;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.github.key != null) {
|
||||||
|
SOCIAL_AUTH_GITHUB_KEY = cfg.socialAuth.github.key;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.github.secret != null) {
|
||||||
|
SOCIAL_AUTH_GITHUB_SECRET = cfg.socialAuth.github.secret;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.gitlab.key != null) {
|
||||||
|
SOCIAL_AUTH_GITLAB_KEY = cfg.socialAuth.gitlab.key;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.gitlab.secret != null) {
|
||||||
|
SOCIAL_AUTH_GITLAB_SECRET = cfg.socialAuth.gitlab.secret;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.microsoftGraph.key != null) {
|
||||||
|
SOCIAL_AUTH_MICROSOFT_GRAPH_KEY = cfg.socialAuth.microsoftGraph.key;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.microsoftGraph.secret != null) {
|
||||||
|
SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET = cfg.socialAuth.microsoftGraph.secret;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.googleOauth2.key != null) {
|
||||||
|
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = cfg.socialAuth.googleOauth2.key;
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.socialAuth.googleOauth2.secret != null) {
|
||||||
|
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = cfg.socialAuth.googleOauth2.secret;
|
||||||
|
}
|
||||||
|
// cfg.extraEnvironment;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ./options.nix ];
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# Create user and group
|
||||||
|
users.users.${cfg.user} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = cfg.group;
|
||||||
|
home = cfg.dataDir;
|
||||||
|
createHome = true;
|
||||||
|
description = "Tabby Web service user";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.${cfg.group} = { };
|
||||||
|
|
||||||
|
# Ensure data directory exists with correct permissions
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${cfg.dataDir}' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
"d '${cfg.dataDir}/dist' 0750 ${cfg.user} ${cfg.group} - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Create the systemd service
|
||||||
|
systemd.services.tabby-web = {
|
||||||
|
description = "Tabby Web Terminal Application Server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ] ++ optional (hasPrefix "postgresql://" cfg.databaseUrl) "postgresql.service";
|
||||||
|
|
||||||
|
environment = environmentVars;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "exec";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
|
||||||
|
# Use the tabby-web package from our custom packages
|
||||||
|
ExecStart = "${pkgs.${namespace}.tabby-web}/bin/tabby-web --workers ${toString cfg.workers} --timeout ${toString cfg.timeout}";
|
||||||
|
|
||||||
|
# Run database migrations before starting the service
|
||||||
|
ExecStartPre = "${pkgs.${namespace}.tabby-web}/bin/tabby-web-manage migrate";
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
ReadWritePaths = [ cfg.dataDir ];
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
|
||||||
|
# Restart policy
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "10s";
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
LimitNOFILE = "65536";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Ensure the service starts after database if using PostgreSQL
|
||||||
|
requisite = mkIf (hasPrefix "postgresql://" cfg.databaseUrl) [ "postgresql.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Open firewall if requested
|
||||||
|
networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [ cfg.port ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add the tabby-web package to system packages
|
||||||
|
environment.systemPackages = [ pkgs.${namespace}.tabby-web ];
|
||||||
|
};
|
||||||
|
}
|
||||||
45
modules/nixos/services/tabby-web/example.nix
Normal file
45
modules/nixos/services/tabby-web/example.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Example configuration for Tabby Web service
|
||||||
|
# Add this to your NixOS configuration to enable tabby-web
|
||||||
|
|
||||||
|
{
|
||||||
|
# Basic configuration - SQLite database, local storage
|
||||||
|
mjallen.services.tabby-web = {
|
||||||
|
enable = true;
|
||||||
|
port = 9000;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Advanced configuration example (commented out)
|
||||||
|
/*
|
||||||
|
mjallen.services.tabby-web = {
|
||||||
|
enable = true;
|
||||||
|
port = 8080;
|
||||||
|
openFirewall = true;
|
||||||
|
|
||||||
|
# Use PostgreSQL database
|
||||||
|
databaseUrl = "postgresql://tabby:password@localhost:5432/tabby";
|
||||||
|
|
||||||
|
# Use S3 for app distribution storage
|
||||||
|
appDistStorage = "s3://my-bucket/tabby-dist";
|
||||||
|
|
||||||
|
# Configure GitHub OAuth
|
||||||
|
socialAuth.github = {
|
||||||
|
key = "your-github-oauth-key";
|
||||||
|
secret = "your-github-oauth-secret";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Performance tuning
|
||||||
|
workers = 8;
|
||||||
|
timeout = 300;
|
||||||
|
|
||||||
|
# Custom data directory
|
||||||
|
dataDir = "/srv/tabby-web";
|
||||||
|
|
||||||
|
# Additional environment variables
|
||||||
|
extraEnvironment = {
|
||||||
|
DEBUG = "0";
|
||||||
|
LOG_LEVEL = "info";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
}
|
||||||
127
modules/nixos/services/tabby-web/options.nix
Normal file
127
modules/nixos/services/tabby-web/options.nix
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
{ lib, namespace, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.${namespace}.services.tabby-web = {
|
||||||
|
enable = mkEnableOption "Tabby Web terminal application server";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 9000;
|
||||||
|
description = "Port for tabby-web server";
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to open firewall for tabby-web";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "tabby-web";
|
||||||
|
description = "User to run tabby-web as";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "tabby-web";
|
||||||
|
description = "Group to run tabby-web as";
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/tabby-web";
|
||||||
|
description = "Directory to store tabby-web data";
|
||||||
|
};
|
||||||
|
|
||||||
|
databaseUrl = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "sqlite:///var/lib/tabby-web/tabby.db";
|
||||||
|
description = "Database connection URL";
|
||||||
|
example = "postgresql://user:password@localhost:5432/tabby";
|
||||||
|
};
|
||||||
|
|
||||||
|
appDistStorage = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "file:///var/lib/tabby-web/dist";
|
||||||
|
description = "Storage URL for app distributions";
|
||||||
|
example = "s3://my-bucket/tabby-dist";
|
||||||
|
};
|
||||||
|
|
||||||
|
socialAuth = {
|
||||||
|
github = {
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "GitHub OAuth key";
|
||||||
|
};
|
||||||
|
secret = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "GitHub OAuth secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gitlab = {
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "GitLab OAuth key";
|
||||||
|
};
|
||||||
|
secret = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "GitLab OAuth secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
microsoftGraph = {
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Microsoft Graph OAuth key";
|
||||||
|
};
|
||||||
|
secret = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Microsoft Graph OAuth secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
googleOauth2 = {
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Google OAuth2 key";
|
||||||
|
};
|
||||||
|
secret = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Google OAuth2 secret";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraEnvironment = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = "Extra environment variables for tabby-web";
|
||||||
|
example = {
|
||||||
|
DEBUG = "1";
|
||||||
|
LOG_LEVEL = "info";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
workers = mkOption {
|
||||||
|
type = types.ints.positive;
|
||||||
|
default = 4;
|
||||||
|
description = "Number of gunicorn worker processes";
|
||||||
|
};
|
||||||
|
|
||||||
|
timeout = mkOption {
|
||||||
|
type = types.ints.positive;
|
||||||
|
default = 120;
|
||||||
|
description = "Worker timeout in seconds";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
186
packages/tabby-web/default.nix
Normal file
186
packages/tabby-web/default.nix
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchFromGitHub,
|
||||||
|
nodejs,
|
||||||
|
yarn,
|
||||||
|
python3,
|
||||||
|
poetry,
|
||||||
|
makeWrapper,
|
||||||
|
fetchYarnDeps,
|
||||||
|
fixup-yarn-lock,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "tabby-web";
|
||||||
|
version = "0.0.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Eugeny";
|
||||||
|
repo = "tabby-web";
|
||||||
|
rev = "16847cea93f730814c1855241d8ebdea20b1ff6e";
|
||||||
|
sha256 = "sha256-FaVJdizSQq600awY9HAwMNv6vpcjLVAVqdWnn+sYAxk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Fetch yarn dependencies separately for reproducibility
|
||||||
|
yarnDeps = fetchYarnDeps {
|
||||||
|
yarnLock = "${src}/frontend/yarn.lock";
|
||||||
|
hash = "sha256-NInsyKgp2+ppHJZLFn3qKW08rvSSIShhh2JbR91WgOk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
nodejs
|
||||||
|
yarn
|
||||||
|
python3
|
||||||
|
poetry
|
||||||
|
makeWrapper
|
||||||
|
fixup-yarn-lock
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
python3
|
||||||
|
];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with python3.pkgs; [
|
||||||
|
gunicorn
|
||||||
|
django
|
||||||
|
];
|
||||||
|
|
||||||
|
configurePhase = ''
|
||||||
|
runHook preConfigure
|
||||||
|
|
||||||
|
# Set up yarn
|
||||||
|
export HOME=$TMPDIR
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Fix up yarn.lock and set up offline cache
|
||||||
|
fixup-yarn-lock yarn.lock
|
||||||
|
yarn config --offline set yarn-offline-mirror ${yarnDeps}
|
||||||
|
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
|
||||||
|
patchShebangs node_modules/
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Set up poetry
|
||||||
|
export POETRY_CACHE_DIR=$TMPDIR/poetry-cache
|
||||||
|
export POETRY_VENV_IN_PROJECT=1
|
||||||
|
|
||||||
|
runHook postConfigure
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
echo "Building frontend..."
|
||||||
|
cd frontend
|
||||||
|
yarn run build
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo "Backend is ready (dependencies will be handled by Nix)"
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
# Create output directories
|
||||||
|
mkdir -p $out/lib/tabby-web
|
||||||
|
mkdir -p $out/bin
|
||||||
|
mkdir -p $out/share/tabby-web
|
||||||
|
|
||||||
|
# Install backend
|
||||||
|
cp -r backend/* $out/lib/tabby-web/
|
||||||
|
|
||||||
|
# Install frontend build output
|
||||||
|
if [ -d frontend/dist ]; then
|
||||||
|
cp -r frontend/dist/* $out/share/tabby-web/
|
||||||
|
elif [ -d frontend/build ]; then
|
||||||
|
cp -r frontend/build/* $out/share/tabby-web/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create main executable wrapper
|
||||||
|
makeWrapper ${python3.withPackages (ps: with ps; [ gunicorn django ])}/bin/python $out/bin/tabby-web \
|
||||||
|
--add-flags "-m gunicorn tabby_web.wsgi:application" \
|
||||||
|
--set PYTHONPATH "$out/lib/tabby-web" \
|
||||||
|
--set DJANGO_SETTINGS_MODULE "tabby_web.settings" \
|
||||||
|
--set STATIC_ROOT "$out/share/tabby-web" \
|
||||||
|
--run "cd $out/lib/tabby-web" \
|
||||||
|
--run 'export DATABASE_URL="''${DATABASE_URL:-sqlite:///tmp/tabby-web.db}"' \
|
||||||
|
--run 'export APP_DIST_STORAGE="''${APP_DIST_STORAGE:-file:///tmp/tabby-web-dist}"' \
|
||||||
|
--run 'export PORT="''${PORT:-9000}"' \
|
||||||
|
--add-flags '--bind "0.0.0.0:$PORT"' \
|
||||||
|
--add-flags "--workers 4" \
|
||||||
|
--add-flags "--timeout 120"
|
||||||
|
|
||||||
|
# Create Django management wrapper
|
||||||
|
makeWrapper ${python3.withPackages (ps: with ps; [ django ])}/bin/python $out/bin/tabby-web-manage \
|
||||||
|
--add-flags "manage.py" \
|
||||||
|
--set PYTHONPATH "$out/lib/tabby-web" \
|
||||||
|
--set DJANGO_SETTINGS_MODULE "tabby_web.settings" \
|
||||||
|
--set STATIC_ROOT "$out/share/tabby-web" \
|
||||||
|
--run "cd $out/lib/tabby-web" \
|
||||||
|
--run 'export DATABASE_URL="''${DATABASE_URL:-sqlite:///tmp/tabby-web.db}"' \
|
||||||
|
--run 'export APP_DIST_STORAGE="''${APP_DIST_STORAGE:-file:///tmp/tabby-web-dist}"'
|
||||||
|
|
||||||
|
# Create a help script
|
||||||
|
cat > $out/bin/tabby-web-help << 'HELP_EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
cat << 'HELP'
|
||||||
|
Tabby Web - Terminal application server
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
tabby-web Start the server
|
||||||
|
tabby-web-manage <command> Run Django management commands
|
||||||
|
tabby-web-help Show this help
|
||||||
|
|
||||||
|
Environment Variables:
|
||||||
|
DATABASE_URL Database connection URL
|
||||||
|
Examples: sqlite:///path/to/db.sqlite
|
||||||
|
postgresql://user:pass@host:5432/dbname
|
||||||
|
|
||||||
|
APP_DIST_STORAGE Storage URL for app distributions
|
||||||
|
Examples: file:///path/to/storage
|
||||||
|
s3://bucket-name/path
|
||||||
|
gcs://bucket-name/path
|
||||||
|
|
||||||
|
PORT Server port (default: 9000)
|
||||||
|
|
||||||
|
Social Authentication (optional):
|
||||||
|
SOCIAL_AUTH_GITHUB_KEY GitHub OAuth key
|
||||||
|
SOCIAL_AUTH_GITHUB_SECRET GitHub OAuth secret
|
||||||
|
SOCIAL_AUTH_GITLAB_KEY GitLab OAuth key
|
||||||
|
SOCIAL_AUTH_GITLAB_SECRET GitLab OAuth secret
|
||||||
|
SOCIAL_AUTH_MICROSOFT_GRAPH_KEY Microsoft Graph OAuth key
|
||||||
|
SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET Microsoft Graph OAuth secret
|
||||||
|
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY Google OAuth2 key
|
||||||
|
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET Google OAuth2 secret
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Development with defaults
|
||||||
|
tabby-web
|
||||||
|
|
||||||
|
# Production with PostgreSQL
|
||||||
|
DATABASE_URL="postgresql://user:pass@localhost:5432/tabby" tabby-web
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
tabby-web-manage migrate
|
||||||
|
|
||||||
|
# Add app version
|
||||||
|
tabby-web-manage add_version 1.0.156-nightly.2
|
||||||
|
HELP
|
||||||
|
HELP_EOF
|
||||||
|
|
||||||
|
chmod +x $out/bin/tabby-web-help
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Web-based terminal application";
|
||||||
|
homepage = "https://github.com/Eugeny/tabby-web";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = [ ];
|
||||||
|
platforms = platforms.linux ++ platforms.darwin;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -151,6 +151,12 @@
|
|||||||
htpasswdFile = "/media/nas/main/backup/restic/.htpasswd";
|
htpasswdFile = "/media/nas/main/backup/restic/.htpasswd";
|
||||||
extraFlags = [ "--no-auth" ];
|
extraFlags = [ "--no-auth" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tabby-web = {
|
||||||
|
enable = true;
|
||||||
|
port = 9000;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user