Sign inSign up

tundrasoft/deno

By tundrasoft

Updated 4 days ago

Image
0

50K+

tundrasoft/deno repository overview

🦕 TundraSoft Deno Runtime Image

A lightweight, secure Deno runtime image built on Alpine Linux with S6 overlay, comprehensive permissions management, and developer-friendly utilities.

GitHub Workflow Status Security Scan Docker Pulls License


📋 Table of Contents


🚀 Quick Start

📦 Available Registries

This image is available on multiple registries:

  • Docker Hub: tundrasoft/deno
  • GitHub Container Registry: ghcr.io/tundrasoft/deno
# Pull from Docker Hub (recommended)
docker pull tundrasoft/deno:latest

# Pull from GitHub Container Registry
docker pull ghcr.io/tundrasoft/deno:latest

# Run a simple Deno application
docker run -d \
  -p 8080:8080 \
  -e FILE=https://deno.land/std/examples/chat/server.ts \
  -e ALLOW_NET=1 \
  --name deno-app \
  tundrasoft/deno:latest

# Run with custom timezone and permissions
docker run -d \
  -e TZ=Asia/Kolkata \
  -e ALLOW_NET=1 \
  -e ALLOW_READ=1 \
  -v $(pwd):/app \
  --name my-deno-app \
  tundrasoft/deno:latest

🏷️ Available Tags

Tags


✨ Features

  • 🦕 Latest Deno Runtime - Modern JavaScript/TypeScript runtime
  • 🐧 Alpine Linux Base - Minimal, secure base OS
  • 🔧 S6 Overlay - Advanced process supervision and service management
  • 👤 Pre-configured User - Non-root tundra user (UID/GID: 1000)
  • 🔒 Granular Permissions - Fine-grained control over Deno runtime permissions
  • 🌍 Timezone Support - Easy timezone configuration
  • Cron Support - Dynamic cron job loading with environment variables
  • 📊 Health Monitoring - Built-in health checks for application monitoring
  • 🔄 envsubst - Environment variable substitution in config files

📖 Usage

Basic Usage

Use as a base image in your Dockerfile:

# From Docker Hub
FROM tundrasoft/deno:latest
# Your Deno application setup here
COPY . /app
# From GitHub Container Registry
FROM ghcr.io/tundrasoft/deno:latest
# Your Deno application setup here
COPY . /app

For specific versions:

FROM tundrasoft/deno:2.5.6
# or with specific Alpine version
FROM tundrasoft/deno:alpine-3.22-2.5.6
🎯 Running Applications

Run a remote script:

docker run -p 8080:8080 \
  -e FILE=https://deno.land/std/examples/chat/server.ts \
  -e ALLOW_NET=1 \
  tundrasoft/deno:latest

Run with Deno tasks:

docker run -v $(pwd):/app \
  -e TASK=start \
  -e ALLOW_ALL=1 \
  tundrasoft/deno:latest

Run with environment variables and permissions:

docker run -d \
  -e FILE=/app/server.ts \
  -e ALLOW_NET=1 \
  -e ALLOW_READ=/app,/etc/config \
  -e ALLOW_WRITE=/tmp \
  -e PUID=1001 \
  -e PGID=1001 \
  -e TZ=America/New_York \
  -v $(pwd):/app \
  tundrasoft/deno:latest
Environment Variables
VariableDescriptionDefault
DENO_DIRDirectory where cached items are stored/deno-dir
TASKRun a task from deno.json (ignores permission flags)N/A
FILEThe file to run with permission flagsN/A
PUIDUser ID for the tundra user1000
PGIDGroup ID for the tundra group1000
TZTimezone (e.g., Asia/Kolkata, America/New_York)UTC
DENO_LOGDeno logging level (e.g., debug, info)N/A
DENO_NO_LOCKDisable lock file generation (1 to disable)N/A
DEBUGEnable debug mode with verbose output (1 to enable)N/A
WATCHEnable watch mode for file changes (1 to enable)N/A
S6_CMD_WAIT_FOR_SERVICES_MAXTIMEMax time (ms) to wait for services to start (0 = infinite)0
S6_KILL_FINISH_MAXTIMEGrace period (ms) for graceful shutdown5000
Permission Flags

