diff --git a/Dockerfile b/Dockerfile
index f6ba64d..20c8517 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,7 +17,7 @@ RUN npm run build
#
# STAGE 2: build executable binary
#
-FROM golang:1.17-buster as builder
+FROM golang:1.18-buster as builder
WORKDIR /app
COPY . .
@@ -33,7 +33,7 @@ COPY --from=frontend /src/dist/ /var/www
ENV DOCKER_API_VERSION=1.39
ENV NEKO_ROOMS_BIND=:8080
-ENV NEKO_ROOMS_STATIC=/var/www
+ENV NEKO_ROOMS_ADMIN_STATIC=/var/www
EXPOSE 8080
diff --git a/OpenApi.yml b/OpenApi.yml
index 330e120..42f3ea4 100644
--- a/OpenApi.yml
+++ b/OpenApi.yml
@@ -307,6 +307,7 @@ components:
max_connections:
type: number
example: 10
+ description: 0 when using mux
running:
type: boolean
example: true
@@ -361,6 +362,7 @@ components:
max_connections:
type: number
default: 10
+ description: 0 when using mux
user_pass:
type: string
example: neko
diff --git a/README.md b/README.md
index 4e9240a..bdf1277 100644
--- a/README.md
+++ b/README.md
@@ -16,70 +16,25 @@ Simple room management system for [n.eko](https://github.com/m1k1o/neko). Self h
-## Zero-knowledge installation
+## Zero-knowledge installation (with HTTPS and Traefik)
If you don't have any clue about docker and stuff but only want to have fun with friends in a shared browser, we got you covered!
- Rent a VPS with public IP and OS Ubuntu.
- Get a domain name pointing to your IP (you can even get some for free).
- Run install script and follow instructions.
+- Secure using HTTPs thanks to Let's Encrypt and Traefik.
```bash
-wget -O neko-rooms.sh https://raw.githubusercontent.com/m1k1o/neko-rooms/master/install
+wget -O neko-rooms.sh https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/install
sudo bash neko-rooms.sh
```
## How to start
-You need to have installed `Docker` and `docker-compose`. You need to have a custom domain pointing to your server's IP.
+If you want to use Traefik as reverse proxy, visit [installation guide for traefik as reverse proxy](./traefik/).
-You can watch installation video provided by *Dr R1ck*:
-
-https://www.youtube.com/watch?v=cCmnw-pq0gA
-
-### Installation guide
-
-You only need `.env.example`, `docker-compose.yml` and `traefik/`.
-
-#### Do I need to use traefik?
-
-- Traefik needs to be used to forward traffic to the rooms. You can put nginx in front of it, but not replace it.
-- See example configuration for [nginx](docs/nginx).
-
-You can use `docker-compose.http.yml` that will expose this service to `8080` or any port. Authentication is optional. Start it quickly with `docker-compose -f docker-compose.http.yml up -d`.
-
-### Step 1
-
-Copy `.env.example` to `.env` and customize.
-
-```bash
-cp .env.example .env
-```
-
-### Step 2
-
-Create `usersfile` with your users:
-
-```bash
-touch traefik/usersfile
-```
-
-And add as many users as you like:
-
-```bash
-echo $(htpasswd -nb user password) >> traefik/usersfile
-```
-
-### Step 3 (HTTPS only)
-
-Create `acme.json`
-
-```bash
-touch traefik/acme.json
-chmod 600 traefik/acme.json
-```
-
-Update your email in `traefik/traefik.yml`.
+Otherwise modify variables in `docker-compose.yml` and just run `docker-compose up -d`.
### Download images / update
@@ -116,6 +71,7 @@ For more information visit [docs](./docs).
- [x] add authentication provider for traefik
- [x] allow specifying custom ENV variables
- [x] allow mounting directories for persistent data
+ - [x] optionally remove Traefik as dependency
- [ ] add upgrade button
- [ ] auto pull images, that do not exist
- [ ] add bearer token to for API
diff --git a/client/src/components/RoomInfo.vue b/client/src/components/RoomInfo.vue
index d9c07cf..ee9109e 100644
--- a/client/src/components/RoomInfo.vue
+++ b/client/src/components/RoomInfo.vue
@@ -25,10 +25,10 @@
:rotate="270"
:size="100"
:width="15"
- :value="usesMux ? 100 : ((stats.connections / settings.max_connections) * 100)"
+ :value="settings.max_connections == 0 ? 100 : ((stats.connections / settings.max_connections) * 100)"
color="blue"
>
- {{ stats.connections }} / {{ settings.max_connections }}
+ {{ stats.connections }} / {{ settings.max_connections }}
@@ -99,7 +99,10 @@
Invite link for admins
-
Max connections | {{ settings.max_connections }} |
+ Max connections |
+ {{ settings.max_connections }}
+ not limited because uses mux
+ |
Control protection | {{ settings.control_protection }} |
Implicit Control | {{ settings.implicit_control }} |
@@ -275,8 +278,7 @@ export default class RoomInfo extends Vue {
}
get usesMux() {
- // old rooms might not use mux despite enabled server wide, simple check for that
- return this.$store.state.roomsConfig.uses_mux && this.settings?.max_connections == 1
+ return this.$store.state.roomsConfig.uses_mux
}
get allBrowserExtensions() {
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index 8546f3f..b78bd29 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -604,7 +604,7 @@ export default class RoomsCreate extends Vue {
// eslint-disable-next-line
admin_pass: this.data.admin_pass || randomPassword(),
// eslint-disable-next-line
- max_connections: Number(this.data.max_connections), // not needed when uses mux
+ max_connections: Number(this.data.max_connections), // ignored when uses mux
// eslint-disable-next-line
control_protection: Boolean(this.data.control_protection),
// eslint-disable-next-line
diff --git a/client/src/components/RoomsList.vue b/client/src/components/RoomsList.vue
index 6f92daa..95afd82 100644
--- a/client/src/components/RoomsList.vue
+++ b/client/src/components/RoomsList.vue
@@ -33,8 +33,8 @@
- {{ item.max_connections }}
- --not-specified--
+ {{ item.max_connections }}
+ uses mux
{{ item.status }}
diff --git a/client/src/views/Home.vue b/client/src/views/Home.vue
index 7aa1463..73e6923 100644
--- a/client/src/views/Home.vue
+++ b/client/src/views/Home.vue
@@ -101,7 +101,7 @@ export default class Home extends Vue {
get usedConnections() {
// eslint-disable-next-line
- return this.$store.state.rooms.reduce((sum: number, { max_connections }: RoomEntry) => sum + (max_connections || 0), 0)
+ return this.$store.state.rooms.reduce((sum: number, { max_connections }: RoomEntry) => sum + (max_connections || 1/* 0 when using mux */), 0)
}
async LoadRooms() {
diff --git a/cmd/serve.go b/cmd/serve.go
index 7a8b5b3..06ad02f 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -18,7 +18,6 @@ func init() {
configs := []config.Config{
nekoRooms.Service.Configs.Server,
- nekoRooms.Service.Configs.API,
nekoRooms.Service.Configs.Room,
}
diff --git a/dev/serve b/dev/serve
index c3131b5..d477f08 100755
--- a/dev/serve
+++ b/dev/serve
@@ -1,24 +1,31 @@
#!/bin/sh
cd "$(dirname "$0")"
-if [ ! -f "../.env" ]
-then
- echo "../.env file not found!"
- exit 1
+if [ -z $APP_PORT ]; then
+ APP_PORT="8080"
fi
-export $(cat ../.env | sed 's/#.*//g' | xargs)
+if [ -z $APP_HOST ]; then
+ for i in $(ifconfig -l 2>/dev/null); do
+ APP_HOST=$(ipconfig getifaddr $i)
+ if [ ! -z $APP_HOST ]; then
+ break
+ fi
+ done
+
+ if [ -z $APP_HOST ]; then
+ APP_HOST=$(hostname -i 2>/dev/null)
+ fi
+fi
+
+echo "Using app port: ${APP_PORT}"
+echo "Using IP address: ${APP_HOST}"
docker run --rm -it \
- --name="neko_rooms_client" \
- -v "${PWD}/../client:/app" \
- -e "TZ=${TZ}" \
- --net="${NEKO_ROOMS_TRAEFIK_NETWORK}" \
- -l "traefik.enable=true" \
- -l "traefik.http.services.neko-rooms-client-fe.loadbalancer.server.port=8080" \
- -l "traefik.http.routers.neko-rooms-client.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
- -l "traefik.http.routers.neko-rooms-client.rule=Host(\`${NEKO_ROOMS_TRAEFIK_DOMAIN}\`)" \
+ -p 8081:8080 \
+ -e "API_PROXY=http://${APP_HOST}:${APP_PORT}" \
--user="$(id -u):$(id -g)" \
- --workdir="/app" \
+ --volume "${PWD}/../client:/app" \
--entrypoint="npm" \
+ --workdir="/app" \
node:14 run serve;
diff --git a/dev/start b/dev/start
index fbfb64e..fed2a65 100755
--- a/dev/start
+++ b/dev/start
@@ -1,13 +1,36 @@
#!/bin/sh
cd "$(dirname "$0")"
-if [ ! -f "../.env" ]
-then
- echo "../.env file not found!"
- exit 1
+if [ -z $NEKO_ROOMS_PORT ]; then
+ NEKO_ROOMS_PORT="8080"
fi
-export $(cat ../.env | sed 's/#.*//g' | xargs)
+if [ -z $NEKO_ROOMS_EPR ]; then
+ NEKO_ROOMS_EPR="52090-52099"
+fi
+
+if [ -z $NEKO_ROOMS_NAT1TO1 ]; then
+ for i in $(ifconfig -l 2>/dev/null); do
+ NEKO_ROOMS_NAT1TO1=$(ipconfig getifaddr $i)
+ if [ ! -z $NEKO_ROOMS_NAT1TO1 ]; then
+ break
+ fi
+ done
+
+ if [ -z $NEKO_ROOMS_NAT1TO1 ]; then
+ NEKO_ROOMS_NAT1TO1=$(hostname -i 2>/dev/null)
+ fi
+fi
+
+NEKO_ROOMS_INSTANCE_NETWORK="neko-rooms-net"
+docker network create --attachable "${NEKO_ROOMS_INSTANCE_NETWORK}";
+
+trap on_exit EXIT
+
+on_exit() {
+ echo "Removing neko-rooms network"
+ docker network rm "${NEKO_ROOMS_INSTANCE_NETWORK}";
+}
DATA_PATH="./data"
mkdir -p "${DATA_PATH}"
@@ -17,24 +40,22 @@ mkdir -p "${EXTERNAL_PATH}"
docker run --rm -it \
--name="neko_rooms_server" \
+ -p "${NEKO_ROOMS_PORT}:8080" \
-v "`realpath ..`:/app" \
-v "`realpath ${DATA_PATH}`:/data" \
-e "TZ=${TZ}" \
- -e "NEKO_ROOMS_EPR=${NEKO_ROOMS_EPR}" \
-e "NEKO_ROOMS_MUX=true" \
+ -e "NEKO_ROOMS_EPR=${NEKO_ROOMS_EPR}" \
-e "NEKO_ROOMS_NAT1TO1=${NEKO_ROOMS_NAT1TO1}" \
+ -e "NEKO_ROOMS_INSTANCE_URL=http://${NEKO_ROOMS_NAT1TO1}:${NEKO_ROOMS_PORT}/" \
+ -e "NEKO_ROOMS_INSTANCE_NETWORK=${NEKO_ROOMS_INSTANCE_NETWORK}" \
-e "NEKO_ROOMS_STORAGE_INTERNAL=/data" \
-e "NEKO_ROOMS_STORAGE_EXTERNAL=`realpath ${DATA_PATH}`" \
-e "NEKO_ROOMS_MOUNTS_WHITELIST=`realpath ${EXTERNAL_PATH}`" \
- -e "NEKO_ROOMS_TRAEFIK_DOMAIN=${NEKO_ROOMS_TRAEFIK_DOMAIN}" \
- -e "NEKO_ROOMS_TRAEFIK_ENTRYPOINT=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
- -e "NEKO_ROOMS_TRAEFIK_NETWORK=${NEKO_ROOMS_TRAEFIK_NETWORK}" \
+ -e "NEKO_ROOMS_PATH_PREFIX=/room/" \
+ -e "NEKO_ROOMS_TRAEFIK_ENABLED=false" \
-e 'DOCKER_API_VERSION=1.39' \
-v "/var/run/docker.sock:/var/run/docker.sock" \
- --net="${NEKO_ROOMS_TRAEFIK_NETWORK}" \
- -l "traefik.enable=true" \
- -l "traefik.http.services.neko-rooms-server-fe.loadbalancer.server.port=8080" \
- -l "traefik.http.routers.neko-rooms-server.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
- -l "traefik.http.routers.neko-rooms-server.rule=Host(\`${NEKO_ROOMS_TRAEFIK_DOMAIN}\`) && PathPrefix(\`/api\`)" \
+ --net="${NEKO_ROOMS_INSTANCE_NETWORK}" \
--entrypoint="/app/bin/neko_rooms" \
neko_rooms_img serve --bind :8080;
diff --git a/.env.example b/dev/traefik/.env.example
similarity index 100%
rename from .env.example
rename to dev/traefik/.env.example
diff --git a/dev/traefik/rebuild b/dev/traefik/rebuild
new file mode 100755
index 0000000..345525a
--- /dev/null
+++ b/dev/traefik/rebuild
@@ -0,0 +1,11 @@
+#!/bin/sh
+cd "$(dirname "$0")"
+
+set -e
+
+docker run --rm -it \
+ -v "${PWD}/../../:/app" \
+ --entrypoint="go" \
+ neko_rooms_img build -o bin/neko_rooms cmd/neko_rooms/main.go
+
+./start
diff --git a/dev/traefik/serve b/dev/traefik/serve
new file mode 100755
index 0000000..d51306e
--- /dev/null
+++ b/dev/traefik/serve
@@ -0,0 +1,25 @@
+#!/bin/sh
+cd "$(dirname "$0")"
+
+if [ ! -f ".env" ]
+then
+ echo ".env file not found!"
+ exit 1
+fi
+
+export $(cat .env | sed 's/#.*//g' | xargs)
+
+docker run --rm -it \
+ --name="neko_rooms_client" \
+ -v "${PWD}/../../client:/app" \
+ -e "TZ=${TZ}" \
+ --net="${NEKO_ROOMS_TRAEFIK_NETWORK}" \
+ -l "traefik.enable=true" \
+ -l "traefik.http.services.neko-rooms-client-fe.loadbalancer.server.port=8080" \
+ -l "traefik.http.routers.neko-rooms-client.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
+ -l "traefik.http.routers.neko-rooms-client.rule=Host(\`${NEKO_ROOMS_TRAEFIK_DOMAIN}\`)" \
+ -l "traefik.http.routers.neko-rooms-client.priority=1" \
+ --user="$(id -u):$(id -g)" \
+ --workdir="/app" \
+ --entrypoint="npm" \
+ node:14 run serve;
diff --git a/dev/traefik/start b/dev/traefik/start
new file mode 100755
index 0000000..f89b31e
--- /dev/null
+++ b/dev/traefik/start
@@ -0,0 +1,47 @@
+#!/bin/sh
+cd "$(dirname "$0")"
+
+if [ ! -f ".env" ]
+then
+ echo ".env file not found!"
+ exit 1
+fi
+
+export $(cat .env | sed 's/#.*//g' | xargs)
+
+DATA_PATH="../data"
+mkdir -p "${DATA_PATH}"
+
+EXTERNAL_PATH="../ext"
+mkdir -p "${EXTERNAL_PATH}"
+
+docker run --rm -it \
+ --name="neko_rooms_server" \
+ -v "`realpath ../../`:/app" \
+ -v "`realpath ${DATA_PATH}`:/data" \
+ -e "TZ=${TZ}" \
+ -e "NEKO_ROOMS_EPR=${NEKO_ROOMS_EPR}" \
+ -e "NEKO_ROOMS_MUX=true" \
+ -e "NEKO_ROOMS_NAT1TO1=${NEKO_ROOMS_NAT1TO1}" \
+ -e "NEKO_ROOMS_PATH_PREFIX=/room/" \
+ -e "NEKO_ROOMS_STORAGE_INTERNAL=/data" \
+ -e "NEKO_ROOMS_STORAGE_EXTERNAL=`realpath ${DATA_PATH}`" \
+ -e "NEKO_ROOMS_MOUNTS_WHITELIST=`realpath ${EXTERNAL_PATH}`" \
+ -e "NEKO_ROOMS_TRAEFIK_ENABLED=true" \
+ -e "NEKO_ROOMS_TRAEFIK_DOMAIN=${NEKO_ROOMS_TRAEFIK_DOMAIN}" \
+ -e "NEKO_ROOMS_TRAEFIK_ENTRYPOINT=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
+ -e "NEKO_ROOMS_TRAEFIK_NETWORK=${NEKO_ROOMS_TRAEFIK_NETWORK}" \
+ -e 'DOCKER_API_VERSION=1.39' \
+ -v "/var/run/docker.sock:/var/run/docker.sock" \
+ --net="${NEKO_ROOMS_TRAEFIK_NETWORK}" \
+ -l "traefik.enable=true" \
+ -l "traefik.http.services.neko-rooms-server-fe.loadbalancer.server.port=8080" \
+ -l "traefik.http.routers.neko-rooms-server.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
+ -l "traefik.http.routers.neko-rooms-server.rule=Host(\`${NEKO_ROOMS_TRAEFIK_DOMAIN}\`) && PathPrefix(\`/room\`)" \
+ -l "traefik.http.routers.neko-rooms-server.priority=2" \
+ -l "traefik.http.routers.neko-rooms-server.service=neko-rooms-server-fe" \
+ -l "traefik.http.routers.neko-rooms-server-api.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}" \
+ -l "traefik.http.routers.neko-rooms-server-api.rule=Host(\`${NEKO_ROOMS_TRAEFIK_DOMAIN}\`) && PathPrefix(\`/api\`)" \
+ -l "traefik.http.routers.neko-rooms-server-api.service=neko-rooms-server-fe" \
+ --entrypoint="/app/bin/neko_rooms" \
+ neko_rooms_img serve --bind :8080;
diff --git a/dev/traefik b/dev/traefik/traefik
similarity index 85%
rename from dev/traefik
rename to dev/traefik/traefik
index 6970692..c787d74 100755
--- a/dev/traefik
+++ b/dev/traefik/traefik
@@ -1,13 +1,13 @@
#!/bin/sh
cd "$(dirname "$0")"
-if [ ! -f "../.env" ]
+if [ ! -f ".env" ]
then
- echo "../.env file not found!"
+ echo ".env file not found!"
exit 1
fi
-export $(cat ../.env | sed 's/#.*//g' | xargs)
+export $(cat .env | sed 's/#.*//g' | xargs)
docker network create --attachable "${NEKO_ROOMS_TRAEFIK_NETWORK}";
@@ -22,7 +22,7 @@ docker run --rm -it \
--name="neko_rooms_traefik" \
-p "${1:-80}:80" \
-p "8080:8080" \
- -v "${PWD}/../:/app" \
+ -v "${PWD}/../../:/app" \
-e "TZ=${TZ}" \
-v "/var/run/docker.sock:/var/run/docker.sock" \
--net="${NEKO_ROOMS_TRAEFIK_NETWORK}" \
diff --git a/docker-compose.yml b/docker-compose.yml
index 909e750..cee1537 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,43 +1,24 @@
version: "3.5"
-#
-# This docker compose needs .env file.
-# Copy .env.example to .env and modify.
-#
-
networks:
default:
- attachable: "true"
- name: "${NEKO_ROOMS_TRAEFIK_NETWORK}"
+ attachable: true
+ name: "neko-rooms-net"
services:
- traefik:
- image: "traefik:2.4"
- restart: "unless-stopped"
- environment:
- - "TZ"
- ports:
- - "80:80"
- - "443:443"
- volumes:
- - "/var/run/docker.sock:/var/run/docker.sock:ro"
- - "./traefik/traefik.yml:/etc/traefik/traefik.yml:ro"
- - "./traefik/usersfile:/usersfile:ro"
- - "./traefik/acme.json:/acme.json"
- - "./traefik/config:/config"
-
neko-rooms:
image: "m1k1o/neko-rooms:latest"
restart: "unless-stopped"
- env_file:
- - ".env"
+ environment:
+ - "TZ=Europe/Vienna"
+ - "NEKO_ROOMS_MUX=true"
+ - "NEKO_ROOMS_EPR=59000-59049"
+ - "NEKO_ROOMS_NAT1TO1=127.0.0.1" # IP address of your server that is reachable from client
+ - "NEKO_ROOMS_INSTANCE_URL=http://127.0.0.1:8080/" # external URL
+ - "NEKO_ROOMS_INSTANCE_NETWORK=neko-rooms-net"
+ - "NEKO_ROOMS_TRAEFIK_ENABLED=false"
+ - "NEKO_ROOMS_PATH_PREFIX=/room/"
+ ports:
+ - "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- labels:
- - "traefik.enable=true"
- - "traefik.http.services.neko-rooms-frontend.loadbalancer.server.port=8080"
- - "traefik.http.routers.neko-rooms.entrypoints=${NEKO_ROOMS_TRAEFIK_ENTRYPOINT}"
- - "traefik.http.routers.neko-rooms.rule=Host(`${NEKO_ROOMS_TRAEFIK_DOMAIN}`)"
- - "traefik.http.routers.neko-rooms.tls=true"
- - "traefik.http.routers.neko-rooms.tls.certresolver=${NEKO_ROOMS_TRAEFIK_CERTRESOLVER}"
- - "traefik.http.routers.neko-rooms.middlewares=basicauth@file"
diff --git a/go.mod b/go.mod
index 41a66fa..31aac8b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/m1k1o/neko-rooms
-go 1.17
+go 1.18
require (
github.com/Microsoft/go-winio v0.5.2 // indirect
diff --git a/internal/api/api.go b/internal/api/api.go
index e82fda1..490f00c 100644
--- a/internal/api/api.go
+++ b/internal/api/api.go
@@ -5,7 +5,6 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/m1k1o/neko-rooms/internal/config"
"github.com/m1k1o/neko-rooms/internal/types"
)
@@ -13,15 +12,13 @@ type ApiManagerCtx struct {
logger zerolog.Logger
rooms types.RoomManager
pull types.PullManager
- conf *config.API
}
-func New(rooms types.RoomManager, pull types.PullManager, conf *config.API) *ApiManagerCtx {
+func New(rooms types.RoomManager, pull types.PullManager) *ApiManagerCtx {
return &ApiManagerCtx{
logger: log.With().Str("module", "api").Logger(),
rooms: rooms,
pull: pull,
- conf: conf,
}
}
diff --git a/internal/config/api.go b/internal/config/api.go
deleted file mode 100644
index 0331d47..0000000
--- a/internal/config/api.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package config
-
-import (
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-type API struct {
- Lobby bool
-}
-
-func (API) Init(cmd *cobra.Command) error {
- cmd.PersistentFlags().Bool("lobby", true, "show lobby when room is not started yet; in order to show lobby, neko-rooms must run on the same subdomain where rooms are published")
- if err := viper.BindPFlag("lobby", cmd.PersistentFlags().Lookup("lobby")); err != nil {
- return err
- }
-
- return nil
-}
-
-func (s *API) Set() {
- s.Lobby = viper.GetBool("lobby")
-}
diff --git a/internal/config/room.go b/internal/config/room.go
index 272f524..b65dbfc 100644
--- a/internal/config/room.go
+++ b/internal/config/room.go
@@ -13,6 +13,14 @@ import (
"github.com/spf13/viper"
)
+type Traefik struct {
+ Enabled bool
+ Domain string
+ Entrypoint string
+ Certresolver string
+ Port string // deprecated
+}
+
type Room struct {
Mux bool
EprMin uint16
@@ -30,14 +38,11 @@ type Room struct {
MountsWhitelist []string
- InstanceName string
- InstanceUrl *url.URL
+ InstanceName string
+ InstanceUrl *url.URL
+ InstanceNetwork string
- TraefikDomain string
- TraefikEntrypoint string
- TraefikCertresolver string
- TraefikNetwork string
- TraefikPort string // deprecated
+ Traefik Traefik
}
func (Room) Init(cmd *cobra.Command) error {
@@ -78,7 +83,7 @@ func (Room) Init(cmd *cobra.Command) error {
return err
}
- cmd.PersistentFlags().String("path_prefix", "", "path prefix that is added to every room path")
+ cmd.PersistentFlags().String("path_prefix", "/", "path prefix that is added to every room path")
if err := viper.BindPFlag("path_prefix", cmd.PersistentFlags().Lookup("path_prefix")); err != nil {
return err
}
@@ -122,8 +127,18 @@ func (Room) Init(cmd *cobra.Command) error {
return err
}
+ cmd.PersistentFlags().String("instance.network", "", "docker network that will be used for this instance to communicate with rooms")
+ if err := viper.BindPFlag("instance.network", cmd.PersistentFlags().Lookup("instance.network")); err != nil {
+ return err
+ }
+
// Traefik
+ cmd.PersistentFlags().Bool("traefik.enabled", true, "traefik: enabled or disabled")
+ if err := viper.BindPFlag("traefik.enabled", cmd.PersistentFlags().Lookup("traefik.enabled")); err != nil {
+ return err
+ }
+
cmd.PersistentFlags().String("traefik.domain", "", "traefik: domain on which will be container hosted (if empty or '*', match all; for neko-rooms as subdomain use '*.domain.tld')")
if err := viper.BindPFlag("traefik.domain", cmd.PersistentFlags().Lookup("traefik.domain")); err != nil {
return err
@@ -139,7 +154,7 @@ func (Room) Init(cmd *cobra.Command) error {
return err
}
- cmd.PersistentFlags().String("traefik.network", "traefik", "traefik: docker network name")
+ cmd.PersistentFlags().String("traefik.network", "traefik", "traefik: docker network name (deprecated, use instance.network)")
if err := viper.BindPFlag("traefik.network", cmd.PersistentFlags().Lookup("traefik.network")); err != nil {
return err
}
@@ -182,7 +197,7 @@ func (s *Room) Set() {
s.NAT1To1IPs = viper.GetStringSlice("nat1to1")
s.NekoImages = viper.GetStringSlice("neko_images")
s.NekoPrivilegedImages = viper.GetStringSlice("neko_privileged_images")
- s.PathPrefix = viper.GetString("path_prefix")
+ s.PathPrefix = path.Join("/", path.Clean(viper.GetString("path_prefix")))
s.Labels = viper.GetStringSlice("labels")
s.StorageEnabled = viper.GetBool("storage.enabled")
@@ -224,18 +239,33 @@ func (s *Room) Set() {
}
}
- s.TraefikDomain = viper.GetString("traefik.domain")
- s.TraefikEntrypoint = viper.GetString("traefik.entrypoint")
- s.TraefikCertresolver = viper.GetString("traefik.certresolver")
- s.TraefikNetwork = viper.GetString("traefik.network")
-
- // deprecated
- s.TraefikPort = viper.GetString("traefik.port")
- if s.TraefikPort != "" {
- if s.InstanceUrl != nil {
- log.Warn().Msg("deprecated `traefik.port` config item is ignored when `instance.url` is set")
- } else {
- log.Warn().Msg("you are using deprecated `traefik.port` config item, you should consider moving to `instance.url`")
+ s.InstanceNetwork = viper.GetString("instance.network")
+
+ s.Traefik.Enabled = viper.GetBool("traefik.enabled")
+ if s.Traefik.Enabled {
+ s.Traefik.Domain = viper.GetString("traefik.domain")
+ s.Traefik.Entrypoint = viper.GetString("traefik.entrypoint")
+ s.Traefik.Certresolver = viper.GetString("traefik.certresolver")
+
+ // deprecated
+ traefikNetwork := viper.GetString("traefik.network")
+ if traefikNetwork != "" {
+ if s.InstanceNetwork != "" {
+ log.Warn().Msg("deprecated `traefik.network` config item is ignored when `instance.network` is set")
+ } else {
+ log.Warn().Msg("you are using deprecated `traefik.network` config item, you should consider moving to `instance.network`")
+ s.InstanceNetwork = traefikNetwork
+ }
+ }
+
+ // deprecated
+ s.Traefik.Port = viper.GetString("traefik.port")
+ if s.Traefik.Port != "" {
+ if s.InstanceUrl != nil {
+ log.Warn().Msg("deprecated `traefik.port` config item is ignored when `instance.url` is set")
+ } else {
+ log.Warn().Msg("you are using deprecated `traefik.port` config item, you should consider moving to `instance.url`")
+ }
}
}
}
@@ -251,17 +281,19 @@ func (s *Room) GetInstanceUrl() url.URL {
Path: "/",
}
- if s.TraefikCertresolver != "" {
- instanceUrl.Scheme = "https"
- }
+ if s.Traefik.Enabled {
+ if s.Traefik.Certresolver != "" {
+ instanceUrl.Scheme = "https"
+ }
- if s.TraefikDomain != "" && s.TraefikDomain != "*" {
- instanceUrl.Host = s.TraefikDomain
- }
+ if s.Traefik.Domain != "" && s.Traefik.Domain != "*" {
+ instanceUrl.Host = s.Traefik.Domain
+ }
- // deprecated
- if s.TraefikPort != "" {
- instanceUrl.Host += ":" + s.TraefikPort
+ // deprecated
+ if s.Traefik.Port != "" {
+ instanceUrl.Host += ":" + s.Traefik.Port
+ }
}
return instanceUrl
diff --git a/internal/config/server.go b/internal/config/server.go
index 7d35626..bbdf4ae 100644
--- a/internal/config/server.go
+++ b/internal/config/server.go
@@ -5,13 +5,21 @@ import (
"github.com/spf13/viper"
)
+type Admin struct {
+ Static string
+ ProxyAuth string
+ Username string
+ Password string
+}
+
type Server struct {
- Cert string
- Key string
- Bind string
- Static string
- Proxy bool
- PProf bool
+ Cert string
+ Key string
+ Bind string
+ Proxy bool
+ PProf bool
+
+ Admin Admin
}
func (Server) Init(cmd *cobra.Command) error {
@@ -30,11 +38,6 @@ func (Server) Init(cmd *cobra.Command) error {
return err
}
- cmd.PersistentFlags().String("static", "./www", "path to neko_rooms client files to serve")
- if err := viper.BindPFlag("static", cmd.PersistentFlags().Lookup("static")); err != nil {
- return err
- }
-
cmd.PersistentFlags().Bool("proxy", false, "trust reverse proxy headers")
if err := viper.BindPFlag("proxy", cmd.PersistentFlags().Lookup("proxy")); err != nil {
return err
@@ -45,6 +48,28 @@ func (Server) Init(cmd *cobra.Command) error {
return err
}
+ // Admin
+
+ cmd.PersistentFlags().String("admin.static", "", "path to neko_rooms admin client files to serve")
+ if err := viper.BindPFlag("admin.static", cmd.PersistentFlags().Lookup("admin.static")); err != nil {
+ return err
+ }
+
+ cmd.PersistentFlags().String("admin.proxy_auth", "", "require auth: proxy authentication URL, only allow if it returns 200")
+ if err := viper.BindPFlag("admin.proxy_auth", cmd.PersistentFlags().Lookup("admin.proxy_auth")); err != nil {
+ return err
+ }
+
+ cmd.PersistentFlags().String("admin.username", "admin", "require auth: admin username")
+ if err := viper.BindPFlag("admin.username", cmd.PersistentFlags().Lookup("admin.username")); err != nil {
+ return err
+ }
+
+ cmd.PersistentFlags().String("admin.password", "", "require auth: admin password")
+ if err := viper.BindPFlag("admin.password", cmd.PersistentFlags().Lookup("admin.password")); err != nil {
+ return err
+ }
+
return nil
}
@@ -52,7 +77,11 @@ func (s *Server) Set() {
s.Cert = viper.GetString("cert")
s.Key = viper.GetString("key")
s.Bind = viper.GetString("bind")
- s.Static = viper.GetString("static")
s.Proxy = viper.GetBool("proxy")
s.PProf = viper.GetBool("pprof")
+
+ s.Admin.Static = viper.GetString("admin.static")
+ s.Admin.ProxyAuth = viper.GetString("admin.proxy_auth")
+ s.Admin.Username = viper.GetString("admin.username")
+ s.Admin.Password = viper.GetString("admin.password")
}
diff --git a/internal/api/lobby.go b/internal/proxy/lobby.go
similarity index 72%
rename from internal/api/lobby.go
rename to internal/proxy/lobby.go
index f7a4394..fc81add 100644
--- a/internal/api/lobby.go
+++ b/internal/proxy/lobby.go
@@ -1,41 +1,12 @@
-package api
+package proxy
import (
"net/http"
- "strings"
-
- "github.com/go-chi/chi"
"github.com/m1k1o/neko-rooms/internal/utils"
)
-func (manager *ApiManagerCtx) RoomLobby(w http.ResponseWriter, r *http.Request) {
- if !manager.conf.Lobby {
- http.NotFound(w, r)
- }
-
- roomName := chi.URLParam(r, "roomName")
- response, err := manager.rooms.FindByName(roomName)
-
- if err != nil || response.Name != roomName {
- manager.roomNotFound(w, r)
- return
- }
-
- if !response.Running {
- manager.roomNotRunning(w, r)
- return
- }
-
- if strings.Contains(response.Status, "starting") {
- manager.roomNotReady(w, r)
- return
- }
-
- manager.roomReady(w, r)
-}
-
-func (manager *ApiManagerCtx) roomNotFound(w http.ResponseWriter, r *http.Request) {
+func RoomNotFound(w http.ResponseWriter, r *http.Request) {
utils.Swal2Response(w, `