···11-# # [jneen] DO NOT EDIT THIS FILE
22-# # instead, override values in a separate private.env
33-#
44-# export APP_PORT=9000
55-# export DB_PORT=5432
66-# export HTTP_PORT=6001
77-# export HTTPS_PORT=6000
88-# # note: must be localhost for login to work
99-# export LISTEN_HOST=localhost
1010-#
1111-# export ENABLE_API_DEV_USER='true'
1212-# export FORCE_HTTP='false'
1313-# export DEBUG_LEVEL='light'
1414-# export COURSE_IMPORT_REQUIRE_VERIFY='false'
1515-# export COURSE_IMPORT_ENABLE_CACHE='true'
1616-# export USE_DUMP_FOR_SEARCHES='false'
1717-# export DUMP_FILENAME='fake.db'
1818-# export MIXED_DIFFICULTY='false'
1919-# export JWT_SECRET='localdev'
2020-# export DATA_VIEW_TYPE='combined_dyna'
2121-#
2222-# export TWITCH_CLIENT_ID=ufm5q62qafbnkp3leizjli8z89xo9w
2323-# export TWITCH_CLIENT_SECRET="set this in private.env"
2424-# export DISCORD_CLIENT_ID=1080395755581349908
2525-# export DISCORD_CLIENT_SECRET="set this in private.env"
2626-# export ENABLE_TAGS=false
2727-#
2828-# # load override values
2929-# . private.env
3030-#
3131-# export APP_URLS="http://$LISTEN_HOST:$APP_PORT"
3232-# export API_URLS="http://$LISTEN_HOST:$HTTP_PORT,https://$LISTEN_HOST:$HTTPS_PORT"
3333-# export REDIRECT_URLS="http://$LISTEN_HOST:$HTTP_PORT/api/connect/discord/callback"
3434-# export DYNA_URL="postgres://$LISTEN_HOST:$DB_PORT/opencourseworld?sslmode=disable&user=root&options=-c%20search_path=ocw,smm2srv,public"
3535-# export LISTEN_ADDRESS="$LISTEN_HOST:$HTTPS_PORT"
3636-# export LISTEN_ADDRESS_HTTP="$LISTEN_HOST:$HTTP_PORT"
3737-# export DNS_WHITELIST="$LISTEN_HOST:$HTTPS_PORT,$LISTEN_HOST:$HTTP_PORT"
+7-7
.gitignore
···11_vendor
22-data/*/*.json
33-data/*/*.bcd
44-data/*/*.jpg
55-data/*/*.jpeg
66-data/*.db
22+33+/data
74__pycache__
8596nex/.git_old
···2017env/
21182219*.bin
2020+*.zip
23212422.DS_Store
2523···2725*.dll
28262927/private.env
3030-/dev-db/data
2828+/.env
3129/smm2_gameserver
3232-certs
3030+3131+# unused, but still ignore just in case, as it may contain secrets
3232+/private.env
+48-18
Dockerfile
···11-FROM golang:latest as builder
11+# This Dockerfile is for both local development and production.
22+# See docker-compose.yml for local dev configuration.
33+FROM golang:latest AS builder
44+RUN go install -tags 'cockroachdb' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
2536WORKDIR /app
4758COPY go.mod go.sum ./
69RUN go mod download && go mod verify
71088-COPY main.go ./
99-COPY config config
1010-COPY db db
1111-COPY nex nex
1212-COPY util util
1313-COPY api api
1414-COPY orm orm
1111+COPY main.go /app/main.go
1212+COPY config /app/config
1313+COPY db /app/db
1414+COPY nex /app/nex
1515+COPY util /app/util
1616+COPY api /app/api
1717+COPY orm /app/orm
15181616-RUN go build -v -o /app/server *.go
1717-RUN go build -v -o /app/serve_cache util/serve_dump_cache/*.go
1818-RUN echo '{}' > /app/config.json
1919+ENV GOCACHE=/go-cache
2020+# use a docker cache mount to avoid recompiling all dependencies each time
2121+RUN --mount=type=cache,target=/go-cache \
2222+ go build -v -o /app/server *.go
2323+RUN --mount=type=cache,target=/go-cache \
2424+ go build -v -o /app/serve_cache util/serve_dump_cache/*.go
19252020-# be sure to have config.json inside /app/ mounted
2121-CMD ["/app/server"]
2626+CMD bash
22272323-#FROM gcr.io/distroless/base-debian10
2424-FROM golang:latest
2828+FROM debian:bookworm-slim
2929+RUN apt update && apt install -y curl
3030+3131+ARG TARGETARCH
3232+ENV COCKROACH_VERSION=v22.2.6.linux-$TARGETARCH
3333+ENV CRDB_CKSM_ARM64=aa3b695171235d143d8d0dc6ebdbec9908b7009b0e6f5b2f750cb3126d7e9298
3434+ENV CRDB_CKSM_AMD64=de670f9823d0794880ef0c72dfec213470cf6ea3fc96ed27e1706170bae6573b
3535+3636+# install the cockroach-sql standalone binary
3737+RUN curl -q https://binaries.cockroachdb.com/cockroach-sql-$COCKROACH_VERSION.tgz | \
3838+ tar -xzvf - -C /usr/local/bin --strip-components 1 cockroach-sql-$COCKROACH_VERSION/cockroach-sql \
3939+ && if [ $TARGETARCH = "arm64" ]; then checksum=$CRDB_CKSM_ARM64; elif [ $TARGETARCH = "amd64" ]; then checksum=$CRDB_CKSM_AMD64; fi \
4040+ && echo "$checksum /usr/local/bin/cockroach-sql" | sha256sum --check
4141+4242+COPY --from=builder /go/bin/migrate /bin/migrate
2543COPY --from=builder /app/server /bin/server
2644COPY --from=builder /app/serve_cache /bin/serve_cache
2727-COPY --from=builder /app/config.json /app/config.json
2845COPY --from=builder /app/db/migrations /app/db/migrations
4646+4747+# only scripts that can be used in production are listed here.
4848+# in dev, the entire scripts/ directory is mounted.
4949+COPY \
5050+ ./scripts/db-console.sh \
5151+ ./scripts/db-restore-aws.sh \
5252+ ./scripts/env.sh \
5353+ ./scripts/migrate.sh \
5454+ ./scripts/util.sh \
5555+ /app/scripts/
2956WORKDIR /app
3030-ENV HOSTNAME localhost
3131-CMD ["server"]
5757+5858+ENV IS_DOCKER=1
5959+ENV DB_CONSOLE_TYPE=cockroach-sql
6060+6161+CMD /bin/server
+29-11
README.md
···10101111### Set up a dev environment
12121313-Most of the configuration options can be found in `.env`, and can be overridden by creating a file called `private.env`. This can be used to set up secrets, or override ports or binding hosts.
1313+Documentation of the configuration options can be found in `scripts/defaults.sh`. Each of these can be overridden using the syntax `VAR=value` in a `.env` file, or overridden in your environment by other means, such as `direnv`.
14141515#### The Database
16161717We use CockroachDB for our database, which should be run through Docker. Once you have set up docker, run:
18181919```bash
2020-./dev-db/start.sh
2020+./scripts/db-start.sh
2121```
22222323to start the docker container for the database.
24242525-To restore a backup from production to your local database, you will need an AWS access key and secret. Put these in your `private.env`:
2525+To restore a backup from production to your local database, you will need an AWS access key and secret. Put these in your `.env`:
26262727```bash
2828export AWS_ACCESS_KEY_ID=...
2929export AWS_SECRET_ACCESS_KEY=...
3030```
31313232-and run `./dev-db/backup.sh` from the project root.
3232+and run `./scripts/db-restore-aws.sh` from the project root.
33333434#### Auth
35353636-In order to log in via Twitch and/or Discord, you will need to obtain client secrets from the team. Add them to your `private.env`:
3636+In order to log in via Twitch and/or Discord, you will need to obtain client secrets from the team. Add them to your `.env`:
37373838```bash
3939export DISCORD_CLIENT_SECRET=...
···4141```
42424343#### The App
4444-Once the database is running, source the environment and run the app with `go`:
4444+Once the database is running, run the app with `./scripts/app.sh`:
45454646```bash
4747-$ source .env
4848-$ go run -v main.go
4747+$ ./scripts/app.sh
4948```
50495150Once you have your server running, you can point your frontend to the http url configured in your env - by default, `http://localhost:6001`.
52515352#### Connecting Ryujinx
54535555-In order to connect Ryujinx to your local server, you must build a version yourself with SSL verification patched out. (TODO [jneen] get everything running behind caddy by default). The patch can be found in `ryujinx/ryujinx_disable_ssl_verify_for_local_testing.patch`.
5454+In order to connect Ryujinx to your local server, you must build a version yourself with SSL verification patched out. This is available on [our Ryujinx fork](https://github.com/mm2srv/Ryujinx), which we try to keep reasonably up to date. Alternatively, the patch can be found in this repository at `ryujinx/ryujinx_disable_ssl_verify_for_local_testing.patch`.
56555756## Game Client Mod
58575958[client-mod](https://github.com/mm2srv/client-mod) and [releases](https://github.com/mm2srv/client-mod/releases)
60596161-## Support
6060+## Running With Docker (recommended for Windows)
62616363-At this time there is no support to get your own server up and running.
6262+### Setup
6363+Before we get running with docker, you will need to:
6464+6565+* Install Docker.
6666+* Create a file in the project called `.env` - you can place config overrides here.
6767+* Open a terminal and `cd` or `dir` into the project root.
6868+6969+### Running
7070+7171+* Build the containers with `docker compose build`.
7272+* Run `docker compose up` and all the services will start.
7373+* To restart, quit the server using Ctrl-C and run both the above commands again.
7474+* For faster restarts, it's recommended to run the db in a separate terminal with `docker compose up db`. You can then run the app with `docker compose build app` and `docker compose run app`. Run both commands to restart when you've made code changes.
7575+7676+### Scripts
7777+* To run scripts, use `docker compose exec app bash`, or `docker compose exec app ./scripts/some-script.sh`.
7878+ - For example, to run a database console, use `docker compose exec app ./scripts/db-console.sh`
7979+ - To print `ocw-config.json` for the dev user, use `docker compose exec app ./scripts/ocw-api.sh ocw-config.json`
8080+ - You can do similar for other scripts documented above.
8181+* If the app isn't running, use `docker compose run --rm` in place of `docker compose exec`. This will create a temporary container for running scripts in.
···11+#!/usr/bin/env bash
22+33+. ./scripts/util.sh
44+55+[[ -n "$IS_DOCKER" ]] && \
66+ fail 'no need to use this script inside docker, use /bin/server instead'
77+88+check-exe go 'you must install golang to run the server: https://go.dev'
99+1010+go run -v main.go
···11+#!/usr/bin/env bash
22+33+. ./scripts/util.sh
44+55+[[ -z "$AWS_SECRET_ACCESS_KEY" ]] && fail 'please set AWS_SECRET_ACCESS_KEY.'
66+[[ -z "$AWS_ACCESS_KEY_ID" ]] && fail 'please set AWS_ACCESS_KEY_ID.'
77+88+sql "drop database if exists opencourseworld"
99+sql "restore database opencourseworld from latest in 's3://ocw-db/single_backups/opencourseworld?AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID&AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY'"
+7
scripts/db-start.sh
···11+#!/usr/bin/env bash
22+33+. ./scripts/util.sh
44+55+[[ -n "$IS_DOCKER" ]] && fail 'no need to run scripts/db-start.sh inside docker'
66+77+execd docker compose up db
+80
scripts/defaults.sh
···11+#!/usr/bin/env bash
22+33+# Default configs for the app. override these in .env or in your OS environment.
44+#
55+# DO NOT EDIT THIS FILE, you should override these variables in .env instead
66+#
77+# If you are changing or adding defaults *for everyone*, you can do it here,
88+# but please make sure they are in sync with the defaults in docker-compose.yml.
99+1010+default() {
1111+ local __var="$1"; shift
1212+ local __val="$1"; shift
1313+1414+ [[ -z "${!__var}" ]] && export "$__var"="$__val"
1515+}
1616+1717+# Specify the port for ocw-web.
1818+default APP_PORT 9000
1919+2020+# Specify the port for the database.
2121+default DB_PORT 5432
2222+default HTTP_PORT 6001
2323+default HTTPS_PORT 6000
2424+2525+# note: for local dev, must be localhost for login to work
2626+default LISTEN_HOST localhost
2727+2828+# variables for accessing cockroachdb.
2929+# Note: these are provided for overriding convenience only. Scripts and the app
3030+# should only rely on the value of $DYNA_URL.
3131+default DB_HOST localhost
3232+default DB_USER root
3333+default DB_NAME opencourseworld
3434+3535+# General app configs
3636+default ENABLE_API_DEV_USER true
3737+default FORCE_HTTP false
3838+default DEBUG_LEVEL light
3939+default COURSE_IMPORT_REQUIRE_VERIFY false
4040+default COURSE_IMPORT_ENABLE_CACHE true
4141+default USE_DUMP_FOR_SEARCHES false
4242+default MIXED_DIFFICULTY false
4343+default DATA_VIEW_TYPE combined_dyna
4444+4545+default DATA_DIR ./data
4646+4747+# Location of dumps on your system, if in use. Note: if using docker,
4848+# these must live in ./data, and you should use a symbolic link if you
4949+# need them elsewhere.
5050+default DUMP_FILENAME ./data/dumps/dump.db
5151+default DUMP_THUMBS_FILENAME ./data/dumps/dump_thumbs.db
5252+5353+# A secret to use for logins. Does not have to be secure in local dev.
5454+default JWT_SECRET localdev
5555+5656+# can be overridden to cockroach or psql, depending on which interface
5757+# you prefer. by default we try to detect which is installed.
5858+default DB_CONSOLE_TYPE auto
5959+6060+# can be overridden to cockroach or psql, depending on which interface
6161+# you prefer. by default we try to detect which is installed.
6262+default DB_CONSOLE_TYPE auto
6363+6464+default TWITCH_CLIENT_ID ufm5q62qafbnkp3leizjli8z89xo9w
6565+default TWITCH_CLIENT_SECRET 'please set TWITCH_CLIENT_SECRET in .env'
6666+default DISCORD_CLIENT_ID 1080395755581349908
6767+default DISCORD_CLIENT_SECRET 'please set DISCORD_CLIENT_SECRET in .env'
6868+default ENABLE_TAGS false
6969+default DB_SCHEMA_NAME smm2srv
7070+7171+default AWS_ACCESS_KEY_ID 'please set AWS_ACCESS_KEY_ID in .env'
7272+default AWS_SECRET_ACCESS_KEY 'please set AWS_SECRET_ACCESS_KEY in .env'
7373+7474+default APP_URLS "http://$LISTEN_HOST:$APP_PORT"
7575+default API_URLS "http://$LISTEN_HOST:$HTTP_PORT,https://$LISTEN_HOST:$HTTPS_PORT"
7676+default REDIRECT_URLS "http://$LISTEN_HOST:$HTTP_PORT/api/connect/discord/callback"
7777+default DYNA_URL "postgres://$DB_HOST:$DB_PORT/$DB_NAME?sslmode=disable&user=$DB_USER&options=-c%20search_path%3D$DB_SCHEMA_NAME,public"
7878+default LISTEN_ADDRESS "$LISTEN_HOST:$HTTPS_PORT"
7979+default LISTEN_ADDRESS_HTTP "$LISTEN_HOST:$HTTP_PORT"
8080+default DNS_WHITELIST "$LISTEN_HOST:$HTTPS_PORT,$LISTEN_HOST:$HTTP_PORT"