These environment variables control Deno's runtime permissions (used only with FILE mode):

VariableDescriptionDefault
ALLOW_ALLEnable all permissions (-A or --allow-all)N/A
ALLOW_HRTIMEAllow high-resolution time measurementN/A
ALLOW_SYSAllow system information accessN/A
ALLOW_ENVAllow environment variable accessN/A
ALLOW_NETNetwork access (1 for all, or specify domains)1
ALLOW_READFile system read access (1 for all, or specify paths)N/A
ALLOW_WRITEFile system write access (1 for all, or specify paths)N/A
ALLOW_RUNCommand execution (1 for all, or CSV of commands)N/A
UNSTABLEEnable unstable APIs (specific features: ffi,cron,etc)0
Volumes
PathDescription
/appApplication root directory (recommended to mount as volume)
/cronsDirectory for cron job files (automatically loaded)
/deno-dirDeno cache directory (for persisting dependencies)

🏗️ Build-Time Optimization

Cache Warming for Faster Deployments

Pre-warm the Deno cache during image build to eliminate cold-start dependency downloads:

Simple file caching:

FROM tundrasoft/deno:latest

COPY . /app

# Pre-warm cache during build
RUN deno cache /app/main.ts

ENV FILE=/app/main.ts
ENV ALLOW_NET=1

With dependencies file:

FROM tundrasoft/deno:latest

COPY deps.ts /app/
COPY main.ts /app/

# Cache all dependencies first (better layer caching)
RUN deno cache /app/deps.ts
# Then cache the main app
RUN deno cache /app/main.ts

ENV FILE=/app/main.ts
ENV ALLOW_NET=1

With deno.json tasks:

FROM tundrasoft/deno:latest

COPY . /app

# Cache dependencies defined in deno.json
RUN deno cache --reload /app/deno.json

ENV TASK=start
ENV ALLOW_ALL=1

Multi-stage optimized build:

FROM tundrasoft/deno:latest AS cache

COPY deno.lock deps.ts /app/
RUN deno cache --reload /app/deps.ts

FROM tundrasoft/deno:latest

# Copy pre-cached dependencies
COPY --from=cache /deno-dir /deno-dir
COPY . /app

RUN deno cache /app/main.ts

ENV FILE=/app/main.ts
ENV ALLOW_NET=1
Benefits
  • Faster cold starts - No dependency downloads at runtime
  • 📦 Reproducible builds - Same dependencies every build
  • 🔒 Offline compatible - Works in isolated environments
  • 🎯 Layer caching - Separate cache layer for better Docker caching
  • 🚀 Production ready - No surprise downloads in production

🔧 Development Mode

Development setup

Development mode combines DEBUG, WATCH, and DENO_LOG for optimal developer experience:

Development setup:

docker run -it \
  -e DEBUG=1 \
  -e WATCH=1 \
  -e DENO_LOG=debug \
  -e FILE=/app/main.ts \
  -e ALLOW_ALL=1 \
  -v $(pwd):/app \
  -p 8080:8080 \
  tundrasoft/deno:latest

What this enables:

  • 🐛 DEBUG=1: Verbose startup output with argument inspection
  • 👁️ WATCH=1: File watching with auto-restart on changes
  • 📋 DENO_LOG=debug: Detailed Deno runtime logging

With Deno tasks:

docker run -it \
  -e DEBUG=1 \
  -e WATCH=1 \
  -e TASK=dev \
  -v $(pwd):/app \
  -p 8080:8080 \
  tundrasoft/deno:latest

Lock file disabled (useful for read-only containers):

docker run -d \
  -e DENO_NO_LOCK=1 \
  -e FILE=/app/server.ts \
  -e ALLOW_NET=1 \
  -v /app:ro \
  tundrasoft/deno:latest

⚙️ Service Management

