mirror of
https://github.com/m1k1o/neko.git
synced 2025-06-20 11:37:57 +02:00
Compare commits
No commits in common. "master" and "v3.0.0-beta.12" have entirely different histories.
master
...
v3.0.0-bet
174 changed files with 1398 additions and 2710 deletions
23
.github/workflows/client_build.yml
vendored
23
.github/workflows/client_build.yml
vendored
|
@ -1,21 +1,17 @@
|
||||||
name: Build Client
|
name: Build and Publish Client Artifacts
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
#pull_request: # Change to push when ready to deploy
|
||||||
with-artifact:
|
# branches:
|
||||||
required: false
|
# - master
|
||||||
type: boolean
|
# paths:
|
||||||
default: true
|
# - client/**
|
||||||
description: |
|
# - .github/workflows/client_build.yml
|
||||||
If true, the build artifacts will be uploaded as a GitHub Actions artifact.
|
|
||||||
This is useful for debugging and testing purposes. If false, the artifacts
|
|
||||||
will not be uploaded. This is useful for test builds where you don't need
|
|
||||||
the artifacts.
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-client:
|
client_build:
|
||||||
name: Build Client
|
name: Build and Publish Client Artifacts
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -39,7 +35,6 @@ jobs:
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ inputs.with-artifact }}
|
|
||||||
with:
|
with:
|
||||||
name: client
|
name: client
|
||||||
path: client/dist
|
path: client/dist
|
||||||
|
|
32
.github/workflows/client_test.yml
vendored
32
.github/workflows/client_test.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Test Client
|
name: Test Client Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -6,14 +6,28 @@ on:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- client/**
|
- client/**
|
||||||
- .github/workflows/client_build.yml
|
|
||||||
- .github/workflows/client_test.yml
|
- .github/workflows/client_test.yml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-client:
|
client_test:
|
||||||
name: Test Client
|
name: Test Client Build
|
||||||
uses: ./.github/workflows/client_build.yml
|
runs-on: ubuntu-latest
|
||||||
with:
|
|
||||||
# Do not upload artifacts for test builds
|
steps:
|
||||||
with-artifact: false
|
- uses: actions/checkout@v4
|
||||||
secrets: inherit
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: client/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
working-directory: ./client
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build client
|
||||||
|
working-directory: ./client
|
||||||
|
run: npm run build
|
||||||
|
|
132
.github/workflows/dockerhub.yml
vendored
132
.github/workflows/dockerhub.yml
vendored
|
@ -1,11 +1,8 @@
|
||||||
name: Build and Push to Docker Hub
|
name: "build and push amd64 images to Docker Hub"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: [ master ]
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- 'webpage/**'
|
|
||||||
#
|
#
|
||||||
# Run this action periodically to keep browsers up-to-date
|
# Run this action periodically to keep browsers up-to-date
|
||||||
# even if there is no activity in this repo.
|
# even if there is no activity in this repo.
|
||||||
|
@ -13,119 +10,68 @@ on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "43 2 * * 1"
|
- cron: "43 2 * * 1"
|
||||||
|
|
||||||
# allow only one workflow to run at a time
|
|
||||||
# and cancel in-progress jobs if a new one is triggered
|
|
||||||
concurrency:
|
|
||||||
group: "dockerhub"
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_IMAGE: m1k1o/neko
|
DOCKER_IMAGE: m1k1o/neko
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-base:
|
build-base:
|
||||||
name: Base Image
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
#
|
#
|
||||||
# do not run on forks
|
# do not run on forks
|
||||||
#
|
#
|
||||||
if: github.repository_owner == 'm1k1o'
|
if: github.repository_owner == 'm1k1o'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Check Out Repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Extract metadata (tags, labels) for Docker
|
|
||||||
uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: ${{ env.DOCKER_IMAGE }}
|
|
||||||
tags: |
|
|
||||||
type=raw,value=base
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
run: |
|
||||||
with:
|
docker login --username "${DOCKER_USERNAME}" --password-stdin "${DOCKER_REGISTRY}" <<< "${DOCKER_TOKEN}"
|
||||||
username: ${{ github.actor }}
|
env:
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }}
|
||||||
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
|
||||||
- name: Generate base Dockerfile
|
- name: Build base
|
||||||
run: go run utils/docker/main.go -i Dockerfile.tmpl -o Dockerfile
|
run: |
|
||||||
|
./build -b ${DOCKER_IMAGE}:base
|
||||||
|
docker push ${DOCKER_IMAGE}:base
|
||||||
|
|
||||||
- name: Build and push
|
build:
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: ./
|
|
||||||
push: true
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
|
|
||||||
build-app:
|
|
||||||
name: App Image
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
#
|
#
|
||||||
# do not run on forks
|
# do not run on forks
|
||||||
#
|
#
|
||||||
if: github.repository_owner == 'm1k1o'
|
if: github.repository_owner == 'm1k1o'
|
||||||
needs: build-base
|
needs: [ build-base ]
|
||||||
strategy:
|
strategy:
|
||||||
# Will build all images even if some fail.
|
# Will build all images even if some fail.
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
tag:
|
tags: [ firefox, waterfox, chromium, google-chrome, ungoogled-chromium, microsoft-edge, brave, vivaldi, opera, tor-browser, remmina, vlc, xfce, kde ]
|
||||||
- firefox
|
env:
|
||||||
# Temporarily disabled due to Cloudflare blocked download link
|
DOCKER_TAG: ${{ matrix.tags }}
|
||||||
#- waterfox
|
|
||||||
- chromium
|
|
||||||
- google-chrome
|
|
||||||
- ungoogled-chromium
|
|
||||||
- microsoft-edge
|
|
||||||
- brave
|
|
||||||
- vivaldi
|
|
||||||
- opera
|
|
||||||
- tor-browser
|
|
||||||
- remmina
|
|
||||||
- vlc
|
|
||||||
- xfce
|
|
||||||
- kde
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Check Out Repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Extract metadata (tags, labels) for Docker
|
|
||||||
uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: ${{ env.DOCKER_IMAGE }}
|
|
||||||
tags: |
|
|
||||||
type=raw,value=latest,enable=${{ matrix.tag == 'firefox' }}
|
|
||||||
type=raw,value=${{ matrix.tag }}
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
run: |
|
||||||
with:
|
docker login --username "${DOCKER_USERNAME}" --password-stdin "${DOCKER_REGISTRY}" <<< "${DOCKER_TOKEN}"
|
||||||
username: ${{ github.actor }}
|
env:
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }}
|
||||||
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build container
|
||||||
uses: docker/build-push-action@v6
|
run: |
|
||||||
with:
|
./build -b ${DOCKER_IMAGE}:base -i ${DOCKER_IMAGE}
|
||||||
context: apps/${{ matrix.tag }}
|
docker tag ${DOCKER_IMAGE}/${DOCKER_TAG} ${DOCKER_IMAGE}:${DOCKER_TAG}
|
||||||
push: true
|
docker push ${DOCKER_IMAGE}:${DOCKER_TAG}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
- name: Push latest tag
|
||||||
build-args: |
|
if: ${{ matrix.tags == 'firefox' }}
|
||||||
BASE_IMAGE=${{ env.DOCKER_IMAGE }}:base
|
run: |
|
||||||
cache-from: type=gha
|
docker pull ${DOCKER_IMAGE}:${DOCKER_TAG}
|
||||||
cache-to: type=gha,mode=max
|
docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest
|
||||||
|
docker push ${DOCKER_IMAGE}:latest
|
||||||
|
|
57
.github/workflows/ghcr.yml
vendored
57
.github/workflows/ghcr.yml
vendored
|
@ -1,57 +0,0 @@
|
||||||
name: Build and Push to GHCR
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-base:
|
|
||||||
name: Base Image
|
|
||||||
uses: ./.github/workflows/image_base.yml
|
|
||||||
with:
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
build-app:
|
|
||||||
name: App Image
|
|
||||||
uses: ./.github/workflows/image_app.yml
|
|
||||||
needs: build-base
|
|
||||||
strategy:
|
|
||||||
# Will build all images even if some fail.
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- name: firefox
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
# Temporarily disabled due to Cloudflare blocked download link
|
|
||||||
#- name: waterfox
|
|
||||||
# platforms: linux/amd64
|
|
||||||
- name: chromium
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
- name: google-chrome
|
|
||||||
platforms: linux/amd64
|
|
||||||
- name: ungoogled-chromium
|
|
||||||
platforms: linux/amd64
|
|
||||||
- name: microsoft-edge
|
|
||||||
platforms: linux/amd64
|
|
||||||
- name: brave
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
- name: vivaldi
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
- name: opera
|
|
||||||
platforms: linux/amd64
|
|
||||||
- name: tor-browser
|
|
||||||
platforms: linux/amd64
|
|
||||||
- name: remmina
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
- name: vlc
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
- name: xfce
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
- name: kde
|
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.name }}
|
|
||||||
platforms: ${{ matrix.platforms }}
|
|
||||||
secrets: inherit
|
|
44
.github/workflows/ghcr_amd64.yml
vendored
Normal file
44
.github/workflows/ghcr_amd64.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
name: "amd64 images"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-base:
|
||||||
|
uses: ./.github/workflows/image_base.yml
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
build-apps:
|
||||||
|
uses: ./.github/workflows/image_app.yml
|
||||||
|
needs: [ build-base ]
|
||||||
|
strategy:
|
||||||
|
# Will build all images even if some fail.
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: firefox
|
||||||
|
- name: waterfox
|
||||||
|
- name: chromium
|
||||||
|
- name: google-chrome
|
||||||
|
- name: ungoogled-chromium
|
||||||
|
- name: microsoft-edge
|
||||||
|
- name: brave
|
||||||
|
- name: vivaldi
|
||||||
|
- name: opera
|
||||||
|
- name: tor-browser
|
||||||
|
- name: remmina
|
||||||
|
- name: vlc
|
||||||
|
- name: xfce
|
||||||
|
- name: kde
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
dockerfile: ${{ matrix.dockerfile }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
36
.github/workflows/ghcr_arm.yml
vendored
Normal file
36
.github/workflows/ghcr_arm.yml
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
name: "arm64v8 and arm32v7 images"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-base:
|
||||||
|
uses: ./.github/workflows/image_base.yml
|
||||||
|
with:
|
||||||
|
flavor: arm
|
||||||
|
platforms: linux/arm64,linux/arm/v7
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
build-apps:
|
||||||
|
uses: ./.github/workflows/image_app.yml
|
||||||
|
needs: [ build-base ]
|
||||||
|
strategy:
|
||||||
|
# Will build all images even if some fail.
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: firefox
|
||||||
|
- name: chromium
|
||||||
|
- name: vlc
|
||||||
|
- name: xfce
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
dockerfile: ${{ matrix.dockerfile }}
|
||||||
|
flavor: arm
|
||||||
|
platforms: linux/arm64,linux/arm/v7
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
21
.github/workflows/ghcr_intel.yml
vendored
21
.github/workflows/ghcr_intel.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Build and Push to GHCR for Intel
|
name: "intel gpu supported images"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -7,26 +7,24 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-base:
|
build-base:
|
||||||
name: Base Image
|
|
||||||
uses: ./.github/workflows/image_base.yml
|
uses: ./.github/workflows/image_base.yml
|
||||||
with:
|
with:
|
||||||
flavor: intel
|
flavor: intel
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
dockerfile: Dockerfile.intel
|
dockerfile: Dockerfile.intel
|
||||||
secrets: inherit
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
||||||
build-app:
|
build-apps:
|
||||||
name: App Image
|
|
||||||
uses: ./.github/workflows/image_app.yml
|
uses: ./.github/workflows/image_app.yml
|
||||||
needs: build-base
|
needs: [ build-base ]
|
||||||
strategy:
|
strategy:
|
||||||
# Will build all images even if some fail.
|
# Will build all images even if some fail.
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: firefox
|
- name: firefox
|
||||||
# Temporarily disabled due to Cloudflare blocked download link
|
- name: waterfox
|
||||||
#- name: waterfox
|
|
||||||
- name: chromium
|
- name: chromium
|
||||||
- name: google-chrome
|
- name: google-chrome
|
||||||
- name: ungoogled-chromium
|
- name: ungoogled-chromium
|
||||||
|
@ -41,7 +39,8 @@ jobs:
|
||||||
- name: kde
|
- name: kde
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
flavor: intel
|
|
||||||
platforms: ${{ matrix.platforms }}
|
|
||||||
dockerfile: ${{ matrix.dockerfile }}
|
dockerfile: ${{ matrix.dockerfile }}
|
||||||
secrets: inherit
|
flavor: intel
|
||||||
|
platforms: linux/amd64
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
18
.github/workflows/ghcr_nvidia.yml
vendored
18
.github/workflows/ghcr_nvidia.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Build and Push to GHCR for Nvidia
|
name: "nvidia gpu supported images"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -7,18 +7,17 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-base:
|
build-base:
|
||||||
name: Base Image
|
|
||||||
uses: ./.github/workflows/image_base.yml
|
uses: ./.github/workflows/image_base.yml
|
||||||
with:
|
with:
|
||||||
flavor: nvidia
|
flavor: nvidia
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
dockerfile: Dockerfile.nvidia
|
dockerfile: Dockerfile.nvidia
|
||||||
secrets: inherit
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
||||||
build-app:
|
build-apps:
|
||||||
name: App Image
|
|
||||||
uses: ./.github/workflows/image_app.yml
|
uses: ./.github/workflows/image_app.yml
|
||||||
needs: build-base
|
needs: [ build-base ]
|
||||||
strategy:
|
strategy:
|
||||||
# Will build all images even if some fail.
|
# Will build all images even if some fail.
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
@ -36,7 +35,8 @@ jobs:
|
||||||
dockerfile: Dockerfile.nvidia
|
dockerfile: Dockerfile.nvidia
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.name }}
|
name: ${{ matrix.name }}
|
||||||
flavor: nvidia
|
|
||||||
platforms: ${{ matrix.platforms }}
|
|
||||||
dockerfile: ${{ matrix.dockerfile }}
|
dockerfile: ${{ matrix.dockerfile }}
|
||||||
secrets: inherit
|
flavor: nvidia
|
||||||
|
platforms: linux/amd64
|
||||||
|
secrets:
|
||||||
|
GHCR_ACCESS_TOKEN: ${{ secrets.GHCR_ACCESS_TOKEN }}
|
||||||
|
|
23
.github/workflows/image_app.yml
vendored
23
.github/workflows/image_app.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Build App Image
|
name: Build and Publish Application Image
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
@ -6,7 +6,12 @@ on:
|
||||||
name:
|
name:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
description: "The name of the app to build."
|
description: "The name of the application to build."
|
||||||
|
dockerfile:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: "Dockerfile"
|
||||||
|
description: "The Dockerfile to use for building the image."
|
||||||
flavor:
|
flavor:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
@ -17,18 +22,17 @@ on:
|
||||||
type: string
|
type: string
|
||||||
default: "linux/amd64"
|
default: "linux/amd64"
|
||||||
description: "The platforms to build for."
|
description: "The platforms to build for."
|
||||||
dockerfile:
|
secrets:
|
||||||
required: false
|
GHCR_ACCESS_TOKEN:
|
||||||
type: string
|
required: true
|
||||||
default: "Dockerfile"
|
description: "GitHub Container Registry access token."
|
||||||
description: "The Dockerfile to use for building the image."
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }}
|
FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-app:
|
build-app:
|
||||||
name: Build App Image
|
name: Build and Publish Application Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -48,7 +52,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}${{ inputs.name }}
|
images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}${{ inputs.name }}
|
||||||
tags: |
|
tags: |
|
||||||
type=edge,branch=master
|
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
|
@ -72,5 +75,3 @@ jobs:
|
||||||
build-args: |
|
build-args: |
|
||||||
BASE_IMAGE=ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}base:sha-${{ github.sha }}
|
BASE_IMAGE=ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}base:sha-${{ github.sha }}
|
||||||
platforms: ${{ inputs.platforms || 'linux/amd64' }}
|
platforms: ${{ inputs.platforms || 'linux/amd64' }}
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
|
|
26
.github/workflows/image_base.yml
vendored
26
.github/workflows/image_base.yml
vendored
|
@ -1,8 +1,13 @@
|
||||||
name: Build Base Image
|
name: Build and Publish Base Image
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
|
dockerfile:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: "Dockerfile"
|
||||||
|
description: "The Dockerfile to use for building the image."
|
||||||
flavor:
|
flavor:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
@ -13,24 +18,22 @@ on:
|
||||||
type: string
|
type: string
|
||||||
default: "linux/amd64"
|
default: "linux/amd64"
|
||||||
description: "The platforms to build for."
|
description: "The platforms to build for."
|
||||||
dockerfile:
|
secrets:
|
||||||
required: false
|
GHCR_ACCESS_TOKEN:
|
||||||
type: string
|
required: true
|
||||||
default: "Dockerfile"
|
description: "GitHub Container Registry access token."
|
||||||
description: "The Dockerfile to use for building the image."
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }}
|
FLAVOR_PREFIX: ${{ inputs.flavor && format('{0}-', inputs.flavor) || '' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-client:
|
build-client:
|
||||||
name: Build Client Artifacts
|
|
||||||
uses: ./.github/workflows/client_build.yml
|
uses: ./.github/workflows/client_build.yml
|
||||||
|
|
||||||
build-base:
|
build-base:
|
||||||
name: Build Base Image
|
name: Build and Publish Base Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build-client
|
needs: [ build-client ]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -55,7 +58,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}base
|
images: ghcr.io/${{ github.repository }}/${{ env.FLAVOR_PREFIX }}base
|
||||||
tags: |
|
tags: |
|
||||||
type=edge,branch=master
|
|
||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
|
@ -71,7 +73,7 @@ jobs:
|
||||||
- name: Generate base Dockerfile
|
- name: Generate base Dockerfile
|
||||||
env:
|
env:
|
||||||
RUNTIME_DOCKERFILE: ${{ inputs.dockerfile || 'Dockerfile' }}
|
RUNTIME_DOCKERFILE: ${{ inputs.dockerfile || 'Dockerfile' }}
|
||||||
run: go run utils/docker/main.go -i Dockerfile.tmpl -o Dockerfile -client client/dist
|
run: go run docker/main.go -i Dockerfile.tmpl -o Dockerfile -client client/dist
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
|
@ -81,5 +83,3 @@ jobs:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
platforms: ${{ inputs.platforms || 'linux/amd64' }}
|
platforms: ${{ inputs.platforms || 'linux/amd64' }}
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
|
|
65
.github/workflows/server_build.yml
vendored
Normal file
65
.github/workflows/server_build.yml
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
name: Build and Publish Server Artifacts
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
#pull_request: # Change to push when ready to deploy
|
||||||
|
# branches:
|
||||||
|
# - master
|
||||||
|
# paths:
|
||||||
|
# - server/**
|
||||||
|
# - .github/workflows/server_build.yml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
server_build:
|
||||||
|
name: Build and Publish Server Artifacts
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
variant:
|
||||||
|
- name: server-amd64
|
||||||
|
platform: linux/amd64
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
- name: server-arm64
|
||||||
|
platform: linux/arm64
|
||||||
|
dockerfile: Dockerfile.bookworm
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
# Temporary hotfix for the setup-qemu-action
|
||||||
|
# Ref: https://github.com/tonistiigi/binfmt/issues/240
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
image: tonistiigi/binfmt:qemu-v7.0.0-28
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
id: build
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ./server/
|
||||||
|
file: ./server/${{ matrix.variant.dockerfile }}
|
||||||
|
tags: ${{ matrix.variant.name }}
|
||||||
|
platforms: ${{ matrix.variant.platform }}
|
||||||
|
load: true
|
||||||
|
|
||||||
|
- name: Copy artifacts
|
||||||
|
run: |
|
||||||
|
container_id=$(docker create ${{ matrix.variant.name }})
|
||||||
|
mkdir -p artifacts/${{ matrix.variant.name }}
|
||||||
|
docker cp $container_id:/src/bin/. artifacts/${{ matrix.variant.name }}/
|
||||||
|
docker rm $container_id
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.variant.name }}
|
||||||
|
path: artifacts/${{ matrix.variant.name }}
|
24
.github/workflows/server_test.yml
vendored
24
.github/workflows/server_test.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Test Server
|
name: Test Server Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -9,8 +9,8 @@ on:
|
||||||
- .github/workflows/server_test.yml
|
- .github/workflows/server_test.yml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-amd64:
|
server_test:
|
||||||
name: Build amd64
|
name: Test Server Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -24,21 +24,3 @@ jobs:
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: ./server
|
context: ./server
|
||||||
platforms: linux/amd64
|
|
||||||
|
|
||||||
build-arm64:
|
|
||||||
name: Build arm64
|
|
||||||
runs-on: ubuntu-24.04-arm
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Build Docker image
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: ./server
|
|
||||||
platforms: linux/arm64
|
|
||||||
|
|
45
.github/workflows/webpage_build.yml
vendored
45
.github/workflows/webpage_build.yml
vendored
|
@ -1,45 +0,0 @@
|
||||||
name: Build Webpage
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
with-artifact:
|
|
||||||
required: false
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
description: |
|
|
||||||
If true, the build artifacts will be uploaded as a GitHub Actions artifact.
|
|
||||||
This is useful for debugging and testing purposes. If false, the artifacts
|
|
||||||
will not be uploaded. This is useful for test builds where you don't need
|
|
||||||
the artifacts.
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-webpage:
|
|
||||||
name: Build Webpage
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
cache: npm
|
|
||||||
cache-dependency-path: webpage/package-lock.json
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: ./webpage
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Build webpage
|
|
||||||
working-directory: ./webpage
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
- if: ${{ inputs.with-artifact }}
|
|
||||||
name: Upload artifacts
|
|
||||||
uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
artifact-name: github-pages
|
|
||||||
path: ./webpage/build
|
|
57
.github/workflows/webpage_deploy.yml
vendored
57
.github/workflows/webpage_deploy.yml
vendored
|
@ -1,39 +1,50 @@
|
||||||
name: Build and Deploy Webpage to GitHub Pages
|
name: Build and Deploy Webpage to GitHub Pages
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Runs on pushes targeting the default branch
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- webpage/**
|
- webpage/**
|
||||||
- .github/workflows/webpage_build.yml
|
|
||||||
- .github/workflows/webpage_deploy.yml
|
- .github/workflows/webpage_deploy.yml
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
|
||||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
|
||||||
concurrency:
|
|
||||||
group: "pages"
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-webpage:
|
webpage_build:
|
||||||
name: Build Webpage
|
name: Build and Deploy Webpage to GitHub Pages
|
||||||
uses: ./.github/workflows/webpage_build.yml
|
runs-on: ubuntu-latest
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
deploy-webpage:
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: webpage/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
working-directory: ./webpage
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build webpage
|
||||||
|
working-directory: ./webpage
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload Build Artifact
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
artifact-name: github-pages
|
||||||
|
path: ./webpage/build
|
||||||
|
|
||||||
|
webpage_deploy:
|
||||||
name: Deploy to GitHub Pages
|
name: Deploy to GitHub Pages
|
||||||
needs: build-webpage
|
needs: webpage_build
|
||||||
|
|
||||||
|
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
|
||||||
|
permissions:
|
||||||
|
pages: write # to deploy to Pages
|
||||||
|
id-token: write # to verify the deployment originates from an appropriate source
|
||||||
|
|
||||||
# Deploy to the github-pages environment
|
# Deploy to the github-pages environment
|
||||||
environment:
|
environment:
|
||||||
|
|
30
.github/workflows/webpage_test.yml
vendored
30
.github/workflows/webpage_test.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Test Webpage
|
name: Test Webpage Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -6,14 +6,26 @@ on:
|
||||||
- master
|
- master
|
||||||
paths:
|
paths:
|
||||||
- webpage/**
|
- webpage/**
|
||||||
- .github/workflows/webpage_build.yml
|
|
||||||
- .github/workflows/webpage_test.yml
|
- .github/workflows/webpage_test.yml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-webpage:
|
webpage_test:
|
||||||
name: Test Webpage
|
name: Test Webpage Build
|
||||||
uses: ./.github/workflows/webpage_build.yml
|
runs-on: ubuntu-latest
|
||||||
with:
|
|
||||||
# Do not upload artifacts for test builds
|
steps:
|
||||||
with-artifact: false
|
- uses: actions/checkout@v4
|
||||||
secrets: inherit
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: webpage/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
working-directory: ./webpage
|
||||||
|
run: npm ci
|
||||||
|
- name: Build webpage
|
||||||
|
working-directory: ./webpage
|
||||||
|
run: npm run build
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
# This Dockerfile is pre-processed by the ./utils/docker script, it is not meant to be used directly.
|
# This Dockerfile is pre-processed by the ./docker script, it is not meant to be used directly.
|
||||||
|
|
||||||
|
FROM ./runtime/xorg-deps/ AS xorg-deps
|
||||||
FROM ./server/ AS server
|
FROM ./server/ AS server
|
||||||
FROM ./client/ AS client
|
FROM ./client/ AS client
|
||||||
FROM ./utils/xorg-deps/ AS xorg-deps
|
|
||||||
FROM ./runtime/$RUNTIME_DOCKERFILE AS runtime
|
FROM ./runtime/$RUNTIME_DOCKERFILE AS runtime
|
||||||
|
|
||||||
# tells neko-rooms which version of the API to use
|
COPY --from=xorg-deps /usr/local/lib/xorg/modules/drivers/dummy_drv.so /usr/lib/xorg/modules/drivers/dummy_drv.so
|
||||||
LABEL net.m1k1o.neko.api-version=3
|
COPY --from=xorg-deps /usr/local/lib/xorg/modules/input/neko_drv.so /usr/lib/xorg/modules/input/neko_drv.so
|
||||||
|
|
||||||
COPY --from=server /src/bin/plugins/ /etc/neko/plugins/
|
COPY --from=server /src/bin/plugins/ /etc/neko/plugins/
|
||||||
COPY --from=server /src/bin/neko /usr/bin/neko
|
COPY --from=server /src/bin/neko /usr/bin/neko
|
||||||
COPY --from=client /src/dist/ /var/www
|
COPY --from=client /src/dist/ /var/www
|
||||||
COPY --from=xorg-deps /usr/local/lib/xorg/modules/drivers/dummy_drv.so /usr/lib/xorg/modules/drivers/dummy_drv.so
|
|
||||||
COPY --from=xorg-deps /usr/local/lib/xorg/modules/input/neko_drv.so /usr/lib/xorg/modules/input/neko_drv.so
|
|
||||||
|
|
||||||
COPY config.yml /etc/neko/neko.yaml
|
COPY config.yml /etc/neko/neko.yaml
|
||||||
|
|
118
README.md
118
README.md
|
@ -1,6 +1,6 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://github.com/m1k1o/neko" title="Neko's Github repository.">
|
<a href="https://github.com/m1k1o/neko" title="Neko's Github repository.">
|
||||||
<img src="https://neko.m1k1o.net/img/logo.png" width="400" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/logo.png" width="400" height="auto"/>
|
||||||
</a>
|
</a>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/m1k1o/neko/releases">
|
<a href="https://github.com/m1k1o/neko/releases">
|
||||||
|
@ -21,14 +21,11 @@
|
||||||
<a href="https://discord.gg/3U6hWpC">
|
<a href="https://discord.gg/3U6hWpC">
|
||||||
<img src="https://discordapp.com/api/guilds/665851821906067466/widget.png" alt="Chat on discord">
|
<img src="https://discordapp.com/api/guilds/665851821906067466/widget.png" alt="Chat on discord">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hellogithub.com/repository/4536d4546af24196af3f08a023dfa007" target="_blank">
|
|
||||||
<img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=4536d4546af24196af3f08a023dfa007&claim_uid=0x19e4dJwD83aW2&theme=small" alt="Featured|HelloGitHub" />
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/m1k1o/neko/actions">
|
<a href="https://github.com/m1k1o/neko/actions">
|
||||||
<img src="https://github.com/m1k1o/neko/actions/workflows/ghcr.yml/badge.svg" alt="build">
|
<img src="https://github.com/m1k1o/neko/actions/workflows/ghcr-amd.yml/badge.svg" alt="build">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<img src="https://neko.m1k1o.net/img/intro.gif" width="650" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/intro.gif" width="650" height="auto"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
# n.eko
|
# n.eko
|
||||||
|
@ -86,60 +83,47 @@ Compared to clientless remote desktop gateway (e.g. [Apache Guacamole](https://g
|
||||||
### Supported browsers
|
### Supported browsers
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#firefox">
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/firefox.svg" title="m1k1o/neko:firefox" width="60" height="auto"/>
|
||||||
<img src="https://neko.m1k1o.net/img/icons/firefox.svg" title="ghcr.io/m1k1o/neko/firefox" width="60" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/google-chrome.svg" title="m1k1o/neko:google-chrome" width="60" height="auto"/>
|
||||||
</a>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/chromium.svg" title="m1k1o/neko:chromium" width="60" height="auto"/>
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#tor-browser">
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/microsoft-edge.svg" title="m1k1o/neko:microsoft-edge" width="60" height="auto"/>
|
||||||
<img src="https://neko.m1k1o.net/img/icons/tor-browser.svg" title="ghcr.io/m1k1o/neko/tor-browser" width="60" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/brave.svg" title="m1k1o/neko:brave" width="60" height="auto"/>
|
||||||
</a>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/vivaldi.svg" title="m1k1o/neko:vivaldi" width="60" height="auto"/>
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#waterfox">
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/opera.svg" title="m1k1o/neko:opera" width="60" height="auto"/>
|
||||||
<img src="https://neko.m1k1o.net/img/icons/waterfox.svg" title="ghcr.io/m1k1o/neko/waterfox" width="60" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/tor-browser.svg" title="m1k1o/neko:tor-browser" width="60" height="auto"/>
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#chromium">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/chromium.svg" title="ghcr.io/m1k1o/neko/chromium" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#google-chrome">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/google-chrome.svg" title="ghcr.io/m1k1o/neko/google-chrome" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#ungoogled-chromium">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/ungoogled-chromium.svg" title="ghcr.io/m1k1o/neko/google-chrome" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#microsoft-edge">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/microsoft-edge.svg" title="ghcr.io/m1k1o/neko/microsoft-edge" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#brave">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/brave.svg" title="ghcr.io/m1k1o/neko/brave" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#vivaldi">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/vivaldi.svg" title="ghcr.io/m1k1o/neko/vivaldi" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#opera">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/opera.svg" title="ghcr.io/m1k1o/neko/opera" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
... see [all available images](https://neko.m1k1o.net/docs/v3/installation/docker-images)
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Other applications
|
### Other programs
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#xfce">
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/remmina.png" title="m1k1o/neko:remmina" width="60" height="auto"/>
|
||||||
<img src="https://neko.m1k1o.net/img/icons/xfce.svg" title="ghcr.io/m1k1o/neko/xfce" width="60" height="auto"/>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/vlc.svg" title="m1k1o/neko:vlc" width="60" height="auto"/>
|
||||||
</a>
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/xfce.svg" title="m1k1o/neko:xfce" width="60" height="auto"/>
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#kde">
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/icons/kde.svg" title="m1k1o/neko:kde" width="60" height="auto"/>
|
||||||
<img src="https://neko.m1k1o.net/img/icons/kde.svg" title="ghcr.io/m1k1o/neko/kde" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#remmina">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/remmina.svg" title="ghcr.io/m1k1o/neko/remmina" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://neko.m1k1o.net/docs/v3/installation/docker-images#vlc">
|
|
||||||
<img src="https://neko.m1k1o.net/img/icons/vlc.svg" title="ghcr.io/m1k1o/neko/vlc" width="60" height="auto"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
... others in <a href="https://github.com/m1k1o/neko-apps">m1k1o/neko-apps</a>
|
... others in <a href="https://github.com/m1k1o/neko-apps">m1k1o/neko-apps</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Why neko?
|
### Features
|
||||||
|
|
||||||
|
* Text Chat (With basic markdown support, discord flavor)
|
||||||
|
* Admin users (Kick, Ban & Force Give/Release Controls, Lock room)
|
||||||
|
* Clipboard synchronization (on [supported browsers](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText))
|
||||||
|
* Emote overlay
|
||||||
|
* Ignore user (chat and emotes)
|
||||||
|
* Persistent settings
|
||||||
|
* Automatic Login with custom url args. (add `?usr=<your-user-name>&pwd=<room-pass>` to the url.)
|
||||||
|
* Broadcasting room content using RTMP (to e.g. twitch or youtube...)
|
||||||
|
* Bidirectional file transfer (if enabled)
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
With `NEKO_FILE_TRANSFER_ENABLED=true`:
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/m1k1o/neko/master/docs/_media/file-transfer.gif" width="650" height="auto"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Why n.eko?
|
||||||
|
|
||||||
I like cats 🐱 (`Neko` is the Japanese word for cat), I'm a weeb/nerd.
|
I like cats 🐱 (`Neko` is the Japanese word for cat), I'm a weeb/nerd.
|
||||||
|
|
||||||
|
@ -147,26 +131,28 @@ I like cats 🐱 (`Neko` is the Japanese word for cat), I'm a weeb/nerd.
|
||||||
|
|
||||||
## Multiple rooms
|
## Multiple rooms
|
||||||
|
|
||||||
For neko room management software, visit [neko-rooms](https://github.com/m1k1o/neko-rooms).
|
For n.eko room management software, visit [neko-rooms](https://github.com/m1k1o/neko-rooms).
|
||||||
|
|
||||||
It also offers [Zero-knowledge installation (with HTTPS)](https://github.com/m1k1o/neko-rooms/?tab=readme-ov-file#zero-knowledge-installation-with-https).
|
It also offers zero-knowledge [installation script (with HTTPS and Traefik)](https://github.com/m1k1o/neko-rooms/#zero-knowledge-installation-with-https-and-traefik).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Full documentation is available at [neko.m1k1o.net](https://neko.m1k1o.net/). Key sections include:
|
* [Getting Started](https://neko.m1k1o.net/#/getting-started/)
|
||||||
|
* [Quick Start](https://neko.m1k1o.net/#/getting-started/quick-start)
|
||||||
|
* [Examples](https://neko.m1k1o.net/#/getting-started/examples)
|
||||||
|
* [Reverse Proxy](https://neko.m1k1o.net/#/getting-started/reverse-proxy)
|
||||||
|
* [Configuration](https://neko.m1k1o.net/#/getting-started/configuration)
|
||||||
|
* [Troubleshooting](https://neko.m1k1o.net/#/getting-started/troubleshooting)
|
||||||
|
* [Mobile Support](https://neko.m1k1o.net/#/mobile-support)
|
||||||
|
* [Contributing](https://neko.m1k1o.net/#/contributing)
|
||||||
|
* [Non Goals](https://neko.m1k1o.net/#/non-goals)
|
||||||
|
* [Technologies](https://neko.m1k1o.net/#/technologies)
|
||||||
|
* [Changelog](https://neko.m1k1o.net/#/changelog)
|
||||||
|
|
||||||
- [Migration from V2](https://neko.m1k1o.net/docs/v3/migration-from-v2)
|
## How to contribute? How to build?
|
||||||
- [Getting Started](https://neko.m1k1o.net/docs/v3/quick-start)
|
|
||||||
- [Installation](https://neko.m1k1o.net/docs/v3/installation)
|
|
||||||
- [Examples](https://neko.m1k1o.net/docs/v3/installation/examples)
|
|
||||||
- [Configuration](https://neko.m1k1o.net/docs/v3/configuration)
|
|
||||||
- [Frequently Asked Questions](https://neko.m1k1o.net/docs/v3/faq)
|
|
||||||
- [Troubleshooting](https://neko.m1k1o.net/docs/v3/troubleshooting)
|
|
||||||
|
|
||||||
## How to Contribute
|
Navigate to [.docker](.docker) folder for further information.
|
||||||
|
|
||||||
Contributions are welcome! Check the [Contributing Guide](https://neko.m1k1o.net/contributing) for details.
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
If you find Neko useful, consider supporting the project via [GitHub Sponsors](https://github.com/sponsors/m1k1o).
|
If you want to support this project, you can do it [here](https://github.com/sponsors/m1k1o).
|
||||||
|
|
19
SECURITY.md
19
SECURITY.md
|
@ -1,19 +0,0 @@
|
||||||
# Security Policy
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
If there are any vulnerabilities in **m1k1o/neko**, don't hesitate to _report them_.
|
|
||||||
|
|
||||||
1. Send an email to `security@m1k1o.net`.
|
|
||||||
|
|
||||||
2. Describe the vulnerability.
|
|
||||||
|
|
||||||
If you have a fix, that is most welcome -- please attach or summarize it in your message!
|
|
||||||
|
|
||||||
3. We will evaluate the vulnerability and, if necessary, release a fix or mitigating steps to address it. We will contact you to let you know the outcome, and will credit you in the report.
|
|
||||||
|
|
||||||
Please **do not disclose the vulnerability publicly** until a fix is released!
|
|
||||||
|
|
||||||
4. Once we have either a) published a fix, or b) declined to address the vulnerability for whatever reason, you are free to publicly disclose it.
|
|
||||||
|
|
||||||
We appreciate your help in keeping Neko secure.
|
|
|
@ -1,13 +1,12 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
RUN set -eux; apt-get update; \
|
RUN set -eux; apt-get update; \
|
||||||
apt-get install -y --no-install-recommends apt-transport-https curl openbox; \
|
apt-get install -y --no-install-recommends apt-transport-https curl openbox; \
|
||||||
#
|
#
|
||||||
# install brave browser
|
# install brave browser
|
||||||
ARCH=$(dpkg --print-architecture); \
|
|
||||||
curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg; \
|
curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg; \
|
||||||
echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=${ARCH}] https://brave-browser-apt-release.s3.brave.com/ stable main" \
|
echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg arch=amd64] https://brave-browser-apt-release.s3.brave.com/ stable main" \
|
||||||
| tee /etc/apt/sources.list.d/brave-browser-release.list; \
|
| tee /etc/apt/sources.list.d/brave-browser-release.list; \
|
||||||
apt-get update; \
|
apt-get update; \
|
||||||
apt-get install -y --no-install-recommends brave-browser; \
|
apt-get install -y --no-install-recommends brave-browser; \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/nvidia-base:latest
|
ARG BASE_IMAGE=m1k1o/neko:nvidia-base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
RUN set -eux; apt-get update; \
|
RUN set -eux; apt-get update; \
|
||||||
|
|
|
@ -12,11 +12,9 @@ command=/bin/entrypoint.sh /usr/bin/brave-browser
|
||||||
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
||||||
--ignore-gpu-blocklist
|
--ignore-gpu-blocklist
|
||||||
--disable-seccomp-filter-sandbox
|
--disable-seccomp-filter-sandbox
|
||||||
--use-angle=vulkan
|
--use-gl=egl
|
||||||
--disable-software-rasterizer
|
--disable-software-rasterizer
|
||||||
--disable-dev-shm-usage
|
--disable-dev-shm-usage
|
||||||
--disable-vulkan-surface
|
|
||||||
--enable-unsafe-webgpu
|
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
autorestart=true
|
autorestart=true
|
||||||
priority=800
|
priority=800
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/nvidia-base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -12,11 +12,9 @@ command=/bin/entrypoint.sh /usr/bin/chromium
|
||||||
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
||||||
--ignore-gpu-blocklist
|
--ignore-gpu-blocklist
|
||||||
--disable-seccomp-filter-sandbox
|
--disable-seccomp-filter-sandbox
|
||||||
--use-angle=vulkan
|
--use-gl=egl
|
||||||
--disable-software-rasterizer
|
--disable-software-rasterizer
|
||||||
--disable-dev-shm-usage
|
--disable-dev-shm-usage
|
||||||
--disable-vulkan-surface
|
|
||||||
--enable-unsafe-webgpu
|
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
autorestart=true
|
autorestart=true
|
||||||
priority=800
|
priority=800
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -10,7 +10,7 @@ RUN set -eux; apt-get update; \
|
||||||
#
|
#
|
||||||
# install firefox-esr for armhf
|
# install firefox-esr for armhf
|
||||||
apt-get install -y --no-install-recommends firefox-esr; \
|
apt-get install -y --no-install-recommends firefox-esr; \
|
||||||
ln -s /usr/lib/firefox-esr /usr/lib/firefox; \
|
ln -s /usr/bin/firefox-esr /usr/bin/firefox; \
|
||||||
#
|
#
|
||||||
# install extensions
|
# install extensions
|
||||||
mkdir -p /usr/lib/firefox-esr/distribution/extensions; \
|
mkdir -p /usr/lib/firefox-esr/distribution/extensions; \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/nvidia-base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG SRC_URL="https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US"
|
ARG SRC_URL="https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US"
|
||||||
|
|
|
@ -15,8 +15,8 @@ lockPref("plugins.hide_infobar_for_missing_plugin", true);
|
||||||
lockPref("profile.allow_automigration", false);
|
lockPref("profile.allow_automigration", false);
|
||||||
lockPref("signon.prefillForms", false);
|
lockPref("signon.prefillForms", false);
|
||||||
lockPref("signon.rememberSignons", false);
|
lockPref("signon.rememberSignons", false);
|
||||||
//lockPref("xpinstall.enabled", false);
|
lockPref("xpinstall.enabled", false);
|
||||||
//lockPref("xpinstall.whitelist.required", true);
|
lockPref("xpinstall.whitelist.required", true);
|
||||||
lockPref("browser.download.manager.retention", 0);
|
lockPref("browser.download.manager.retention", 0);
|
||||||
lockPref("browser.download.folderList", 2);
|
lockPref("browser.download.folderList", 2);
|
||||||
lockPref("browser.download.forbid_open_with", true);
|
lockPref("browser.download.forbid_open_with", true);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG SRC_URL="https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
|
ARG SRC_URL="https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/nvidia-base:latest
|
ARG BASE_IMAGE=m1k1o/neko:nvidia-base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
# latest working version with EGL: 111.0.5563.146, revert when resolved
|
# latest working version with EGL: 111.0.5563.146, revert when resolved
|
||||||
|
|
|
@ -12,11 +12,9 @@ command=/bin/entrypoint.sh /usr/bin/google-chrome
|
||||||
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
||||||
--ignore-gpu-blocklist
|
--ignore-gpu-blocklist
|
||||||
--disable-seccomp-filter-sandbox
|
--disable-seccomp-filter-sandbox
|
||||||
--use-angle=vulkan
|
--use-gl=egl
|
||||||
--disable-software-rasterizer
|
--disable-software-rasterizer
|
||||||
--disable-dev-shm-usage
|
--disable-dev-shm-usage
|
||||||
--disable-vulkan-surface
|
|
||||||
--enable-unsafe-webgpu
|
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
autorestart=true
|
autorestart=true
|
||||||
priority=800
|
priority=800
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG API_URL="https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/"
|
ARG API_URL="https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG API_URL="https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/"
|
ARG API_URL="https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/"
|
||||||
|
|
|
@ -12,11 +12,9 @@ command=/bin/entrypoint.sh /usr/bin/microsoft-edge
|
||||||
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
--enable-features=Vulkan,UseSkiaRenderer,VaapiVideoEncoder,VaapiVideoDecoder,CanvasOopRasterization
|
||||||
--ignore-gpu-blocklist
|
--ignore-gpu-blocklist
|
||||||
--disable-seccomp-filter-sandbox
|
--disable-seccomp-filter-sandbox
|
||||||
--use-angle=vulkan
|
--use-gl=egl
|
||||||
--disable-software-rasterizer
|
--disable-software-rasterizer
|
||||||
--disable-dev-shm-usage
|
--disable-dev-shm-usage
|
||||||
--disable-vulkan-surface
|
|
||||||
--enable-unsafe-webgpu
|
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
autorestart=true
|
autorestart=true
|
||||||
priority=800
|
priority=800
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG API_URL="https://download5.operacdn.com/pub/opera/desktop/"
|
ARG API_URL="https://download5.operacdn.com/pub/opera/desktop/"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
# install remmina
|
# install remmina
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -u
|
||||||
|
|
||||||
err() {
|
err() {
|
||||||
echo "ERROR: $*" >&2
|
echo "ERROR: $*" >&2
|
||||||
|
@ -15,28 +16,23 @@ if [[ -n "$REMMINA_PROFILE" ]]; then
|
||||||
exec remmina -c "$profile"
|
exec remmina -c "$profile"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -z "$REMMINA_URL" ]]; then
|
[[ -z "$REMMINA_URL" ]] && err "Neither 'REMMINA_PROFILE' nor 'REMMINA_URL' found in env vars"
|
||||||
readarray -t arr < <( echo -n "$REMMINA_URL" | perl -pe 's|^(\w+)\:\/\/(?:([^:]+)(?::([^@]+))?@)?(.*)$|\1\n\2\n\3\n\4|' )
|
|
||||||
proto="${arr[0]}"
|
|
||||||
user="${arr[1]}"
|
|
||||||
pw="${arr[2]}"
|
|
||||||
host="${arr[3]}"
|
|
||||||
echo "Parsed url in 'REMMINA_URL': proto:$proto username:$user host:$host"
|
|
||||||
|
|
||||||
[[ "$proto" != "vnc" && "$proto" != "rdp" && "$proto" != "spice" ]] && err "Unsupported protocol $proto in connection url 'REMMINA_URL'"
|
readarray -t arr < <( echo -n "$REMMINA_URL" | perl -pe 's|^(\w+)\:\/\/(?:([^:]+)(?::([^@]+))?@)?(.*)$|\1\n\2\n\3\n\4|' )
|
||||||
|
proto="${arr[0]}"
|
||||||
|
user="${arr[1]}"
|
||||||
|
pw="${arr[2]}"
|
||||||
|
host="${arr[3]}"
|
||||||
|
echo "Parsed url in 'REMMINA_URL': proto:$proto username:$user host:$host"
|
||||||
|
|
||||||
profile="$profile_dir"/"$proto".remmina
|
[[ "$proto" != "vnc" && "$proto" != "rdp" && "$proto" != "spice" ]] && err "Unsupported protocol $proto in connection url 'REMMINA_URL'"
|
||||||
remmina --set-option username="$user" --update-profile "$profile"
|
|
||||||
remmina --set-option password="$pw" --update-profile "$profile"
|
|
||||||
remmina --set-option server="$host" --update-profile "$profile"
|
|
||||||
|
|
||||||
# remmina --set-option window_maximize=1 --update-profile "$profile"
|
profile="$profile_dir"/"$proto".remmina
|
||||||
# remmina --set-option scale=1 --update-profile "$profile"
|
remmina --set-option username="$user" --update-profile "$profile"
|
||||||
|
remmina --set-option password="$pw" --update-profile "$profile"
|
||||||
|
remmina --set-option server="$host" --update-profile "$profile"
|
||||||
|
|
||||||
echo "Running remmina with URL $REMMINA_URL"
|
# remmina --set-option window_maximize=1 --update-profile "$profile"
|
||||||
exec remmina -c "$profile"
|
# remmina --set-option scale=1 --update-profile "$profile"
|
||||||
fi
|
|
||||||
|
|
||||||
|
exec remmina -c "$profile"
|
||||||
echo "Running remmina without connection profile"
|
|
||||||
exec remmina
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG API_URL="https://api.github.com/repos/macchrome/linchrome/releases/latest"
|
ARG API_URL="https://api.github.com/repos/macchrome/linchrome/releases/latest"
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
|
ARG VIVALDI_VERSION="5.3.2679.34-1"
|
||||||
|
# TODO: Get chromium version from vivaldi
|
||||||
|
ARG CHROMIUM_VERSION="102.0.5005.72"
|
||||||
|
|
||||||
#
|
#
|
||||||
# install vivaldi
|
# install vivaldi
|
||||||
SHELL ["/bin/bash", "-c"]
|
SHELL ["/bin/bash", "-c"]
|
||||||
RUN set -eux; apt-get update; \
|
RUN set -eux; apt-get update; \
|
||||||
ARCH=$(dpkg --print-architecture); \
|
wget -O /tmp/vivaldi.deb "https://downloads.vivaldi.com/stable/vivaldi-stable_${VIVALDI_VERSION}_amd64.deb"; \
|
||||||
wget -O /tmp/vivaldi.deb "https://downloads.vivaldi.com/stable/vivaldi-stable_${ARCH}.deb"; \
|
apt-get install -y --no-install-recommends wget unzip xz-utils jq openbox /tmp/vivaldi.deb; \
|
||||||
apt-get install -y --no-install-recommends wget unzip xz-utils jq openbox; \
|
/opt/vivaldi/update-ffmpeg; \
|
||||||
apt install -y --no-install-recommends /tmp/vivaldi.deb; \
|
|
||||||
#
|
#
|
||||||
# install latest version of uBlock Origin and SponsorBlock for YouTube
|
# install latest version of uBlock Origin and SponsorBlock for YouTube
|
||||||
EXTENSIONS_DIR="/usr/share/chromium/extensions"; \
|
EXTENSIONS_DIR="/usr/share/chromium/extensions"; \
|
||||||
|
@ -19,7 +22,7 @@ RUN set -eux; apt-get update; \
|
||||||
mkdir -p "${EXTENSIONS_DIR}"; \
|
mkdir -p "${EXTENSIONS_DIR}"; \
|
||||||
for EXT_ID in "${EXTENSIONS[@]}"; \
|
for EXT_ID in "${EXTENSIONS[@]}"; \
|
||||||
do \
|
do \
|
||||||
EXT_URL="https://clients2.google.com/service/update2/crx?response=redirect&prodversion=100&acceptformat=crx2,crx3&x=id%3D${EXT_ID}%26installsource%3Dondemand%26uc"; \
|
EXT_URL="https://clients2.google.com/service/update2/crx?response=redirect&nacl_arch=x86-64&prodversion=${CHROMIUM_VERSION}&acceptformat=crx2,crx3&x=id%3D${EXT_ID}%26installsource%3Dondemand%26uc"; \
|
||||||
EXT_PATH="${EXTENSIONS_DIR}/${EXT_ID}.crx"; \
|
EXT_PATH="${EXTENSIONS_DIR}/${EXT_ID}.crx"; \
|
||||||
wget -O "${EXT_PATH}" "${EXT_URL}"; \
|
wget -O "${EXT_PATH}" "${EXT_URL}"; \
|
||||||
EXT_VERSION="$(unzip -p "${EXT_PATH}" manifest.json 2>/dev/null | jq -r ".version")"; \
|
EXT_VERSION="$(unzip -p "${EXT_PATH}" manifest.json 2>/dev/null | jq -r ".version")"; \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
ARG SRC_URL="https://cdn1.waterfox.net/waterfox/releases/latest/linux"
|
ARG SRC_URL="https://cdn1.waterfox.net/waterfox/releases/latest/linux"
|
||||||
|
@ -10,7 +10,7 @@ RUN set -eux; apt-get update; \
|
||||||
xz-utils bzip2 libgtk-3-0 libdbus-glib-1-2; \
|
xz-utils bzip2 libgtk-3-0 libdbus-glib-1-2; \
|
||||||
#
|
#
|
||||||
# fetch latest release
|
# fetch latest release
|
||||||
wget --user-agent="Mozilla/5.0" -O /tmp/waterfox-setup.tar.bz2 "${SRC_URL}"; \
|
wget -O /tmp/waterfox-setup.tar.bz2 "${SRC_URL}"; \
|
||||||
mkdir /usr/lib/waterfox; \
|
mkdir /usr/lib/waterfox; \
|
||||||
tar -xjf /tmp/waterfox-setup.tar.bz2 -C /usr/lib; \
|
tar -xjf /tmp/waterfox-setup.tar.bz2 -C /usr/lib; \
|
||||||
rm -f /tmp/waterfox-setup.tar.bz2; \
|
rm -f /tmp/waterfox-setup.tar.bz2; \
|
||||||
|
|
|
@ -15,8 +15,8 @@ lockPref("plugins.hide_infobar_for_missing_plugin", true);
|
||||||
lockPref("profile.allow_automigration", false);
|
lockPref("profile.allow_automigration", false);
|
||||||
lockPref("signon.prefillForms", false);
|
lockPref("signon.prefillForms", false);
|
||||||
lockPref("signon.rememberSignons", false);
|
lockPref("signon.rememberSignons", false);
|
||||||
//lockPref("xpinstall.enabled", false);
|
lockPref("xpinstall.enabled", false);
|
||||||
//lockPref("xpinstall.whitelist.required", true);
|
lockPref("xpinstall.whitelist.required", true);
|
||||||
lockPref("browser.download.manager.retention", 0);
|
lockPref("browser.download.manager.retention", 0);
|
||||||
lockPref("browser.download.folderList", 2);
|
lockPref("browser.download.folderList", 2);
|
||||||
lockPref("browser.download.forbid_open_with", true);
|
lockPref("browser.download.forbid_open_with", true);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BASE_IMAGE=ghcr.io/m1k1o/neko/base:latest
|
ARG BASE_IMAGE=m1k1o/neko:base
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
98
build
98
build
|
@ -2,57 +2,39 @@
|
||||||
set -e
|
set -e
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
#
|
|
||||||
# This script builds the neko base image and all the applications
|
|
||||||
#
|
|
||||||
|
|
||||||
# disable buildx because of https://github.com/docker/buildx/issues/847
|
# disable buildx because of https://github.com/docker/buildx/issues/847
|
||||||
# if you want to use buildx, set USE_BUILDX=1
|
|
||||||
if [ -z "$USE_BUILDX" ]; then
|
if [ -z "$USE_BUILDX" ]; then
|
||||||
USE_BUILDX=0
|
USE_BUILDX=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check if docker buildx is available, its not docker-buildx command but rather subcommand of docker
|
# check if docker buildx is available, its not docker-buildx command but rather subcommand of docker
|
||||||
#if [ -z "$USE_BUILDX" ] && [ -x "$(command -v docker)" ]; then
|
if [ -z "$USE_BUILDX" ] && [ -x "$(command -v docker)" ]; then
|
||||||
# if docker buildx version >/dev/null 2>&1; then
|
if docker buildx version >/dev/null 2>&1; then
|
||||||
# USE_BUILDX=1
|
USE_BUILDX=1
|
||||||
# fi
|
fi
|
||||||
#fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# This script builds the neko base image and all the applications
|
||||||
|
#
|
||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
echo "$(date +'%Y-%m-%d %H:%M:%S') - [NEKO] - $1" > /dev/stderr
|
echo "$(date +'%Y-%m-%d %H:%M:%S') - [NEKO] - $1" > /dev/stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
function help() {
|
function help() {
|
||||||
echo "Usage: $0 [options] [image]"
|
echo "Usage: $0"
|
||||||
echo
|
echo " -p, --platform : The platform (default: linux/amd64)"
|
||||||
echo "Options:"
|
echo " -r, --repository : The repository prefix (default: ghcr.io/m1k1o/neko)"
|
||||||
echo " -p, --platform : The platform (default: system architecture)"
|
echo " -t, --tag : The image tag, can be specified multiple times, if not specified"
|
||||||
echo " -r, --repository : The repository prefix (default: ghcr.io/m1k1o/neko)"
|
echo " uses 'latest' and if available, current git semver tag (v*.*.*)"
|
||||||
echo " -t, --tag : The image tag, can be specified multiple times, if not specified"
|
echo " -f, --flavor : The flavor, if not specified, builds without flavor"
|
||||||
echo " uses 'latest' and if available, current git semver tag (v*.*.*)"
|
echo " -b, --base : The base image name (default: <repository>[<flavor>-]base:<tag>)"
|
||||||
echo " -f, --flavor : The flavor, if not specified, builds without flavor"
|
echo " -a, --app : The app to build, if not specified, builds the base image"
|
||||||
echo " -b, --base_image : The base image name (default: <repository>[<flavor>-]base:<tag>)"
|
echo " -y, --yes : Skip confirmation prompts"
|
||||||
echo " -a, --application : The app to build, if not specified, builds the base image"
|
echo " --no-cache : Build without docker cache"
|
||||||
echo " -y, --yes : Skip confirmation prompts"
|
echo " --push : Push the image to the registry after building"
|
||||||
echo " --no-cache : Build without docker cache"
|
echo " -h, --help : Show this help message"
|
||||||
echo " --push : Push the image to the registry after building"
|
|
||||||
echo " -h, --help : Show this help message"
|
|
||||||
echo
|
|
||||||
echo "Positional arguments:"
|
|
||||||
echo " <image> : The image name, if not specified, uses the full image name"
|
|
||||||
echo " in the format <repository>/<flavor>-<application>:<tag>"
|
|
||||||
echo " Example: ghcr.io/m1k1o/neko/nvidia-firefox:latest"
|
|
||||||
echo " You can override any of the above options by specifying them"
|
|
||||||
echo " after the image name."
|
|
||||||
echo
|
|
||||||
echo "Environment variables:"
|
|
||||||
echo " USE_BUILDX : Set to 1 to use docker buildx instead of docker build"
|
|
||||||
echo " (default: 0)"
|
|
||||||
echo " CLIENT_DIST : The client dist file to use, if not specified, builds them"
|
|
||||||
echo " from the source code."
|
|
||||||
echo " (options) : Options can be specified as environment variables, for example:"
|
|
||||||
echo " PLATFORM=linux/arm64 $0 --repository ghcr.io/m1k1o/neko"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FULL_IMAGE=""
|
FULL_IMAGE=""
|
||||||
|
@ -62,8 +44,8 @@ while [[ "$#" -gt 0 ]]; do
|
||||||
--repository|-r) REPOSITORY="$2"; shift ;;
|
--repository|-r) REPOSITORY="$2"; shift ;;
|
||||||
--tag|-t) TAGS+=("$2"); TAG="$2"; shift ;;
|
--tag|-t) TAGS+=("$2"); TAG="$2"; shift ;;
|
||||||
--flavor|-f) FLAVOR="$2"; shift ;;
|
--flavor|-f) FLAVOR="$2"; shift ;;
|
||||||
--base_image|-b) BASE_IMAGE="$2"; shift ;;
|
--base|-b) BASE_IMAGE="$2"; shift ;;
|
||||||
--application|-a) APPLICATION="$2"; shift ;;
|
--app|-a) APPLICATION="$2"; shift ;;
|
||||||
--yes|-y) YES=1 ;;
|
--yes|-y) YES=1 ;;
|
||||||
--no-cache) NO_CACHE="--no-cache" log "Building without cache" ;;
|
--no-cache) NO_CACHE="--no-cache" log "Building without cache" ;;
|
||||||
--push) PUSH=1 ;;
|
--push) PUSH=1 ;;
|
||||||
|
@ -149,12 +131,17 @@ function build_image() {
|
||||||
local APPLICATION_IMAGE="$1"
|
local APPLICATION_IMAGE="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# get list of tags in full format: <image>:<tag>
|
|
||||||
local IMAGE_NO_TAG="${APPLICATION_IMAGE%:*}"
|
|
||||||
local FULL_TAGS=()
|
local FULL_TAGS=()
|
||||||
for T in "${TAGS[@]}"; do
|
# if the image name starts with local/, just use the tag as is
|
||||||
FULL_TAGS+=("$IMAGE_NO_TAG:$T")
|
if [[ "$APPLICATION_IMAGE" == *"local/"* ]]; then
|
||||||
done
|
FULL_TAGS=("$APPLICATION_IMAGE")
|
||||||
|
else
|
||||||
|
# get list of tags in full format: <image>:<tag>
|
||||||
|
local IMAGE_NO_TAG="${APPLICATION_IMAGE%:*}"
|
||||||
|
for T in "${TAGS[@]}"; do
|
||||||
|
FULL_TAGS+=("$IMAGE_NO_TAG:$T")
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$USE_BUILDX" ] || [ "$USE_BUILDX" != "1" ]; then
|
if [ -z "$USE_BUILDX" ] || [ "$USE_BUILDX" != "1" ]; then
|
||||||
# if buildx is not available, use docker build
|
# if buildx is not available, use docker build
|
||||||
|
@ -210,18 +197,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$PLATFORM" ]; then
|
if [ -z "$PLATFORM" ]; then
|
||||||
# use system architecture if not specified
|
PLATFORM="linux/amd64"
|
||||||
UNAME="$(uname -m)"
|
|
||||||
if [ "$UNAME" == "x86_64" ]; then
|
|
||||||
PLATFORM="linux/amd64"
|
|
||||||
elif [ "$UNAME" == "aarch64" ] || [ "$UNAME" == "arm64" ]; then
|
|
||||||
PLATFORM="linux/arm64"
|
|
||||||
elif [ "$UNAME" == "armv7l" ]; then
|
|
||||||
PLATFORM="linux/arm/v7"
|
|
||||||
else
|
|
||||||
log "Unknown architecture: $UNAME"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
log "Using platform: $PLATFORM"
|
log "Using platform: $PLATFORM"
|
||||||
|
|
||||||
|
@ -314,10 +290,10 @@ fi
|
||||||
|
|
||||||
log "Building base image: $BASE_IMAGE"
|
log "Building base image: $BASE_IMAGE"
|
||||||
docker run --rm -i \
|
docker run --rm -i \
|
||||||
-v "$(pwd)":/src \
|
-v ./:/src \
|
||||||
-e "RUNTIME_DOCKERFILE=$RUNTIME_DOCKERFILE" \
|
-e "RUNTIME_DOCKERFILE=$RUNTIME_DOCKERFILE" \
|
||||||
--workdir /src \
|
--workdir /src \
|
||||||
--entrypoint go \
|
--entrypoint go \
|
||||||
golang:1.24-bullseye \
|
golang:1.24-bullseye \
|
||||||
run utils/docker/main.go \
|
run ./docker/main.go \
|
||||||
-i Dockerfile.tmpl -client "$CLIENT_DIST" | build_image $BASE_IMAGE -f - .
|
-i Dockerfile.tmpl -client $CLIENT_DIST | build_image $BASE_IMAGE -f - .
|
||||||
|
|
|
@ -119,43 +119,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1024px) {
|
@media only screen and (max-width: 600px) {
|
||||||
html,
|
#neko.expanded {
|
||||||
body {
|
|
||||||
overflow-y: auto !important;
|
|
||||||
width: auto !important;
|
|
||||||
height: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body > p {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#neko {
|
|
||||||
position: relative;
|
|
||||||
flex-direction: column;
|
|
||||||
max-height: initial !important;
|
|
||||||
|
|
||||||
.neko-main {
|
.neko-main {
|
||||||
height: 100vh;
|
transform: translateX(calc(-100% + 65px));
|
||||||
|
|
||||||
|
video {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.neko-menu {
|
.neko-menu {
|
||||||
height: 100vh;
|
position: absolute;
|
||||||
width: 100% !important;
|
top: 0;
|
||||||
}
|
right: 0;
|
||||||
}
|
bottom: 0;
|
||||||
}
|
left: 65px;
|
||||||
|
width: calc(100% - 65px);
|
||||||
@media only screen and (max-width: 1024px) and (orientation: portrait) {
|
|
||||||
#neko {
|
|
||||||
&.expanded .neko-main {
|
|
||||||
height: 40vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.expanded .neko-menu {
|
|
||||||
height: 60vh;
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,20 +217,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch('side')
|
|
||||||
onSide(side: boolean) {
|
|
||||||
if (side) {
|
|
||||||
console.log('side enabled')
|
|
||||||
// scroll to the side
|
|
||||||
this.$nextTick(() => {
|
|
||||||
const side = document.querySelector('aside')
|
|
||||||
if (side) {
|
|
||||||
side.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
controlAttempt() {
|
controlAttempt() {
|
||||||
if (this.shakeKbd || this.$accessor.remote.hosted) return
|
if (this.shakeKbd || this.$accessor.remote.hosted) return
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.connect {
|
.connect {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
@ -60,9 +60,8 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
import { messages } from '~/locale'
|
import { messages } from '~/locale'
|
||||||
import { set } from '~/utils/localstorage'
|
|
||||||
|
|
||||||
@Component({ name: 'neko-menu' })
|
@Component({ name: 'neko-menu' })
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
@ -78,11 +77,6 @@
|
||||||
this.$accessor.client.toggleAbout()
|
this.$accessor.client.toggleAbout()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch('$i18n.locale')
|
|
||||||
onLanguageChange(newLang: string) {
|
|
||||||
set('lang', newLang)
|
|
||||||
}
|
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
const default_lang = new URL(location.href).searchParams.get('lang')
|
const default_lang = new URL(location.href).searchParams.get('lang')
|
||||||
if (default_lang && this.langs.includes(default_lang)) {
|
if (default_lang && this.langs.includes(default_lang)) {
|
||||||
|
|
|
@ -40,12 +40,7 @@
|
||||||
<li v-if="admin"><i @click.stop.prevent="openResolution" class="fas fa-desktop"></i></li>
|
<li v-if="admin"><i @click.stop.prevent="openResolution" class="fas fa-desktop"></i></li>
|
||||||
<li v-if="!controlLocked && !implicitHosting" :class="extraControls || 'extra-control'">
|
<li v-if="!controlLocked && !implicitHosting" :class="extraControls || 'extra-control'">
|
||||||
<i
|
<i
|
||||||
:class="[
|
:class="[hosted && !hosting ? 'disabled' : '', !hosted && !hosting ? 'faded' : '', 'fas', 'fa-keyboard']"
|
||||||
hosted && !hosting ? 'disabled' : '',
|
|
||||||
!hosted && !hosting ? 'faded' : '',
|
|
||||||
'fas',
|
|
||||||
'fa-computer-mouse',
|
|
||||||
]"
|
|
||||||
@click.stop.prevent="toggleControl"
|
@click.stop.prevent="toggleControl"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
@ -62,13 +57,6 @@
|
||||||
class="fas fa-external-link-alt"
|
class="fas fa-external-link-alt"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li
|
|
||||||
v-if="hosting && is_touch_device"
|
|
||||||
:class="extraControls || 'extra-control'"
|
|
||||||
@click.stop.prevent="openMobileKeyboard"
|
|
||||||
>
|
|
||||||
<i class="fas fa-keyboard" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<neko-resolution ref="resolution" v-if="admin" />
|
<neko-resolution ref="resolution" v-if="admin" />
|
||||||
<neko-clipboard ref="clipboard" v-if="hosting && (!clipboard_read_available || !clipboard_write_available)" />
|
<neko-clipboard ref="clipboard" v-if="hosting && (!clipboard_read_available || !clipboard_write_available)" />
|
||||||
|
@ -129,7 +117,7 @@
|
||||||
}
|
}
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
&.extra-control {
|
&.extra-control {
|
||||||
display: block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +251,6 @@
|
||||||
return this.$accessor.connecting
|
return this.$accessor.connecting
|
||||||
}
|
}
|
||||||
|
|
||||||
get controlling() {
|
|
||||||
return this.$accessor.remote.controlling
|
|
||||||
}
|
|
||||||
|
|
||||||
get hosting() {
|
get hosting() {
|
||||||
return this.$accessor.remote.hosting
|
return this.$accessor.remote.hosting
|
||||||
}
|
}
|
||||||
|
@ -369,16 +353,6 @@
|
||||||
return this.$accessor.video.horizontal
|
return this.$accessor.video.horizontal
|
||||||
}
|
}
|
||||||
|
|
||||||
get is_touch_device() {
|
|
||||||
return (
|
|
||||||
// detect if the device has touch support
|
|
||||||
('ontouchstart' in window || navigator.maxTouchPoints > 0) &&
|
|
||||||
// the primary input mechanism includes a pointing device of
|
|
||||||
// limited accuracy, such as a finger on a touchscreen.
|
|
||||||
window.matchMedia('(pointer: coarse)').matches
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Watch('width')
|
@Watch('width')
|
||||||
onWidthChanged() {
|
onWidthChanged() {
|
||||||
this.onResize()
|
this.onResize()
|
||||||
|
@ -756,17 +730,12 @@
|
||||||
first.target.dispatchEvent(simulatedEvent)
|
first.target.dispatchEvent(simulatedEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
isMouseDown = false
|
|
||||||
|
|
||||||
onMouseDown(e: MouseEvent) {
|
onMouseDown(e: MouseEvent) {
|
||||||
this.isMouseDown = true
|
if (!this.hosting) {
|
||||||
|
this.$emit('control-attempt', e)
|
||||||
if (this.locked) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.controlling) {
|
if (!this.hosting || this.locked) {
|
||||||
this.implicitHostingRequest(e)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,16 +744,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseUp(e: MouseEvent) {
|
onMouseUp(e: MouseEvent) {
|
||||||
// only if we are the one who started the mouse down
|
if (!this.hosting || this.locked) {
|
||||||
if (!this.isMouseDown) return
|
|
||||||
this.isMouseDown = false
|
|
||||||
|
|
||||||
if (this.locked) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.controlling) {
|
|
||||||
this.implicitHostingRequest(e)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,40 +752,6 @@
|
||||||
this.$client.sendData('mouseup', { key: e.button + 1 })
|
this.$client.sendData('mouseup', { key: e.button + 1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
private reqMouseDown: MouseEvent | null = null
|
|
||||||
private reqMouseUp: MouseEvent | null = null
|
|
||||||
|
|
||||||
@Watch('controlling')
|
|
||||||
onControlChange(controlling: boolean) {
|
|
||||||
if (controlling && this.reqMouseDown) {
|
|
||||||
this.onMouseDown(this.reqMouseDown)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controlling && this.reqMouseUp) {
|
|
||||||
this.onMouseUp(this.reqMouseUp)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reqMouseDown = null
|
|
||||||
this.reqMouseUp = null
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitHostingRequest(e: MouseEvent) {
|
|
||||||
if (this.implicitHosting) {
|
|
||||||
if (e.type === 'mousedown') {
|
|
||||||
this.reqMouseDown = e
|
|
||||||
this.reqMouseUp = null
|
|
||||||
this.$accessor.remote.request()
|
|
||||||
} else if (e.type === 'mouseup') {
|
|
||||||
this.reqMouseUp = e
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.type === 'mousedown') {
|
|
||||||
this.$emit('control-attempt', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMouseMove(e: MouseEvent) {
|
onMouseMove(e: MouseEvent) {
|
||||||
if (!this.hosting || this.locked) {
|
if (!this.hosting || this.locked) {
|
||||||
return
|
return
|
||||||
|
@ -873,20 +799,10 @@
|
||||||
@Watch('hosting')
|
@Watch('hosting')
|
||||||
@Watch('locked')
|
@Watch('locked')
|
||||||
onFocus() {
|
onFocus() {
|
||||||
// focus opens the keyboard on mobile
|
|
||||||
if (this.is_touch_device) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// in order to capture key events, overlay must be focused
|
// in order to capture key events, overlay must be focused
|
||||||
if (this.focused && this.hosting && !this.locked) {
|
if (this.focused && this.hosting && !this.locked) {
|
||||||
this._overlay.focus()
|
this._overlay.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openMobileKeyboard() {
|
|
||||||
// focus opens the keyboard on mobile
|
|
||||||
this._overlay.focus()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const EVENT = {
|
||||||
ERROR: 'system/error',
|
ERROR: 'system/error',
|
||||||
},
|
},
|
||||||
CLIENT: {
|
CLIENT: {
|
||||||
HEARTBEAT: 'client/heartbeat',
|
HEARTBEAT: 'client/heartbeat'
|
||||||
},
|
},
|
||||||
SIGNAL: {
|
SIGNAL: {
|
||||||
OFFER: 'signal/offer',
|
OFFER: 'signal/offer',
|
||||||
|
|
|
@ -1,31 +1,11 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueI18n from 'vue-i18n'
|
import VueI18n from 'vue-i18n'
|
||||||
import { messages } from '~/locale'
|
import { messages } from '~/locale'
|
||||||
import { get } from '~/utils/localstorage'
|
|
||||||
|
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
const fallbackLocale = 'en'
|
|
||||||
|
|
||||||
function detectBrowserLanguage(): string {
|
|
||||||
const browserLang = navigator.language.toLowerCase()
|
|
||||||
|
|
||||||
const supportedLangs = Object.keys(messages)
|
|
||||||
if (supportedLangs.includes(browserLang)) {
|
|
||||||
return browserLang
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseLang = browserLang.split('-')[0]
|
|
||||||
const matchingLang = supportedLangs.find((lang) => lang.startsWith(baseLang))
|
|
||||||
if (matchingLang) {
|
|
||||||
return matchingLang
|
|
||||||
}
|
|
||||||
|
|
||||||
return fallbackLocale
|
|
||||||
}
|
|
||||||
|
|
||||||
export const i18n = new VueI18n({
|
export const i18n = new VueI18n({
|
||||||
locale: get<string>('lang', detectBrowserLanguage()),
|
locale: 'en',
|
||||||
fallbackLocale,
|
fallbackLocale: 'en',
|
||||||
messages,
|
messages,
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,9 +18,6 @@ export const state = () => ({
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getters = getterTree(state, {
|
export const getters = getterTree(state, {
|
||||||
controlling: (state, getters, root) => {
|
|
||||||
return root.user.id === state.id
|
|
||||||
},
|
|
||||||
hosting: (state, getters, root) => {
|
hosting: (state, getters, root) => {
|
||||||
return root.user.id === state.id || state.implicitHosting
|
return root.user.id === state.id || state.implicitHosting
|
||||||
},
|
},
|
||||||
|
@ -92,7 +89,7 @@ export const actions = actionTree(
|
||||||
},
|
},
|
||||||
|
|
||||||
request({ getters }) {
|
request({ getters }) {
|
||||||
if (!accessor.connected || getters.controlling) {
|
if (!accessor.connected || getters.hosting) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,6 @@ session:
|
||||||
cookie:
|
cookie:
|
||||||
# needed for legacy API
|
# needed for legacy API
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
|
webrtc:
|
||||||
|
icelite: true
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
|
version: "3.4"
|
||||||
services:
|
services:
|
||||||
neko:
|
neko:
|
||||||
image: "ghcr.io/m1k1o/neko/firefox:latest"
|
image: "m1k1o/neko:firefox"
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
shm_size: "2gb"
|
shm_size: "2gb"
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
- "52000-52100:52000-52100/udp"
|
- "52000-52100:52000-52100/udp"
|
||||||
environment:
|
environment:
|
||||||
NEKO_DESKTOP_SCREEN: 1920x1080@30
|
NEKO_SCREEN: 1920x1080@30
|
||||||
NEKO_MEMBER_MULTIUSER_USER_PASSWORD: neko
|
NEKO_PASSWORD: neko
|
||||||
NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD: admin
|
NEKO_PASSWORD_ADMIN: admin
|
||||||
NEKO_WEBRTC_EPR: 52000-52100
|
NEKO_EPR: 52000-52100
|
||||||
NEKO_WEBRTC_ICELITE: 1
|
NEKO_ICELITE: 1
|
||||||
|
|
3
docker/go.mod
Normal file
3
docker/go.mod
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/m1k1o/neko/docker
|
||||||
|
|
||||||
|
go 1.24.1
|
|
@ -103,9 +103,7 @@ ENV NEKO_PLUGINS_DIR=/etc/neko/plugins/
|
||||||
#
|
#
|
||||||
# add healthcheck
|
# add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
||||||
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || exit 1
|
||||||
wget --no-check-certificate -O - https://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# run neko
|
# run neko
|
||||||
|
|
|
@ -95,9 +95,8 @@ ENV NEKO_PLUGINS_DIR=/etc/neko/plugins/
|
||||||
#
|
#
|
||||||
# add healthcheck
|
# add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
||||||
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || exit 1
|
||||||
wget --no-check-certificate -O - https://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
|
||||||
exit 1
|
|
||||||
#
|
#
|
||||||
# run neko
|
# run neko
|
||||||
CMD ["/usr/bin/supervisord", "-c", "/etc/neko/supervisord.conf"]
|
CMD ["/usr/bin/supervisord", "-c", "/etc/neko/supervisord.conf"]
|
||||||
|
|
|
@ -115,9 +115,8 @@ ENV RENDER_GID=
|
||||||
#
|
#
|
||||||
# add healthcheck
|
# add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
||||||
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || exit 1
|
||||||
wget --no-check-certificate -O - https://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
|
||||||
exit 1
|
|
||||||
#
|
#
|
||||||
# run neko
|
# run neko
|
||||||
CMD ["/usr/bin/supervisord", "-c", "/etc/neko/supervisord.conf"]
|
CMD ["/usr/bin/supervisord", "-c", "/etc/neko/supervisord.conf"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
ARG UBUNTU_RELEASE=20.04
|
ARG UBUNTU_RELEASE=20.04
|
||||||
ARG CUDA_VERSION=11.4.3
|
ARG CUDA_VERSION=11.4.3
|
||||||
ARG VIRTUALGL_VERSION=3.1.3-20250409
|
ARG VIRTUALGL_VERSION=3.1
|
||||||
ARG GSTREAMER_VERSION=1.20
|
ARG GSTREAMER_VERSION=1.20
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -61,13 +61,13 @@ ARG UBUNTU_RELEASE
|
||||||
ARG VIRTUALGL_VERSION
|
ARG VIRTUALGL_VERSION
|
||||||
|
|
||||||
# Make all NVIDIA GPUs visible by default
|
# Make all NVIDIA GPUs visible by default
|
||||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
ENV NVIDIA_VISIBLE_DEVICES all
|
||||||
# All NVIDIA driver capabilities should preferably be used, check `NVIDIA_DRIVER_CAPABILITIES` inside the container if things do not work
|
# All NVIDIA driver capabilities should preferably be used, check `NVIDIA_DRIVER_CAPABILITIES` inside the container if things do not work
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES=all
|
ENV NVIDIA_DRIVER_CAPABILITIES all
|
||||||
|
|
||||||
#
|
#
|
||||||
# set vgl-display to headless 3d gpu card/// correct values are egl[n] or /dev/dri/card0:if this is passed into container
|
# set vgl-display to headless 3d gpu card/// correct values are egl[n] or /dev/dri/card0:if this is passed into container
|
||||||
ENV VGL_DISPLAY=egl
|
ENV VGL_DISPLAY egl
|
||||||
|
|
||||||
#
|
#
|
||||||
# set custom user
|
# set custom user
|
||||||
|
@ -205,22 +205,23 @@ RUN VULKAN_API_VERSION=$(dpkg -s libvulkan1 | grep -oP 'Version: [0-9|\.]+' | gr
|
||||||
}" > /etc/vulkan/icd.d/nvidia_icd.json
|
}" > /etc/vulkan/icd.d/nvidia_icd.json
|
||||||
|
|
||||||
#
|
#
|
||||||
# install an up-to-date version of VirtualGL
|
# install VirtualGL and make libraries available for preload
|
||||||
RUN apt-get update; \
|
RUN set -eux; \
|
||||||
apt-get install -y --no-install-recommends wget gpg ca-certificates; \
|
|
||||||
# Add VirtualGL GPG key
|
|
||||||
wget -q -O- https://packagecloud.io/dcommander/virtualgl/gpgkey | \
|
|
||||||
gpg --dearmor >/etc/apt/trusted.gpg.d/VirtualGL.gpg; \
|
|
||||||
# Download the official VirtualGL.list file
|
|
||||||
wget -q -O /etc/apt/sources.list.d/VirtualGL.list \
|
|
||||||
https://raw.githubusercontent.com/VirtualGL/repo/main/VirtualGL.list; \
|
|
||||||
# Install packages
|
|
||||||
apt-get update; \
|
apt-get update; \
|
||||||
apt-get install -y --no-install-recommends virtualgl=${VIRTUALGL_VERSION}; \
|
wget "https://sourceforge.net/projects/virtualgl/files/virtualgl_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
wget "https://sourceforge.net/projects/virtualgl/files/virtualgl32_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
apt-get install -y --no-install-recommends ./virtualgl_${VIRTUALGL_VERSION}_amd64.deb ./virtualgl32_${VIRTUALGL_VERSION}_amd64.deb; \
|
||||||
|
rm -f "virtualgl_${VIRTUALGL_VERSION}_amd64.deb" "virtualgl32_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
chmod u+s /usr/lib/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib/libdlfaker.so; \
|
||||||
|
chmod u+s /usr/lib32/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib32/libdlfaker.so; \
|
||||||
|
chmod u+s /usr/lib/i386-linux-gnu/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib/i386-linux-gnu/libdlfaker.so; \
|
||||||
#
|
#
|
||||||
# clean up
|
# clean up
|
||||||
apt-get clean -y; \
|
apt-get clean -y; \
|
||||||
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/*;
|
||||||
|
|
||||||
#
|
#
|
||||||
# copy runtime configs
|
# copy runtime configs
|
||||||
|
@ -261,9 +262,7 @@ COPY --from=gstreamer /usr/share/gstreamer /usr/share/gstreamer
|
||||||
#
|
#
|
||||||
# add healthcheck
|
# add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
||||||
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || exit 1
|
||||||
wget --no-check-certificate -O - https://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# run neko
|
# run neko
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
ARG UBUNTU_RELEASE=22.04
|
ARG UBUNTU_RELEASE=22.04
|
||||||
ARG CUDA_VERSION=12.2.0
|
ARG CUDA_VERSION=12.2.0
|
||||||
ARG VIRTUALGL_VERSION=3.1.3-20250409
|
ARG VIRTUALGL_VERSION=3.1
|
||||||
ARG GSTREAMER_VERSION=1.22
|
ARG GSTREAMER_VERSION=1.22
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -61,13 +61,13 @@ ARG UBUNTU_RELEASE
|
||||||
ARG VIRTUALGL_VERSION
|
ARG VIRTUALGL_VERSION
|
||||||
|
|
||||||
# Make all NVIDIA GPUs visible by default
|
# Make all NVIDIA GPUs visible by default
|
||||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
ENV NVIDIA_VISIBLE_DEVICES all
|
||||||
# All NVIDIA driver capabilities should preferably be used, check `NVIDIA_DRIVER_CAPABILITIES` inside the container if things do not work
|
# All NVIDIA driver capabilities should preferably be used, check `NVIDIA_DRIVER_CAPABILITIES` inside the container if things do not work
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES=all
|
ENV NVIDIA_DRIVER_CAPABILITIES all
|
||||||
|
|
||||||
#
|
#
|
||||||
# set vgl-display to headless 3d gpu card/// correct values are egl[n] or /dev/dri/card0:if this is passed into container
|
# set vgl-display to headless 3d gpu card/// correct values are egl[n] or /dev/dri/card0:if this is passed into container
|
||||||
ENV VGL_DISPLAY=egl
|
ENV VGL_DISPLAY egl
|
||||||
|
|
||||||
#
|
#
|
||||||
# set custom user
|
# set custom user
|
||||||
|
@ -199,22 +199,23 @@ RUN VULKAN_API_VERSION=$(dpkg -s libvulkan1 | grep -oP 'Version: [0-9|\.]+' | gr
|
||||||
}" > /etc/vulkan/icd.d/nvidia_icd.json
|
}" > /etc/vulkan/icd.d/nvidia_icd.json
|
||||||
|
|
||||||
#
|
#
|
||||||
# install an up-to-date version of VirtualGL
|
# install VirtualGL and make libraries available for preload
|
||||||
RUN apt-get update; \
|
RUN set -eux; \
|
||||||
apt-get install -y --no-install-recommends wget gpg ca-certificates; \
|
|
||||||
# Add VirtualGL GPG key
|
|
||||||
wget -q -O- https://packagecloud.io/dcommander/virtualgl/gpgkey | \
|
|
||||||
gpg --dearmor >/etc/apt/trusted.gpg.d/VirtualGL.gpg; \
|
|
||||||
# Download the official VirtualGL.list file
|
|
||||||
wget -q -O /etc/apt/sources.list.d/VirtualGL.list \
|
|
||||||
https://raw.githubusercontent.com/VirtualGL/repo/main/VirtualGL.list; \
|
|
||||||
# Install packages
|
|
||||||
apt-get update; \
|
apt-get update; \
|
||||||
apt-get install -y --no-install-recommends virtualgl=${VIRTUALGL_VERSION}; \
|
wget "https://sourceforge.net/projects/virtualgl/files/virtualgl_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
wget "https://sourceforge.net/projects/virtualgl/files/virtualgl32_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
apt-get install -y --no-install-recommends ./virtualgl_${VIRTUALGL_VERSION}_amd64.deb ./virtualgl32_${VIRTUALGL_VERSION}_amd64.deb; \
|
||||||
|
rm -f "virtualgl_${VIRTUALGL_VERSION}_amd64.deb" "virtualgl32_${VIRTUALGL_VERSION}_amd64.deb"; \
|
||||||
|
chmod u+s /usr/lib/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib/libdlfaker.so; \
|
||||||
|
chmod u+s /usr/lib32/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib32/libdlfaker.so; \
|
||||||
|
chmod u+s /usr/lib/i386-linux-gnu/libvglfaker.so; \
|
||||||
|
chmod u+s /usr/lib/i386-linux-gnu/libdlfaker.so; \
|
||||||
#
|
#
|
||||||
# clean up
|
# clean up
|
||||||
apt-get clean -y; \
|
apt-get clean -y; \
|
||||||
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/*;
|
||||||
|
|
||||||
#
|
#
|
||||||
# copy runtime configs
|
# copy runtime configs
|
||||||
|
@ -253,9 +254,7 @@ COPY --from=gstreamer /usr/share/gstreamer /usr/share/gstreamer
|
||||||
#
|
#
|
||||||
# add healthcheck
|
# add healthcheck
|
||||||
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
HEALTHCHECK --interval=10s --timeout=5s --retries=8 \
|
||||||
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
CMD wget -O - http://localhost:${NEKO_SERVER_BIND#*:}/health || exit 1
|
||||||
wget --no-check-certificate -O - https://localhost:${NEKO_SERVER_BIND#*:}/health || \
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# run neko
|
# run neko
|
||||||
|
|
|
@ -33,7 +33,7 @@ redirect_stderr=true
|
||||||
|
|
||||||
[program:neko]
|
[program:neko]
|
||||||
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
|
environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s"
|
||||||
command=/usr/bin/neko serve --server.static "/var/www"
|
command=/usr/bin/neko serve --static "/var/www"
|
||||||
stopsignal=INT
|
stopsignal=INT
|
||||||
stopwaitsecs=3
|
stopwaitsecs=3
|
||||||
autorestart=true
|
autorestart=true
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue