Compare commits
142 Commits
v0.1.0
...
feat/cloud
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4512385b1 | ||
|
|
1d68ec71b8 | ||
|
|
a32c212a7e | ||
|
|
5d350bda1f | ||
|
|
2bbd705af9 | ||
|
|
a23ae8025b | ||
|
|
7de6e243ed | ||
|
|
060718d8b0 | ||
|
|
93327bdf1a | ||
|
|
4546eb6767 | ||
|
|
9d084011a2 | ||
|
|
0642d0b787 | ||
|
|
ec8d4f81da | ||
|
|
421aa70a7b | ||
|
|
29bc44ab83 | ||
|
|
c14626b104 | ||
|
|
614bbbfce0 | ||
|
|
c2363b0bce | ||
|
|
be6ea11052 | ||
|
|
fbaa8835a3 | ||
|
|
431733a0e8 | ||
|
|
4c33d7fe00 | ||
|
|
bec5ba7c99 | ||
|
|
056d7e070d | ||
|
|
fb77dc9572 | ||
|
|
9b8d187887 | ||
|
|
4a27f54e80 | ||
|
|
0d0b1f4b14 | ||
|
|
f480ced756 | ||
|
|
dfe37a6cec | ||
|
|
3be481e260 | ||
|
|
a3ff8bff9f | ||
|
|
4df031d1bb | ||
|
|
f6287ef586 | ||
|
|
56b877fa27 | ||
|
|
c15657a0d1 | ||
|
|
b47448255f | ||
|
|
dede878c3c | ||
|
|
83908122bf | ||
|
|
2c27420126 | ||
|
|
fc5a755408 | ||
|
|
33895974a7 | ||
|
|
137b60edb8 | ||
|
|
b479875924 | ||
|
|
7d6a7542e2 | ||
|
|
8c808bafcb | ||
|
|
08f2643dcd | ||
|
|
82c1a3baea | ||
|
|
9fd7c6ff47 | ||
|
|
c6c7b6a36d | ||
|
|
c39866a019 | ||
|
|
0d36acb983 | ||
|
|
2c39517a27 | ||
|
|
aa7d3c5607 | ||
|
|
9715cd9f8a | ||
|
|
a85c10a281 | ||
|
|
8d6b7f744b | ||
|
|
b6196b1c69 | ||
|
|
20d5ff511e | ||
|
|
379db1c87b | ||
|
|
5eb21eeadb | ||
|
|
339779fce1 | ||
|
|
565c459a5b | ||
|
|
be17ba026b | ||
|
|
86be67ad12 | ||
|
|
7b29d68aed | ||
|
|
cc51bd6f70 | ||
|
|
390ee2ac0f | ||
|
|
bae089e223 | ||
|
|
c4a6895726 | ||
|
|
efe95a7c8d | ||
|
|
e322693b70 | ||
|
|
1693fef708 | ||
|
|
41dbaf1b21 | ||
|
|
9665549d0c | ||
|
|
6b422ca290 | ||
|
|
f2f3386bdb | ||
|
|
58e93b28e9 | ||
|
|
3088b050ed | ||
|
|
7663e17644 | ||
|
|
5b713521a1 | ||
|
|
b1f35c9953 | ||
|
|
0696c9fc60 | ||
|
|
abb4874749 | ||
|
|
0d4f0bce11 | ||
|
|
c641d413a9 | ||
|
|
cac927196a | ||
|
|
c30673f5a1 | ||
|
|
1b1bedff36 | ||
|
|
df9f1cfe95 | ||
|
|
b347115eae | ||
|
|
5b4ea64b94 | ||
|
|
8cc5a8b9e6 | ||
|
|
d66248cb97 | ||
|
|
1555dd7ab2 | ||
|
|
168be939a6 | ||
|
|
2e26ed08a1 | ||
|
|
e2e5497c62 | ||
|
|
62b7a841ed | ||
|
|
2b6a048ccd | ||
|
|
ba15f30bbf | ||
|
|
8b42688bd4 | ||
|
|
1f9d3be2a6 | ||
|
|
22d43411b1 | ||
|
|
a90fe4ba7a | ||
|
|
9a17df391a | ||
|
|
e0b7e46c76 | ||
|
|
dc5a36b9d6 | ||
|
|
73cec51728 | ||
|
|
d13d3dc5d8 | ||
|
|
666aabeda2 | ||
|
|
5520883f00 | ||
|
|
1cef08ebdf | ||
|
|
fd16947e14 | ||
|
|
81fc5e8f85 | ||
|
|
19923845c0 | ||
|
|
3df53e7e38 | ||
|
|
cf69f6c93a | ||
|
|
b12b26223c | ||
|
|
19e2f62603 | ||
|
|
9e9411c83f | ||
|
|
904f300ead | ||
|
|
e729e1c57e | ||
|
|
04a277dede | ||
|
|
51366d3b4b | ||
|
|
25c29f007e | ||
|
|
fd4f575b46 | ||
|
|
3991027587 | ||
|
|
5c9cb8e563 | ||
|
|
f05494c08a | ||
|
|
705f953e66 | ||
|
|
3fed8605fa | ||
|
|
674124e819 | ||
|
|
9a11f459cb | ||
|
|
46fe87a715 | ||
|
|
204730450c | ||
|
|
e6fa6ea6e1 | ||
|
|
ea157b4898 | ||
|
|
df332b66bc | ||
|
|
8304ca08a4 | ||
|
|
9bb194091d | ||
|
|
ad210f2b75 |
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
**/target/
|
||||
**/.git
|
||||
**/.env
|
||||
17
.github/CODEOWNERS
vendored
@@ -1 +1,16 @@
|
||||
* @wanjohiryan
|
||||
* @dev-team
|
||||
|
||||
/apps/ @victorpahuus @AquaWolf
|
||||
/packages/ui/ @wanjohiryan @victorpahuus @AquaWolf
|
||||
|
||||
/protobuf/ @AquaWolf
|
||||
|
||||
/infra/ @wanjohiryan
|
||||
/packages/core/ @wanjohiryan
|
||||
/packages/functions/ @wanjohiryan
|
||||
|
||||
/containers/ @DatCaptainHorse
|
||||
/packages/server/ @DatCaptainHorse
|
||||
/packages/relay/ @DatCaptainHorse
|
||||
/packages/scripts/ @DatCaptainHorse
|
||||
/packages/input/ @DatCaptainHorse
|
||||
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
polar: nestri
|
||||
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
## Description
|
||||
<!-- Briefly describe the purpose and scope of your changes -->
|
||||
|
||||
## Related Issues
|
||||
<!-- List any related issues (e.g., "Closes #123", "Fixes #456") -->
|
||||
|
||||
## Type of Change
|
||||
|
||||
- [ ] Bug fix (non-breaking change)
|
||||
- [ ] New feature (non-breaking change)
|
||||
- [ ] Breaking change (fix or feature that changes existing functionality)
|
||||
- [ ] Documentation update
|
||||
- [ ] Other (please describe):
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I have updated relevant documentation
|
||||
- [ ] My code follows the project's coding style
|
||||
- [ ] My changes generate no new warnings/errors
|
||||
|
||||
## Notes for Reviewers
|
||||
<!-- Point out areas you'd like reviewers to focus on, questions you have, or decisions that need discussion -->
|
||||
|
||||
## Screenshots/Demo
|
||||
<!-- If applicable, add screenshots or a GIF demo of your changes (especially for UI changes) -->
|
||||
|
||||
## Additional Context
|
||||
<!-- Add any other context about the pull request here -->
|
||||
18
.github/dependabot.yml
vendored
@@ -1,18 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'gitsubmodule'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'type/build'
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
labels:
|
||||
- 'type/build'
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-patch"]
|
||||
119
.github/labeler.yml
vendored
@@ -1,119 +0,0 @@
|
||||
version: 2
|
||||
labels:
|
||||
- label: 'type/chore'
|
||||
branch: '^chore/.*'
|
||||
title: '^\s*.*?\schore(?:(.+))?!?:'
|
||||
|
||||
- label: 'type/fix'
|
||||
branch: '^fix/.*'
|
||||
title: '^\s*.*?\sfix(?:(.+))?!?:'
|
||||
|
||||
- label: 'type/feat'
|
||||
branch: '^feat/.*'
|
||||
title: '^\s*.*?\sfeat(?:(.+))?!?:'
|
||||
|
||||
- label: 'type/breaking'
|
||||
body: '(?i)breaking.*'
|
||||
|
||||
- label: 'type/docs'
|
||||
branch: '^docs/.*'
|
||||
title: '^\s*.*?\sdocs(?:(.+))?!?:'
|
||||
branch: '^docs/.*'
|
||||
files:
|
||||
- '**/*.md$'
|
||||
- '**/*.mdx$'
|
||||
|
||||
- label: 'type/ci'
|
||||
branch: '^ci/.*'
|
||||
title: '^\s*.*?\sci(?:(.+))?!?:'
|
||||
files:
|
||||
- '.github/.+'
|
||||
|
||||
- label: 'type/build'
|
||||
branch: '^dependabot/.*'
|
||||
title: '^\s*.*?\sbuild(?:(.+))?!?:'
|
||||
|
||||
- label: 'type/perf'
|
||||
title: '^\s*.*?\sperf(?:(.+))?!?:'
|
||||
|
||||
- label: 'mergeable/false'
|
||||
mergeable: False
|
||||
|
||||
- label: 'usr/dependabot'
|
||||
branch: '^dependabot/.*'
|
||||
authors:
|
||||
- 'dependabot[bot]'
|
||||
|
||||
- label: 'scope/back-end'
|
||||
files:
|
||||
- 'server.Dockerfile'
|
||||
|
||||
- label: 'scope/base'
|
||||
files:
|
||||
- 'base.Dockerfile'
|
||||
|
||||
- label: 'scope/ffmpeg'
|
||||
files:
|
||||
- 'ffmpeg.Dockerfile'
|
||||
|
||||
- label: 'scope/recorder'
|
||||
files:
|
||||
- 'recorder.Dockerfile'
|
||||
|
||||
- label: 'scope/relay'
|
||||
files:
|
||||
- 'relay.Dockerfile'
|
||||
|
||||
- label: 'scope/front-end'
|
||||
files:
|
||||
- 'apps/www/.+'
|
||||
|
||||
- label: 'pkg/www'
|
||||
files:
|
||||
- 'apps/www/.+'
|
||||
|
||||
- label: 'scope/git'
|
||||
files:
|
||||
- '**/.gitignore$'
|
||||
- '.github/.+'
|
||||
|
||||
- label: "size/xs"
|
||||
size:
|
||||
below: 10
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "size/s"
|
||||
size:
|
||||
above: 9
|
||||
below: 100
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "size/m"
|
||||
size:
|
||||
above: 49
|
||||
below: 200
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "size/l"
|
||||
size:
|
||||
above: 199
|
||||
below: 500
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "size/xl"
|
||||
size:
|
||||
above: 499
|
||||
below: 1000
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "size/xxl"
|
||||
size:
|
||||
above: 999
|
||||
exclude-files: ["pnpm-lock.yml","yarn.lock"]
|
||||
|
||||
- label: "usr/wanjohi"
|
||||
authors: ['wanjohiryan']
|
||||
|
||||
- label: "usr/unknown"
|
||||
negate: True
|
||||
authors: ['wanjohiryan','apps/dependabot','dependabot', 'dependabot[bot]']
|
||||
108
.github/labels.yml
vendored
@@ -1,108 +0,0 @@
|
||||
# Default labels
|
||||
- name: "type/fix"
|
||||
color: "B60205"
|
||||
|
||||
- name: "type/build"
|
||||
color: "6C55D7"
|
||||
|
||||
- name: "type/feat"
|
||||
color: "0ADE12"
|
||||
|
||||
- name: "type/docs"
|
||||
color: "891059"
|
||||
|
||||
- name: "type/refactor"
|
||||
color: "8D44DF"
|
||||
|
||||
- name: "type/revert"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "type/style"
|
||||
color: "D71964"
|
||||
|
||||
- name: "type/test"
|
||||
color: "0B9EE8"
|
||||
|
||||
- name: "type/breaking"
|
||||
color: "0590CC"
|
||||
|
||||
- name: "type/chore"
|
||||
color: "B44A63"
|
||||
|
||||
- name: "type/ci"
|
||||
color: "4FE1A6"
|
||||
|
||||
- name: "type/perf"
|
||||
color: "4FE1A6"
|
||||
|
||||
- name: "mergeable/false"
|
||||
color: "B60205"
|
||||
|
||||
- name: "priority/high"
|
||||
color: "D4E734"
|
||||
|
||||
- name: "priority/mid"
|
||||
color: "D4E734"
|
||||
|
||||
- name: "priority/low"
|
||||
color: "D4E734"
|
||||
|
||||
- name: "reg/docker"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "reg/npm"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "pkg/www"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "pkg/lib"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "pkg/aws"
|
||||
color: "5319e7"
|
||||
|
||||
- name: "scope/git"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "scope/infra"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "scope/front-end"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "scope/relay"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "scope/base"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "scope/back-end"
|
||||
color: "B61B66"
|
||||
|
||||
- name: "size/xs"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "size/s"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "size/m"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "size/l"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "size/xl"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "size/xxl"
|
||||
color: "AD4322"
|
||||
|
||||
- name: "usr/wanjohi"
|
||||
color: "09469C"
|
||||
|
||||
- name: "usr/dependabot"
|
||||
color: "09469C"
|
||||
|
||||
- name: "usr/unknown"
|
||||
color: "09469C"
|
||||
3
.github/pull_request_template.md
vendored
@@ -1,3 +0,0 @@
|
||||
## Description
|
||||
|
||||
**What issue are you solving (or what feature are you adding) and how are you doing it?**
|
||||
45
.github/release-drafter.yml
vendored
@@ -1,45 +0,0 @@
|
||||
name-template: 'v$RESOLVED_VERSION'
|
||||
tag-template: 'v$RESOLVED_VERSION'
|
||||
template: |
|
||||
# What's Changed
|
||||
|
||||
$CHANGES
|
||||
|
||||
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
|
||||
categories:
|
||||
- title: '⚠ Breaking Changes'
|
||||
label: 'type/breaking'
|
||||
- title: '🚀 New Features'
|
||||
label: 'type/feat'
|
||||
- title: '🐜 Bug Fixes'
|
||||
label: 'type/fix'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'type/chore'
|
||||
- title: '📖 Documentation'
|
||||
label: 'type/docs'
|
||||
- title: '⬆ Version Upgrades'
|
||||
label: 'type/build'
|
||||
collapse-after: 10
|
||||
- title: 'Other changes'
|
||||
collapse-after: 10
|
||||
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'type/breaking'
|
||||
minor:
|
||||
labels:
|
||||
- 'type/feat'
|
||||
patch:
|
||||
labels:
|
||||
- 'type/fix'
|
||||
- 'type/build'
|
||||
- 'type/docs'
|
||||
- 'type/chore'
|
||||
- 'type/refactor'
|
||||
- 'type/ci'
|
||||
- 'type/style'
|
||||
- 'type/test'
|
||||
|
||||
exclude-labels:
|
||||
- 'skip-changelog'
|
||||
93
.github/workflows/autolabeller.yml
vendored
@@ -1,93 +0,0 @@
|
||||
name: Pull request auto-labeller
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- labeled
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
- edited
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@cfb60706e18bc85e8aec535e3c577abe8f70378e
|
||||
id: lint_pr_title
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GIT_MASTER_TOKEN }}
|
||||
with:
|
||||
types: |-
|
||||
build
|
||||
chore
|
||||
ci
|
||||
deprecate
|
||||
docs
|
||||
feat
|
||||
fix
|
||||
perf
|
||||
refactor
|
||||
remove
|
||||
revert
|
||||
security
|
||||
style
|
||||
test
|
||||
requireScope: false
|
||||
# Ensures the subject start with an uppercase character.
|
||||
subjectPattern: ^([A-Z]).+$
|
||||
headerPattern: '^\s*.*?\s(\w*)(?:\(([\w$.\-*/ ]*)\))?: (.*)$'
|
||||
headerPatternCorrespondence: type, scope, subject
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
starts with an uppercase character
|
||||
|
||||
- uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
|
||||
# When the previous steps fails, the workflow would stop. By adding this
|
||||
# condition you can continue the execution with the populated error message.
|
||||
if: always() && (steps.lint_pr_title.outputs.error_message != null)
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
message: |
|
||||
Hey there and thank you for opening this pull request! 👋🏼
|
||||
|
||||
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
|
||||
Additionally, the subject of the title must start with an uppercase character (e.g. feat: New `search` component).
|
||||
|
||||
```
|
||||
${{ steps.lint_pr_title.outputs.error_message }}
|
||||
```
|
||||
# Delete a previous comment when the issue has been resolved
|
||||
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
|
||||
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
delete: true
|
||||
|
||||
label:
|
||||
needs: [ validate ]
|
||||
runs-on: ubuntu-latest
|
||||
name: Add labels
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout your code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: srvaroa/labeler@v1
|
||||
with:
|
||||
config_path: .github/labeler.yml
|
||||
use_local_config: true #FIXME:
|
||||
fail_on_error: true
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GIT_MASTER_TOKEN }}"
|
||||
33
.github/workflows/labels.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: GH labels maintainer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- '.github/labels.yml'
|
||||
- '.github/workflows/labels.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/labels.yml'
|
||||
- '.github/workflows/labels.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Run Labeler
|
||||
uses: crazy-max/ghaction-github-labeler@v5
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GIT_MASTER_TOKEN }}"
|
||||
with:
|
||||
dry-run: ${{ github.event_name == 'pull_request' }}
|
||||
github-token: ${{ secrets.GIT_MASTER_TOKEN }}
|
||||
33
.github/workflows/relay.yml
vendored
@@ -1,36 +1,31 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:relay
|
||||
|
||||
name: Build nestri:relay
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "relay.Dockerfile"
|
||||
- "containers/relay.Containerfile"
|
||||
- "packages/relay/**"
|
||||
- ".github/workflows/relay.yml"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "relay.Dockerfile"
|
||||
- "containers/relay.Containerfile"
|
||||
- ".github/workflows/relay.yml"
|
||||
- "packages/relay/**"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
IMAGE_NAME: nestrilabs/nestri
|
||||
BASE_TAG_PREFIX: relay
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
name: Build image on PR
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
@@ -44,15 +39,15 @@ jobs:
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: relay.Dockerfile
|
||||
file: containers/relay.Containerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:relay
|
||||
|
||||
tags: nestri:relay
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
name: Build image on main
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -67,7 +62,7 @@ jobs:
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
password: ${{ github.token }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
@@ -86,7 +81,7 @@ jobs:
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: relay.Dockerfile
|
||||
file: containers/relay.Containerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
16
.github/workflows/release-drafter.yml
vendored
@@ -1,16 +0,0 @@
|
||||
name: Release drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,37 +1,43 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:base
|
||||
name: Build nestri:runner
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "base.Dockerfile"
|
||||
- ".github/workflows/base.yml"
|
||||
- "containers/runner.Containerfile"
|
||||
- "packages/scripts/**"
|
||||
- ".github/workflows/runner.yml"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
- cron: 7 0 * * 1,3,6 # Regularly to keep that build cache warm
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "base.Dockerfile"
|
||||
- ".github/workflows/base.yml"
|
||||
- "containers/runner.Containerfile"
|
||||
- ".github/workflows/runner.yml"
|
||||
- "packages/scripts/**"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
BASE_TAG_PREFIX: base
|
||||
IMAGE_NAME: nestrilabs/nestri
|
||||
BASE_TAG_PREFIX: runner
|
||||
|
||||
# This makes our release ci quit prematurely
|
||||
# concurrency:
|
||||
# group: ci-${{ github.ref }}
|
||||
# cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
name: Build image on PR
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
-
|
||||
@@ -40,19 +46,26 @@ jobs:
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@master
|
||||
with:
|
||||
swap-size-gb: 20
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: base.Dockerfile
|
||||
file: containers/runner.Containerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:base
|
||||
tags: nestri:runner
|
||||
cache-from: type=gha,mode=max
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
name: Build image on main
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -67,7 +80,7 @@ jobs:
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
password: ${{ github.token }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
@@ -82,12 +95,22 @@ jobs:
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@master
|
||||
with:
|
||||
swap-size-gb: 20
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: base.Dockerfile
|
||||
file: containers/runner.Containerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha,mode=max
|
||||
cache-to: type=gha,mode=max
|
||||
95
.github/workflows/server.yml
vendored
@@ -1,95 +0,0 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:server
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "server.Dockerfile"
|
||||
- ".scripts/**"
|
||||
- ".github/workflows/server.yml"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "server.Dockerfile"
|
||||
- ".scripts/**"
|
||||
- ".github/workflows/server.yml"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
BASE_TAG_PREFIX: server
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: server.Dockerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:server
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge to main
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Log into registry ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ env.BASE_TAG_PREFIX }}
|
||||
#
|
||||
#tag on release, and a nightly build for 'dev'
|
||||
tags: |
|
||||
type=raw,value=nightly,enable={{is_default_branch}}
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: server.Dockerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
191
.github/workflows/warp-input.yml
vendored
@@ -1,191 +0,0 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:warp-input
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "warp-input.Dockerfile"
|
||||
- ".github/workflows/warp-input.yml"
|
||||
- "bin/input/**"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "warp-input.Dockerfile"
|
||||
- ".github/workflows/warp-input.yml"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [published, created]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
BASE_TAG_PREFIX: warp-input
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp-input.Dockerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:warp-input
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge to main
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Log into registry ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ env.BASE_TAG_PREFIX }}
|
||||
#
|
||||
#tag on release, and a nightly build for 'dev'
|
||||
tags: |
|
||||
type=raw,value=nightly,enable={{is_default_branch}}
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp-input.Dockerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-warp-input-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bin/input
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
bundles: appimage
|
||||
asset_name: warp-input-ubuntu-amd64
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
bundles: msi
|
||||
asset_name: warp-input-windows-amd64
|
||||
# - host: macos-latest
|
||||
# target: x86_64-apple-darwin
|
||||
# bundles: dmg
|
||||
# asset_name: warp-input-macos-amd64
|
||||
# - host: macos-latest
|
||||
# target: aarch64-apple-darwin
|
||||
# bundles: dmg
|
||||
# asset_name: warp-input-macos-apple-silicon
|
||||
# - host: ubuntu-20.04
|
||||
# target: x86_64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: armv7-unknown-linux-gnueabihf
|
||||
name: Build warp-input on release
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Rust
|
||||
id: toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.settings.target }}
|
||||
toolchain: stable
|
||||
components: clippy, rustfmt
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
save-if: false
|
||||
prefix-key: 'v0-rust-deps'
|
||||
shared-key: ${{ matrix.settings.target }}
|
||||
|
||||
- name: Cargo build
|
||||
run: cargo build --target ${{ matrix.settings.target }} --release
|
||||
|
||||
- name: Copy and rename artifacts (Linux)
|
||||
if: ${{ matrix.settings.host == 'ubuntu-20.04' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/warp-input ./warp-input
|
||||
|
||||
- name: Copy and rename artifacts (Windows)
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
run: |
|
||||
cp "target/${{ matrix.settings.target }}/release/warp-input.exe" ./warp-input.exe
|
||||
|
||||
- name: Copy and rename artifacts (macOS)
|
||||
if: ${{ matrix.settings.host == 'macos-latest' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/warp-input ./warp-input
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./bin/input/warp-input.exe
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host != 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./bin/input/warp-input
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
190
.github/workflows/warp.yml
vendored
@@ -1,190 +0,0 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:warp
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "warp.Dockerfile"
|
||||
- ".github/workflows/warp.yml"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "warp.Dockerfile"
|
||||
- ".github/workflows/warp.yml"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [published, created]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
BASE_TAG_PREFIX: warp
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp.Dockerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:warp
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge to main
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Log into registry ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ env.BASE_TAG_PREFIX }}
|
||||
#
|
||||
#tag on release, and a nightly build for 'dev'
|
||||
tags: |
|
||||
type=raw,value=nightly,enable={{is_default_branch}}
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp.Dockerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-warp-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: moq-server
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
bundles: appimage
|
||||
asset_name: warp-ubuntu-amd64
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
bundles: msi
|
||||
asset_name: warp-windows-amd64
|
||||
- host: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
bundles: dmg
|
||||
asset_name: warp-macos-amd64
|
||||
- host: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
bundles: dmg
|
||||
asset_name: warp-macos-apple-silicon
|
||||
# - host: ubuntu-20.04
|
||||
# target: x86_64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: armv7-unknown-linux-gnueabihf
|
||||
name: Build warp on release
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Rust
|
||||
id: toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.settings.target }}
|
||||
toolchain: stable
|
||||
components: clippy, rustfmt
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
save-if: false
|
||||
prefix-key: 'v0-rust-deps'
|
||||
shared-key: ${{ matrix.settings.target }}
|
||||
|
||||
- name: Cargo build
|
||||
run: cargo build --target ${{ matrix.settings.target }} --manifest-path ./moq-pub/Cargo.toml --release
|
||||
|
||||
- name: Copy and rename artifacts (Linux)
|
||||
if: ${{ matrix.settings.host == 'ubuntu-20.04' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/moq-pub ./warp
|
||||
|
||||
- name: Copy and rename artifacts (Windows)
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
run: |
|
||||
cp "target/${{ matrix.settings.target }}/release/moq-pub.exe" ./warp.exe
|
||||
|
||||
- name: Copy and rename artifacts (macOS)
|
||||
if: ${{ matrix.settings.host == 'macos-latest' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/moq-pub ./warp
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./moq-server/warp.exe
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host != 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./moq-server/warp
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
57
.gitignore
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# Dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
.idea/
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
|
||||
# Turbo
|
||||
.turbo
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
# Build Outputs
|
||||
.next/
|
||||
out/
|
||||
build
|
||||
dist
|
||||
|
||||
|
||||
# Debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# sst
|
||||
.sst
|
||||
|
||||
#Bun merging errors, EVERY time :(
|
||||
bun.lockb
|
||||
|
||||
#tests
|
||||
id_*
|
||||
|
||||
#Rust
|
||||
target
|
||||
|
||||
tmp
|
||||
.partykit
|
||||
|
||||
key_*
|
||||
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "moq-server"]
|
||||
path = moq-server
|
||||
url = https://github.com/kixelated/moq-rs
|
||||
@@ -1,20 +0,0 @@
|
||||
#This fixes the error where x11-apps in docker cannot seem to access the hosts DISPLAY server
|
||||
# Error: No protocol specified
|
||||
# Error: Can't open display: :10.0
|
||||
#https://askubuntu.com/a/1470341 //Run it on host OS
|
||||
xhost +Local:*
|
||||
xhost
|
||||
|
||||
#Fun fact Weston won't run if you do not have Wayland running on the host (i have yet to try running with Xwayland inside the container)
|
||||
#Run weston using your host's X11 display server
|
||||
weston --backend=x11-backend.so
|
||||
|
||||
#Run inside the terminal of the weston you just created... cool right?
|
||||
weston --backend=wayland-backend.so
|
||||
|
||||
#Run
|
||||
docker run --gpus all --entrypoint /bin/bash --rm -it -v $(pwd):/games -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY --cap-add=SYS_NICE --cap-add=SYS_ADMIN recorder
|
||||
|
||||
docker run --gpus all --entrypoint /bin/bash --device=/dev/dri --rm -it -v $(pwd):/game --cap-add=SYS_NICE --cap-add=SYS_ADMIN ghcr.io/wanjohiryan/netris/server:nightly
|
||||
|
||||
ffmpeg -hide_banner -v quiet -stream_loop -1 -re -i /game/test.mp4 -an -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | RUST_LOG=moq_pub=info warp --name "netris" https://fst.so:4443
|
||||
@@ -1,169 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
trap "echo TRAPed signal" HUP INT QUIT TERM
|
||||
|
||||
# Create and modify permissions of XDG_RUNTIME_DIR
|
||||
sudo -u netris mkdir -pm700 /tmp/runtime-1000
|
||||
sudo chown netris:netris /tmp/runtime-1000
|
||||
sudo -u netris chmod 700 /tmp/runtime-1000
|
||||
# Make user directory owned by the user in case it is not
|
||||
sudo chown netris:netris /home/netris || sudo chown netris:netris /home/netris/* || { echo "$(date +"[%Y-%m-%d %H:%M:%S]") Failed to change user directory permissions. There may be permission issues."; }
|
||||
|
||||
#Input devices ownable by our default user
|
||||
export REQUIRED_DEVICES=${REQUIRED_DEVICES:-/dev/uinput /dev/input/event*}
|
||||
|
||||
declare -A group_map
|
||||
|
||||
for dev in $REQUIRED_DEVICES; do
|
||||
if [ -e "$dev" ]; then
|
||||
dev_group=$(stat -c "%G" "$dev")
|
||||
dev_gid=$(stat -c "%g" "$dev")
|
||||
|
||||
if [ "$dev_group" = "UNKNOWN" ]; then
|
||||
new_name="netris-gid-$dev_gid"
|
||||
# We only have a GID for this group; create a named group for it
|
||||
# this isn't 100% necessary but it prevents some useless noise in the console
|
||||
sudo groupadd -g "$dev_gid" "$new_name"
|
||||
group_map[$new_name]=1
|
||||
else
|
||||
# the group already exists; just add it to the list
|
||||
group_map[$dev_group]=1
|
||||
fi
|
||||
|
||||
# is this device read/writable by the group? if not, make it so
|
||||
if [ "$(stat -c "%a" "$dev" | cut -c2)" -lt 6 ]; then
|
||||
sudo chmod g+rw "$dev"
|
||||
fi
|
||||
else
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Path '$dev' is not present."
|
||||
fi
|
||||
done
|
||||
|
||||
join_by() { local IFS="$1"; shift; echo "$*"; }
|
||||
|
||||
groups=$(join_by "," "${!group_map[@]}")
|
||||
if [ "$groups" != "" ]; then
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Adding user '${USER}' to groups: $groups"
|
||||
sudo usermod -a -G "$groups" "${USER}"
|
||||
else
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Not modifying user groups ($groups)"
|
||||
fi
|
||||
|
||||
# Remove directories to make sure the desktop environment starts
|
||||
sudo rm -rf /tmp/.X* ~/.cache
|
||||
# Change time zone from environment variable
|
||||
sudo ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" | sudo tee /etc/timezone >/dev/null
|
||||
# Add gamescope directories to path
|
||||
export PATH="${PATH:+${PATH}:}/usr/local/games:/usr/games"
|
||||
|
||||
# This symbolic link enables running Xorg inside a container with `-sharevts`
|
||||
sudo ln -snf /dev/ptmx /dev/tty7
|
||||
# Start DBus without systemd
|
||||
sudo /etc/init.d/dbus start
|
||||
|
||||
# Install NVIDIA userspace driver components including X graphic libraries
|
||||
if ! command -v nvidia-xconfig &>/dev/null; then
|
||||
# Driver version is provided by the kernel through the container toolkit
|
||||
export DRIVER_ARCH="$(dpkg --print-architecture | sed -e 's/arm64/aarch64/' -e 's/armhf/32bit-ARM/' -e 's/i.*86/x86/' -e 's/amd64/x86_64/' -e 's/unknown/x86_64/')"
|
||||
export DRIVER_VERSION="$(head -n1 </proc/driver/nvidia/version | awk '{print $8}')"
|
||||
cd /tmp
|
||||
# If version is different, new installer will overwrite the existing components
|
||||
if [ ! -f "/tmp/NVIDIA-Linux-${DRIVER_ARCH}-${DRIVER_VERSION}.run" ]; then
|
||||
# Check multiple sources in order to probe both consumer and datacenter driver versions
|
||||
curl -fsSL -O "https://international.download.nvidia.com/XFree86/Linux-${DRIVER_ARCH}/${DRIVER_VERSION}/NVIDIA-Linux-${DRIVER_ARCH}-${DRIVER_VERSION}.run" || curl -fsSL -O "https://international.download.nvidia.com/tesla/${DRIVER_VERSION}/NVIDIA-Linux-${DRIVER_ARCH}-${DRIVER_VERSION}.run" || {
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Failed NVIDIA GPU driver download. Exiting."
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
# Extract installer before installing
|
||||
sudo sh "NVIDIA-Linux-${DRIVER_ARCH}-${DRIVER_VERSION}.run" -x
|
||||
cd "NVIDIA-Linux-${DRIVER_ARCH}-${DRIVER_VERSION}"
|
||||
# Run installation without the kernel modules and host components
|
||||
sudo ./nvidia-installer --silent \
|
||||
--no-kernel-module \
|
||||
--install-compat32-libs \
|
||||
--no-nouveau-check \
|
||||
--no-nvidia-modprobe \
|
||||
--no-rpms \
|
||||
--no-backup \
|
||||
--no-check-for-alternate-installs
|
||||
sudo rm -rf /tmp/NVIDIA* && cd ~
|
||||
fi
|
||||
|
||||
# Allow starting Xorg from a pseudoterminal instead of strictly on a tty console
|
||||
if [ ! -f /etc/X11/Xwrapper.config ]; then
|
||||
echo -e "allowed_users=anybody\nneeds_root_rights=yes" | sudo tee /etc/X11/Xwrapper.config >/dev/null
|
||||
fi
|
||||
if grep -Fxq "allowed_users=console" /etc/X11/Xwrapper.config; then
|
||||
sudo sed -i "s/allowed_users=console/allowed_users=anybody/;$ a needs_root_rights=yes" /etc/X11/Xwrapper.config
|
||||
fi
|
||||
|
||||
# Remove existing Xorg configuration
|
||||
if [ -f "/etc/X11/xorg.conf" ]; then
|
||||
sudo rm -f "/etc/X11/xorg.conf"
|
||||
fi
|
||||
|
||||
# Get first GPU device if all devices are available or `NVIDIA_VISIBLE_DEVICES` is not set
|
||||
if [ "$NVIDIA_VISIBLE_DEVICES" == "all" ] || [ -z "$NVIDIA_VISIBLE_DEVICES" ]; then
|
||||
export GPU_SELECT="$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)"
|
||||
# Get first GPU device out of the visible devices in other situations
|
||||
else
|
||||
export GPU_SELECT="$(sudo nvidia-smi --id=$(echo "$NVIDIA_VISIBLE_DEVICES" | cut -d ',' -f1) --query-gpu=uuid --format=csv | sed -n 2p)"
|
||||
if [ -z "$GPU_SELECT" ]; then
|
||||
export GPU_SELECT="$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$GPU_SELECT" ]; then
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") No NVIDIA GPUs detected or nvidia-container-toolkit not configured. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Setting `VIDEO_PORT` to none disables RANDR/XRANDR, do not set this if using datacenter GPUs
|
||||
if [ "${VIDEO_PORT,,}" = "none" ]; then
|
||||
export CONNECTED_MONITOR="--use-display-device=None"
|
||||
# The X server is otherwise deliberately set to a specific video port despite not being plugged to enable RANDR/XRANDR, monitor will display the screen if plugged to the specific port
|
||||
else
|
||||
export CONNECTED_MONITOR="--connected-monitor=${VIDEO_PORT}"
|
||||
fi
|
||||
|
||||
# Bus ID from nvidia-smi is in hexadecimal format and should be converted to decimal format (including the domain) which Xorg understands, required because nvidia-xconfig doesn't work as intended in a container
|
||||
HEX_ID="$(sudo nvidia-smi --query-gpu=pci.bus_id --id="$GPU_SELECT" --format=csv | sed -n 2p)"
|
||||
IFS=":." ARR_ID=($HEX_ID)
|
||||
unset IFS
|
||||
BUS_ID="PCI:$((16#${ARR_ID[1]}))@$((16#${ARR_ID[0]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))"
|
||||
# A custom modeline should be generated because there is no monitor to fetch this information normally
|
||||
export MODELINE="$(cvt -r "${SIZEW}" "${SIZEH}" "${REFRESH}" | sed -n 2p)"
|
||||
# Generate /etc/X11/xorg.conf with nvidia-xconfig
|
||||
sudo nvidia-xconfig --virtual="${SIZEW}x${SIZEH}" --depth="$CDEPTH" --mode="$(echo "$MODELINE" | awk '{print $2}' | tr -d '\"')" --allow-empty-initial-configuration --no-probe-all-gpus --busid="$BUS_ID" --include-implicit-metamodes --mode-debug --no-sli --no-base-mosaic --only-one-x-screen ${CONNECTED_MONITOR}
|
||||
# Guarantee that the X server starts without a monitor by adding more options to the configuration
|
||||
sudo sed -i '/Driver\s\+"nvidia"/a\ Option "ModeValidation" "NoMaxPClkCheck,NoEdidMaxPClkCheck,NoMaxSizeCheck,NoHorizSyncCheck,NoVertRefreshCheck,NoVirtualSizeCheck,NoExtendedGpuCapabilitiesCheck,NoTotalSizeCheck,NoDualLinkDVICheck,NoDisplayPortBandwidthCheck,AllowNon3DVisionModes,AllowNonHDMI3DModes,AllowNonEdidModes,NoEdidHDMI2Check,AllowDpInterlaced"' /etc/X11/xorg.conf
|
||||
# Add custom generated modeline to the configuration
|
||||
sudo sed -i '/Section\s\+"Monitor"/a\ '"$MODELINE" /etc/X11/xorg.conf
|
||||
# Prevent interference between GPUs, add this to the host or other containers running Xorg as well
|
||||
echo -e "Section \"ServerFlags\"\n Option \"AutoAddGPU\" \"false\"\nEndSection" | sudo tee -a /etc/X11/xorg.conf >/dev/null
|
||||
|
||||
# Default display is :0 across the container
|
||||
export DISPLAY=":0"
|
||||
# Run Xorg server with required extensions
|
||||
/usr/bin/Xorg vt7 -noreset -novtswitch -sharevts -dpi "${DPI}" +extension "COMPOSITE" +extension "DAMAGE" +extension "GLX" +extension "RANDR" +extension "RENDER" +extension "MIT-SHM" +extension "XFIXES" +extension "XTEST" "${DISPLAY}" &
|
||||
|
||||
# Wait for X11 to start
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Waiting for X socket"
|
||||
until [ -S "/tmp/.X11-unix/X${DISPLAY/:/}" ]; do sleep 1; done
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") X socket is ready"
|
||||
|
||||
if [[ -z "${NAME}" ]]; then
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") No stream name was found, did you forget to set the env variable NAME?" && exit 1
|
||||
else
|
||||
/usr/bin/gpu-screen-recorder -w screen -c flv -f 60 -a "$(pactl get-default-sink).monitor" | ffmpeg -hide_banner -v quiet -i pipe:0 -c copy -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | /usr/bin/warp --name "${NAME}" https://fst.so:4443 &
|
||||
fi
|
||||
|
||||
openbox-session &
|
||||
|
||||
#Now we can safely run our input server without permission errors
|
||||
sudo /inputtino/input-server &
|
||||
|
||||
/usr/games/gamescope -- mangohud glxgears > /dev/null &
|
||||
|
||||
echo "$(date +"[%Y-%m-%d %H:%M:%S]") Session Running. Press [Return] to exit."
|
||||
read
|
||||
358
.scripts/proton
@@ -1,358 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Version 0.0.1
|
||||
|
||||
#Big thanks to github/@noabody
|
||||
#For his wmstart script https://github.com/noabody/unibuild/blob/master/data/wstart
|
||||
|
||||
#Dependencies: git, jq, curl, vulkan & wget
|
||||
|
||||
# top level linux steam dir
|
||||
pntop="$HOME/.steam"
|
||||
# steamapps subdir
|
||||
pnapp="$pntop/steam/steamapps"
|
||||
# proton subdir normally under top/app
|
||||
pnbin="$pnapp/common"
|
||||
# proton prefix subdir normally under top/app
|
||||
pnpfx="$pnapp/compatdata"
|
||||
# proton ge
|
||||
pnpge="$pntop/root/compatibilitytools.d"
|
||||
# Program Files standard subdir
|
||||
progs="drive_c/Program Files"
|
||||
# windows steam client subdir under progs
|
||||
stcmn="Steam/steamapps/common"
|
||||
# temp folder
|
||||
temp="$HOME/Downloads"
|
||||
|
||||
# store cmdline args minus first option
|
||||
clprm=("${@:2}")
|
||||
|
||||
xcmd=()
|
||||
i_mnus=()
|
||||
myprnt=()
|
||||
i_syms=()
|
||||
# scalable built-in programs menu
|
||||
pmenu=("Command Prompt/wineconsole.exe" "Control Panel/control.exe" "Registry Editor/regedit.exe" "Task Manager/taskmgr.exe" "Windows Explorer/explorer.exe" "Wine Configuration/winecfg.exe")
|
||||
# prevent shell inheritance of env vars we use
|
||||
unset WINEARCH WINEDLLPATH WINEPREFIX STEAM_COMPAT_CLIENT_INSTALL_PATH STEAM_COMPAT_DATA_PATH
|
||||
|
||||
xarg="$1"
|
||||
|
||||
xnint() {
|
||||
xnbin="$pnbin"
|
||||
xnpfx="$pnpfx"
|
||||
dpth=(4 3)
|
||||
}
|
||||
|
||||
xpge() {
|
||||
test -d "$pnpge" || mkdir -p "$pnpge"
|
||||
test -d "$pnbin" || mkdir -p "$pnbin"
|
||||
|
||||
if [[ ! -d "$(dirname "$pnpge")" ]]; then
|
||||
echo -e "Could not create folder 'compatibilitytools.d/protonge' in:\n $(dirname "$pnpge")\n because that path does not exist.\nVerify script variable 'pnpge'"
|
||||
elif [[ ! -d "$pnbin" ]]; then
|
||||
echo -e "Could not create sym-link 'protonge' in:\n $pnbin\n because that path does not exist.\nVerify script variable 'pnbin'"
|
||||
else
|
||||
gedl="$(curl -sL https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest | jq -r ".tag_name")"
|
||||
# gedl="$(gh release list -R GloriousEggroll/proton-ge-custom -L 1 | grep -Pio '^ge[^ ]+')"
|
||||
gever="$(echo "$gedl" | grep -Pio '(?<=ge-proton).*')"
|
||||
if [[ -f "$pnpge/protonge/version" ]]; then
|
||||
if [[ -z "$(grep -Pio "$gever" "$pnpge/protonge/version")" ]]; then
|
||||
echo -e "Available Proton GE $gever differs from installed, updating...\n"
|
||||
chse=y
|
||||
else
|
||||
echo -e "Available Proton GE $gever matches installed, nothing to do.\n"
|
||||
fi
|
||||
else
|
||||
echo -e "Proton GE not found, installing...\n"
|
||||
chse=y
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$chse" ]]; then
|
||||
wget --progress=dot:giga "$(curl -s https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest | grep browser_download_url | cut -d\" -f4 | grep .tar.gz)" -P "$temp"/
|
||||
|
||||
rm -rf "$pnpge/protonge"
|
||||
tar -xf "$temp/$gedl".tar.gz -C "$pnpge/"
|
||||
mv "$pnpge"/*roton* "$pnpge/protonge"
|
||||
rm -f "$temp/$gedl".tar.gz
|
||||
grep -Piq "$gever" "$pnpge/protonge/version" || perl -pi -e "s|(?<=ge-proton).*|$gever|gi" "$pnpge/protonge/version"
|
||||
test -h "$pnbin/protonge" || ln -sf "$pnpge/protonge" "$pnbin"
|
||||
fi
|
||||
}
|
||||
|
||||
xn64() {
|
||||
xstrt="wine64"
|
||||
xnldl="$xnbin/lib64:$xnbin/lib"
|
||||
xndll="$xnbin/lib64/wine:$xnbin/lib/wine"
|
||||
}
|
||||
|
||||
xn32() {
|
||||
xstrt="wine"
|
||||
xnldl="$xnbin/lib"
|
||||
xndll="$xnbin/lib/wine"
|
||||
}
|
||||
|
||||
w_menu() {
|
||||
PS3="Please enter your choice: "
|
||||
select answer in "${i_mnus[@]}"; do
|
||||
for item in "${i_mnus[@]}"; do
|
||||
if [[ $item == "$answer" ]]; then
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
# repeating menu requires valid selection from array
|
||||
if [[ "$answer" = "quit" ]]; then
|
||||
# pop quit from end of array for menu option
|
||||
exit
|
||||
else
|
||||
xmrtn="$answer"
|
||||
fi
|
||||
unset i_mnus
|
||||
clear
|
||||
}
|
||||
|
||||
xnexe() {
|
||||
# menu installed wine/proton or exit
|
||||
readarray -t i_mnus < <(
|
||||
find -L "$xnbin" -maxdepth "${dpth[0]}" -type f -iname 'wine' ! \( -ipath '*/sbin*' \) 2>/dev/null | perl -pe "s|\Q$xnbin\E/(.*)[/]*bin/wine|\1| ; s|/$||" | sort
|
||||
echo "quit"
|
||||
)
|
||||
if [[ ${#i_mnus[@]} -gt 2 ]]; then
|
||||
clear
|
||||
w_menu
|
||||
xnbin="$(realpath "$xnbin/$xmrtn")"
|
||||
unset xmrtn
|
||||
elif [[ ${#i_mnus[@]} -eq 2 ]]; then
|
||||
xnbin="$(realpath "$xnbin/${i_mnus[0]}")"
|
||||
else
|
||||
echo "No installed Wine/Proton found."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
xnenv() {
|
||||
# core env vars allow proper targetting of wine/proton
|
||||
xpath="$xnbin/bin:$PATH"
|
||||
xcmd=(env PATH="$xpath" WINEDLLPATH="$xndll" LD_LIBRARY_PATH="$xnldl" WINEPREFIX="$xnpfx")
|
||||
|
||||
xcmd+=(STEAM_COMPAT_DATA_PATH="${xnpfx///pfx}" STEAM_COMPAT_CLIENT_INSTALL_PATH="$pntop")
|
||||
}
|
||||
|
||||
xlnch() {
|
||||
#command line launcher
|
||||
if [[ -z "$dbg" ]]; then
|
||||
("${xcmd[@]}" >/dev/null 2>&1 &)
|
||||
else
|
||||
if [[ "$dbg" = "1" ]]; then
|
||||
("${xcmd[@]}" &)
|
||||
elif [[ "$dbg" = "2" ]]; then
|
||||
(WINEDEBUG="warn+all" "${xcmd[@]}" &)
|
||||
fi
|
||||
fi
|
||||
# prepend cmd with dbg=1 to see command and default debug output
|
||||
# dbg=2 to see command and all debug output, dbg=? for command only
|
||||
}
|
||||
|
||||
xbld() {
|
||||
# cross-function custom prefix builder
|
||||
pnpfx="$pnpfx/${clprm[0]}"
|
||||
xnint
|
||||
|
||||
if [[ -z "${clprm[0]}" ]]; then
|
||||
echo -e "\n Proton prefix name required, use an appid from Steam: (e.g. 0, 730 ) \n"
|
||||
elif [[ -d "$xnpfx" ]]; then
|
||||
echo -e "\n Proton Prefix exists: $xnpfx \n"
|
||||
else
|
||||
xnexe
|
||||
echo "Creating Proton Prefix: ${clprm[0]}"
|
||||
|
||||
xnenv
|
||||
mkdir -p "$xnpfx"
|
||||
xcmd+=(STEAM_COMPAT_DATA_PATH="$xnpfx" "${xnbin%/*}/proton" "run")
|
||||
|
||||
xlnch
|
||||
fi
|
||||
}
|
||||
|
||||
xnpre() {
|
||||
if [[ -d "$xnpfx/$progs (x86)" ]]; then
|
||||
xn64
|
||||
else
|
||||
xn32
|
||||
fi
|
||||
}
|
||||
|
||||
xndef() {
|
||||
# create default prefix cross-function
|
||||
if [[ -z "$prfx" ]]; then
|
||||
echo "INFO: to use a specific prefix, append prfx='your prefix' to this command"
|
||||
if [[ ! -d "$xnpfx/0" ]]; then
|
||||
# always create default 0 prefix
|
||||
xnpfx="$xnpfx/0"
|
||||
echo "Creating default prefix: $xnpfx"
|
||||
mkdir -p "$xnpfx"
|
||||
STEAM_COMPAT_DATA_PATH="$xnpfx" "${xnbin%/*}/proton" run >/dev/null 2>&1 &
|
||||
xnpfx="$xnpfx/pfx"
|
||||
else
|
||||
xnpfx="$xnpfx/0"
|
||||
xnpfx="$xnpfx/pfx"
|
||||
fi
|
||||
else
|
||||
xnpfx="$xnpfx/$prfx"
|
||||
if [[ ! -d "$xnpfx" ]]; then
|
||||
echo "Creating default prefix: $xnpfx"
|
||||
mkdir -p "$xnpfx"
|
||||
STEAM_COMPAT_DATA_PATH="$xnpfx" "${xnbin%/*}/proton" run >/dev/null 2>&1 &
|
||||
xnpfx="$xnpfx/pfx"
|
||||
else
|
||||
xnpfx="$xnpfx/pfx"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
fewoth() {
|
||||
# filtered list of variable type in standard paths
|
||||
readarray -t i_mnus < <(
|
||||
env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended ! \( -ipath '*cache*' -o -ipath '*/microsoft*' -o -ipath '*/windows*' -o -ipath '*/temp*' \) ! \( -iregex '.*(capture|clokspl|helper|iexplore|install|internal|kernel|[^ ]launcher|legacypm|overlay|proxy|redist|renderer|(crash|error)reporter|serv(er|ice)|setup|streaming|tutorial|unins|update).*' \) -iname "$xflt" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort
|
||||
echo "quit"
|
||||
)
|
||||
}
|
||||
|
||||
fewexe() {
|
||||
# filtered list of exe in standard paths
|
||||
readarray -t i_mnus < <(
|
||||
env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended ! \( -ipath '*cache*' -o -ipath '*/microsoft*' -o -ipath '*/windows*' -o -ipath '*/temp*' \) ! \( -iregex '.*(capture|clokspl|helper|iexplore|install|internal|kernel|[^ ]launcher|legacypm|overlay|proxy|redist|renderer|(crash|error)reporter|serv(er|ice)|setup|streaming|tutorial|unins|update).*' \) -iname '*.exe' -exec sh -c '(readpe -h optional "$1" 2>/dev/null | grep -Piq '0x2.*gui') && (wrestool "$1" 2>/dev/null | grep -Piq 'type=icon') && echo "$1" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|"' -- {} \; 2>/dev/null | sort
|
||||
echo "quit"
|
||||
)
|
||||
# valid exe will have gui and icon
|
||||
}
|
||||
|
||||
alloth() {
|
||||
# unfiltered list of variable type in specified path
|
||||
readarray -t i_mnus < <(
|
||||
find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname "$xflt" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort
|
||||
echo "quit"
|
||||
)
|
||||
}
|
||||
|
||||
allexe() {
|
||||
# unfiltered list of exe in specified path
|
||||
if [[ -n "$(stat --file-system --format=%T "$(stat --format=%m "$pedir" 2>/dev/null)" 2>/dev/null | grep -Pio 'fuse')" ]]; then
|
||||
readarray -t i_mnus < <(
|
||||
find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname '*.exe' 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort
|
||||
echo "quit"
|
||||
)
|
||||
# skip exe validity tests if file is on network drive
|
||||
else
|
||||
readarray -t i_mnus < <(
|
||||
env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname '*.exe' -exec sh -c '(readpe -h optional "$1" 2>/dev/null | grep -Piq '0x2.*gui') && (wrestool "$1" 2>/dev/null | grep -Piq 'type=icon') && echo "$1" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|"' -- {} \; 2>/dev/null | sort
|
||||
echo "quit"
|
||||
)
|
||||
# perform exe validity tests if file is on local drive
|
||||
fi
|
||||
}
|
||||
|
||||
xpmn() {
|
||||
# use specified exe, menu specified folder, or menu system
|
||||
if [[ -f "${clprm[0]}" ]]; then
|
||||
# parse 1st cmdline arg, queue if valid file
|
||||
pedir="$(realpath "${clprm[0]}")"
|
||||
xmrtn="$(basename "$pedir")"
|
||||
pedir="$(dirname "$pedir")"
|
||||
else
|
||||
if [[ -d "${clprm[0]}" ]]; then
|
||||
# parse 1st cmdline arg, use as path if valid
|
||||
pedir="$(realpath "${clprm[0]}")"
|
||||
test -z "$xflt" && allexe || alloth
|
||||
else
|
||||
# if no cmdline path, use prefix drive_c
|
||||
pedir="$xnpfx/drive_c"
|
||||
test -z "$xflt" && fewexe || fewoth
|
||||
fi
|
||||
# create menu, from path, of file
|
||||
test ${#i_mnus[@]} -gt 1 && w_menu
|
||||
fi
|
||||
}
|
||||
|
||||
xnldr() {
|
||||
# loader default to proton as applicable, otherwise wine
|
||||
if [[ -z "$wn" ]]; then
|
||||
xcmd+=("${xnbin%/*}/proton" "run")
|
||||
else
|
||||
if [[ "$wn" = "true" ]]; then
|
||||
xcmd+=("$xstrt")
|
||||
else
|
||||
echo "unrecognised run option"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
xlyt() {
|
||||
# prepare layout for launch
|
||||
# 64-bit prefix, 32-bit prefix header, reset env to 32
|
||||
if [[ -n "$(readpe -h optional "$pedir/$xmrtn" 2>/dev/null | grep -Pi 'magic number.*0x10b')" && -d "$xnpfx/$progs (x86)" ]]; then
|
||||
xn32
|
||||
xnenv
|
||||
fi
|
||||
xnldr
|
||||
# if 1st arg is file/folder, skip it and run selection + remaining args
|
||||
if [[ -e "${clprm[0]}" ]]; then
|
||||
xcmd+=("$pedir/$xmrtn" "${clprm[@]:1}")
|
||||
else
|
||||
xcmd+=("$pedir/$xmrtn" "${clprm[@]}")
|
||||
fi
|
||||
}
|
||||
|
||||
xnset() {
|
||||
# set cross-fuction
|
||||
xnint
|
||||
# proton menu
|
||||
xnexe
|
||||
# create default prefix as required
|
||||
xndef
|
||||
# proton prefix
|
||||
xnpre
|
||||
# proton env vars
|
||||
xnenv
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo -e "\n$(basename $0): ERROR - $*" 1>&2
|
||||
echo -e "\nusage: $(basename $0)\n [-i,--install] [-b,--build] [-r,--run] \n \n (install) install proton-ge \n (build) build a custom proton prefix \n (run) run an .exe program \n \n" 1>&2
|
||||
}
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
usage "one option required!"
|
||||
else
|
||||
case $xarg in
|
||||
-i | --install)
|
||||
# proton ge
|
||||
xpge
|
||||
;;
|
||||
-p | --prefix)
|
||||
# prefix builder
|
||||
xbld
|
||||
;;
|
||||
-r | --run)
|
||||
# second arg should be the prefix to use.
|
||||
# run program - 1st arg valid file to run, folder to menu,
|
||||
# neither (sys menu), 2nd arg... passed to exe
|
||||
xnset
|
||||
xpmn
|
||||
if [[ -n "$xmrtn" ]]; then
|
||||
xlyt
|
||||
# change to exe dir before run
|
||||
cd "$(dirname "$pedir/$xmrtn")"
|
||||
xlnch
|
||||
fi
|
||||
;;
|
||||
-* | \* | *)
|
||||
# do_usage
|
||||
usage "invalid option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#FIXME: it won't run anything AAAArgh!
|
||||
@@ -1,28 +0,0 @@
|
||||
[supervisord]
|
||||
user=netris
|
||||
nodaemon=true
|
||||
loglevel=info
|
||||
logfile=/tmp/supervisord.log
|
||||
pidfile=/tmp/supervisord.pid
|
||||
|
||||
[program:entrypoint]
|
||||
command=/etc/entrypoint.sh
|
||||
logfile=/tmp/entrypoint.log
|
||||
pidfile=/tmp/entrypoint.pid
|
||||
stopsignal=INT
|
||||
autostart=true
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
priority=1
|
||||
|
||||
[program:pulseaudio]
|
||||
user=netris
|
||||
command=bash -c "until [ -S \"/tmp/.X11-unix/X${DISPLAY/:/}\" ]; do sleep 1; done; sudo /usr/bin/pulseaudio -k >/dev/null 2>&1 || sudo /usr/bin/pulseaudio --system --verbose --log-target=stderr --realtime=true --disallow-exit -L 'module-native-protocol-tcp auth-ip-acl=127.0.0.0/8 port=4713 auth-anonymous=1'"
|
||||
environment=DISPLAY=":0"
|
||||
logfile=/tmp/pulseaudio.log
|
||||
pidfile=/tmp/pulseaudio.pid
|
||||
stopsignal=INT
|
||||
autostart=true
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
priority=10
|
||||
4
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["dbaeumer.vscode-eslint", "unifiedjs.vscode-mdx"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
12
.vscode/settings.json
vendored
@@ -1,3 +1,11 @@
|
||||
{
|
||||
"files.eol": "\n"
|
||||
}
|
||||
"material-icon-theme.activeIconPack": "qwik",
|
||||
"emmet.includeLanguages": {
|
||||
"typescriptreact": "html"
|
||||
},
|
||||
"emmet.preferences": {
|
||||
// to ensure closing tags are used (e.g. <img/> not just <img> like in HTML)
|
||||
// https://github.com/microsoft/vscode/commit/083bf9020407ea5a91199eb1f0b373859df8d600#diff-88456bc9b7caa2f8126aea0107b4671db0f094961aaf39a7c689f890e23aaaba
|
||||
"output.selfClosingStyle": "xhtml"
|
||||
}
|
||||
}
|
||||
|
||||
4
LICENSE
@@ -629,8 +629,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
Netris: The open-source cloud gaming platform for friends
|
||||
Copyright (C) 2024 Wanjohi Ryan
|
||||
Nestri: Your games, Your rules
|
||||
Copyright (C) 2023 WanjohiRyan
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
|
||||
167
README.md
@@ -1,46 +1,32 @@
|
||||
<div align="center">
|
||||
<div>
|
||||
|
||||
<a href="https://netris.me" >
|
||||
<img height="160" src="/assets/logo.png">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div align="center" >
|
||||
<div align="center">
|
||||
<h1>
|
||||
<a href="https://netris.me" >
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="/assets/logo-name-white.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="/assets/logo-name-black.png">
|
||||
<img alt="netris logo name" src="/assets/logo-name-black.png">
|
||||
</picture>
|
||||
|
||||
<a href="https://nestri.io" >
|
||||
<img src="/apps/www/public/seo/banner.png" alt="Nestri - What will you play next?">
|
||||
</a>
|
||||
|
||||
</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
An open-source cloud gaming platform built for you to play together with your friends. <br/> A GeForce NOW alternative that can be self-hosted.<br/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div align="center" >
|
||||
|
||||
Nestri is an open-source, self-hosted Geforce Now alternative with Stadia's social features. <strong>Built and shaped by our gaming community.</strong>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[![][github-release-shield]][github-release-link]
|
||||
[![][discord-shield]][discord-link]
|
||||
[![][github-license-shield]][github-license-link]
|
||||
[![][github-stars-shield]][github-stars-link]
|
||||
|
||||
**Share the Netris Repository on Social Media**
|
||||
**Share the Nestri Repository on Social Media**
|
||||
|
||||
[![][share-x-shield]][share-x-link]
|
||||
[![][share-reddit-shield]][share-reddit-link]
|
||||
@@ -49,102 +35,81 @@ An open-source cloud gaming platform built for you to play together with your fr
|
||||
|
||||
|
||||
|
||||
<div align="center" >
|
||||
> **Note**
|
||||
> Nestri is more closer (in feature comparison) to Jellyfin/Plex than Moonlight. Our goal is to develop a comprehensive self-hosted cloud gaming solution for your home server.
|
||||
|
||||
[![][image-overview]][website-link]
|
||||
## Features
|
||||
|
||||
</div>
|
||||
- Save and share your game progress easily with friends
|
||||
- Simultaneously run multiple games on your GPU using Virtio-GPU Venus and/or Virgl
|
||||
- Play games using either your integrated GPU or dedicated GPU
|
||||
- Enjoy titles from your preferred Game Stores - Steam, Epic Games, Amazon Games, GOG.com
|
||||
- Experience Android gaming
|
||||
- Organize gaming sessions with friends and family through Nestri Parties
|
||||
- Stream directly to YouTube and Twitch straight from your setup
|
||||
- Family sharing capabilities
|
||||
- Support for Controller, Touchscreen, Keyboard, and Mouse devices
|
||||
|
||||
## Features 🌟
|
||||
## Possible Use Cases
|
||||
|
||||
As Netris navigates through its _experimental_ phase, we're in the process of crafting and testing a variety of features for you:
|
||||
- Organize game nights or LAN parties with friends online or locally
|
||||
- For game developers, showcase your proof-of-concept multiplayer games for testing without installation
|
||||
- Create and manage your custom cloud-gaming platform using our robust API
|
||||
- Establish a game server for your family to enjoy gaming on the go
|
||||
|
||||
1. **🎮 Proton-GE Compatibility:** We utilize Proton-GE for running games, offering extensive game compatibility and ensuring you can play a wide variety of titles.
|
||||
## Goals
|
||||
|
||||
2. **⚡ QUIC Protocol:** For input and video/audio transmission, we use QUIC via [MoQ][moq-github-url] to significantly reduce latency on variable networks, ensuring crisp visuals without sacrificing data or increasing latency.
|
||||
- Provide a user-friendly setup - fire and forget
|
||||
- Deliver a simple and elegant interface for managing and playing your game library
|
||||
- Ensure a high-quality gaming experience out-of-the-box
|
||||
- Optimize for the best gaming performance right from the start
|
||||
|
||||
3. **🔗 Session IDs:** With a `SESSION_ID`, we seamlessly tie your game progress, achievements, and devices without the need for logging into [netris.me][website-link]. Our public CDNs, currently located in Europe (eu-north-1) and the US (us-east-1), further reduce latency for friends playing together from afar. More locations are on the way!
|
||||
## Non-Goals
|
||||
|
||||
4. **🔄 Automatic Game Progress Sync:** Like Stadia's state share, we automatically sync your game progress based on the *.exe file you're running, allowing you to share your progress with friends via a link.
|
||||
- Become a generic cloud-gaming service
|
||||
|
||||
5. **👫 Co-op Gameplay:** Play co-op with up to 8 people, or play single player by sharing mouse and keyboard inputs seamlessly (similar to [neko][neko-url]).
|
||||
## Built With
|
||||
|
||||
6. **🌐 Cross-Platform Play:** Our platform is accessible on any device that can run a Chrome-based browser, including Edge, Chrome, Brave, and Arc. And you do not have to set up anything, it's all done and maintained for you.
|
||||
- Cloudflare Workers
|
||||
- Cloudflare Pages
|
||||
- Supabase
|
||||
- CrosVM (with Virtio-GPU Venus and Virgl support)
|
||||
- Docker
|
||||
- Qwik
|
||||
- Media-Over-Quic
|
||||
- AWS Route53
|
||||
|
||||
7. **📊 Bandwidth Optimization:** Experience hardware-accelerated `VMAF` for optimized bandwidth, ensuring the best possible video quality. [Learn More][vmaf-cuda-link]
|
||||
## Known Issues
|
||||
|
||||
8. **🌟 ...and more:** Stay tuned as we continue to add features _sometimes inspired by platforms like Stadia_, to give you the best and most customizable gaming experience.
|
||||
- CrosVM is still under development and needs to be merged
|
||||
- Currently, the Intel dGPU, particularly the Arc A780, is the only tested and verified GPU
|
||||
|
||||
This platform is in an _experimental_ phase, and we're actively working on adding new features. Your feedback and support is very much appreciated.
|
||||
## Donation
|
||||
|
||||
> \[!IMPORTANT]
|
||||
>
|
||||
> If you're excited about what we're doing and want to support our journey, consider giving us a star ⭐ on our repository. Your support fuels our progress!. \~ ✨
|
||||
If you appreciate our work and wish to support the development of Nestri, consider making a donation [here](https://polar.sh/nestri/donate). Your contributions will help us improve the platform and enhance your gaming experience. Thank you for your support!
|
||||
|
||||
## Demo
|
||||
|
||||
Nestri is still in development, but here is some footage from Behind-The-Scenes
|
||||
|
||||
<img src="/apps/www/public/seo/code.avif" alt="Nestri - What will you play next?">
|
||||
|
||||
|
||||
[![][image-star]][github-stars-link]
|
||||
|
||||
|
||||
## Getting Started 🎮
|
||||
|
||||
Whether you're looking to self-host Netris or simply want to try it out without the need for your own GPU, we've got you covered. Choose the path that best suits your needs:
|
||||
|
||||
<!-- _You can always change your option later without losing game progress_ -->
|
||||
|
||||
| If you don't have a Nvidia GPU or prefer not to self-host, you can visit our website. No installation or set up required ! <br/> This is the perfect option for gamers looking to dive straight into the action without any setup. | [👉🏽 Get Access][website-link] |
|
||||
| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
|
||||
| If you're interested in self-hosting Netris, continue reading for detailed instructions on how to get started. <br/> This option is ideal if you have your own Nvidia GPU and are comfortable with setting up and managing your own server. | [🛠️ Self Host Netris](#self-hosting) |
|
||||
|
||||
> \[!TIP]
|
||||
>
|
||||
> Remember, flexibility is key with Netris. You're free to switch between self-hosting and using `netris.me` whenever you like, without losing your game progress. \~ 💡
|
||||
<a name="self-hosting"></a>
|
||||
|
||||
### Self-Hosting Netris 🔨
|
||||
|
||||
For those interested in self-hosting, here are is what you need to get your own Netris server up and running:
|
||||
|
||||
- **Nvidia GPU**: Unfortunately, this setup is exclusive to Nvidia GPUs. If you don't own one, consider renting from cloud services like AWS, GCP, or Vast.ai. We highly recommend this approach.
|
||||
|
||||
- **CUDA**: For GPU acceleration, CUDA version `12.0` or newer is required. Verify your CUDA installation by running `nvcc --version`.
|
||||
|
||||
- **Docker**: Ensure you have `docker` and `nvidia-docker` are up to date to avoid compatibility issues with CUDA. You can check your Docker version by running `docker --version` in your terminal.
|
||||
|
||||
- **GPU Driver**: Ensure your GPU drivers are up to date to avoid compatibility issues with CUDA. Nvidia driver version `520.56.06` or newer is required.
|
||||
|
||||
- **Xorg Display**: Your Nvidia GPU should not be attached to a running X display server. You can confirm this by running `nvidia-smi`.
|
||||
|
||||
- **Nvidia-DRM**: Make sure that the `nvidia-drm` module has been loaded and that the module is loaded with the flag `modeset=1`. Confirm this by running `sudo cat /sys/module/nvidia_drm/parameters/modeset`
|
||||
|
||||
> \[!TIP]
|
||||
>
|
||||
> Typically, if your setup meets the necessary CUDA requirements, the `nvidia-drm` module will already be loaded, particularly in AWS G4dn instances. \~ 💡
|
||||
|
||||
### Step-by-Step Guide
|
||||
|
||||
Follow these steps to get Netris up and running on your system.
|
||||
|
||||
> \[!IMPORTANT]
|
||||
>
|
||||
> Waiting on this pull request [#43][netris-pr-input] to be merged first. Sorry for the inconvenience. \~ ⚠️
|
||||
|
||||
|
||||
[github-release-link]: https://github.com/wanjohiryan/netris/releases
|
||||
[github-release-shield]: https://img.shields.io/github/v/release/wanjohiryan/netris?color=369eff&labelColor=black&logo=github&style=flat-square
|
||||
[github-release-link]: https://github.com/nestriness/nestri/releases
|
||||
[github-release-shield]: https://img.shields.io/github/v/release/nestriness/nestri?color=369eff&labelColor=black&logo=github&style=flat-square
|
||||
[discord-shield]: https://img.shields.io/discord/1080111004698021909?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
|
||||
[discord-link]: https://discord.com/invite/Y6etn3qKZ3
|
||||
[github-license-shield]: https://img.shields.io/github/license/wanjohiryan/netris?color=white&labelColor=black&style=flat-square
|
||||
[github-license-link]: https://github.com/wanjohiryan/netris/blob/main/LICENSE
|
||||
[github-stars-shield]: https://img.shields.io/github/stars/wanjohiryan/netris?color=ffcb47&labelColor=black&style=flat-square
|
||||
[github-stars-link]: https://github.com/wanjohiryan/netris/network/stargazers
|
||||
[github-license-shield]: https://img.shields.io/github/license/nestriness/nestri?color=white&labelColor=black&style=flat-square
|
||||
[github-license-link]: https://github.com/nestriness/nestri/blob/main/LICENSE
|
||||
[github-stars-shield]: https://img.shields.io/github/stars/nestriness/nestri?color=ffcb47&labelColor=black&style=flat-square
|
||||
[github-stars-link]: https://github.com/nestriness/nestri/network/stargazers
|
||||
[share-x-shield]: https://img.shields.io/badge/-share%20on%20x-black?labelColor=black&logo=x&logoColor=white&style=flat-square
|
||||
[share-x-link]: https://twitter.com/intent/tweet?text=Hey%2C%20check%20out%20this%20Github%20repository.%20It%20is%20an%20open-source%20self-hosted%20Geforce%20Now%20alternative.&url=https%3A%2F%2Fgithub.com%2Fwanjohiryan%2Fnetris
|
||||
[share-x-link]: https://twitter.com/intent/tweet?text=Hey%2C%20check%20out%20this%20Github%20repository.%20It%20is%20an%20open-source%20self-hosted%20Geforce%20Now%20alternative.&url=https%3A%2F%2Fgithub.com%2Fnestriness%2Fnestri
|
||||
[share-reddit-shield]: https://img.shields.io/badge/-share%20on%20reddit-black?labelColor=black&logo=reddit&logoColor=white&style=flat-square
|
||||
[share-reddit-link]: https://www.reddit.com/submit?title=Hey%2C%20check%20out%20this%20Github%20repository.%20It%20is%20an%20open-source%20self-hosted%20Geforce%20Now%20alternative.&url=https%3A%2F%2Fgithub.com%2Fwanjohiryan%2Fnetris
|
||||
[share-reddit-link]: https://www.reddit.com/submit?title=Hey%2C%20check%20out%20this%20Github%20repository.%20It%20is%20an%20open-source%20self-hosted%20Geforce%20Now%20alternative.&url=https%3A%2F%2Fgithub.com%2Fnestriness%2Fnestri
|
||||
[image-overview]: assets/banner.png
|
||||
[website-link]: https://netris.me
|
||||
[website-link]: https://nestri.io
|
||||
[neko-url]: https://github.com/m1k1o/neko
|
||||
[image-star]: assets/star-us.png
|
||||
[moq-github-url]: https://quic.video
|
||||
[vmaf-cuda-link]: https://developer.nvidia.com/blog/calculating-video-quality-using-nvidia-gpus-and-vmaf-cuda/
|
||||
[netris-pr-input]: https://github.com/netrisdotme/netris/pull/43
|
||||
[vmaf-cuda-link]: https://developer.nvidia.com/blog/calculating-video-quality-using-nvidia-gpus-and-vmaf-cuda/
|
||||
14
apps/docs/.eslintrc.cjs
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@nuxt/eslint-config'],
|
||||
ignorePatterns: [
|
||||
'dist',
|
||||
'node_modules',
|
||||
'.output',
|
||||
'.nuxt'
|
||||
],
|
||||
rules: {
|
||||
'vue/max-attributes-per-line': 'off',
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
}
|
||||
12
apps/docs/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
node_modules
|
||||
*.iml
|
||||
.idea
|
||||
*.log*
|
||||
.nuxt
|
||||
.vscode
|
||||
.DS_Store
|
||||
coverage
|
||||
dist
|
||||
sw.*
|
||||
.env
|
||||
.output
|
||||
2
apps/docs/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
||||
shamefully-hoist=true
|
||||
strict-peer-dependencies=false
|
||||
87
apps/docs/RELAY.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# How to Deploy Your Own MoQ Relay on a Server
|
||||
|
||||
This guide will walk you through the steps to deploy your own MoQ relay on a server.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Server Requirements:**
|
||||
- Ensure port 443 is open for both TCP and UDP (`:443/udp & :443/tcp`).
|
||||
- The server should have a minimum of **4GB RAM** and **2 vCPUs**.
|
||||
- Supports ARM or AMD64 architecture.
|
||||
|
||||
2. **Software Requirements:**
|
||||
- Docker and `docker-compose` must be installed on the server. You can use [this installation script](https://github.com/docker/docker-install) for Docker.
|
||||
- Git must be installed to clone the necessary repository.
|
||||
|
||||
3. **Certificates:**
|
||||
- You will need private and public certificates. It is recommended to use certificates from a trusted CA rather than self-signed certificates.
|
||||
|
||||
## Installation Steps
|
||||
|
||||
### Step 1: Clone the Repository
|
||||
|
||||
Clone the `kixelated/moq-rs` repository to your local machine:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kixelated/moq-rs moq
|
||||
```
|
||||
|
||||
### Step 2: Verify Port Availability
|
||||
|
||||
Check if port 443 is already in use on your server:
|
||||
|
||||
```bash
|
||||
sudo netstat -tulpn | grep ':443' | grep LISTEN
|
||||
```
|
||||
or
|
||||
```bash
|
||||
sudo lsof -i -P -n | grep LISTEN | grep 443
|
||||
```
|
||||
|
||||
If you find any processes using port 443, consider terminating them.
|
||||
|
||||
### Step 3: Configure Ports
|
||||
|
||||
Navigate to the cloned directory and edit the Docker compose file to use port 443:
|
||||
|
||||
```bash
|
||||
cd moq
|
||||
vim docker-compose.yml
|
||||
```
|
||||
|
||||
Change the ports section from lines 34 to 35 to:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
```
|
||||
|
||||
### Step 4: Prepare Certificates
|
||||
|
||||
Copy your generated certificates into the `moq/dev` directory and rename them:
|
||||
|
||||
```bash
|
||||
cp cert.pem moq/dev/localhost.crt
|
||||
cp key.pem moq/dev/localhost.key
|
||||
```
|
||||
|
||||
### Step 5: Start Docker Instances
|
||||
|
||||
Ensure you are in the root directory of the `moq` project, then start the Docker containers:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Step 6: Link Domain to Server IP
|
||||
|
||||
Configure your DNS settings to connect your server's IP address to your domain:
|
||||
|
||||
```
|
||||
Record Type: A
|
||||
Subdomain: relay.fst.so
|
||||
IP Address: xx.xxx.xx.xxx
|
||||
```
|
||||
|
||||
Congratulations, your MoQ server is now set up! You can verify its functionality by using the [MoQ Checker](https://nestri.pages.dev/moq/checker).
|
||||
44
apps/docs/app.config.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// https://github.com/nuxt-themes/docus/blob/main/nuxt.schema.ts
|
||||
export default defineAppConfig({
|
||||
docus: {
|
||||
title: 'Nestri',
|
||||
description: 'An open-source, self-hosted Geforce Now alternative',
|
||||
image: 'https://feat-relay-hetzner.nestri.pages.dev/logo.webp',
|
||||
socials: {
|
||||
twitter: 'nestriness',
|
||||
github: 'nestriness/nestri',
|
||||
reddit: '/r/nestri',
|
||||
website: {
|
||||
label: 'Website',
|
||||
icon: 'lucide:house',
|
||||
href: 'https://nestri.io'
|
||||
}
|
||||
},
|
||||
github: {
|
||||
dir: 'apps/docs/content',
|
||||
branch: 'main',
|
||||
repo: 'nestri',
|
||||
owner: 'nestriness',
|
||||
edit: true
|
||||
},
|
||||
aside: {
|
||||
level: 0,
|
||||
collapsed: false,
|
||||
exclude: []
|
||||
},
|
||||
main: {
|
||||
padded: true,
|
||||
fluid: true
|
||||
},
|
||||
logo: "/nestri-logo.svg",
|
||||
header: {
|
||||
logo: true,
|
||||
showLinkIcon: true,
|
||||
exclude: [],
|
||||
fluid: true
|
||||
},
|
||||
footer: {
|
||||
credits: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
62
apps/docs/components/AppSocialIcons.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
const socials = ['twitter', 'facebook', 'instagram', 'tiktok', 'youtube', 'github', 'medium', 'reddit', 'discord']
|
||||
|
||||
const { config } = useDocus()
|
||||
|
||||
const icons = computed<any>(() => {
|
||||
return Object.entries(config.value.socials || {})
|
||||
.map(([key, value]) => {
|
||||
if (typeof value === 'object') {
|
||||
return value
|
||||
} else if (typeof value === 'string' && value && socials.includes(key)) {
|
||||
return {
|
||||
href: /^https?:\/\//.test(value) ? value : `https://${key}.com/${value}`,
|
||||
icon: `fa-brands:${key}`,
|
||||
label: value,
|
||||
rel: 'noopener noreferrer'
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtLink
|
||||
v-for="icon in icons"
|
||||
:key="icon.label"
|
||||
:rel="icon.rel"
|
||||
:title="icon.label"
|
||||
:aria-label="icon.label"
|
||||
:href="icon.href"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon
|
||||
v-if="icon.icon"
|
||||
:name="icon.icon"
|
||||
/>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<style lang="ts" scoped>
|
||||
css({
|
||||
a: {
|
||||
display: 'flex',
|
||||
color: '{color.gray.500}',
|
||||
padding: '{space.4}',
|
||||
|
||||
'@dark': {
|
||||
color: '{color.gray.400}'
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
color: '{color.gray.700}',
|
||||
'@dark': {
|
||||
color: '{color.gray.200}',
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
</style>
|
||||
3
apps/docs/components/Logo.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<img width="120" src="/img/nestri-logo-sm.svg"/>
|
||||
</template>
|
||||
70
apps/docs/components/content/Contributors.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
|
||||
|
||||
|
||||
<div class="py-8">
|
||||
<h2 class="text-3xl lg:text-4xl font-bold mb-12 text-gray-900">
|
||||
Contributors made <span class="text-orange-500">Nestri</span>
|
||||
</h2>
|
||||
<div class="grid grid-cols-4 sm:grid-cols-5 md:grid-cols-8 gap-4 sm:gap-5 lg:gap-6">
|
||||
<div
|
||||
v-for="(contributor, index) in contributors"
|
||||
:key="index"
|
||||
class="pt-[100%] relative"
|
||||
>
|
||||
<NuxtLink
|
||||
v-if="contributor.login"
|
||||
:key="contributor.login"
|
||||
:to="`https://github.com/${contributor.login}`"
|
||||
class="absolute inset-0 flex transition-all"
|
||||
:style="{
|
||||
'transition-delay': `${(index % 8 + Math.floor(index / 8)) * 20}ms`
|
||||
}"
|
||||
>
|
||||
<UTooltip class="w-full text-orange-500" :text="contributor.login">
|
||||
<NuxtImg
|
||||
:src="contributor.avatar_url"
|
||||
provider="ipx"
|
||||
densities="x1 x2"
|
||||
height="80px"
|
||||
width="80px"
|
||||
:alt="contributor.login"
|
||||
loading="lazy"
|
||||
class="rounded-xl w-full h-full transition lg:hover:scale-110"
|
||||
/>
|
||||
</UTooltip>
|
||||
<span class="inline-block rounded-t px-1 bg-gray-950 text-white absolute -bottom-2 right-0 font-medium text-sm">
|
||||
<span class="font-light text-xs text-gray-400">#</span>{{ index + 1 }}
|
||||
</span>
|
||||
|
||||
</NuxtLink>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const contributors = ref([])
|
||||
|
||||
// Fetch contributors data from GitHub without authentication
|
||||
const fetchContributors = async () => {
|
||||
try {
|
||||
const response = await fetch('https://api.github.com/repos/nestriness/nestri/contributors')
|
||||
if (!response.ok) throw new Error('Failed to fetch contributors')
|
||||
contributors.value = await response.json()
|
||||
} catch (error) {
|
||||
console.error('Error fetching contributors:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch contributors when component is mounted
|
||||
onMounted(fetchContributors)
|
||||
</script>
|
||||
<style>
|
||||
:hover.
|
||||
</style>
|
||||
55
apps/docs/content/0.index.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: Home
|
||||
navigation: false
|
||||
layout: page
|
||||
main:
|
||||
fluid: false
|
||||
---
|
||||
|
||||
:ellipsis{right=0px width=75% blur=150px}
|
||||
|
||||
::block-hero
|
||||
---
|
||||
cta:
|
||||
- Get started
|
||||
- /introduction/what-is-nestri
|
||||
|
||||
secondary:
|
||||
- Open on GitHub →
|
||||
- https://github.com/nestriness/nestri
|
||||
---
|
||||
|
||||
#title
|
||||
An open-source, self-hosted Geforce Now alternative.
|
||||
|
||||
#description
|
||||
Play your favorite games on the go or with your friends on your own game cloud.
|
||||
|
||||
#extra
|
||||
::list
|
||||
- **Selfhosted** cloud gaming
|
||||
- **Open Source** and **Free**
|
||||
- 1.5k ⭐️ on GitHub
|
||||
|
||||
|
||||
::
|
||||
|
||||
<!--#support
|
||||
::terminal
|
||||
---
|
||||
content:
|
||||
- npx nuxi@latest init -t themes/docus
|
||||
- cd docs
|
||||
- npm install
|
||||
- npm run dev
|
||||
---
|
||||
::-->
|
||||
::
|
||||
|
||||
|
||||
|
||||
::contributors
|
||||
|
||||
|
||||
|
||||
::
|
||||
21
apps/docs/content/1.introduction/1.what-is-nestri.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# What is Nestri?
|
||||
|
||||
Nestri is a self-hosted cloud gaming platform that enables you to spin up dedicated gaming sessions remotely and play your own games from any device with a browser. Unlike remote desktop solutions like Parsec, which focus on streaming a desktop environment, Nestri is designed specifically for cloud gaming. It works similarly to services like NVIDIA GeForce Now, allowing you to enjoy high-performance gaming without needing to be physically near your gaming PC.
|
||||
|
||||
The key difference with Nestri is that it’s entirely self-hosted, so you have full control over the server, the games you install, and the entire setup. Nestri is ideal for gamers who prioritize privacy, flexibility, and control, offering a way to manage your own gaming infrastructure rather than relying on third-party services. As long as you have a stable internet connection and access to a web browser, you can game from virtually anywhere.
|
||||
|
||||
|
||||
## Nestri Modules
|
||||
|
||||
To provide a smooth and efficient gaming experience, Nestri is composed of the following key components:
|
||||
|
||||
### Nestri Node
|
||||
The Nestri Node is the core of your Nestri setup. It acts as the game server where you install and run your games. The Nestri Node streams gameplay from the machine it’s installed on, allowing you to access your games remotely. It runs on most Linux-based systems and requires an NVIDIA graphics card to ensure a high-quality gaming experience.
|
||||
|
||||
Since Nestri Node cannot run alongside Xorg (the graphical interface), it’s recommended to install it on a dedicated machine. This way, your server can focus solely on streaming your games while avoiding conflicts with your local display setup.
|
||||
|
||||
### Nestri Relay
|
||||
The Nestri Relay is responsible for transporting the video stream from your Nestri Node to the device you're gaming on. By default, Nestri connects to the Nestri-hosted Relay, which requires no configuration and is available for all users. This simplifies the setup process, ensuring a smooth streaming experience without the need for advanced networking or SSL certificate management.
|
||||
|
||||
For advanced users, it's possible to self-host the relay, but this requires the setup of secure SSL certificates. This option is typically more complex and is recommended only for developers or those familiar with network configuration.
|
||||
|
||||
19
apps/docs/content/1.introduction/2.faq.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# FAQ
|
||||
|
||||
|
||||
## Is Nestri free?
|
||||
Yes! Nestri offers two options: a free, self-hosted version and a paid, hosted version.
|
||||
- Self-Hosted Version (Free): If you have your own server, you can install and run Nestri for free. Since Nestri is open-source, you have full access to the codebase, allowing for transparency and flexibility in your setup.
|
||||
- Hosted Version (Paid): The hosted version of Nestri operates similarly to services like NVIDIA GeForce Now. With a subscription, you can play your games on Nestri’s infrastructure without needing any technical knowledge—just sign up, log in, and start gaming!
|
||||
|
||||
## Does Nestri require a high-speed internet connection?
|
||||
Yes, a stable and fast internet connection is essential for a smooth gaming experience. While you don’t need extremely high speeds (like 1 Gbps fiber), low latency is critical. Since cloud gaming is sensitive to delay, your device needs to connect to one of our relays with minimal lag. Ensuring a strong, stable network connection close to a relay server is important to avoid delays in gameplay, especially during fast-paced action sequences.
|
||||
|
||||
## Where are Nestri’s relays located?
|
||||
Currently, we have one relay deployed in Helsinki, Finland. As we grow, we plan to add more relays to reduce latency and improve connection quality for users in different regions. Our next planned relay is in Copenhagen, Denmark. Since we’re a startup with a limited budget, we’ll continue to roll out more relays as demand grows and more users join the platform.
|
||||
|
||||
## Is Nestri like Parsec?
|
||||
No, Nestri is not like Parsec, which is used to access and game on an existing desktop remotely. Nestri is a server application designed specifically for cloud gaming. Rather than connecting to a physical Windows desktop, Nestri runs your games within a Docker or Podman container, allowing you to play remotely without needing to access a traditional desktop environment.
|
||||
|
||||
## Do I need a high-end server with a 4090 GPU and a 64-core CPU?
|
||||
Not necessarily! Nestri doesn’t have strict hardware requirements in terms of having the latest or most powerful CPU or GPU. Just as with traditional gaming, better hardware will enhance your experience with improved graphics and higher FPS. The exact specs you need will depend on the games you want to play and the performance you’re aiming for. Keep in mind that, because Nestri runs games on Linux using Proton and the Gstreamer encoding, there will be a bit of additional processing required, so some extra power will be helpful.
|
||||
2
apps/docs/content/1.introduction/_dir.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
icon: ph:star-duotone
|
||||
navigation.redirect: /introduction/what-is-nestri
|
||||
9
apps/docs/content/2.nestri-node/1.what-is-nestri-node.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# What is Nestri Node?
|
||||
|
||||
Nestri Node is the core component of Nestri's self-hosted cloud-gaming solution, designed for users who want the freedom and flexibility of running their own game-streaming server. Similar to services like NVIDIA GeForce Now, Nestri allows you to play your games remotely via your browser. However, unlike other cloud-gaming platforms, Nestri is fully self-hosted, giving you complete control over your server and gaming experience.
|
||||
|
||||
The Nestri Node is the actual server where you install your games. Once set up, you can stream and play your games remotely from any compatible device. It runs on machines with Linux and requires an NVIDIA, AMD or an Intel graphics card .
|
||||
## ⚠️ Important Note
|
||||
|
||||
We recommend not installing Nestri Node on your primary PC if you only intend to use it over a weekend. This is because Nestri Node cannot run simultaneously with Xorg, the display server responsible for managing the graphical user interface (GUI). This means that while Nestri Node is running, you will not be able to use an attached screen. For this reason, Nestri Node is best set up on a dedicated machine that won’t be used for other tasks.
|
||||
|
||||
53
apps/docs/content/2.nestri-node/2.prerequisite.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Prerequisite
|
||||
|
||||
To run Nestri on your own server, there are several essential preparations required before installing nestri-node. This page outlines the key requirements to get Nestri up and running smoothly.
|
||||
|
||||
Nestri-node supports AMD, NVIDIA, and Intel graphics cards. For optimal performance, however, we recommend using Intel or NVIDIA GPUs. Our testing has shown that these GPUs provide the best results, while AMD graphics cards may encounter limitations due to partial support for Arch Linux in AMD's AMF drivers. As a workaround, we utilize the VA-API plugin for GStreamer with AMD cards to ensure functionality.
|
||||
|
||||
While it might be tempting to skip this setup, we advise against it. Taking the time to prepare now will help you avoid potential issues and wasted hours later.
|
||||
|
||||
## Recommended host configuration
|
||||
|
||||
::list{type="primary"}
|
||||
- **NVIDIA or Intel GPU** (AMD is supported, but not reccomended, due to lack of natively supported API-drivers in CachyOS)
|
||||
- **AVX supported CPU** (If your CPU doesent support AVX, you can use our `noavx` image)
|
||||
- **Fedora or Arch** based distributions ( [Debian and Ubuntu is **not** supported](/nestri-node/node-faq#can-i-run-nestri-node-on-debianubuntu) )
|
||||
::
|
||||
|
||||
## Software Requirements
|
||||
|
||||
::list{type="primary"}
|
||||
- **Nvidia Drivers**
|
||||
- **[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt)**
|
||||
- **[Docker](https://linuxiac.com/how-to-install-docker-on-ubuntu-24-04-lts/)**
|
||||
|
||||
::
|
||||
|
||||
## Disconnect monitor
|
||||
Since Nestri requires access to your GPU, then you need to unplug you screen from it.
|
||||
If you want to see the Desktop and have a integrated graphicscard in your CPU, then you can connect your monitor to the motherboard.
|
||||
### Change the Default Boot Target to Multi-User (Non-GUI Mode)
|
||||
Ubuntu typically starts in graphical mode (using the graphical.target systemd target). You should change to the non-graphical multi-user.target, which will prevent Xorg from starting.
|
||||
|
||||
1. Open a terminal or access your system via SSH.
|
||||
2. To check your current default target (which should be graphical.target)
|
||||
|
||||
```bash
|
||||
systemctl get-default
|
||||
|
||||
```
|
||||
|
||||
3. Change the default target to multi-user.target (which corresponds to text mode, without Xorg):
|
||||
```bash
|
||||
sudo systemctl set-default multi-user.target
|
||||
|
||||
|
||||
```
|
||||
|
||||
4. Reboot the system
|
||||
|
||||
5. Verify that Xorg is not running
|
||||
```bash
|
||||
nvidia-smi
|
||||
```
|
||||
|
||||
101
apps/docs/content/2.nestri-node/3.getting-started.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Getting Started
|
||||
|
||||
::alert{type="danger"}
|
||||
Nestri is in a **very early-beta phase**, so errors and bugs may occur.
|
||||
::
|
||||
|
||||
### Step 0: Construct Your Docker Image
|
||||
Checkout your branch with the latest version of nestri and build the image `<your-nestri-image>` within git root folder:
|
||||
```bash
|
||||
docker buildx build -t <your-nestri-image>:latest -f Containerfile.runner .
|
||||
```
|
||||
|
||||
::alert{type="info"}
|
||||
You can right now also pull the docker image from DatHorse GitHub Containter Registry with:
|
||||
```bash
|
||||
docker pull ghcr.io/datcaptainhorse/nestri-cachyos:latest
|
||||
```
|
||||
::
|
||||
|
||||
### Step 1: Navigate to Your Game Directory
|
||||
First, change your directory to the location of your `.exe` file. For Steam games, this typically means:
|
||||
```bash
|
||||
cd $HOME/.steam/steam/steamapps
|
||||
ls -la .
|
||||
```
|
||||
### Step 2: Generate a Session ID
|
||||
Create a unique session ID using the following command:
|
||||
```bash
|
||||
echo "$(head /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | head -c 16)"
|
||||
```
|
||||
This command generates a random 16-character string. Be sure to note this string carefully, as you'll need it for the next step.
|
||||
### Step 3: Launch the Nestri Server
|
||||
With your SESSION_ID ready, insert it into the command below, replacing `<your_session_id>` with your actual session ID, also replace `<relay_url>` with your relay URL and `<your-nestri-image>` with your build nestri image or nestri remote image. Then run the command to start the Nestri server:
|
||||
|
||||
```bash
|
||||
docker run --rm -it --shm-size=1g --gpus all -e NVIDIA_DRIVER_CAPABILITIES=all --runtime=nvidia -e RELAY_URL='<relay_url>' -e NESTRI_ROOM=<your_session_id> -e RESOLUTION=1920x1080 -e FRAMERATE=60 -e NESTRI_PARAMS='--verbose=true --video-codec=h264 --video-bitrate=4000 --video-bitrate-max=6000'--name nestri -d -v "$(pwd)":/mnt/game/ <your-nestri-image>:latest
|
||||
```
|
||||
|
||||
### Step 4: Get Into your container
|
||||
Get into your container to start your game:
|
||||
```bash
|
||||
sudo docker exec -it nestri bash
|
||||
```
|
||||
### Step 5: Installing a Launcher
|
||||
For most games that are not DRM free you need a launcher. In this case use the umu launcher and optional mangohud:
|
||||
```bash
|
||||
pacman -S --overwrite="*" umu-launcher mangohud
|
||||
```
|
||||
|
||||
### Step 5: Running Your Game
|
||||
You have to execute your game now with nestri user. If you have a linux game just execute it with the nestri user
|
||||
```bash
|
||||
su nestri
|
||||
source /etc/nestri/envs.sh
|
||||
GAMEID=0 PROTONPATH=GE-Proton mangohud umu-run /mnt/game/<your-game.exe>
|
||||
```
|
||||
|
||||
### Step 6: Begin Playing
|
||||
Finally, construct the play URL with your session ID:
|
||||
`https://nestri.io/play/<your_session_id>`
|
||||
|
||||
Navigate to this URL in your browser, click on the page to capture your mouse pointer, and start playing!
|
||||
|
||||
::alert{type="info"}
|
||||
You can also use other relays/frontends depending on your choosen `<relay_url>`
|
||||
For testing you can use DatHorse Relay and Frontend:
|
||||
|
||||
| **Placeholder** | **URL** |
|
||||
| ---------------------------- | ---------- |
|
||||
| `<relay_url>` | `https://relay.dathorse.com/` |
|
||||
| `<frontend_url>` | `https://nestritest.dathorse.com/play/<your_session_id>` |
|
||||
::
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
Nestri Node is easy to install using the provided installation script. Follow the steps below to get started.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download the installation script using `wget`:
|
||||
|
||||
```bash
|
||||
wget https://github.com/nestriness/nestri/nestri-node-install.sh
|
||||
|
||||
```
|
||||
|
||||
2. Make the script executable:
|
||||
```bash
|
||||
chmod +x nestri-node-install.sh
|
||||
|
||||
|
||||
```
|
||||
3. Run the script to start the installation process:
|
||||
```bash
|
||||
./nestri-node-install.sh
|
||||
```
|
||||
::-->
|
||||
|
||||
|
||||
2
apps/docs/content/2.nestri-node/4.troubleshooting.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Troubleshooting
|
||||
|
||||
22
apps/docs/content/2.nestri-node/5.container-cli.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Container CLI
|
||||
The Container CLI for Nestri provides parameters to configure and manage your container environment. Use these options to set values like `relay-url`, `video resolution`, and `frame rate`. Additionally, activate `verbose` mode and logging to assist in debugging and error tracking. This documentation details each parameter to help you optimize your container setup effectively
|
||||
|
||||
|
||||
| **Parameter** | **Type** | **Default** | **Description** |
|
||||
| ---------------------------- | ---------- | --------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `-v, --verbose` | `string` | false | Shows more logs, for issues we recommend turning it on before running nestri-server and sending the logs for debugging (i.e. `nestri-server --verbose=true > logs.txt`) |
|
||||
| `-d, --debug-feed` | `string` | false | Adds a timer overlay at bottom-right in the video stream, along with spawning an X11 window on host for doing comparisons against |
|
||||
| `-u, --relay-url` | `string` | https://relay.fst.so | [MoQ relay](/nestri-relay/what-is-nestri-node) endpoint URL (must begin with `https://` as MoQ __can't work with unsafe connections__) |
|
||||
| `-p, --relay-path` | `string` | default generated on start if not set | namespace/path for the stream, identifies the stream (basically stream name), must be unique |
|
||||
| **Video** | | | |
|
||||
| `-r, --resolution ` | `string` | 1280x720 | Sets nestri virtual display + stream resolution using `WIDTHxHEIGHT` format |
|
||||
| `-f, --framerate` | `integer` | 60 | Framerate for nestri virtual display + stream |
|
||||
| `-g, --gpu-vendor` | `string` | | allows selecting specific GPU by vendor name (`nvidia`, `amd` or `intel`) |
|
||||
| `-i, --gpu-index` | `string` | | allows selecting a GPU by it's general name, doesn't have to be full name as it's matched partially (i.e. `3060` would get you `RTX 3060` GPU, but it would also let `RTX 3060 Ti` pass) |
|
||||
| `-a, --gpu-card-path` | `string` | | allows specifying GPU by `/dev/dri/cardX` or `/dev/dri/renderX` path, this won't work with the other 3 gpu parameters as it's explicitly setting the GPU |
|
||||
| **Encoder** | | | |
|
||||
| `-c, --encoder-vcodec` | `string` | h264 | Sets the stream video codec (`h264` or `av1`) |
|
||||
| `-t, --encoder-type` | `string` | hardware | Sets whether to use GPU encoder (`hardware`), or CPU encoder (`software`, only should be used with debugging or if GPU has no encoding capabilities) |
|
||||
| `-e, --encoder-name` | `string` | | forces a specific encoder by GStreamer element name (i.e. `vah264enc`) |
|
||||
| `-q, --encoder-cqp` | `string` | 25 | sets the stream quality level, lower means higher quality and much more bitrate used |
|
||||
|
||||
12
apps/docs/content/2.nestri-node/6.node-faq.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Node FAQ
|
||||
|
||||
This FAQ is made to address common questions about Nestri Node, the container which runs your games. Whether you're curious about compatibility, setup, or performance, you'll find answers to help you get started..
|
||||
|
||||
## Can I run Nestri Node on Debian/Ubuntu? :icon{name="logos:ubuntu" style="opacity:100"} :icon{name="logos:debian" style="opacity:100"}
|
||||
Unfortunately, it is not possible to run Nestri Node on Debian-based distributions like Ubuntu at this time. After extensive debugging efforts, we have decided to focus on platforms that currently work well, such as Fedora and Arch-based distributions. We may revisit the possibility of supporting Debian in the future, but for now, it is not supported.
|
||||
|
||||
## Can I run Nestri Node in a virtualized environment like Proxmox?
|
||||
Yes, you can run Nestri Node in a virtualized environment, provided you passthrough your GPU to the virtual machine. However, we do not recommend this setup as virtualization may introduce additional overhead and latency. For the best performance, we recommend running Nestri Node on bare-metal hardware.
|
||||
|
||||
## Can I run Nestri Node on Windows-based systems?
|
||||
No, the Nestri Node service does not support Windows-based systems. It can only be deployed on Linux servers.
|
||||
2
apps/docs/content/2.nestri-node/_dir.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
title: 'Nestri Node'
|
||||
icon: heroicons-outline:bookmark-alt
|
||||
@@ -0,0 +1,9 @@
|
||||
# What is Nestri Relay?
|
||||
|
||||
Nestri Relay is an essential component in the Nestri cloud-gaming ecosystem, responsible for transporting the video gameplay stream from your Nestri Node to the device you’re playing on. It is built on the moq-rs protocol, designed for efficient and smooth video transmission, ensuring a low-latency gaming experience.
|
||||
|
||||
By default, your Nestri Node will connect to the Nestri-hosted Relay, which we manage and is available for all users. This is the simplest and most straightforward option, requiring no additional configuration on your end.
|
||||
## ⚠️ Important Note
|
||||
|
||||
We recommend not installing Nestri Node on your primary PC if you only intend to use it over a weekend. This is because Nestri Node cannot run simultaneously with Xorg, the display server responsible for managing the graphical user interface (GUI). This means that while Nestri Node is running, you will not be able to use an attached screen. For this reason, Nestri Node is best set up on a dedicated machine that won’t be used for other tasks.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
## Self-hosted Nestri Relay
|
||||
|
||||
For those who prefer full control over their infrastructure, it is possible to self-host the Nestri Relay. However, setting this up can be a bit complex, as it requires generating SSL certificates for secure communication between your Nestri Node and your gaming devices. There are three main options:
|
||||
|
||||
- **Let's Encrypt Certificate**: This is the **recommended option** for self-hosting and requires a domain name. You can generate a certificate using tools like **certbot** or **acme.sh**. Let's Encrypt provides free SSL certificates that are trusted by most browsers and are relatively straightforward to set up.
|
||||
|
||||
- **Purchased SSL Certificate**: The **easiest option** for most users is to buy an SSL certificate from a trusted Certificate Authority (CA). This option eliminates much of the hassle involved with certificate generation, as these certificates are already trusted by browsers and don’t require as much manual setup.
|
||||
|
||||
While self-hosting offers more flexibility, most users will find the **Nestri-hosted Relay** to be the easiest and most reliable option for getting started with cloud gaming on Nestri. This hosted relay is available to everyone and requires no configuration.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Server Requirements:**
|
||||
- Ensure **port 443** is open for both **TCP and UDP** (`:443/udp & :443/tcp`).
|
||||
- The server should have at least **4GB RAM** and **2 vCPUs**.
|
||||
- Supports both ARM or AMD64 architecture.
|
||||
|
||||
2. **Software Requirements:**
|
||||
- Docker and `docker-compose` must be installed on the server. You can use [this installation script](https://github.com/docker/docker-install) to set up Docker.
|
||||
- Git must be installed to clone the necessary repository.
|
||||
|
||||
3. **Certificates:**
|
||||
- You will need both private and public SSL certificates. It is recommended to use certificates from a **trusted Certificate Authority** (CA), either by using **Let's Encrypt** or purchasing a commercial SSL certificate, for secure communication. Avoid using self-signed certificates, as they can lead to compatibility issues and security warnings in browsers.
|
||||
69
apps/docs/content/3.nestri-relay/3.deploy-moq.md
Normal file
@@ -0,0 +1,69 @@
|
||||
## Installation Steps
|
||||
|
||||
### Step 1: Clone the Repository
|
||||
|
||||
Clone the `kixelated/moq-rs` repository to your local machine:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kixelated/moq-rs moq
|
||||
```
|
||||
|
||||
### Step 2: Verify Port Availability
|
||||
|
||||
Check if port 443 is already in use on your server:
|
||||
|
||||
```bash
|
||||
sudo netstat -tulpn | grep ':443' | grep LISTEN
|
||||
```
|
||||
or
|
||||
```bash
|
||||
sudo lsof -i -P -n | grep LISTEN | grep 443
|
||||
```
|
||||
|
||||
If you find any processes using port 443, consider terminating them.
|
||||
|
||||
### Step 3: Configure Ports
|
||||
|
||||
Navigate to the cloned directory and edit the Docker compose file to use port 443:
|
||||
|
||||
```bash
|
||||
cd moq
|
||||
vim docker-compose.yml
|
||||
```
|
||||
|
||||
Change the ports section from lines 34 to 35 to:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
```
|
||||
|
||||
### Step 4: Prepare Certificates
|
||||
|
||||
Copy your generated certificates into the `moq/dev` directory and rename them:
|
||||
|
||||
```bash
|
||||
cp cert.pem moq/dev/localhost.crt
|
||||
cp key.pem moq/dev/localhost.key
|
||||
```
|
||||
|
||||
### Step 5: Start Docker Instances
|
||||
|
||||
Ensure you are in the root directory of the `moq` project, then start the Docker containers:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Step 6: Link Domain to Server IP
|
||||
|
||||
Configure your DNS settings to connect your server's IP address to your domain:
|
||||
|
||||
```
|
||||
Record Type: A
|
||||
Subdomain: relay.fst.so
|
||||
IP Address: xx.xxx.xx.xxx
|
||||
```
|
||||
|
||||
Congratulations, your MoQ server is now set up! You can verify its functionality by using the [MoQ Checker](https://nestri.pages.dev/moq/checker).
|
||||
42
apps/docs/content/3.nestri-relay/4.advanced-users.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# ⚠️ Advanced users
|
||||
|
||||
## Generating an SSL Certificate for Nestri Relay
|
||||
|
||||
This guide is for developers and advanced users who wish to self-host Nestri Relay. We strongly discourage this setup for general users due to its complexity, particularly when it comes to configuring SSL certificates correctly. Using a self-signed certificate or manually generating certificates can lead to issues with browser compatibility and security warnings, making it difficult to ensure a smooth experience.
|
||||
|
||||
For most users, we highly recommend using the **Nestri-hosted Relay**, which requires no manual setup and is ready to use out of the box.
|
||||
|
||||
---
|
||||
|
||||
## Generating an SSL Certificate Using Terraform
|
||||
|
||||
If you still wish to proceed with self-hosting, we recommend using Terraform to generate a valid SSL certificate. This method provides a secure, automated way to obtain the necessary certificates for Nestri Relay.
|
||||
|
||||
### Usage
|
||||
|
||||
1. **Update the `terraform.tfvars`** file with your domain and email.
|
||||
2. Run the following command to initialize the Terraform working directory:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
```bash
|
||||
terraform plan
|
||||
```
|
||||
```bash
|
||||
terraform apply
|
||||
```
|
||||
The configuration provides two sensitive outputs:
|
||||
```bash
|
||||
certificate_pem: The full certificate chain
|
||||
private_key_pem: The private key for the certificate
|
||||
```
|
||||
|
||||
These can be then be used in your `moq-relay` as it requires SSL/TLS certificates.
|
||||
|
||||
## Note
|
||||
The generated certificate and key files are saved locally and ignored by git:
|
||||
```git
|
||||
.terraform
|
||||
relay_*
|
||||
```
|
||||
4
apps/docs/content/3.nestri-relay/5.moq-tester.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## MOQ Tester
|
||||
Test your Nestri Relay, with our MOQ tester tool.
|
||||
|
||||
:button-link[Try MOQ Test Tool]{size="small" icon="IconStackBlitz" href="https://nestri.pages.dev/moq/checker" blank}
|
||||
2
apps/docs/content/3.nestri-relay/_dir.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
title: 'Nestri Relay'
|
||||
icon: heroicons-outline:bookmark-alt
|
||||
14
apps/docs/nuxt.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export default defineNuxtConfig({
|
||||
// https://github.com/nuxt-themes/docus
|
||||
extends: ['@nuxt-themes/docus'],
|
||||
components: true,
|
||||
|
||||
|
||||
devtools: { enabled: true },
|
||||
|
||||
modules: [// Remove it if you don't use Plausible analytics
|
||||
// https://github.com/nuxt-modules/plausible
|
||||
'@nuxtjs/plausible', '@nuxt/ui'],
|
||||
|
||||
compatibilityDate: '2024-09-29'
|
||||
})
|
||||
19811
apps/docs/package-lock.json
generated
Normal file
22
apps/docs/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "docus-starter",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"nestri.dev": "nuxi dev",
|
||||
"build": "nuxi build",
|
||||
"generate": "nuxi generate",
|
||||
"preview": "nuxi preview",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt-themes/docus": "latest",
|
||||
"@nuxt/devtools": "^1.4.1",
|
||||
"@nuxt/eslint-config": "^0.5.6",
|
||||
"@nuxt/ui": "^2.19.2",
|
||||
"@nuxtjs/plausible": "^1.0.2",
|
||||
"@types/node": "^20.16.5",
|
||||
"eslint": "^9.10.0",
|
||||
"nuxt": "^3.15.4"
|
||||
}
|
||||
}
|
||||
BIN
apps/docs/public/cover.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
apps/docs/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
1
apps/docs/public/img/nestri-logo-sm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 167 44" width="167" height="44"><defs><image width="47" height="36" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAkCAMAAAAuPpNdAAAAAXNSR0IB2cksfwAAAEJQTFRF/1gO/1MG/1MG/1UJ/08B/08B/14X/1oQ/1oQAAAA/18Z/1oR/1oR/1kP/1MH/1MH/2ck/2Me/2Me/24v/2sq/2sqUcSXkwAAABZ0Uk5T//+f//+fp6hpACsrG3BwRmdoQUpKLmJsmB4AAAA6SURBVHicY2RgZCABMDIyj6ofUPVsJKrnJEU5UAOp6rkGWfiMqqeuet5Blt4EBln4jKqnrnph0tQDAHjbARfH6mW/AAAAAElFTkSuQmCC"/></defs><style>.a{fill:#0a0a0a}</style><use href="#img1" x="6" y="4"/><path class="a" d="m69.2 34h-5.8v-24h7.9l8.5 16.3h0.1v-16.3h5.8v24h-7.4l-9-16.8h-0.1zm28.4 0.5q-2.8 0-4.6-0.7-1.8-0.8-3-2.2-1.1-1.3-1.6-3.1-0.5-1.7-0.5-3.6 0-2.1 0.5-4 0.6-1.9 1.7-3.3 1.1-1.5 2.8-2.4 1.8-0.8 4.3-0.8 2.5 0 4.2 0.8 1.8 0.9 2.8 2.4 1.1 1.5 1.4 3.5 0.3 2-0.1 4.3l-13.9 0.2v-3.1l9.4-0.2-0.8 1.8q0.3-1.6 0-2.8-0.3-1.1-1-1.7-0.7-0.6-2-0.6-1.4 0-2.1 0.7-0.8 0.7-1.2 1.9-0.3 1.3-0.3 3 0 2.9 1 4.2 1 1.4 3 1.4 0.9 0 1.4-0.2 0.6-0.2 1-0.6 0.3-0.5 0.5-1.1 0.1-0.6 0.1-1.3l5.4 0.2q0.1 1.2-0.3 2.5-0.3 1.3-1.3 2.4-0.9 1.1-2.6 1.8-1.7 0.6-4.2 0.6zm18.7 0q-1.9 0-3.6-0.3-1.6-0.4-2.8-1.3-1.2-0.8-1.9-2.2-0.6-1.4-0.5-3.4l5.1-0.4q0.1 1.2 0.6 2 0.4 0.7 1.3 1.1 0.8 0.4 2 0.4 1.1 0 1.9-0.4 0.9-0.4 0.9-1.3 0-0.5-0.3-0.8-0.3-0.3-1.1-0.5-0.8-0.3-2.3-0.7-1.8-0.5-3.3-0.9-1.5-0.5-2.6-1.2-1-0.6-1.5-1.6-0.6-0.9-0.6-2.4 0-2 1.1-3.3 1-1.4 2.9-2.2 1.9-0.7 4.4-0.7 2.2 0 4.1 0.7 2 0.6 3 2.2 1.2 1.6 0.9 4.1l-5 0.5q0.1-1-0.3-1.8-0.4-0.7-1.2-1.1-0.7-0.4-1.8-0.4-1.3 0-2 0.5-0.6 0.4-0.6 1.1 0 0.5 0.4 0.9 0.4 0.4 1.3 0.7 0.9 0.3 2.3 0.6 1.3 0.2 2.6 0.6 1.3 0.4 2.5 1.1 1.2 0.7 1.9 1.8 0.7 1.1 0.7 2.7 0 1.8-1 3.1-0.9 1.4-2.8 2.1-1.9 0.7-4.7 0.7zm18.1 0q-3.4 0-5.1-1.7-1.6-1.8-1.6-5.4v-8h-2.1v-3.7h0.1q2.2-0.2 3.2-1.4 0.9-1.3 1.1-3.7v-0.1h3.5v4.4h4.4v4.7h-4.4v7.2q0 1.4 0.6 2 0.7 0.6 1.7 0.6 0.5 0 1.1-0.2 0.5-0.1 1-0.4v5.2q-1.1 0.3-2 0.4-0.9 0.1-1.5 0.1zm11.5-0.5h-5.8v-10.4-8.7h5v7.6h0.3q0.2-3.1 0.9-4.8 0.6-1.8 1.6-2.5 0.9-0.8 2.1-0.8 0.7 0 1.4 0.2 0.7 0.2 1.4 0.6l-0.3 6.5q-0.8-0.4-1.6-0.7-0.7-0.2-1.4-0.2-1.2 0-2 0.6-0.8 0.7-1.2 2-0.4 1.2-0.4 3zm14.5 0h-5.8v-19.1h5.8zm-2.9-20.6q-1.7 0-2.6-0.6-0.9-0.8-0.9-2.1 0-1.4 0.9-2.1 0.9-0.7 2.6-0.7 1.7 0 2.6 0.7 0.9 0.7 0.9 2.1 0 1.3-0.9 2-0.9 0.7-2.6 0.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
BIN
apps/docs/public/img/nestri-logo.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
1
apps/docs/public/img/nestri-logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1080 1080" width="1080" height="1080"><defs><image width="308" height="234" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATQAAADqCAMAAAAbHElGAAAAAXNSR0IB2cksfwAAADNQTFRF/5Bf/2wr/3tB/08B/4VQ/2Uh/9K//9K/AAAA/5xw/3tA/5Fg/2wr/5Zo/4NN/9K//9K/u/+9NwAAABF0Uk5T/f////H/HCsAVVWAgLjVOVVGDSqkAAACDElEQVR4nO3cQQrCAAxFwUaKKCK9/217hryNCDMnCG/7IXPMwdI8RFsTLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLZhTtLV5irY2r19f8IdEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAvmbSNYM+EFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBfMRbc2nvkC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0QLRAtEC0YL6GlTUTXiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaIFogWiBaMKdoa3OJtnYDtq8EmnzQ7p8AAAAASUVORK5CYII="/></defs><style>.a{fill:#0a0a0a}</style><use href="#img1" x="8" y="423"/><path class="a" d="m426 624h-38.4v-158.4h52.1l56.4 107.3h0.5v-107.3h38.4v158.4h-49l-59.5-110.9h-0.5zm187.4 3.4q-18 0-30.2-5.1-12-5.2-19.4-14.1-7.5-9.1-10.8-20.7-3.2-11.5-3.2-24.2 0-13.7 3.4-26.2 3.6-12.4 10.8-22 7.4-9.9 19-15.4 11.7-5.8 28-5.8 16.4 0 27.9 5.8 11.7 5.5 18.7 15.6 7 10.1 8.9 23.3 2.1 13.2-0.5 28.5l-91.9 1.5v-21.1l62.1-1.2-5 12.2q1.4-11-0.5-18.5-1.7-7.7-6.5-11.5-4.8-4.1-13.2-4.1-8.8 0-14.1 4.6-5.3 4.5-7.5 12.9-2.1 8.2-2.1 19.5 0 19.4 6.5 28.3 6.4 8.9 19.9 8.9 5.7 0 9.6-1.5 3.8-1.4 6.2-4 2.4-2.9 3.4-6.8 0.9-4 0.7-9.1l35.5 1.9q0.7 8-1.7 16.4-2.1 8.4-8.4 15.6-6.2 7.2-17.5 11.7-11 4.6-28.1 4.6zm124.1 0q-12.7 0-23.7-2.4-10.8-2.7-19-8.2-7.9-5.5-12.2-14.6-4.1-9.4-3.4-22.6l33.8-2.9q0.5 8 3.6 13.2 3.2 5.1 8.7 7.5 5.5 2.4 13.4 2.4 7.5 0 12.7-2.4 5.6-2.7 5.6-8.7 0-3.1-2-5-1.9-2.2-7.2-3.8-5-2-14.8-4.4-12.3-3.1-22.1-6.2-9.9-3.1-16.8-7.4-7-4.4-10.6-10.6-3.6-6.5-3.6-15.8 0-13.2 7-22.4 7.2-9.3 19.7-14.1 12.4-5.1 28.8-5.1 14.6 0 27.3 4.6 12.7 4.6 19.9 14.9 7.5 10.3 5.6 27.3l-33.2 3.2q0.8-7-1.9-11.8-2.6-5-7.7-7.4-5-2.7-12.2-2.7-8.2 0-12.7 3.1-4.3 2.9-4.3 7.5 0 3.6 2.6 6.2 2.9 2.4 8.6 4.3 6 1.7 15.4 3.9 8.2 1.7 17 4.3 8.9 2.6 16.6 7.2 7.7 4.3 12.5 11.5 4.8 7.2 4.8 18.3 0 11.7-6.5 20.6-6.5 8.9-19 13.7-12.4 4.8-30.7 4.8zm119.3-0.5q-22.3 0-33.4-11.3-10.8-11.5-10.8-35.5v-52.6h-13.9v-24.4h0.7q14.9-2 21.2-9.9 6.2-8.1 7.6-24.5v-0.4h22.8v29h29.1v31.2h-29.1v48q0 9.1 4.4 13 4.5 3.8 11 3.8 3.4 0 7-1 3.6-0.9 6.7-2.6v33.8q-7.5 2.2-13.2 2.9-5.8 0.5-10.1 0.5zm76.3-2.9h-38.6v-68.9-57.8h33.6v50.4h1.9q1.4-20.2 5.5-31.7 4.3-11.7 10.6-16.5 6.5-5.1 14.4-5.1 4.3 0 8.9 1.2 4.8 1.2 9.3 3.9l-1.9 43.2q-5.3-3.2-10.3-4.6-5.1-1.7-9.6-1.7-7.7 0-13 4.3-5.3 4.4-8.1 12.8-2.7 8.4-2.7 20.4zm96.3 0h-38.9v-126.8h38.9zm-19.7-135.8q-11.1 0-17.1-4.6-5.7-4.8-5.7-13.6 0-9.2 5.7-13.7 6-4.8 17.1-4.8 11.3 0 17 4.8 6 4.8 6 13.7 0 8.6-6 13.4-5.7 4.8-17 4.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
6
apps/docs/renovate.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": ["github>nuxt/renovate-config-nuxt"],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
9
apps/docs/sst-env.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/* This file is auto-generated by SST. Do not edit. */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/* deno-fmt-ignore-file */
|
||||
|
||||
/// <reference path="../../sst-env.d.ts" />
|
||||
|
||||
import "sst"
|
||||
export {}
|
||||
218
apps/docs/tokens.config.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
import { defineTheme } from 'pinceau'
|
||||
|
||||
export default defineTheme({
|
||||
color: {
|
||||
black: '#0B0A0A',
|
||||
// Primary is modified lightblue
|
||||
primary: {
|
||||
50: '#fff6ec',
|
||||
100: '#ffebd3',
|
||||
200: '#ffd4a5',
|
||||
300: '#ffb56d',
|
||||
400: '#ff8a32',
|
||||
500: '#ff680a',
|
||||
600: '#ff4f01',
|
||||
700: '#cc3602',
|
||||
800: '#a12b0b',
|
||||
900: '#82260c'
|
||||
},
|
||||
gray: {
|
||||
50: '#FBFBFB',
|
||||
100: '#F6F5F4',
|
||||
200: '#ECEBE8',
|
||||
300: '#DBD9D3',
|
||||
400: '#ADA9A4',
|
||||
500: '#97948F',
|
||||
600: '#67635D',
|
||||
700: '#36332E',
|
||||
800: '#201E1B',
|
||||
900: '#121110'
|
||||
},
|
||||
red: {
|
||||
50: '#FFF9F8',
|
||||
100: '#FFF3F0',
|
||||
200: '#FFDED7',
|
||||
300: '#FFA692',
|
||||
400: '#FF7353',
|
||||
500: '#FF3B10',
|
||||
600: '#BB2402',
|
||||
700: '#701704',
|
||||
800: '#340A01',
|
||||
900: '#1C0301'
|
||||
},
|
||||
blue: {
|
||||
50: '#F2FAFF',
|
||||
100: '#DFF3FF',
|
||||
200: '#C6EAFF',
|
||||
300: '#A1DDFF',
|
||||
400: '#64C7FF',
|
||||
500: '#1AADFF',
|
||||
600: '#0069A6',
|
||||
700: '#014267',
|
||||
800: '#002235',
|
||||
900: '#00131D'
|
||||
},
|
||||
green: {
|
||||
50: '#ECFFF7',
|
||||
100: '#DEFFF1',
|
||||
200: '#C3FFE6',
|
||||
300: '#86FBCB',
|
||||
400: '#3CEEA5',
|
||||
500: '#0DD885',
|
||||
600: '#00B467',
|
||||
700: '#006037',
|
||||
800: '#002817',
|
||||
900: '#00190F'
|
||||
},
|
||||
yellow: {
|
||||
50: '#FFFCEE',
|
||||
100: '#FFF6D3',
|
||||
200: '#FFF0B1',
|
||||
300: '#FFE372',
|
||||
400: '#FFDC4E',
|
||||
500: '#FBCA05',
|
||||
600: '#CBA408',
|
||||
700: '#614E02',
|
||||
800: '#292100',
|
||||
900: '#1B1500'
|
||||
},
|
||||
shadow: {
|
||||
initial: '{color.gray.400}',
|
||||
dark: '{color.gray.800}'
|
||||
}
|
||||
},
|
||||
shadow: {
|
||||
xs: '0px 1px 2px 0px {color.shadow}',
|
||||
sm: '0px 1px 3px 0px {color.shadow}, 0px 1px 2px -1px {color.shadow}',
|
||||
md: '0px 4px 6px -1px {color.shadow}, 0px 2px 4px -2px {color.shadow}',
|
||||
lg: '0px 10px 15px -3px {color.shadow}, 0px 4px 6px -4px {color.shadow}',
|
||||
xl: '0px 20px 25px -5px {color.shadow}, 0px 8px 10px -6px {color.shadow}',
|
||||
'2xl': '0px 25px 50px -12px {color.shadow}',
|
||||
none: '0px 0px 0px 0px transparent'
|
||||
},
|
||||
docus: {
|
||||
$schema: {
|
||||
title: 'All the configurable tokens from Docus.',
|
||||
tags: [
|
||||
'@studioIcon material-symbols:docs'
|
||||
]
|
||||
},
|
||||
body: {
|
||||
backgroundColor: {
|
||||
initial: '{color.white}',
|
||||
dark: '{color.black}'
|
||||
},
|
||||
color: {
|
||||
initial: '{color.gray.800}',
|
||||
dark: '{color.gray.200}'
|
||||
},
|
||||
fontFamily: '{font.sans}'
|
||||
},
|
||||
header: {
|
||||
height: '64px',
|
||||
logo: {
|
||||
height: {
|
||||
initial: '{space.6}',
|
||||
sm: '{space.7}'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
fontSize: '{fontSize.2xl}',
|
||||
fontWeight: '{fontWeight.bold}',
|
||||
color: {
|
||||
static: {
|
||||
initial: '{color.gray.900}',
|
||||
dark: '{color.gray.100}',
|
||||
},
|
||||
hover: '{color.primary.500}',
|
||||
}
|
||||
}
|
||||
},
|
||||
footer: { height: { initial: '145px', sm: '100px' }, padding: '{space.4} 0' },
|
||||
readableLine: '78ch',
|
||||
loadingBar: {
|
||||
height: '3px',
|
||||
gradientColorStop1: '#00dc82',
|
||||
gradientColorStop2: '#34cdfe',
|
||||
gradientColorStop3: '#0047e1'
|
||||
},
|
||||
search: {
|
||||
backdropFilter: 'blur(24px)',
|
||||
input: {
|
||||
borderRadius: '{radii.2xs}',
|
||||
borderWidth: '1px',
|
||||
borderStyle: 'solid',
|
||||
borderColor: {
|
||||
initial: '{color.gray.200}',
|
||||
dark: 'transparent'
|
||||
},
|
||||
fontSize: '{fontSize.sm}',
|
||||
gap: '{space.2}',
|
||||
padding: '{space.2} {space.4}',
|
||||
backgroundColor: {
|
||||
initial: '{color.gray.200}',
|
||||
dark: '{color.gray.800}'
|
||||
},
|
||||
},
|
||||
results: {
|
||||
window: {
|
||||
marginX: {
|
||||
initial: '0',
|
||||
sm: '{space.4}'
|
||||
},
|
||||
borderRadius: {
|
||||
initial: 'none',
|
||||
sm: '{radii.xs}'
|
||||
},
|
||||
marginTop: {
|
||||
initial: '0',
|
||||
sm: '20vh'
|
||||
},
|
||||
maxWidth: '640px',
|
||||
maxHeight: {
|
||||
initial: '100%',
|
||||
sm: '320px'
|
||||
},
|
||||
},
|
||||
selected: {
|
||||
backgroundColor: {
|
||||
initial: '{color.gray.300}',
|
||||
dark: '{color.gray.700}'
|
||||
},
|
||||
},
|
||||
highlight: {
|
||||
color: 'white',
|
||||
backgroundColor: '{color.primary.500}'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
typography: {
|
||||
color: {
|
||||
primary: {
|
||||
50: '{color.primary.50}',
|
||||
100: '{color.primary.100}',
|
||||
200: '{color.primary.200}',
|
||||
300: '{color.primary.300}',
|
||||
400: '{color.primary.400}',
|
||||
500: '{color.primary.500}',
|
||||
600: '{color.primary.600}',
|
||||
700: '{color.primary.700}',
|
||||
800: '{color.primary.800}',
|
||||
900: '{color.primary.900}'
|
||||
},
|
||||
secondary: {
|
||||
50: '{color.gray.50}',
|
||||
100: '{color.gray.100}',
|
||||
200: '{color.gray.200}',
|
||||
300: '{color.gray.300}',
|
||||
400: '{color.gray.400}',
|
||||
500: '{color.gray.500}',
|
||||
600: '{color.gray.600}',
|
||||
700: '{color.gray.700}',
|
||||
800: '{color.gray.800}',
|
||||
900: '{color.gray.900}'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
4
apps/docs/tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
// "extends": "./.nuxt/tsconfig.json",
|
||||
"ignoreConfigErrors": true
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "qwik-project-name",
|
||||
"scripts": {
|
||||
"build": "qwik build",
|
||||
"build.client": "vite build",
|
||||
"build.preview": "vite build --ssr src/entry.preview.tsx",
|
||||
"build.types": "tsc --incremental --noEmit",
|
||||
"dev": "vite --mode ssr",
|
||||
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
|
||||
"fmt": "prettier --write .",
|
||||
"fmt.check": "prettier --check .",
|
||||
"lint": "eslint \"src/**/*.ts*\"",
|
||||
"preview": "qwik build preview && vite preview --open",
|
||||
"start": "vite --open --mode ssr",
|
||||
"deploy": "echo 'Run \"npm run qwik add\" to install a server adapter'",
|
||||
"qwik": "qwik"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/qwik": "^1.5.1",
|
||||
"@builder.io/qwik-city": "^1.5.1",
|
||||
"@types/eslint": "^8.56.5",
|
||||
"@types/node": "^20.11.24",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-qwik": "^1.5.1",
|
||||
"prettier": "^3.2.5",
|
||||
"typescript": "5.3.3",
|
||||
"undici": "*",
|
||||
"vite": "^5.1.4",
|
||||
"vite-tsconfig-paths": "^4.2.1"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
"sharp"
|
||||
],
|
||||
"trustedDependencies-annotation": "Needed for bun to allow running install scripts",
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=10.0.0",
|
||||
"pnpm": ">=8.0.0",
|
||||
"yarn": ">=3.0.0"
|
||||
},
|
||||
"engines-annotation": "Mostly required by sharp which needs a Node-API v9 compatible runtime",
|
||||
"private": true,
|
||||
"type": "module"
|
||||
}
|
||||
@@ -35,8 +35,8 @@ module.exports = {
|
||||
"prefer-spread": "off",
|
||||
"no-case-declarations": "off",
|
||||
"no-console": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["warn"],
|
||||
"@typescript-eslint/no-unused-vars": ["error"],
|
||||
"@typescript-eslint/consistent-type-imports": "warn",
|
||||
"@typescript-eslint/no-unnecessary-condition": "warn",
|
||||
},
|
||||
};
|
||||
};
|
||||
8
apps/www/.gitignore
vendored
@@ -40,5 +40,9 @@ lerna-debug.log*
|
||||
.yarn/*
|
||||
!.yarn/releases
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
# Cloudflare
|
||||
functions/**/*.js
|
||||
|
||||
#Typescript
|
||||
*.tsbuildinfo
|
||||
tmp
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default {
|
||||
plugins: ['prettier-plugin-tailwindcss'],
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
# Qwik City App ⚡️
|
||||
|
||||
- [Qwik Docs](https://qwik.builder.io/)
|
||||
- [Discord](https://qwik.builder.io/chat)
|
||||
- [Qwik GitHub](https://github.com/BuilderIO/qwik)
|
||||
- [Qwik Docs](https://qwik.dev/)
|
||||
- [Discord](https://qwik.dev/chat)
|
||||
- [Qwik GitHub](https://github.com/QwikDev/qwik)
|
||||
- [@QwikDev](https://twitter.com/QwikDev)
|
||||
- [Vite](https://vitejs.dev/)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## Project Structure
|
||||
|
||||
This project is using Qwik with [QwikCity](https://qwik.builder.io/qwikcity/overview/). QwikCity is just an extra set of tools on top of Qwik to make it easier to build a full site, including directory-based routing, layouts, and more.
|
||||
This project is using Qwik with [QwikCity](https://qwik.dev/qwikcity/overview/). QwikCity is just an extra set of tools on top of Qwik to make it easier to build a full site, including directory-based routing, layouts, and more.
|
||||
|
||||
Inside your project, you'll see the following directory structure:
|
||||
|
||||
@@ -24,7 +24,7 @@ Inside your project, you'll see the following directory structure:
|
||||
└── ...
|
||||
```
|
||||
|
||||
- `src/routes`: Provides the directory-based routing, which can include a hierarchy of `layout.tsx` layout files, and an `index.tsx` file as the page. Additionally, `index.ts` files are endpoints. Please see the [routing docs](https://qwik.builder.io/qwikcity/routing/overview/) for more info.
|
||||
- `src/routes`: Provides the directory-based routing, which can include a hierarchy of `layout.tsx` layout files, and an `index.tsx` file as the page. Additionally, `index.ts` files are endpoints. Please see the [routing docs](https://qwik.dev/qwikcity/routing/overview/) for more info.
|
||||
|
||||
- `src/components`: Recommended directory for components.
|
||||
|
||||
@@ -32,10 +32,10 @@ Inside your project, you'll see the following directory structure:
|
||||
|
||||
## Add Integrations and deployment
|
||||
|
||||
Use the `pnpm qwik add` command to add additional integrations. Some examples of integrations includes: Cloudflare, Netlify or Express Server, and the [Static Site Generator (SSG)](https://qwik.builder.io/qwikcity/guides/static-site-generation/).
|
||||
Use the `bun qwik add` command to add additional integrations. Some examples of integrations includes: Cloudflare, Netlify or Express Server, and the [Static Site Generator (SSG)](https://qwik.dev/qwikcity/guides/static-site-generation/).
|
||||
|
||||
```shell
|
||||
pnpm qwik add # or `pnpm qwik add`
|
||||
bun qwik add # or `bun qwik add`
|
||||
```
|
||||
|
||||
## Development
|
||||
@@ -43,7 +43,7 @@ pnpm qwik add # or `pnpm qwik add`
|
||||
Development mode uses [Vite's development server](https://vitejs.dev/). The `dev` command will server-side render (SSR) the output during development.
|
||||
|
||||
```shell
|
||||
npm start # or `pnpm start`
|
||||
npm start # or `bun start`
|
||||
```
|
||||
|
||||
> Note: during dev mode, Vite may request a significant number of `.js` files. This does not represent a Qwik production build.
|
||||
@@ -53,7 +53,7 @@ npm start # or `pnpm start`
|
||||
The preview command will create a production build of the client modules, a production build of `src/entry.preview.tsx`, and run a local server. The preview server is only for convenience to preview a production build locally and should not be used as a production server.
|
||||
|
||||
```shell
|
||||
pnpm preview # or `pnpm preview`
|
||||
bun preview # or `bun preview`
|
||||
```
|
||||
|
||||
## Production
|
||||
@@ -61,49 +61,52 @@ pnpm preview # or `pnpm preview`
|
||||
The production build will generate client and server modules by running both client and server build commands. The build command will use Typescript to run a type check on the source code.
|
||||
|
||||
```shell
|
||||
pnpm build # or `pnpm build`
|
||||
bun build # or `bun build`
|
||||
```
|
||||
|
||||
## Vercel Edge
|
||||
## Cloudflare Pages
|
||||
|
||||
This starter site is configured to deploy to [Vercel Edge Functions](https://vercel.com/docs/concepts/functions/edge-functions), which means it will be rendered at an edge location near to your users.
|
||||
|
||||
## Installation
|
||||
|
||||
The adaptor will add a new `vite.config.ts` within the `adapters/` directory, and a new entry file will be created, such as:
|
||||
Cloudflare's [wrangler](https://github.com/cloudflare/wrangler) CLI can be used to preview a production build locally. To start a local server, run:
|
||||
|
||||
```
|
||||
└── adapters/
|
||||
└── vercel-edge/
|
||||
└── vite.config.ts
|
||||
└── src/
|
||||
└── entry.vercel-edge.tsx
|
||||
bun serve
|
||||
```
|
||||
|
||||
Additionally, within the `package.json`, the `build.server` script will be updated with the Vercel Edge build.
|
||||
Then visit [http://localhost:8787/](http://localhost:8787/)
|
||||
|
||||
## Production build
|
||||
### Deployments
|
||||
|
||||
To build the application for production, use the `build` command, this command will automatically run `pnpm build.server` and `pnpm build.client`:
|
||||
[Cloudflare Pages](https://pages.cloudflare.com/) are deployable through their [Git provider integrations](https://developers.cloudflare.com/pages/platform/git-integration/).
|
||||
|
||||
```shell
|
||||
pnpm build
|
||||
If you don't already have an account, then [create a Cloudflare account here](https://dash.cloudflare.com/sign-up/pages). Next go to your dashboard and follow the [Cloudflare Pages deployment guide](https://developers.cloudflare.com/pages/framework-guides/deploy-anything/).
|
||||
|
||||
Within the projects "Settings" for "Build and deployments", the "Build command" should be `bun build`, and the "Build output directory" should be set to `dist`.
|
||||
|
||||
### Function Invocation Routes
|
||||
|
||||
Cloudflare Page's [function-invocation-routes config](https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes) can be used to include, or exclude, certain paths to be used by the worker functions. Having a `_routes.json` file gives developers more granular control over when your Function is invoked.
|
||||
This is useful to determine if a page response should be Server-Side Rendered (SSR) or if the response should use a static-site generated (SSG) `index.html` file.
|
||||
|
||||
By default, the Cloudflare pages adaptor _does not_ include a `public/_routes.json` config, but rather it is auto-generated from the build by the Cloudflare adaptor. An example of an auto-generate `dist/_routes.json` would be:
|
||||
|
||||
```
|
||||
{
|
||||
"include": [
|
||||
"/*"
|
||||
],
|
||||
"exclude": [
|
||||
"/_headers",
|
||||
"/_redirects",
|
||||
"/build/*",
|
||||
"/favicon.ico",
|
||||
"/manifest.json",
|
||||
"/service-worker.js",
|
||||
"/about"
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
```
|
||||
|
||||
[Read the full guide here](https://github.com/BuilderIO/qwik/blob/main/starters/adapters/vercel-edge/README.md)
|
||||
In the above example, it's saying _all_ pages should be SSR'd. However, the root static files such as `/favicon.ico` and any static assets in `/build/*` should be excluded from the Functions, and instead treated as a static file.
|
||||
|
||||
## Dev deploy
|
||||
|
||||
To deploy the application for development:
|
||||
|
||||
```shell
|
||||
pnpm deploy
|
||||
```
|
||||
|
||||
Notice that you might need a [Vercel account](https://docs.Vercel.com/get-started/) in order to complete this step!
|
||||
|
||||
## Production deploy
|
||||
|
||||
The project is ready to be deployed to Vercel. However, you will need to create a git repository and push the code to it.
|
||||
|
||||
You can [deploy your site to Vercel](https://vercel.com/docs/concepts/deployments/overview) either via a Git provider integration or through the Vercel CLI.
|
||||
In most cases the generated `dist/_routes.json` file is ideal. However, if you need more granular control over each path, you can instead provide you're own `public/_routes.json` file. When the project provides its own `public/_routes.json` file, then the Cloudflare adaptor will not auto-generate the routes config and instead use the committed one within the `public` directory.
|
||||
|
||||
15
apps/www/adapters/cloudflare-pages/vite.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { cloudflarePagesAdapter } from "@builder.io/qwik-city/adapters/cloudflare-pages/vite";
|
||||
import { extendConfig } from "@builder.io/qwik-city/vite";
|
||||
import baseConfig from "../../vite.config";
|
||||
|
||||
export default extendConfig(baseConfig, () => {
|
||||
return {
|
||||
build: {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: ["src/entry.cloudflare-pages.tsx", "@qwik-city-plan"],
|
||||
},
|
||||
},
|
||||
plugins: [cloudflarePagesAdapter()],
|
||||
};
|
||||
});
|
||||
23
apps/www/adapters/deno/vite.config.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { denoServerAdapter } from "@builder.io/qwik-city/adapters/deno-server/vite";
|
||||
import { extendConfig } from "@builder.io/qwik-city/vite";
|
||||
import baseConfig from "../../vite.config";
|
||||
|
||||
export default extendConfig(baseConfig, () => {
|
||||
return {
|
||||
build: {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: ["src/entry.deno.ts", "@qwik-city-plan"],
|
||||
},
|
||||
minify: false,
|
||||
},
|
||||
plugins: [
|
||||
denoServerAdapter({
|
||||
ssg: {
|
||||
include: ["/*"],
|
||||
origin: "https://yoursite.dev",
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { vercelEdgeAdapter } from "@builder.io/qwik-city/adapters/vercel-edge/vite";
|
||||
import { extendConfig } from "@builder.io/qwik-city/vite";
|
||||
import baseConfig from "../../vite.config";
|
||||
|
||||
export default extendConfig(baseConfig, () => {
|
||||
return {
|
||||
build: {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: ["src/entry.vercel-edge.tsx", "@qwik-city-plan"],
|
||||
},
|
||||
outDir: ".vercel/output/functions/_qwik-city.func",
|
||||
},
|
||||
plugins: [vercelEdgeAdapter()],
|
||||
};
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-qwik-empty-starter",
|
||||
"description": "App with Routing built-in ready to create your app",
|
||||
"name": "@nestri/web",
|
||||
"description": "Your games. Your rules.",
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
@@ -15,44 +15,61 @@
|
||||
"build": "qwik build",
|
||||
"build.client": "vite build",
|
||||
"build.preview": "vite build --ssr src/entry.preview.tsx",
|
||||
"build.server": "vite build -c adapters/vercel-edge/vite.config.ts",
|
||||
"build.server": "vite build -c adapters/cloudflare-pages/vite.config.ts",
|
||||
"deno:build.server": "vite build -c adapters/deno/vite.config.ts",
|
||||
"build.types": "tsc --incremental --noEmit",
|
||||
"deploy": "vercel deploy",
|
||||
"deploy": "wrangler pages deploy ./dist",
|
||||
"dev": "vite --mode ssr",
|
||||
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
|
||||
"fmt": "prettier --write .",
|
||||
"fmt.check": "prettier --check .",
|
||||
"lint": "eslint \"src/**/*.ts*\"",
|
||||
"preview": "qwik build preview && vite preview --open",
|
||||
"serve": "wrangler pages dev ./dist --compatibility-flags=nodejs_als",
|
||||
"deno:serve": "deno run --allow-net --allow-read --allow-env server/entry.deno.js",
|
||||
"start": "vite --open --mode ssr",
|
||||
"qwik": "qwik"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@builder.io/qwik": "^1.5.1",
|
||||
"@builder.io/qwik-city": "^1.5.1",
|
||||
"@builder.io/partytown": "^0.8.1",
|
||||
"@builder.io/qwik": "^1.8.0",
|
||||
"@builder.io/qwik-city": "^1.8.0",
|
||||
"@builder.io/qwik-react": "0.5.0",
|
||||
"@types/eslint": "^8.56.5",
|
||||
"@types/node": "^20.11.24",
|
||||
"@fontsource-variable/bricolage-grotesque": "^5.1.1",
|
||||
"@fontsource-variable/mona-sans": "^5.0.1",
|
||||
"@modular-forms/qwik": "^0.29.0",
|
||||
"@nestri/input": "*",
|
||||
"@nestri/libmoq": "*",
|
||||
"@nestri/sdk": "0.1.0-alpha.14",
|
||||
"@nestri/ui": "*",
|
||||
"@openauthjs/openauth": "^0.2.6",
|
||||
"@polar-sh/checkout": "^0.1.8",
|
||||
"@polar-sh/sdk": "^0.21.1",
|
||||
"@qwik-ui/headless": "^0.6.4",
|
||||
"@types/eslint": "8.56.10",
|
||||
"@types/howler": "^2.2.12",
|
||||
"@types/node": "^22.5.1",
|
||||
"@types/react": "^18.2.28",
|
||||
"@types/react-dom": "^18.2.13",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-qwik": "^1.5.1",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "7.16.1",
|
||||
"@typescript-eslint/parser": "7.16.1",
|
||||
"ajv": "^8.17.1",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-plugin-qwik": "^1.8.0",
|
||||
"howler": "^2.2.4",
|
||||
"posthog-js": "^1.207.0",
|
||||
"prettier": "3.3.3",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"tailwindcss": "3.3.3",
|
||||
"typescript": "5.3.3",
|
||||
"typescript": "5.4.5",
|
||||
"undici": "*",
|
||||
"vercel": "^29.1.1",
|
||||
"vite": "^5.1.4",
|
||||
"vite-tsconfig-paths": "^4.2.1"
|
||||
"valibot": "^0.42.1",
|
||||
"vite": "5.4.12",
|
||||
"vite-tsconfig-paths": "^4.2.1",
|
||||
"wrangler": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/geist-sans": "^5.0.2"
|
||||
"@types/pako": "^2.0.3",
|
||||
"pako": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
9347
apps/www/pnpm-lock.yaml
generated
@@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
9
apps/www/public/_headers
Normal file
@@ -0,0 +1,9 @@
|
||||
# https://developers.cloudflare.com/pages/platform/headers/
|
||||
|
||||
/*service-worker.js
|
||||
Cache-Control: no-store
|
||||
Content-Type: application/javascript
|
||||
X-Content-Type-Options: nosniff
|
||||
|
||||
/build/*
|
||||
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable
|
||||
1
apps/www/public/_redirects
Normal file
@@ -0,0 +1 @@
|
||||
# https://developers.cloudflare.com/pages/platform/redirects/
|
||||
BIN
apps/www/public/audio/click.wav
Normal file
BIN
apps/www/public/changelog/v0.0.3/game-play.png
Normal file
|
After Width: | Height: | Size: 6.9 MiB |
BIN
apps/www/public/changelog/v0.0.3/gameplay-right.png
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
apps/www/public/changelog/v0.0.3/gameplay.avifs
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
apps/www/public/changelog/v0.0.3/header.avif
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
apps/www/public/changelog/v0.0.3/header.png
Normal file
|
After Width: | Height: | Size: 4.5 MiB |
BIN
apps/www/public/changelog/v0.0.3/nestrivalheim.mp4
Normal file
BIN
apps/www/public/changelog/v0.0.3/new-site.png
Normal file
|
After Width: | Height: | Size: 5.5 MiB |
BIN
apps/www/public/changelog/v0.0.3/new-website-design.avif
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
apps/www/public/changelog/v0.0.3/new-website-design.png
Normal file
|
After Width: | Height: | Size: 5.3 MiB |
BIN
apps/www/public/changelog/v0.0.3/new-website.png
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
BIN
apps/www/public/changelog/v0.0.3/steam-integration.png
Normal file
|
After Width: | Height: | Size: 6.3 MiB |
BIN
apps/www/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 365 B |
|
Before Width: | Height: | Size: 23 KiB |
14
apps/www/public/favicon.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="48.672001"
|
||||
height="36.804001"
|
||||
viewBox="0 0 12.8778 9.7377253"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="layer1">
|
||||
<path
|
||||
d="m 2.093439,1.7855532 h 8.690922 V 2.2639978 H 2.093439 Z m 0,2.8440874 h 8.690922 V 5.1080848 H 2.093439 Z m 0,2.8440866 h 8.690922 V 7.952172 H 2.093439 Z"
|
||||
style="font-size:12px;fill:#ff4f01;fill-opacity:1;fill-rule:evenodd;stroke:#ff4f01;stroke-width:1.66201;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 590 B |
BIN
apps/www/public/fonts/BasementGrotesque-Black.otf
Normal file
BIN
apps/www/public/fonts/BasementGrotesque-Black.woff
Normal file
BIN
apps/www/public/fonts/BasementGrotesque-Black.woff2
Normal file
BIN
apps/www/public/images/avatars/dathorse.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
apps/www/public/images/avatars/janried.png
Normal file
|
After Width: | Height: | Size: 137 KiB |