This image uses S6 Overlay for advanced process supervision and service management. S6 is a lightweight init system that provides reliable service supervision, dependency management, and graceful shutdown handling.

The Deno service runs your application via the S6 system, ensuring:

  • Automatic restart on failure
  • Graceful shutdown handling
  • Proper signal handling
  • Logging integration
  • Health monitoring
Service Startup & Shutdown Configuration

Control S6 service supervision timeouts:

# Custom startup timeout (30 seconds max wait)
docker run -d \
  -e S6_CMD_WAIT_FOR_SERVICES_MAXTIME=30000 \
  -e FILE=/app/server.ts \
  tundrasoft/deno:latest

# Extended graceful shutdown (10 seconds)
docker run -d \
  -e S6_KILL_FINISH_MAXTIME=10000 \
  -e FILE=/app/server.ts \
  tundrasoft/deno:latest

# Infinite startup wait (for slow-starting apps)
docker run -d \
  -e S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
  -e FILE=/app/server.ts \
  tundrasoft/deno:latest
🎯 Service Triggers

S6 provides dependency management through trigger points:

TriggerDescription
os-readyContainer booted, basic setup complete
config-startStart configuration changes
config-readyConfiguration complete
service-startApplication services begin
service-readyAll services initialized
Adding Custom Services

You can extend the Deno image with additional services:

FROM tundrasoft/deno:latest

# Install additional tools
RUN apk add --no-cache redis

# Create Redis service
RUN mkdir -p /etc/s6-overlay/s6-rc.d/redis/dependencies.d
RUN echo "longrun" > /etc/s6-overlay/s6-rc.d/redis/type

RUN cat > /etc/s6-overlay/s6-rc.d/redis/run << 'EOF'
#!/command/with-contenv sh
exec 2>&1
exec redis-server --bind 127.0.0.1
EOF

RUN chmod +x /etc/s6-overlay/s6-rc.d/redis/run
RUN touch /etc/s6-overlay/s6-rc.d/redis/dependencies.d/service-start
RUN touch /etc/s6-overlay/s6-rc.d/user/contents.d/redis

⏰ Cron Jobs

Dynamic Cron Setup

This image provides dynamic cron job loading with environment variable substitution support:

  1. Create cron files in the /crons directory
  2. Use environment variables with $VARIABLE_NAME syntax
  3. Pass environment variables when running the container
  4. S6 automatically loads and installs jobs at startup
Cron Examples
Example 1: Basic Scheduled Task

File: /crons/daily-cleanup

# Run cleanup at 3 AM daily
0 3 * * * find /tmp -type f -mtime +7 -delete

Run container:

docker run -d \
  -v /host/crons:/crons:ro \
  tundrasoft/deno:latest
Example 2: Application Health Check

File: /crons/health-check

# Check application health every 5 minutes
*/5 * * * * curl -f http://localhost:8080/health || exit 1

Run container:

docker run -d \
  -p 8080:8080 \
  -e FILE=/app/server.ts \
  -e ALLOW_NET=1 \
  -v /host/crons:/crons:ro \
  -v $(pwd):/app \
  tundrasoft/deno:latest
Example 3: Complex Configuration

File: /crons/maintenance-jobs

# Database backup
$BACKUP_TIME /usr/local/bin/backup.sh >> /var/log/cron-backup.log 2>&1

# Log rotation
$LOG_ROTATE_TIME logrotate /etc/logrotate.conf

# Cleanup caches
$CLEANUP_TIME rm -rf /tmp/deno-cache-*

Run container with environment substitution:

docker run -d \
  -e BACKUP_TIME='0 2 * * *' \
  -e LOG_ROTATE_TIME='0 0 * * *' \
  -e CLEANUP_TIME='0 4 * * 0' \
  -v /host/crons:/crons:ro \
  tundrasoft/deno:latest

🔧 Building

🏗️ Build Command
docker build \
  --build-arg ALPINE_VERSION=latest \
  --build-arg DENO_VERSION=2.5.6 \
  -t my-deno-image .
⚙️ Build Arguments
ArgumentDescriptionExample
ALPINE_VERSIONAlpine Linux version (base image)latest, 3.22, 3.21
DENO_VERSIONDeno runtime version2.5.6, 2.4.5, 2.3.7

🔒 Security

This repository implements comprehensive security scanning:

  • 🛡️ Multi-layered scanning with Trivy, CodeQL, Semgrep, and Grype
  • 🔍 Secret detection with GitLeaks (runs early in build process)
  • 📊 Automated reporting to GitHub Security tab
  • 🔄 Daily security scans and vulnerability monitoring
Permission Model

Deno provides fine-grained permissions for runtime security:

# Minimal permissions (read-only access)
docker run -e FILE=/app/script.ts \
  -e ALLOW_READ=/app \
  tundrasoft/deno:latest

# Network with specific domain whitelist
docker run -e FILE=/app/fetch.ts \
  -e ALLOW_NET=api.example.com,cdn.jsdelivr.net \
  tundrasoft/deno:latest

# Restricted execution (no command execution)
docker run -e FILE=/app/processor.ts \
  -e ALLOW_READ=/app \
  -e ALLOW_WRITE=/tmp \
  tundrasoft/deno:latest

For security issues, please use GitHub's private vulnerability reporting.

🛡️ Security Best Practices

Container Runtime Security:

# Run with read-only root filesystem
docker run --read-only --tmpfs /tmp --tmpfs /run tundrasoft/deno:latest

# Use specific user and drop capabilities
docker run --user 1000:1000 --cap-drop=ALL tundrasoft/deno:latest

# Limit resources
docker run --memory=512m --cpus=1 --pids-limit=100 tundrasoft/deno:latest

# Restrict network access to specific domains
docker run -e ALLOW_NET=api.example.com,cdn.jsdelivr.net tundrasoft/deno:latest

File System Security:

# Mount application files as read-only
docker run -v $(pwd):/app:ro tundrasoft/deno:latest

# Use specific read/write permissions
docker run -e ALLOW_READ=/app,/etc/ssl -e ALLOW_WRITE=/tmp tundrasoft/deno:latest

# Mount secrets securely
docker run -v /host/secrets:/secrets:ro,Z -e ALLOW_READ=/secrets tundrasoft/deno:latest

Production Deployment:

# Always use specific version tags
docker run tundrasoft/deno:2.1.4 # Not 'latest'

# Use custom networks
docker network create --driver bridge secure-app-net
docker run --network secure-app-net tundrasoft/deno:2.1.4

# Enable logging
docker run --log-driver=json-file --log-opt max-size=10m tundrasoft/deno:2.1.4

For security issues, please use GitHub's private vulnerability reporting.


📚 Components

Base System
  • Alpine Linux 3.22 - Minimal, secure, and reliable
  • S6 Overlay v3 - Process supervision with lifecycle management
  • OpenSSL 3.x - Cryptographic and TLS support
Runtime
  • Deno 2.5.6 - Modern JavaScript/TypeScript runtime
  • Node.js runtime support - Via Deno's Node compatibility
  • TypeScript 5.x - Built-in TypeScript support
Utilities
  • cURL - HTTP client for network operations
  • Git - Version control (for development)
  • Bash/sh - Shell scripting
  • Healthcheck script - S6-integrated service monitoring

📖 Reference

Container Lifecycle
StageDescriptionServices
BootInitialize system and useros-readyservice-ready
ConfigLoad configurationconfig-startconfig-ready
MainRun application/crondeno or crond
ShutdownClean terminationS6 async handlers
Directory Structure
/deno-dir/        - Deno cache directory (mounted volume)
/app/             - Application code
/etc/s6-overlay/  - S6 service definitions
/etc/crontabs/    - Cron jobs (if using cron)
/etc/timezone     - TZ configuration
/run/s6/          - S6 runtime (temporary)
Docker Compose Example
version: '3.8'

services:
  app:
    image: tundrasoft/deno:latest
    environment:
      - FILE=/app/src/main.ts
      - ALLOW_NET=api.example.com
      - ALLOW_READ=/app
      - ALLOW_WRITE=/tmp
    volumes:
      - ./src:/app
      - deno-cache:/deno-dir
    ports:
      - "8000:8000"
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck.sh"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  deno-cache:
Troubleshooting
"Permission denied" errors

Symptoms: Files cannot be read/written, or network calls fail

Solutions:

# Grant read permission to specific path
docker run -e ALLOW_READ=/app \
  -e FILE=/app/main.ts tundrasoft/deno:latest

# Grant read + write permissions
docker run -e ALLOW_READ=/app \
  -e ALLOW_WRITE=/tmp \
  -e FILE=/app/main.ts tundrasoft/deno:latest

# Grant network access to specific domain
docker run -e ALLOW_NET=api.example.com \
  -e FILE=/app/main.ts tundrasoft/deno:latest

# Allow all permissions (development only)
docker run -e ALLOW_ALL=1 \
  -e FILE=/app/main.ts tundrasoft/deno:latest
Application not starting

Symptoms: Container exits immediately or hangs

Debug steps:

# View logs to see startup errors
docker logs <container-id>

# Run with DEBUG mode for verbose output
docker run -it -e DEBUG=1 -e FILE=/app/main.ts tundrasoft/deno:latest

# Check healthcheck status
docker exec <container-id> /usr/bin/healthcheck.sh

# Verify file exists and is readable
docker exec <container-id> ls -la /app/main.ts
Slow cold start

Symptoms: First run takes 30+ seconds to download dependencies

Root causes & solutions:

  1. First-time module download:

    # Persist cache using volume
    docker run -v deno-cache:/deno-dir \
      -e FILE=/app/main.ts tundrasoft/deno:latest
    
  2. Pre-warm cache during build:

    FROM tundrasoft/deno:latest
    COPY . /app
    RUN deno cache /app/main.ts
    ENV FILE=/app/main.ts
    
  3. Network timeouts:

    # Increase S6 startup timeout (default 0 = infinite)
    docker run -e S6_CMD_WAIT_FOR_SERVICES_MAXTIME=60000 \
      -e FILE=/app/main.ts tundrasoft/deno:latest
    
Lock file issues

Symptoms: "Cannot create lock file" or permission errors in read-only containers

Solution:

# Disable lock file for read-only deployments
docker run --read-only \
  -e DENO_NO_LOCK=1 \
  -e FILE=/app/main.ts tundrasoft/deno:latest
Module caching problems

Symptoms: "Module not found" or "Failed to fetch" errors

Solutions:

# Use persistent cache volume
docker run -v deno-cache:/deno-dir \
  -e FILE=/app/main.ts tundrasoft/deno:latest

# Pre-cache dependencies with deno cache
docker run -v deno-cache:/deno-dir \
  -w /app \
  tundrasoft/deno:latest \
  deno cache https://deno.land/[email protected]/mod.ts
Watch mode not restarting

Symptoms: File changes don't trigger app restart with WATCH=1

Check:

# Verify watch mode is working
docker run -it -e WATCH=1 -e DEBUG=1 \
  -e FILE=/app/main.ts \
  -v $(pwd):/app \
  tundrasoft/deno:latest

# Look for file change messages in logs

🤝 Contributing

  1. 🍴 Fork the repository
  2. 🌟 Create a feature branch: git checkout -b feature/amazing-feature
  3. 💾 Commit changes: git commit -m 'Add amazing feature'
  4. 📤 Push to branch: git push origin feature/amazing-feature
  5. 🔄 Open a Pull Request
📋 Changelog

See CHANGELOG.md for release notes and CHANGELOG-GUIDE.md for contribution guidelines.


Built with ❤️ by TundraSoft

View on GitHubDocker HubReport Issue

Tag summary

Content type

Image

Digest

sha256:e898c1e69

Size

50.5 MB

Last updated

4 days ago

docker pull tundrasoft/deno