From 911c34d79c2ddec49da802bc015900eb8dfad995 Mon Sep 17 00:00:00 2001 From: Natalie Rose Date: Thu, 3 Sep 2026 16:01:21 +1000 Subject: [PATCH] =?UTF-8?q?New=20docker/compose=20structure=20=F0=9F=90=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- .prettierignore | 2 +- CLAUDE.md | 60 ++-- bin/dump_body_class_info.pl | 2 +- bin/dump_building_class_info.pl | 2 +- bin/lacuna.psgi | 2 +- bin/run_tests.sh | 11 +- docker-compose.deployed.yml | 275 --------------- docker-compose.yml | 281 --------------- docker/{build-app => app}/Dockerfile | 0 docker/app/docker-compose.yml | 17 + docker/beanstalk/docker-compose.yml | 14 + docker/build-rails/Dockerfile | 19 - docker/docker-compose.dev.yml | 55 +++ docker/docker-compose.homelab.yml | 78 +++++ docker/docker-compose.test.yml | 87 +++++ docker/memcached/docker-compose.yml | 9 + docker/mysql/docker-compose.yml | 11 + docker/{build-nginx => nginx}/Dockerfile | 0 docker/nginx/docker-compose.yml | 21 ++ {etc-docker => docker/nginx}/nginx.conf | 210 ++++++----- docker/phpmyadmin/docker-compose.yml | 15 + docker/{build-server => server}/Dockerfile | 0 docker/server/docker-compose.yml | 93 +++++ .../server/etc-dev}/lacuna.conf | 326 +++++++++--------- .../server/etc-dev}/log4perl.conf | 10 +- docker/server/etc-homelab/lacuna.conf | 163 +++++++++ docker/server/etc-homelab/log4perl.conf | 5 + docker/server/etc-test/lacuna.conf | 163 +++++++++ docker/server/etc-test/log4perl.conf | 5 + {etc-docker => docker/server}/schedule.ini | 18 +- .../{build-super-ui => super-ui}/Dockerfile | 0 docker/super-ui/docker-compose.yml | 13 + .../tailscale/config}/lacuna.json | 0 docker/tailscale/docker-compose.yml | 25 ++ docker/{build-v2-api => v2-api}/Dockerfile | 0 docker/v2-api/docker-compose.yml | 15 + etc-docker/README.md | 6 - info/setup.md | 16 +- lacuna/app/lib/lacuna_server_info.rb | 4 +- lacuna/config/database.yml | 2 +- lacuna/config/initializers/memcached.rb | 4 +- lib/Lacuna.pm | 2 +- package.json | 18 +- t/TestHelper.pm | 2 +- v2-api/index.ts | 2 +- 46 files changed, 1137 insertions(+), 930 deletions(-) delete mode 100644 docker-compose.deployed.yml delete mode 100644 docker-compose.yml rename docker/{build-app => app}/Dockerfile (100%) create mode 100644 docker/app/docker-compose.yml create mode 100644 docker/beanstalk/docker-compose.yml delete mode 100644 docker/build-rails/Dockerfile create mode 100644 docker/docker-compose.dev.yml create mode 100644 docker/docker-compose.homelab.yml create mode 100644 docker/docker-compose.test.yml create mode 100644 docker/memcached/docker-compose.yml create mode 100644 docker/mysql/docker-compose.yml rename docker/{build-nginx => nginx}/Dockerfile (100%) create mode 100644 docker/nginx/docker-compose.yml rename {etc-docker => docker/nginx}/nginx.conf (83%) create mode 100644 docker/phpmyadmin/docker-compose.yml rename docker/{build-server => server}/Dockerfile (100%) create mode 100644 docker/server/docker-compose.yml rename {etc-docker => docker/server/etc-dev}/lacuna.conf (91%) rename {etc-docker => docker/server/etc-dev}/log4perl.conf (97%) create mode 100644 docker/server/etc-homelab/lacuna.conf create mode 100644 docker/server/etc-homelab/log4perl.conf create mode 100644 docker/server/etc-test/lacuna.conf create mode 100644 docker/server/etc-test/log4perl.conf rename {etc-docker => docker/server}/schedule.ini (86%) rename docker/{build-super-ui => super-ui}/Dockerfile (100%) create mode 100644 docker/super-ui/docker-compose.yml rename {etc-docker/tailscale => docker/tailscale/config}/lacuna.json (100%) create mode 100644 docker/tailscale/docker-compose.yml rename docker/{build-v2-api => v2-api}/Dockerfile (100%) create mode 100644 docker/v2-api/docker-compose.yml delete mode 100644 etc-docker/README.md diff --git a/.gitignore b/.gitignore index e580e518..4e8d29c5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,12 +12,10 @@ var/www/public/api var/www/public/captcha data/ data.*.bak/ -data-tailscale/ -etc-docker/logs/ tmp/ log/ captcha/ -memcached/ +/memcached/ node_modules/ .env lacuna/coverage/ diff --git a/.prettierignore b/.prettierignore index 7f9ded15..d96cfe97 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,7 +5,7 @@ data/ homepage/ lacuna/ log/ -memcached/ +/memcached/ missions/ node_modules/ super-ui/ diff --git a/CLAUDE.md b/CLAUDE.md index 9f1f710d..cdf24bfb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,26 +21,24 @@ source of truth. Setup: -1. Copy `etc-docker/*` into a new (gitignored) `etc/` directory — `etc/lacuna.conf` (DB creds, beanstalk, captcha - config), `etc/log4perl.conf`, `etc/nginx.conf`. See `etc-docker/README.md`. -2. `docker compose up` +1. `npm run dev:build` +1. `npm run dev:up` Services defined in `docker-compose.yml` (dev; `docker-compose.deployed.yml` is the prod variant): -- `lacuna-mysql-server` — mysql:5.7, root password `lacuna`, port 3306 -- `lacuna-memcached` — session/cache store -- `lacuna-beanstalkd` (+ `-console` on 2080) — job queue -- `lacuna-phpmyadmin` — port 8888 -- `lacuna-nginx` — port 80→3000, serves static assets/app and proxies to server + v2-api -- `lacuna-v2-api` — newer TypeScript API, port 5999 -- `lacuna-server` — the Perl app, runs `bin/startdev.sh`, port 3050:5000 -- `lacuna-app` / `lacuna-super-ui` — build the frontend submodules -- `lacuna-server-{building,ship,captcha}-scheduler` — Perl scheduler processes -- `lacuna-server-script-scheduler` — ofelia-based cron, driven by `etc-docker/schedule.ini` - -Inside `lacuna-server`, `bin/startdev.sh` runs `perl generate_docs.pl` then -`plackup --env development --app lacuna.psgi`. Production instead uses -`start_server -- starman --workers 7 ... lacuna.psgi` (see `bin/start_lacuna.sh`). +- `mysql` — mysql:5.7, root password `lacuna`, port 3306 +- `memcached` — session/cache store +- `beanstalk` (+ `-console` on 2080) — job queue +- `phpmyadmin` — port 8888 +- `nginx` — port 80→3000, serves static assets/app and proxies to server + v2-api +- `v2-api` — newer TypeScript API, port 5999 +- `server` — the Perl app, runs `bin/startdev.sh`, port 3050:5000 +- `app` / `super-ui` — build the frontend submodules +- `server-{building,ship,captcha}-scheduler` — Perl scheduler processes +- `server-script-scheduler` — ofelia-based cron, driven by `docker/server/schedule.ini` + +Inside `server`, `bin/startdev.sh` runs `perl generate_docs.pl` then `plackup --env development --app lacuna.psgi`. +Production instead uses `start_server -- starman --workers 7 ... lacuna.psgi` (see `bin/start_lacuna.sh`). `bin/setup/server/*.sh` and `bin/setup/install-pm.sh` are legacy CentOS-era bare-metal setup scripts predating Docker — historical/reference only, not the recommended path. @@ -51,12 +49,12 @@ Tests are plain `Test::More`/prove style (no `.proverc`; `Test::Class::Moose` is base class). They are **integration tests that hit a live server over HTTP**, not isolated unit tests — via `t/TestHelper.pm` (LWP::UserAgent, plus helpers like `generate_test_empire`, `build_infrastructure`, `clear_all_test_empires`). `t/TestHelper.pm::post` sends its JSON-RPC calls to `$LACUNA_TEST_SERVER_URL` (default -`http://localhost:5000/` — the plackup server _inside_ the `lacuna-server` container), **not** -`Lacuna->config->get('server_url')` (which points at the deployed server). So the suite must run inside `lacuna-server` -with the compose stack up. +`http://localhost:5000/` — the plackup server _inside_ the `server` container), **not** +`Lacuna->config->get('server_url')` (which points at the deployed server). So the suite must run inside `server` with +the compose stack up. -- Full suite: `docker compose run --rm lacuna-server ./run_tests.sh` -- Single file: `docker compose run --rm lacuna-server ./run_tests.sh t/010_Empire.t` +- Full suite: `npm run dev:run -- server ./run_tests.sh` +- Single file: `npm run dev:run -- server ./run_tests.sh t/010_Empire.t` - `bin/run_tests.sh` just sets `LACUNA_TEST_SERVER_URL`, `cd`s to the server root and runs `prove -Ilib -It` (the `-It` makes `use TestHelper` resolve regardless of each file's own `use lib` line; note that the container's workdir is `bin/` so you don't need to have bin/ in your commands or set the working directory yourself). @@ -169,11 +167,10 @@ Rails fixtures (`lacuna/test/fixtures/*.yml`). ### Shared infrastructure with the Perl app Both apps run in the same `docker compose` stack and talk to the **same** MySQL DB and **same** memcached instance (see -`docker-compose.yml`'s `lacuna-mysql-server`/`lacuna-memcached` services, and `lacuna/config/database.yml` / -`lacuna/config/initializers/memcached.rb`). `etc-docker/`/`etc/` (the Perl app's `Config::JSON` config) is **not** -mounted into the `lacuna-rails` container — any server-level constant Perl reads from that file (version, map_size, -rpc_limit) has to be hand-synced into a Rails constant instead (see `LacunaServerInfo`) with a comment pointing at the -Perl source of truth. +`docker-compose.yml`'s `mysql`/`memcached` services, and `lacuna/config/database.yml` / +`lacuna/config/initializers/memcached.rb`). `etc/` (the Perl app's `Config::JSON` config) is **not** mounted into the +`rails` container — any server-level constant Perl reads from that file (version, map_size, rpc_limit) has to be +hand-synced into a Rails constant instead (see `LacunaServerInfo`) with a comment pointing at the Perl source of truth. ### Perl quirks that must be mirrored exactly @@ -202,7 +199,7 @@ Perl source of truth. - **Per-leaf-class constants aren't hand-transcribed** — where Perl encodes data as `use constant` on ~70 leaf classes (body image name, ore/water concentrations) or a resultset's static config hash (`Lacuna::DB::Result::Medals`' `MEDALS`), Rails reads a JSON file generated by a one-off Perl dump script instead: `config/medals.json` and - `config/body_class_info.json`, produced by `bin/dump_body_class_info.pl` (run inside the `lacuna-server` container: + `config/body_class_info.json`, produced by `bin/dump_body_class_info.pl` (run inside the `server` container: `perl -Ilib bin/dump_body_class_info.pl`). Regenerate via the script if the Perl source changes — don't hand-edit the JSON. - **Aggregate resource fields aren't columns**: `food_stored`/`food_hour`/`ore_stored`/`ore_hour` are Perl methods that @@ -226,10 +223,9 @@ There's no live cross-service comparison at test time (Rails' test DB and Perl's Instead, parity is established once, manually, then frozen: 1. Create a throwaway test empire directly against the shared dev DB — - `perl -Ilib bin/make_rails_test_empire.pl ""` (run inside the `lacuna-server` container; mirrors - `t/TestHelper.pm`'s `generate_test_empire`, working around a pre-existing `probes` table / MySQL 5.7 reserved-word - incompatibility in `Empire#found` by inserting the empire directly and letting the caller seed a home - planet/session). + `perl -Ilib bin/make_rails_test_empire.pl ""` (run inside the `server` container; mirrors `t/TestHelper.pm`'s + `generate_test_empire`, working around a pre-existing `probes` table / MySQL 5.7 reserved-word incompatibility in + `Empire#found` by inserting the empire directly and letting the caller seed a home planet/session). 2. Hit the real Perl JSON-RPC endpoint with that session (`curl -X POST http://localhost:3050/ -d '{"jsonrpc":"2.0","id":1,"method":"get_status","params":[...]}'`) and save the `result` payload as `lacuna/test/fixtures/files//*_golden.json`. diff --git a/bin/dump_body_class_info.pl b/bin/dump_body_class_info.pl index c31a8b37..0280e855 100644 --- a/bin/dump_body_class_info.pl +++ b/bin/dump_body_class_info.pl @@ -2,7 +2,7 @@ # One-off dump of per-leaf-body-class image/water/ore-concentration constants, consumed by # lacuna/config/body_class_info.json (Rails' Body#get_status port). Analogous to how # lacuna/config/medals.json was generated from Lacuna::DB::Result::Medals' MEDALS constant. -# Run inside the lacuna-server container: perl -Ilib bin/dump_body_class_info.pl +# Run inside the server container: perl -Ilib bin/dump_body_class_info.pl use strict; use warnings; use lib 'lib'; diff --git a/bin/dump_building_class_info.pl b/bin/dump_building_class_info.pl index 5f22181c..ac4e1dcd 100644 --- a/bin/dump_building_class_info.pl +++ b/bin/dump_building_class_info.pl @@ -2,7 +2,7 @@ # One-off dump of per-leaf-building-class image/name/url/build-cost constants, consumed by # lacuna/config/building_class_info.json (Rails' Building#get_buildings port). Analogous to # bin/dump_body_class_info.pl for Body#get_status. -# Run inside the lacuna-server container: perl -Ilib bin/dump_building_class_info.pl +# Run inside the server container: perl -Ilib bin/dump_building_class_info.pl use strict; use warnings; use lib 'lib'; diff --git a/bin/lacuna.psgi b/bin/lacuna.psgi index 5c877de9..16024233 100644 --- a/bin/lacuna.psgi +++ b/bin/lacuna.psgi @@ -258,7 +258,7 @@ my $app = builder { } # Dev-only test setup/teardown endpoints. Gated on LACUNA_TEST_SETUP_API, - # which docker-compose.yml sets for lacuna-server and + # which docker-compose.yml sets for server and # docker-compose.deployed.yml deliberately does not -- so /test simply does # not exist in production. See lib/Lacuna/Web/TestSetup.pm. if ($ENV{LACUNA_TEST_SETUP_API}) { diff --git a/bin/run_tests.sh b/bin/run_tests.sh index 3758c8f6..e3880427 100644 --- a/bin/run_tests.sh +++ b/bin/run_tests.sh @@ -1,21 +1,20 @@ #!/bin/bash + # Run the Lacuna Perl integration test suite. # -# MUST run inside the lacuna-server container: it needs the app server on :5000, +# MUST run inside the server container: it needs the app server on :5000, # MySQL + memcached + beanstalkd reachable, and the Carton deps baked into the # image's ./local. From the host: # -# docker compose run --rm lacuna-server ./run_tests.sh # default set -# docker compose run --rm lacuna-server ./run_tests.sh t/010_Empire.t # one file / dir -# # The tests POST their JSON-RPC calls to $LACUNA_TEST_SERVER_URL (see # t/TestHelper.pm), which defaults below to this container's own server. You can # point it elsewhere, but the empire-create tests (t/010_Empire.t) still need to -# run from inside lacuna-server so the server sees the client as 127.0.0.1 -- +# run from inside server so the server sees the client as 127.0.0.1 -- # the IP the test seeds the create-empire captcha under. + set -eu -: "${LACUNA_TEST_SERVER_URL:=http://lacuna-server:5000/}" +: "${LACUNA_TEST_SERVER_URL:=http://server:5000/}" export LACUNA_TEST_SERVER_URL cd /home/lacuna/server diff --git a/docker-compose.deployed.yml b/docker-compose.deployed.yml deleted file mode 100644 index 16bcc4f6..00000000 --- a/docker-compose.deployed.yml +++ /dev/null @@ -1,275 +0,0 @@ -volumes: - app-node_modules: - super-ui-node_modules: - v2-api-node_modules: - -services: - ######################## - ## BEANSTALKD CONSOLE ## - ######################## - - lacuna-beanstalkd-console: - container_name: 'lacuna-beanstalkd-console' - depends_on: - - 'lacuna-beanstalkd' - image: 'schickling/beanstalkd-console' - ports: - - '2080:2080' - - ################ - ## BEANSTALKD ## - ################ - - lacuna-beanstalkd: - container_name: 'lacuna-beanstalkd' - image: 'schickling/beanstalkd' - ports: - - '11300:11300' - - ############### - ## MEMCACHED ## - ############### - - lacuna-memcached: - container_name: 'lacuna-memcached' - image: 'memcached' - command: - # Persist cache in a file to save sessions (and other data) between restarts of the docker container - - --memory-file=/tempfs_mount/memory_file - volumes: - - ./memcached:/tempfs_mount - - ################## - ## MYSQL SERVER ## - ################## - - lacuna-mysql-server: - container_name: 'lacuna-mysql-server' - platform: linux/amd64 - environment: - - 'MYSQL_ROOT_PASSWORD=lacuna' - image: 'mysql:5.5' - volumes: - - './data:/var/lib/mysql' - ports: - - '3306:3306' - - ################ - ## PHPMYADMIN ## - ################ - - lacuna-phpmyadmin: - container_name: 'lacuna-phpmyadmin' - image: 'phpmyadmin:5.2-apache' - environment: - - 'PMA_HOST=lacuna-mysql-server' - ports: - - '8888:80' - depends_on: - - 'lacuna-mysql-server' - links: - - 'lacuna-mysql-server' - - ########### - ## NGINX ## - ########### - - lacuna-tailscale: - image: tailscale/tailscale:latest - container_name: lacuna-tailscale - hostname: lacuna - environment: - - TS_AUTHKEY=${TAILSCALE_AUTHKEY:?error} - - TS_EXTRA_ARGS=--advertise-tags=tag:container - - TS_SERVE_CONFIG=/config/lacuna.json - - TS_STATE_DIR=/var/lib/tailscale - - TS_USERSPACE=false - - TS_ENABLE_HEALTH_CHECK=true - healthcheck: - test: ['CMD', 'wget', '--spider', '-q', 'http://127.0.0.1:9002/healthz'] - interval: 10s - timeout: 3s - volumes: - - ./data-tailscale:/var/lib/tailscale - - ./etc-docker/tailscale:/config - devices: - - /dev/net/tun:/dev/net/tun - cap_add: - - net_admin - - sys_module - restart: unless-stopped - - lacuna-nginx: - build: - context: . - dockerfile: ./docker/build-nginx/Dockerfile - container_name: 'lacuna-nginx' - network_mode: service:lacuna-tailscale - depends_on: - lacuna-server: - condition: service_started - lacuna-tailscale: - condition: service_healthy - lacuna-v2-api: - condition: service_started - volumes: - - ./etc-docker/nginx.conf:/etc/nginx/nginx.conf - - ./etc-docker:/home/lacuna/server/etc - - ./var:/home/lacuna/server/var - - ./log/nginx:/etc/nginx/logs - - ./captcha:/home/lacuna/server/captcha - - ./assets:/home/lacuna/server/var/www/public/assets - - ./homepage:/home/lacuna/server/var/www/public/homepage - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - # TODO: fix CORS etc so that the app can run here properly - # - ./app/dist/index.html:/home/lacuna/server/var/www/public/index.html - # - ./app/dist/app:/home/lacuna/server/var/www/public/app - - ./app/dist:/home/lacuna/server/var/www/public/app - - ./super-ui/dist:/home/lacuna/server/var/www/public/super-ui - - lacuna-v2-api: - build: - context: . - dockerfile: ./docker/build-v2-api/Dockerfile - container_name: 'lacuna-v2-api' - command: node index.ts - ports: - - '5999:5999' - volumes: - - v2-api-node_modules:/usr/src/v2-api/node_modules - - ./v2-api:/usr/src/v2-api - - ######### - ## APP ## - ######### - - lacuna-app: - build: - context: . - dockerfile: ./docker/build-app/Dockerfile - container_name: 'lacuna-app' - command: npx vite build - volumes: - - app-node_modules:/usr/src/app/node_modules - - ./app:/usr/src/app - environment: - - 'LACUNA_ASSETS_URL=https://lacuna.allosaurus-chromatic.ts.net/assets/' - - 'LACUNA_SERVER_URL=https://lacuna.allosaurus-chromatic.ts.net' - - 'LACUNA_API_KEY=anonymous' - - lacuna-super-ui: - build: - context: . - dockerfile: ./docker/build-super-ui/Dockerfile - container_name: lacuna-super-ui - command: npm run build - volumes: - - super-ui-node_modules:/usr/src/app/node_modules - - ./super-ui:/usr/src/app - - ############ - ## SERVER ## - ############ - - lacuna-server: - build: - context: . - dockerfile: ./docker/build-server/Dockerfile - command: '/bin/bash startdev.sh' - container_name: 'lacuna-server' - depends_on: - - 'lacuna-mysql-server' - - 'lacuna-phpmyadmin' - - 'lacuna-memcached' - - 'lacuna-beanstalkd' - environment: - - 'TLE_NO_MIDDLEWARE=1' - ports: - - '3050:5000' - volumes: - - ./bin:/home/lacuna/server/bin - - ./captcha:/home/lacuna/server/captcha - - ./docs:/home/lacuna/server/docs - - ./etc-docker:/home/lacuna/server/etc - - ./lib:/home/lacuna/server/lib - - ./t:/home/lacuna/server/t - - ./var:/home/lacuna/server/var - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - - ./missions:/home/lacuna/server/missions - - ./tmp:/tmp - - lacuna-server-building-scheduler: - build: - context: . - dockerfile: ./docker/build-server/Dockerfile - command: 'perl schedule_building.pl --noquiet --nodaemonize --initialize' - container_name: 'lacuna-server-building-scheduler' - depends_on: - - 'lacuna-mysql-server' - - 'lacuna-phpmyadmin' - - 'lacuna-memcached' - - 'lacuna-beanstalkd' - volumes: - - ./bin:/home/lacuna/server/bin - - ./captcha:/home/lacuna/server/captcha - - ./docs:/home/lacuna/server/docs - - ./etc-docker:/home/lacuna/server/etc - - ./lib:/home/lacuna/server/lib - - ./t:/home/lacuna/server/t - - ./var:/home/lacuna/server/var - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - - ./tmp:/tmp - - lacuna-server-ship-scheduler: - build: - context: . - dockerfile: ./docker/build-server/Dockerfile - command: 'perl schedule_ship_arrival.pl --noquiet --nodaemonize --initialize' - container_name: 'lacuna-server-ship-scheduler' - depends_on: - - 'lacuna-mysql-server' - - 'lacuna-phpmyadmin' - - 'lacuna-memcached' - - 'lacuna-beanstalkd' - volumes: - - ./bin:/home/lacuna/server/bin - - ./captcha:/home/lacuna/server/captcha - - ./docs:/home/lacuna/server/docs - - ./etc-docker:/home/lacuna/server/etc - - ./lib:/home/lacuna/server/lib - - ./t:/home/lacuna/server/t - - ./var:/home/lacuna/server/var - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - - ./tmp:/tmp - - lacuna-server-captcha-scheduler: - build: - context: . - dockerfile: ./docker/build-server/Dockerfile - command: 'perl schedule_captcha.pl --noquiet --nodaemonize' - container_name: 'lacuna-server-captcha-scheduler' - depends_on: - - 'lacuna-mysql-server' - - 'lacuna-phpmyadmin' - - 'lacuna-memcached' - - 'lacuna-beanstalkd' - volumes: - - ./bin:/home/lacuna/server/bin - - ./captcha:/home/lacuna/server/captcha - - ./docs:/home/lacuna/server/docs - - ./etc-docker:/home/lacuna/server/etc - - ./lib:/home/lacuna/server/lib - - ./t:/home/lacuna/server/t - - ./var:/home/lacuna/server/var - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - - ./tmp:/tmp - - lacuna-server-script-scheduler: - container_name: 'lacuna-server-script-scheduler' - image: mcuadros/ofelia:latest - depends_on: - - lacuna-server - command: daemon - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - ./etc-docker/schedule.ini:/etc/ofelia.conf diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index e4a0997a..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,281 +0,0 @@ -volumes: - app-node_modules: - super-ui-node_modules: - v2-api-node_modules: - -services: - ######################## - ## BEANSTALKD CONSOLE ## - ######################## - - lacuna-beanstalkd-console: - container_name: 'lacuna-beanstalkd-console' - depends_on: - - 'lacuna-beanstalkd' - image: 'schickling/beanstalkd-console' - ports: - - '2080:2080' - - ################ - ## BEANSTALKD ## - ################ - - lacuna-beanstalkd: - container_name: 'lacuna-beanstalkd' - image: 'schickling/beanstalkd' - ports: - - '11300:11300' - - ############### - ## MEMCACHED ## - ############### - - lacuna-memcached: - container_name: 'lacuna-memcached' - image: 'memcached' - command: - # Persist cache in a file to save sessions (and other data) between restarts of the docker container - - --memory-file=/tempfs_mount/memory_file - volumes: - - ./memcached:/tempfs_mount - - ################## - ## MYSQL SERVER ## - ################## - - lacuna-mysql-server: - container_name: 'lacuna-mysql-server' - platform: linux/amd64 - environment: - - 'MYSQL_ROOT_PASSWORD=lacuna' - # Matches docker-compose.deployed.yml (prod runs 5.5). Was bumped to 5.7 for - # the lacuna-rails experiment; that service is commented out below for now. - image: 'mysql:5.5' - volumes: - - './data:/var/lib/mysql' - ports: - - '3306:3306' - - ################ - ## PHPMYADMIN ## - ################ - - lacuna-phpmyadmin: - container_name: 'lacuna-phpmyadmin' - image: 'phpmyadmin:5.2-apache' - environment: - - 'PMA_HOST=lacuna-mysql-server' - ports: - - '8888:80' - depends_on: - - 'lacuna-mysql-server' - links: - - 'lacuna-mysql-server' - - ########### - ## NGINX ## - ########### - - lacuna-nginx: - build: - context: . - dockerfile: ./docker/build-nginx/Dockerfile - container_name: 'lacuna-nginx' - ports: - - 3000:80 - depends_on: - lacuna-server: - condition: service_started - lacuna-v2-api: - condition: service_started - # lacuna-rails: - # condition: service_started - volumes: - - ./etc-docker/nginx.conf:/etc/nginx/nginx.conf - - ./etc-docker:/home/lacuna/server/etc - - ./var:/home/lacuna/server/var - - ./log/nginx:/etc/nginx/logs - - ./captcha:/home/lacuna/server/captcha - - ./assets:/home/lacuna/server/var/www/public/assets - - ./homepage:/home/lacuna/server/var/www/public/homepage - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - # TODO: fix CORS etc so that the app can run here properly - # - ./app/dist/index.html:/home/lacuna/server/var/www/public/index.html - # - ./app/dist/app:/home/lacuna/server/var/www/public/app - - ./app/dist:/home/lacuna/server/var/www/public/app - - ./super-ui/dist:/home/lacuna/server/var/www/public/super-ui - - lacuna-v2-api: - build: - context: . - dockerfile: ./docker/build-v2-api/Dockerfile - container_name: 'lacuna-v2-api' - command: node index.ts - ports: - - '5999:5999' - volumes: - - v2-api-node_modules:/usr/src/v2-api/node_modules - - ./v2-api:/usr/src/v2-api - - ######### - ## APP ## - ######### - - lacuna-app: - build: - context: . - dockerfile: ./docker/build-app/Dockerfile - container_name: 'lacuna-app' - command: npx vite dev - volumes: - - app-node_modules:/usr/src/app/node_modules - - ./app:/usr/src/app - environment: - - 'LACUNA_ASSETS_URL=http://localhost:3000/assets/' - - 'LACUNA_SERVER_URL=http://localhost:3000/' - - 'LACUNA_API_KEY=anonymous' - - lacuna-super-ui: - build: - context: . - dockerfile: ./docker/build-super-ui/Dockerfile - container_name: lacuna-super-ui - command: npm run build - volumes: - - super-ui-node_modules:/usr/src/app/node_modules - - ./super-ui:/usr/src/app - - ############ - ## SERVER ## - ############ - - lacuna-server: - build: - context: . - dockerfile: ./docker/build-server/Dockerfile - command: '/bin/bash startdev.sh' - container_name: 'lacuna-server' - depends_on: - - 'lacuna-mysql-server' - - 'lacuna-phpmyadmin' - - 'lacuna-memcached' - - 'lacuna-beanstalkd' - environment: - - 'TLE_NO_MIDDLEWARE=1' - - 'LACUNA_HIGH_SPEED_TEST_MODE=1' - # Mounts the dev-only /test setup/teardown API (lib/Lacuna/Web/TestSetup.pm). - # Deliberately absent from docker-compose.deployed.yml. - - 'LACUNA_TEST_SETUP_API=1' - ports: - - '3050:5000' - volumes: - - ./bin:/home/lacuna/server/bin - - ./captcha:/home/lacuna/server/captcha - - ./docs:/home/lacuna/server/docs - - ./etc-docker:/home/lacuna/server/etc - - ./lib:/home/lacuna/server/lib - - ./t:/home/lacuna/server/t - - ./var:/home/lacuna/server/var - - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - - ./missions:/home/lacuna/server/missions - - ./tmp:/tmp - - # lacuna-server-building-scheduler: - # build: - # context: . - # dockerfile: ./docker/build-server/Dockerfile - # command: 'perl schedule_building.pl --noquiet --nodaemonize --initialize' - # container_name: 'lacuna-server-building-scheduler' - # depends_on: - # - 'lacuna-mysql-server' - # - 'lacuna-phpmyadmin' - # - 'lacuna-memcached' - # - 'lacuna-beanstalkd' - # volumes: - # - ./bin:/home/lacuna/server/bin - # - ./captcha:/home/lacuna/server/captcha - # - ./docs:/home/lacuna/server/docs - # - ./etc-docker:/home/lacuna/server/etc - # - ./lib:/home/lacuna/server/lib - # - ./t:/home/lacuna/server/t - # - ./var:/home/lacuna/server/var - # - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - # - ./tmp:/tmp - - # lacuna-server-ship-scheduler: - # build: - # context: . - # dockerfile: ./docker/build-server/Dockerfile - # command: 'perl schedule_ship_arrival.pl --noquiet --nodaemonize --initialize' - # container_name: 'lacuna-server-ship-scheduler' - # depends_on: - # - 'lacuna-mysql-server' - # - 'lacuna-phpmyadmin' - # - 'lacuna-memcached' - # - 'lacuna-beanstalkd' - # volumes: - # - ./bin:/home/lacuna/server/bin - # - ./captcha:/home/lacuna/server/captcha - # - ./docs:/home/lacuna/server/docs - # - ./etc-docker:/home/lacuna/server/etc - # - ./lib:/home/lacuna/server/lib - # - ./t:/home/lacuna/server/t - # - ./var:/home/lacuna/server/var - # - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - # - ./tmp:/tmp - - # lacuna-server-captcha-scheduler: - # build: - # context: . - # dockerfile: ./docker/build-server/Dockerfile - # command: 'perl schedule_captcha.pl --noquiet --nodaemonize' - # container_name: 'lacuna-server-captcha-scheduler' - # depends_on: - # - 'lacuna-mysql-server' - # - 'lacuna-phpmyadmin' - # - 'lacuna-memcached' - # - 'lacuna-beanstalkd' - # volumes: - # - ./bin:/home/lacuna/server/bin - # - ./captcha:/home/lacuna/server/captcha - # - ./docs:/home/lacuna/server/docs - # - ./etc-docker:/home/lacuna/server/etc - # - ./lib:/home/lacuna/server/lib - # - ./t:/home/lacuna/server/t - # - ./var:/home/lacuna/server/var - # - ./var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css - # - ./tmp:/tmp - - # lacuna-server-script-scheduler: - # container_name: 'lacuna-server-script-scheduler' - # image: mcuadros/ofelia:latest - # depends_on: - # - lacuna-server - # command: daemon - # volumes: - # - /var/run/docker.sock:/var/run/docker.sock:ro - # - ./etc-docker/schedule.ini:/etc/ofelia.conf - - ################### - ## Ruby on Rails ## - ################### - # - # Temporarily disabled: the Rails app needs MySQL 5.7, but the dev DB has been - # reverted to 5.5 to match prod (docker-compose.deployed.yml) while the Perl - # server is moved to Perl 5.40. Re-enable together with `image: 'mysql:5.7'` - # above once the Perl upgrade has landed. - # - # lacuna-rails: - # build: - # context: . - # dockerfile: ./docker/build-rails/Dockerfile - # environment: - # RAILS_ENV: development - # command: bundle exec rails server --port 5001 --binding '0.0.0.0' - # depends_on: - # - lacuna-mysql-server - # - lacuna-memcached - # ports: - # - 5001:5001 - # volumes: - # - ./lacuna:/app diff --git a/docker/build-app/Dockerfile b/docker/app/Dockerfile similarity index 100% rename from docker/build-app/Dockerfile rename to docker/app/Dockerfile diff --git a/docker/app/docker-compose.yml b/docker/app/docker-compose.yml new file mode 100644 index 00000000..ed019c8d --- /dev/null +++ b/docker/app/docker-compose.yml @@ -0,0 +1,17 @@ +volumes: + app-node_modules: + +services: + app: + build: + context: ./../../ + dockerfile: ./docker/app/Dockerfile + container_name: app + command: npx vite dev + volumes: + - app-node_modules:/usr/src/app/node_modules + - ./../../app:/usr/src/app + environment: + LACUNA_ASSETS_URL: http://localhost:3000/assets/ + LACUNA_SERVER_URL: http://localhost:3000/ + LACUNA_API_KEY: anonymous diff --git a/docker/beanstalk/docker-compose.yml b/docker/beanstalk/docker-compose.yml new file mode 100644 index 00000000..53036c23 --- /dev/null +++ b/docker/beanstalk/docker-compose.yml @@ -0,0 +1,14 @@ +services: + beanstalk-console: + container_name: beanstalk-console + depends_on: + - beanstalk + image: schickling/beanstalkd-console + ports: + - 2080:2080 + + beanstalk: + container_name: beanstalk + image: schickling/beanstalkd + ports: + - 11300:11300 diff --git a/docker/build-rails/Dockerfile b/docker/build-rails/Dockerfile deleted file mode 100644 index 73783ce0..00000000 --- a/docker/build-rails/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM ruby:3.3.11 - -# Make sure bundler is up to date -RUN gem install bundler --version 2.5.22 - -# Install tools for local dev like MySql client and vim -RUN apt-get update && apt-get install -y --no-install-recommends \ - vim \ - && rm -rf /var/lib/apt/lists/* - -# Set our working directory inside the image -WORKDIR /app - -# Install Ruby dependencies -COPY ./lacuna/Gemfile ./lacuna/Gemfile.lock ./lacuna/.ruby-version ./ -RUN bundle install - -# Local dev environment variables. This sets the editor when using `rails credentials:edit` -ENV VISUAL='vim' diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml new file mode 100644 index 00000000..c1ada018 --- /dev/null +++ b/docker/docker-compose.dev.yml @@ -0,0 +1,55 @@ +include: + - ./app/docker-compose.yml + - ./beanstalk/docker-compose.yml + - ./memcached/docker-compose.yml + - ./mysql/docker-compose.yml + - ./phpmyadmin/docker-compose.yml + - ./nginx/docker-compose.yml + - ./super-ui/docker-compose.yml + - ./v2-api/docker-compose.yml + +services: + server: + extends: + file: ./server/docker-compose.yml + service: server + environment: + # Disables the prod-only size-limit / profiling middleware (bin/lacuna.psgi). + TLE_NO_MIDDLEWARE: 1 + # Mounts the dev-only /test setup/teardown API (lib/Lacuna/Web/TestSetup.pm). + # Deliberately absent from the test/homelab overlays. + LACUNA_TEST_SETUP_API: 1 + volumes: + - ./server/etc-dev:/home/lacuna/server/etc + + server-building-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-building-scheduler + volumes: + - ./server/etc-dev:/home/lacuna/server/etc + + server-ship-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-ship-scheduler + volumes: + - ./server/etc-dev:/home/lacuna/server/etc + + server-captcha-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-captcha-scheduler + volumes: + - ./server/etc-dev:/home/lacuna/server/etc + + server-script-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-script-scheduler + +networks: + default: + name: lacuna-dev + +name: lacuna-dev diff --git a/docker/docker-compose.homelab.yml b/docker/docker-compose.homelab.yml new file mode 100644 index 00000000..6c50b698 --- /dev/null +++ b/docker/docker-compose.homelab.yml @@ -0,0 +1,78 @@ +# Overlays that customise a service pull it in via `extends` (not `include`): +# Compose rejects a top-level override of a service that was brought in through +# `include` ("conflicts with imported resource"). Services used as-is stay in +# `include` below. +include: + - ./beanstalk/docker-compose.yml + - ./memcached/docker-compose.yml + - ./mysql/docker-compose.yml + - ./super-ui/docker-compose.yml + - ./tailscale/docker-compose.yml + - ./v2-api/docker-compose.yml + +volumes: + # Declared here because `app` is pulled via `extends` rather than `include`, + # so its own top-level `volumes:` block does not come along. + app-node_modules: + +services: + nginx: + extends: + file: ./nginx/docker-compose.yml + service: nginx + network_mode: service:tailscale + # nginx has no network of its own under network_mode: service:*, so the + # inherited published port would be rejected at container create. + ports: !reset [] + depends_on: + tailscale: + condition: service_healthy + + app: + extends: + file: ./app/docker-compose.yml + service: app + command: npx vite build + environment: + LACUNA_ASSETS_URL: https://lacuna.allosaurus-chromatic.ts.net/assets/ + LACUNA_SERVER_URL: https://lacuna.allosaurus-chromatic.ts.net + LACUNA_API_KEY: anonymous + + server: + extends: + file: ./server/docker-compose.yml + service: server + volumes: + - ./server/etc-homelab:/home/lacuna/server/etc + + server-building-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-building-scheduler + volumes: + - ./server/etc-homelab:/home/lacuna/server/etc + + server-ship-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-ship-scheduler + volumes: + - ./server/etc-homelab:/home/lacuna/server/etc + + server-captcha-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-captcha-scheduler + volumes: + - ./server/etc-homelab:/home/lacuna/server/etc + + server-script-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-script-scheduler + +networks: + default: + name: lacuna-homelab + +name: lacuna-homelab diff --git a/docker/docker-compose.test.yml b/docker/docker-compose.test.yml new file mode 100644 index 00000000..3bfe0c37 --- /dev/null +++ b/docker/docker-compose.test.yml @@ -0,0 +1,87 @@ +# Overlays that customise a service pull it in via `extends` (not `include`): +# Compose rejects a top-level override of a service that was brought in through +# `include` ("conflicts with imported resource"). Services used as-is stay in +# `include` below. +include: + - ./beanstalk/docker-compose.yml + - ./memcached/docker-compose.yml + - ./mysql/docker-compose.yml + - ./super-ui/docker-compose.yml + - ./v2-api/docker-compose.yml + +volumes: + # Declared here because `app` is pulled via `extends` rather than `include`, + # so its own top-level `volumes:` block does not come along. + app-node_modules: + +services: + tailscale: + extends: + file: ./tailscale/docker-compose.yml + service: tailscale + hostname: lacuna-test + + nginx: + extends: + file: ./nginx/docker-compose.yml + service: nginx + network_mode: service:tailscale + # nginx has no network of its own under network_mode: service:*, so the + # inherited published port would be rejected at container create. + ports: !reset [] + depends_on: + tailscale: + condition: service_healthy + + app: + extends: + file: ./app/docker-compose.yml + service: app + command: npx vite build + environment: + LACUNA_ASSETS_URL: https://lacuna-test.allosaurus-chromatic.ts.net/assets/ + LACUNA_SERVER_URL: https://lacuna-test.allosaurus-chromatic.ts.net + LACUNA_API_KEY: anonymous + + server: + extends: + file: ./server/docker-compose.yml + service: server + environment: + # Disables the prod-only size-limit / profiling middleware (bin/lacuna.psgi). + TLE_NO_MIDDLEWARE: 1 + LACUNA_HIGH_SPEED_TEST_MODE: 1 + volumes: + - ./server/etc-test:/home/lacuna/server/etc + + server-building-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-building-scheduler + volumes: + - ./server/etc-test:/home/lacuna/server/etc + + server-ship-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-ship-scheduler + volumes: + - ./server/etc-test:/home/lacuna/server/etc + + server-captcha-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-captcha-scheduler + volumes: + - ./server/etc-test:/home/lacuna/server/etc + + server-script-scheduler: + extends: + file: ./server/docker-compose.yml + service: server-script-scheduler + +networks: + default: + name: lacuna-test + +name: lacuna-test diff --git a/docker/memcached/docker-compose.yml b/docker/memcached/docker-compose.yml new file mode 100644 index 00000000..86737e97 --- /dev/null +++ b/docker/memcached/docker-compose.yml @@ -0,0 +1,9 @@ +services: + memcached: + container_name: memcached + image: memcached + command: + # Persist cache in a file to save sessions (and other data) between restarts of the docker container + - --memory-file=/tempfs_mount/memory_file + volumes: + - ./data:/tempfs_mount diff --git a/docker/mysql/docker-compose.yml b/docker/mysql/docker-compose.yml new file mode 100644 index 00000000..12e20abb --- /dev/null +++ b/docker/mysql/docker-compose.yml @@ -0,0 +1,11 @@ +services: + mysql: + container_name: mysql + platform: linux/amd64 + environment: + MYSQL_ROOT_PASSWORD: lacuna + image: mysql:5.5 + volumes: + - ./data:/var/lib/mysql + ports: + - 3306:3306 diff --git a/docker/build-nginx/Dockerfile b/docker/nginx/Dockerfile similarity index 100% rename from docker/build-nginx/Dockerfile rename to docker/nginx/Dockerfile diff --git a/docker/nginx/docker-compose.yml b/docker/nginx/docker-compose.yml new file mode 100644 index 00000000..ca92fe70 --- /dev/null +++ b/docker/nginx/docker-compose.yml @@ -0,0 +1,21 @@ +services: + nginx: + build: + context: ./../../ + dockerfile: ./docker/nginx/Dockerfile + container_name: nginx + depends_on: + server: + condition: service_started + v2-api: + condition: service_started + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + - ./../../var:/home/lacuna/server/var + - ./../../log/nginx:/etc/nginx/logs + - ./../../captcha:/home/lacuna/server/captcha + - ./../../assets:/home/lacuna/server/var/www/public/assets + - ./../../homepage:/home/lacuna/server/var/www/public/homepage + - ./../../var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css + - ./../../app/dist:/home/lacuna/server/var/www/public/app + - ./../../super-ui/dist:/home/lacuna/server/var/www/public/super-ui diff --git a/etc-docker/nginx.conf b/docker/nginx/nginx.conf similarity index 83% rename from etc-docker/nginx.conf rename to docker/nginx/nginx.conf index ee8bbd5d..dc01ccce 100644 --- a/etc-docker/nginx.conf +++ b/docker/nginx/nginx.conf @@ -1,110 +1,100 @@ -worker_processes 1; - -error_log logs/error.log; - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - sendfile on; - - keepalive_timeout 65; - - gzip on; - gzip_types text/plain text/css application/json application/json-rpc application/x-javascript text/xml application/xml application/xml+rss text/javascript; - gzip_comp_level 9; - - server { - listen 80; - server_name 0.0.0.0; - - location * { - add_header Access-Control-Allow-Origin *; - } - - location / { - add_header Cache-Control must-revalidate; - add_header Cache-Control public; - add_header Access-Control-Allow-Origin *; - add_header Access-Control-Allow-Headers 'content-type,x-requested-with'; - root /home/lacuna/server/var/www/public; - # For debugging: - add_header X-URI $uri always; - add_header X-Served-By 'TLE-Static-Handler' always; - try_files $uri - $uri/index.html - /homepage$uri - /homepage$uri/index.html - @backend; - } - - location = /api { - rewrite ^ /api/ permanent; - } - location ^~ /api/ { - root /home/lacuna/server/var/www/public; - index Intro.html; - } - - location = /assets { - rewrite ^ /assets/ permanent; - } - location ^~ /assets/ { - root /home/lacuna/server/var/www/public; - index README.txt; # TODO NJR: make a nicer index page than this readme file - } - - location = /app { - rewrite ^ /app/ permanent; - } - location ^~ /app/ { - root /home/lacuna/server/var/www/public; - } - - location = /starmap { - rewrite ^ /starmap/ permanent; - } - location ^~ /starmap/ { - root /home/lacuna/server/var/www/public; - index index.html; - } - - location ^~ /captcha/ { - root /home/lacuna/server/captcha; - rewrite ^/captcha/(.*)$ /$1 break; - } - - location ~ /v2/.* { - proxy_pass http://lacuna-v2-api:5999; - proxy_set_header X-Forwarded-Host $remote_addr; - # For debugging: - add_header X-Served-By 'TLE-V2-Proxy' always; - } - - # Note - note enabled yet in the deployed environment - # location ~ /v3/.* { - # rewrite ^/v3/(.*)$ /$1 break; - # proxy_pass http://lacuna-rails:5001; - # proxy_set_header X-Forwarded-Host $remote_addr; - # # For debugging: - # add_header X-Served-By 'TLE-V3-Proxy' always; - # } - - location @backend { - proxy_pass http://lacuna-server:5000; - proxy_set_header X-Real-IP $remote_addr; - # For debugging: - add_header X-Served-By 'TLE-V1-Proxy' always; - add_header X-URI $uri always; - } - } -} +worker_processes 1; + +error_log logs/error.log; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + sendfile on; + + keepalive_timeout 65; + + gzip on; + gzip_types text/plain text/css application/json application/json-rpc application/x-javascript text/xml application/xml application/xml+rss text/javascript; + gzip_comp_level 9; + + server { + listen 80; + server_name 0.0.0.0; + + location * { + add_header Access-Control-Allow-Origin *; + } + + location / { + add_header Cache-Control must-revalidate; + add_header Cache-Control public; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers 'content-type,x-requested-with'; + root /home/lacuna/server/var/www/public; + # For debugging: + add_header X-URI $uri always; + add_header X-Served-By 'TLE-Static-Handler' always; + try_files $uri + $uri/index.html + /homepage$uri + /homepage$uri/index.html + @backend; + } + + location = /api { + rewrite ^ /api/ permanent; + } + location ^~ /api/ { + root /home/lacuna/server/var/www/public; + index Intro.html; + } + + location = /assets { + rewrite ^ /assets/ permanent; + } + location ^~ /assets/ { + root /home/lacuna/server/var/www/public; + index README.txt; # TODO NJR: make a nicer index page than this readme file + } + + location = /app { + rewrite ^ /app/ permanent; + } + location ^~ /app/ { + root /home/lacuna/server/var/www/public; + } + + location = /starmap { + rewrite ^ /starmap/ permanent; + } + location ^~ /starmap/ { + root /home/lacuna/server/var/www/public; + index index.html; + } + + location ^~ /captcha/ { + root /home/lacuna/server/captcha; + rewrite ^/captcha/(.*)$ /$1 break; + } + + location ~ /v2/.* { + proxy_pass http://v2-api:5999; + proxy_set_header X-Forwarded-Host $remote_addr; + # For debugging: + add_header X-Served-By 'TLE-V2-Proxy' always; + } + + location @backend { + proxy_pass http://server:5000; + proxy_set_header X-Real-IP $remote_addr; + # For debugging: + add_header X-Served-By 'TLE-V1-Proxy' always; + add_header X-URI $uri always; + } + } +} diff --git a/docker/phpmyadmin/docker-compose.yml b/docker/phpmyadmin/docker-compose.yml new file mode 100644 index 00000000..445d28de --- /dev/null +++ b/docker/phpmyadmin/docker-compose.yml @@ -0,0 +1,15 @@ +# Dev-only DB browser. Included from docker-compose.dev.yml only — deliberately +# absent from the test/homelab overlays (no reason to run it there, and no +# reason to expose port 8888 on a Tailscale-facing host). +services: + phpmyadmin: + container_name: phpmyadmin + image: phpmyadmin:5.2-apache + environment: + PMA_HOST: mysql + ports: + - 8888:80 + depends_on: + - mysql + links: + - mysql diff --git a/docker/build-server/Dockerfile b/docker/server/Dockerfile similarity index 100% rename from docker/build-server/Dockerfile rename to docker/server/Dockerfile diff --git a/docker/server/docker-compose.yml b/docker/server/docker-compose.yml new file mode 100644 index 00000000..e22d77d9 --- /dev/null +++ b/docker/server/docker-compose.yml @@ -0,0 +1,93 @@ +services: + server: + build: + context: ./../../ + dockerfile: ./docker/server/Dockerfile + command: '/bin/bash startdev.sh' + container_name: server + depends_on: + - mysql + - memcached + - beanstalk + ports: + - 3050:5000 + volumes: + - ./../../bin:/home/lacuna/server/bin + - ./../../captcha:/home/lacuna/server/captcha + - ./../../docs:/home/lacuna/server/docs + - ./../../lib:/home/lacuna/server/lib + - ./../../t:/home/lacuna/server/t + - ./../../var:/home/lacuna/server/var + - ./../../var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css + - ./../../missions:/home/lacuna/server/missions + - ./../../tmp:/tmp + + server-building-scheduler: + build: + context: ./../../ + dockerfile: ./docker/server/Dockerfile + command: 'perl schedule_building.pl --noquiet --nodaemonize --initialize' + container_name: server-building-scheduler + depends_on: + - mysql + - memcached + - beanstalk + volumes: + - ./../../bin:/home/lacuna/server/bin + - ./../../captcha:/home/lacuna/server/captcha + - ./../../docs:/home/lacuna/server/docs + - ./../../lib:/home/lacuna/server/lib + - ./../../t:/home/lacuna/server/t + - ./../../var:/home/lacuna/server/var + - ./../../var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css + - ./../../tmp:/tmp + + server-ship-scheduler: + build: + context: ./../../ + dockerfile: ./docker/server/Dockerfile + command: 'perl schedule_ship_arrival.pl --noquiet --nodaemonize --initialize' + container_name: server-ship-scheduler + depends_on: + - mysql + - memcached + - beanstalk + volumes: + - ./../../bin:/home/lacuna/server/bin + - ./../../captcha:/home/lacuna/server/captcha + - ./../../docs:/home/lacuna/server/docs + - ./../../lib:/home/lacuna/server/lib + - ./../../t:/home/lacuna/server/t + - ./../../var:/home/lacuna/server/var + - ./../../var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css + - ./../../tmp:/tmp + + server-captcha-scheduler: + build: + context: ./../../ + dockerfile: ./docker/server/Dockerfile + command: 'perl schedule_captcha.pl --noquiet --nodaemonize' + container_name: server-captcha-scheduler + depends_on: + - mysql + - memcached + - beanstalk + volumes: + - ./../../bin:/home/lacuna/server/bin + - ./../../captcha:/home/lacuna/server/captcha + - ./../../docs:/home/lacuna/server/docs + - ./../../lib:/home/lacuna/server/lib + - ./../../t:/home/lacuna/server/t + - ./../../var:/home/lacuna/server/var + - ./../../var/www/public/api/api.css:/home/lacuna/server/var/www/public/api/api.css + - ./../../tmp:/tmp + + server-script-scheduler: + container_name: server-script-scheduler + image: mcuadros/ofelia:latest + depends_on: + - server + command: daemon + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./schedule.ini:/etc/ofelia.conf diff --git a/etc-docker/lacuna.conf b/docker/server/etc-dev/lacuna.conf similarity index 91% rename from etc-docker/lacuna.conf rename to docker/server/etc-dev/lacuna.conf index 37b8d853..4ca34865 100644 --- a/etc-docker/lacuna.conf +++ b/docker/server/etc-dev/lacuna.conf @@ -1,163 +1,163 @@ -# config-file-type: JSON 1 -{ - "develop_mode" : 0, - - # Amazon S3 details - # "access_key" : "XXXX", - # "secret_key" : "XXXX", - - "bhg_param" : { -# If any are set to 0, use default. - "success" : 0, - "waste_cost" : 0, - "recovery" : 0, - "side_chance" : 0, - }, - "beanstalk" : { - "debug" : 0, - "server" : "lacuna-beanstalkd:11300", - "ttr" : 120, - "max_timeouts" : 10, - "max_reserves" : 10 - }, - "captcha" : { - # path to the fonts being used. - "fontpath" : "/home/lacuna/server/var/fonts", - # .ttf fonts in above path - "fonts" : [ - "Ayuthaya", - "Chalkduster", - "Caveat", - "EduNSWACTCursive", - "Merienda", - "PermanentMarker", - "PlaywriteAUQLD" - ], - }, - "db" : { - "dsn" : "DBI:mysql:host=lacuna-mysql-server;database=lacuna", - "password" : "lacuna", - "username" : "root" - }, - "envolve" : { - "Sn" : 0, - "api_key" : "XXXX" - }, - "essentia_code_server_url" : "", - "facebook" : { - "api_key" : "XXXX", - "app_id" : "XXXX", - "secret" : "XXXX" - }, - "feeds" : { - "bucket" : "XXXX", - "surl" : "https://xxxx/", - "url" : "http://xxxx/" - }, - "itransact" : { - "APIKey" : "XXXX", - "APIUsername" : "XXXX", - "Gateway" : "XXXX", - "OrderFormUID" : "XXXX", - "SendCustomerEmail" : "TRUE", - "SendMerchantEmail" : "TRUE", - "TestMode" : "FALSE" - }, - "jambool" : { - "api_url" : "XXXX", - "offer_id" : "XXXX", - "secret_key" : "XXXX" - }, - "map_size" : { - "x" : [ - -1500, - 1500 - ], - "y" : [ - -1500, - 1500 - ] - }, - "memcached" : [ - { - "host" : "lacuna-memcached", - "port" : "11211" - } - ], - "neutral_area" : { -# If zone is set to a valid zone, x & y are confined to within that zone. -# Coord set to 1 will further narrow Neutral area. -# Setting zone to 0 will only use x & y. -# Setting x & y outside of the zone, will result in nothing be within the NZ. -# If only coord is set, then zone boundries are ignored. - "active" : 1, - "zone" : 1, - "zone_list" : [ - "-3|0" - ], - "coord" : 0, - "x" : [ - -1000, - -750 - ], - "y" : [ - -250, - 250 - ] - }, - "offline" : 0, - "paypal" : { - "APIPassword" : "XXXX", - "APIUsername" : "XXXX", - "Sandbox" : "0", - "Signature" : "XXXX" - }, - "rpc_limit" : 10000, - "rpc_throttle" : 200, - "self_destruct_after_inactive_days" : 9999999, - "server_key" : "XXXX", - "server_keys" : [ - "XXXX" - ], - "server_url" : "https://lacuna.allosaurus-chromatic.ts.net/", - "assets_url": "https://lacuna.allosaurus-chromatic.ts.net/assets/", - "starter_zone" : { -# If zone is set to a valid zone, x & y are confined to within that zone. -# Coord set to 1 will further narrow area. -# Setting zone to 0 will only use x & y. -# Setting x & y outside of the zone, will result in nothing be within the NZ. -# If only coord is set, then zone boundries are ignored. - "active" : 1, - # "max_colonies" : 2, - "zone" : 1, - "zone_list" : [ - "0|0" - # "-1|-1", - # "-1|1", - # "1|-1", - # "1|1" - ], - "coord" : 0, - "x" : [ -50, 50 ], - "y" : [ -50, 50 ] - }, - "voting_sites" : [ - { - "name" : "Rose Harbour", - "url" : "https://nataliethistime.com/" - }, - { - "name" : "YouTube Channel", - "url" : "https://www.youtube.com/@nataliethistime" - }, - { - "name" : "TLE Community GitHub", - "url" : "https://github.com/tlecommunity" - } - ], - "test" : { - "foo" : "bar" - }, - "secret" : "a random code", - "email_secret" : "another random code" -} +# config-file-type: JSON 1 +{ + "develop_mode" : 0, + + # Amazon S3 details + # "access_key" : "XXXX", + # "secret_key" : "XXXX", + + "bhg_param" : { +# If any are set to 0, use default. + "success" : 0, + "waste_cost" : 0, + "recovery" : 0, + "side_chance" : 0, + }, + "beanstalk" : { + "debug" : 0, + "server" : "beanstalk:11300", + "ttr" : 120, + "max_timeouts" : 10, + "max_reserves" : 10 + }, + "captcha" : { + # path to the fonts being used. + "fontpath" : "/home/lacuna/server/var/fonts", + # .ttf fonts in above path + "fonts" : [ + "Ayuthaya", + "Chalkduster", + "Caveat", + "EduNSWACTCursive", + "Merienda", + "PermanentMarker", + "PlaywriteAUQLD" + ], + }, + "db" : { + "dsn" : "DBI:mysql:host=mysql;database=lacuna", + "password" : "lacuna", + "username" : "root" + }, + "envolve" : { + "Sn" : 0, + "api_key" : "XXXX" + }, + "essentia_code_server_url" : "", + "facebook" : { + "api_key" : "XXXX", + "app_id" : "XXXX", + "secret" : "XXXX" + }, + "feeds" : { + "bucket" : "XXXX", + "surl" : "https://xxxx/", + "url" : "http://xxxx/" + }, + "itransact" : { + "APIKey" : "XXXX", + "APIUsername" : "XXXX", + "Gateway" : "XXXX", + "OrderFormUID" : "XXXX", + "SendCustomerEmail" : "TRUE", + "SendMerchantEmail" : "TRUE", + "TestMode" : "FALSE" + }, + "jambool" : { + "api_url" : "XXXX", + "offer_id" : "XXXX", + "secret_key" : "XXXX" + }, + "map_size" : { + "x" : [ + -1500, + 1500 + ], + "y" : [ + -1500, + 1500 + ] + }, + "memcached" : [ + { + "host" : "memcached", + "port" : "11211" + } + ], + "neutral_area" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow Neutral area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + "zone" : 1, + "zone_list" : [ + "-3|0" + ], + "coord" : 0, + "x" : [ + -1000, + -750 + ], + "y" : [ + -250, + 250 + ] + }, + "offline" : 0, + "paypal" : { + "APIPassword" : "XXXX", + "APIUsername" : "XXXX", + "Sandbox" : "0", + "Signature" : "XXXX" + }, + "rpc_limit" : 10000, + "rpc_throttle" : 200, + "self_destruct_after_inactive_days" : 9999999, + "server_key" : "XXXX", + "server_keys" : [ + "XXXX" + ], + "server_url" : "https://lacuna.allosaurus-chromatic.ts.net/", + "assets_url": "https://lacuna.allosaurus-chromatic.ts.net/assets/", + "starter_zone" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + # "max_colonies" : 2, + "zone" : 1, + "zone_list" : [ + "0|0" + # "-1|-1", + # "-1|1", + # "1|-1", + # "1|1" + ], + "coord" : 0, + "x" : [ -50, 50 ], + "y" : [ -50, 50 ] + }, + "voting_sites" : [ + { + "name" : "Rose Harbour", + "url" : "https://nataliethistime.com/" + }, + { + "name" : "YouTube Channel", + "url" : "https://www.youtube.com/@nataliethistime" + }, + { + "name" : "TLE Community GitHub", + "url" : "https://github.com/tlecommunity" + } + ], + "test" : { + "foo" : "bar" + }, + "secret" : "a random code", + "email_secret" : "another random code" +} diff --git a/etc-docker/log4perl.conf b/docker/server/etc-dev/log4perl.conf similarity index 97% rename from etc-docker/log4perl.conf rename to docker/server/etc-dev/log4perl.conf index 79150e63..216b2ce1 100644 --- a/etc-docker/log4perl.conf +++ b/docker/server/etc-dev/log4perl.conf @@ -1,5 +1,5 @@ -log4perl.logger = DEBUG, SCREEN -log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen -log4perl.appender.SCREEN.stderr = 1 -log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::SimpleLayout - +log4perl.logger = DEBUG, SCREEN +log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen +log4perl.appender.SCREEN.stderr = 1 +log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::SimpleLayout + diff --git a/docker/server/etc-homelab/lacuna.conf b/docker/server/etc-homelab/lacuna.conf new file mode 100644 index 00000000..4ca34865 --- /dev/null +++ b/docker/server/etc-homelab/lacuna.conf @@ -0,0 +1,163 @@ +# config-file-type: JSON 1 +{ + "develop_mode" : 0, + + # Amazon S3 details + # "access_key" : "XXXX", + # "secret_key" : "XXXX", + + "bhg_param" : { +# If any are set to 0, use default. + "success" : 0, + "waste_cost" : 0, + "recovery" : 0, + "side_chance" : 0, + }, + "beanstalk" : { + "debug" : 0, + "server" : "beanstalk:11300", + "ttr" : 120, + "max_timeouts" : 10, + "max_reserves" : 10 + }, + "captcha" : { + # path to the fonts being used. + "fontpath" : "/home/lacuna/server/var/fonts", + # .ttf fonts in above path + "fonts" : [ + "Ayuthaya", + "Chalkduster", + "Caveat", + "EduNSWACTCursive", + "Merienda", + "PermanentMarker", + "PlaywriteAUQLD" + ], + }, + "db" : { + "dsn" : "DBI:mysql:host=mysql;database=lacuna", + "password" : "lacuna", + "username" : "root" + }, + "envolve" : { + "Sn" : 0, + "api_key" : "XXXX" + }, + "essentia_code_server_url" : "", + "facebook" : { + "api_key" : "XXXX", + "app_id" : "XXXX", + "secret" : "XXXX" + }, + "feeds" : { + "bucket" : "XXXX", + "surl" : "https://xxxx/", + "url" : "http://xxxx/" + }, + "itransact" : { + "APIKey" : "XXXX", + "APIUsername" : "XXXX", + "Gateway" : "XXXX", + "OrderFormUID" : "XXXX", + "SendCustomerEmail" : "TRUE", + "SendMerchantEmail" : "TRUE", + "TestMode" : "FALSE" + }, + "jambool" : { + "api_url" : "XXXX", + "offer_id" : "XXXX", + "secret_key" : "XXXX" + }, + "map_size" : { + "x" : [ + -1500, + 1500 + ], + "y" : [ + -1500, + 1500 + ] + }, + "memcached" : [ + { + "host" : "memcached", + "port" : "11211" + } + ], + "neutral_area" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow Neutral area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + "zone" : 1, + "zone_list" : [ + "-3|0" + ], + "coord" : 0, + "x" : [ + -1000, + -750 + ], + "y" : [ + -250, + 250 + ] + }, + "offline" : 0, + "paypal" : { + "APIPassword" : "XXXX", + "APIUsername" : "XXXX", + "Sandbox" : "0", + "Signature" : "XXXX" + }, + "rpc_limit" : 10000, + "rpc_throttle" : 200, + "self_destruct_after_inactive_days" : 9999999, + "server_key" : "XXXX", + "server_keys" : [ + "XXXX" + ], + "server_url" : "https://lacuna.allosaurus-chromatic.ts.net/", + "assets_url": "https://lacuna.allosaurus-chromatic.ts.net/assets/", + "starter_zone" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + # "max_colonies" : 2, + "zone" : 1, + "zone_list" : [ + "0|0" + # "-1|-1", + # "-1|1", + # "1|-1", + # "1|1" + ], + "coord" : 0, + "x" : [ -50, 50 ], + "y" : [ -50, 50 ] + }, + "voting_sites" : [ + { + "name" : "Rose Harbour", + "url" : "https://nataliethistime.com/" + }, + { + "name" : "YouTube Channel", + "url" : "https://www.youtube.com/@nataliethistime" + }, + { + "name" : "TLE Community GitHub", + "url" : "https://github.com/tlecommunity" + } + ], + "test" : { + "foo" : "bar" + }, + "secret" : "a random code", + "email_secret" : "another random code" +} diff --git a/docker/server/etc-homelab/log4perl.conf b/docker/server/etc-homelab/log4perl.conf new file mode 100644 index 00000000..216b2ce1 --- /dev/null +++ b/docker/server/etc-homelab/log4perl.conf @@ -0,0 +1,5 @@ +log4perl.logger = DEBUG, SCREEN +log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen +log4perl.appender.SCREEN.stderr = 1 +log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::SimpleLayout + diff --git a/docker/server/etc-test/lacuna.conf b/docker/server/etc-test/lacuna.conf new file mode 100644 index 00000000..4ca34865 --- /dev/null +++ b/docker/server/etc-test/lacuna.conf @@ -0,0 +1,163 @@ +# config-file-type: JSON 1 +{ + "develop_mode" : 0, + + # Amazon S3 details + # "access_key" : "XXXX", + # "secret_key" : "XXXX", + + "bhg_param" : { +# If any are set to 0, use default. + "success" : 0, + "waste_cost" : 0, + "recovery" : 0, + "side_chance" : 0, + }, + "beanstalk" : { + "debug" : 0, + "server" : "beanstalk:11300", + "ttr" : 120, + "max_timeouts" : 10, + "max_reserves" : 10 + }, + "captcha" : { + # path to the fonts being used. + "fontpath" : "/home/lacuna/server/var/fonts", + # .ttf fonts in above path + "fonts" : [ + "Ayuthaya", + "Chalkduster", + "Caveat", + "EduNSWACTCursive", + "Merienda", + "PermanentMarker", + "PlaywriteAUQLD" + ], + }, + "db" : { + "dsn" : "DBI:mysql:host=mysql;database=lacuna", + "password" : "lacuna", + "username" : "root" + }, + "envolve" : { + "Sn" : 0, + "api_key" : "XXXX" + }, + "essentia_code_server_url" : "", + "facebook" : { + "api_key" : "XXXX", + "app_id" : "XXXX", + "secret" : "XXXX" + }, + "feeds" : { + "bucket" : "XXXX", + "surl" : "https://xxxx/", + "url" : "http://xxxx/" + }, + "itransact" : { + "APIKey" : "XXXX", + "APIUsername" : "XXXX", + "Gateway" : "XXXX", + "OrderFormUID" : "XXXX", + "SendCustomerEmail" : "TRUE", + "SendMerchantEmail" : "TRUE", + "TestMode" : "FALSE" + }, + "jambool" : { + "api_url" : "XXXX", + "offer_id" : "XXXX", + "secret_key" : "XXXX" + }, + "map_size" : { + "x" : [ + -1500, + 1500 + ], + "y" : [ + -1500, + 1500 + ] + }, + "memcached" : [ + { + "host" : "memcached", + "port" : "11211" + } + ], + "neutral_area" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow Neutral area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + "zone" : 1, + "zone_list" : [ + "-3|0" + ], + "coord" : 0, + "x" : [ + -1000, + -750 + ], + "y" : [ + -250, + 250 + ] + }, + "offline" : 0, + "paypal" : { + "APIPassword" : "XXXX", + "APIUsername" : "XXXX", + "Sandbox" : "0", + "Signature" : "XXXX" + }, + "rpc_limit" : 10000, + "rpc_throttle" : 200, + "self_destruct_after_inactive_days" : 9999999, + "server_key" : "XXXX", + "server_keys" : [ + "XXXX" + ], + "server_url" : "https://lacuna.allosaurus-chromatic.ts.net/", + "assets_url": "https://lacuna.allosaurus-chromatic.ts.net/assets/", + "starter_zone" : { +# If zone is set to a valid zone, x & y are confined to within that zone. +# Coord set to 1 will further narrow area. +# Setting zone to 0 will only use x & y. +# Setting x & y outside of the zone, will result in nothing be within the NZ. +# If only coord is set, then zone boundries are ignored. + "active" : 1, + # "max_colonies" : 2, + "zone" : 1, + "zone_list" : [ + "0|0" + # "-1|-1", + # "-1|1", + # "1|-1", + # "1|1" + ], + "coord" : 0, + "x" : [ -50, 50 ], + "y" : [ -50, 50 ] + }, + "voting_sites" : [ + { + "name" : "Rose Harbour", + "url" : "https://nataliethistime.com/" + }, + { + "name" : "YouTube Channel", + "url" : "https://www.youtube.com/@nataliethistime" + }, + { + "name" : "TLE Community GitHub", + "url" : "https://github.com/tlecommunity" + } + ], + "test" : { + "foo" : "bar" + }, + "secret" : "a random code", + "email_secret" : "another random code" +} diff --git a/docker/server/etc-test/log4perl.conf b/docker/server/etc-test/log4perl.conf new file mode 100644 index 00000000..216b2ce1 --- /dev/null +++ b/docker/server/etc-test/log4perl.conf @@ -0,0 +1,5 @@ +log4perl.logger = DEBUG, SCREEN +log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen +log4perl.appender.SCREEN.stderr = 1 +log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::SimpleLayout + diff --git a/etc-docker/schedule.ini b/docker/server/schedule.ini similarity index 86% rename from etc-docker/schedule.ini rename to docker/server/schedule.ini index b4f6a6f8..4e7242dc 100644 --- a/etc-docker/schedule.ini +++ b/docker/server/schedule.ini @@ -1,10 +1,10 @@ -# +# # TLE schedule based off of the following example cron file that was probably used in production back in the day # # # 20 * * * * /data/apps/bin/perl /home/lacuna/server/bin/schedule_building.pl --noquiet --daemonize --noinitialize # 50 * * * * /data/apps/bin/perl /home/lacuna/server/bin/schedule_ship_arrival.pl --noquiet --daemonize --noinitialize -# +# # 0 * * * * /home/lacuna/server/bin/run_hourly.sh # 10 1,3,5,7,9,11,13,15,17,19,21,23 * * * /home/lacuna/server/bin/run_two_hourly.sh # 40 2,6,10,14,18,22 * * * /home/lacuna/server/bin/run_four_hourly.sh @@ -18,25 +18,25 @@ [job-exec "hourly-tasks"] schedule = @hourly -container = lacuna-server +container = server command = ./run_hourly.sh [job-exec "two-hourly-tasks"] schedule = 0 10 1,3,5,7,9,11,13,15,17,19,21,23 * * * -container = lacuna-server +container = server command = ./run_two_hourly.sh [job-exec "four-hourly-tasks"] schedule = 0 40 2,6,10,14,18,22 * * * -container = lacuna-server +container = server command = ./run_four_hourly.sh [job-exec "daily-tasks"] schedule = 0 15 3 * * * -container = lacuna-server -command = ./run_daily.sh +container = server +command = ./run_daily.sh [job-exec "weekly-tasks"] schedule = 0 15 6 * * 0 -container = lacuna-server -command = ./run_weekly.sh +container = server +command = ./run_weekly.sh diff --git a/docker/build-super-ui/Dockerfile b/docker/super-ui/Dockerfile similarity index 100% rename from docker/build-super-ui/Dockerfile rename to docker/super-ui/Dockerfile diff --git a/docker/super-ui/docker-compose.yml b/docker/super-ui/docker-compose.yml new file mode 100644 index 00000000..56ee6e5d --- /dev/null +++ b/docker/super-ui/docker-compose.yml @@ -0,0 +1,13 @@ +volumes: + super-ui-node_modules: + +services: + super-ui: + build: + context: ./../../ + dockerfile: ./docker/super-ui/Dockerfile + container_name: super-ui + command: npm run build + volumes: + - super-ui-node_modules:/usr/src/app/node_modules + - ./../../super-ui:/usr/src/app diff --git a/etc-docker/tailscale/lacuna.json b/docker/tailscale/config/lacuna.json similarity index 100% rename from etc-docker/tailscale/lacuna.json rename to docker/tailscale/config/lacuna.json diff --git a/docker/tailscale/docker-compose.yml b/docker/tailscale/docker-compose.yml new file mode 100644 index 00000000..86b0298e --- /dev/null +++ b/docker/tailscale/docker-compose.yml @@ -0,0 +1,25 @@ +services: + tailscale: + image: tailscale/tailscale:latest + container_name: tailscale + hostname: lacuna + environment: + TS_AUTHKEY: ${TAILSCALE_AUTHKEY:?error} + TS_EXTRA_ARGS: --advertise-tags=tag:container + TS_SERVE_CONFIG: /config/lacuna.json + TS_STATE_DIR: /var/lib/tailscale + TS_USERSPACE: false + TS_ENABLE_HEALTH_CHECK: true + healthcheck: + test: ['CMD', 'wget', '--spider', '-q', 'http://127.0.0.1:9002/healthz'] + interval: 10s + timeout: 3s + volumes: + - ./data:/var/lib/tailscale + - ./config:/config + devices: + - /dev/net/tun:/dev/net/tun + cap_add: + - net_admin + - sys_module + restart: unless-stopped diff --git a/docker/build-v2-api/Dockerfile b/docker/v2-api/Dockerfile similarity index 100% rename from docker/build-v2-api/Dockerfile rename to docker/v2-api/Dockerfile diff --git a/docker/v2-api/docker-compose.yml b/docker/v2-api/docker-compose.yml new file mode 100644 index 00000000..7512ec49 --- /dev/null +++ b/docker/v2-api/docker-compose.yml @@ -0,0 +1,15 @@ +volumes: + v2-api-node_modules: + +services: + v2-api: + build: + context: ./../../ + dockerfile: ./docker/v2-api/Dockerfile + container_name: v2-api + command: node index.ts + ports: + - 5999:5999 + volumes: + - v2-api-node_modules:/usr/src/v2-api/node_modules + - ./../../v2-api:/usr/src/v2-api diff --git a/etc-docker/README.md b/etc-docker/README.md deleted file mode 100644 index 74c25cee..00000000 --- a/etc-docker/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Docker-based Configuration File Templates - -This directory contains a number of files **example** configuration files for if you were setting up the Lacuna server -using Docker and Docker Compose. To use, create an `etc` directory and copy all these files into it. These files should -be fine to use out of the box, however, if you're feeling brave, you may make changes to these files as they will not -appear in the git repository. diff --git a/info/setup.md b/info/setup.md index 659e2b2c..0c5c024d 100644 --- a/info/setup.md +++ b/info/setup.md @@ -45,7 +45,7 @@ doesn't work you may need to look at the configuration and try to do what it doe You can connect to the running server (see above) with another bash session. ```bash -docker compose run --rm lacuna-server bash +npm run dev:run -- server bash ``` This will put you in the bin directory. @@ -82,14 +82,14 @@ your session where you did the `docker compose up`). working!) If you _do_ need to make changes in your container (for example to do SQL queries) then you can use the same -`docker compose run --rm lacuna-server bash` script to open another session or as a one-liner: -`docker compose run --rm lacuna-server `. +`npm run dev:run -- server bash` script to open another session or as a one-liner: +`npm run dev:run -- server `. ### Running the test suite The tests in `t/` are integration tests: each one drives the game through the JSON-RPC API over HTTP _and_ reads/writes -the database directly. They must run INSIDE the `lacuna-server` container, talking to that same container's server - not -any deployed server, and not from the host. +the database directly. They must run INSIDE the `server` container, talking to that same container's server - not any +deployed server, and not from the host. 1. Bring the stack up: @@ -101,7 +101,7 @@ docker compose up -d never received. In particular the 'captcha.created' column (see var/upgrades/4.0001.sql): ```bash -docker compose exec lacuna-mysql-server \ +docker compose exec mysql \ mysql -uroot -placuna lacuna \ -e "alter table captcha add column \`created\` datetime NOT NULL default 0" ``` @@ -118,8 +118,8 @@ curl -s http://localhost:3050/starman_ping # -> pong root): ```bash -docker compose run --rm lacuna-server ./run_tests.sh # default set -docker compose run --rm lacuna-server ./run_tests.sh t/010_Empire.t # a single file +npm run dev:run -- server ./run_tests.sh # default set +npm run dev:run -- server ./run_tests.sh t/010_Empire.t # a single file ``` ### Notes diff --git a/lacuna/app/lib/lacuna_server_info.rb b/lacuna/app/lib/lacuna_server_info.rb index 926a0c9a..e00e06aa 100644 --- a/lacuna/app/lib/lacuna_server_info.rb +++ b/lacuna/app/lib/lacuna_server_info.rb @@ -1,6 +1,6 @@ # Server-level fields for the `status.server` block (Lacuna::RPC#format_status, -# lib/Lacuna/RPC.pm). etc-docker/ (the Perl app's Config::JSON source) is not mounted into -# the lacuna-rails container, so these are hand-synced constants rather than read at runtime. +# lib/Lacuna/RPC.pm). The Perl app's Config::JSON source is not mounted into +# the rails container, so these are hand-synced constants rather than read at runtime. # If get_status output ever mismatches Perl on these fields, check both sources are current. module LacunaServerInfo VERSION = 4.0001 # mirrors lib/Lacuna.pm's `our $VERSION = 4.0001;` — a number, not a string, diff --git a/lacuna/config/database.yml b/lacuna/config/database.yml index 0988782f..8d343294 100644 --- a/lacuna/config/database.yml +++ b/lacuna/config/database.yml @@ -7,7 +7,7 @@ default: &default username: root password: lacuna port: 3306 - host: lacuna-mysql-server + host: mysql development: <<: *default diff --git a/lacuna/config/initializers/memcached.rb b/lacuna/config/initializers/memcached.rb index 26789694..34f45768 100644 --- a/lacuna/config/initializers/memcached.rb +++ b/lacuna/config/initializers/memcached.rb @@ -1,4 +1,4 @@ require 'dalli' -# Same memcached instance the Perl app writes sessions to (see etc-docker/lacuna.conf). -Rails.application.config.x.memcached = Dalli::Client.new('lacuna-memcached:11211') +# Same memcached instance the Perl app writes sessions to +Rails.application.config.x.memcached = Dalli::Client.new('memcached:11211') diff --git a/lib/Lacuna.pm b/lib/Lacuna.pm index fe4f5658..53c04390 100644 --- a/lib/Lacuna.pm +++ b/lib/Lacuna.pm @@ -43,7 +43,7 @@ sub queue { } # True only in the local dev docker-compose stack (LACUNA_HIGH_SPEED_TEST_MODE -# is set in docker-compose.yml's lacuna-server service, and deliberately never +# is set in docker-compose.yml's server service, and deliberately never # set in docker-compose.deployed.yml). Collapses build/travel/work timers to # near-instant for manual testing; never changes random-chance odds. sub high_speed_test_mode { diff --git a/package.json b/package.json index dde0e700..9354eba5 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,23 @@ "private": "true", "scripts": { "format:check": "prettier --check .", - "format:fix": "prettier --write ." + "format:fix": "prettier --write .", + "dev:up": "docker compose --file ./docker/docker-compose.dev.yml up", + "dev:down": "docker compose --file ./docker/docker-compose.dev.yml down", + "dev:build": "docker compose --file ./docker/docker-compose.dev.yml build", + "dev:pull": "docker compose --file ./docker/docker-compose.dev.yml pull", + "dev:run": "docker compose --file ./docker/docker-compose.dev.yml run --rm", + "test:up": "docker compose --file ./docker/docker-compose.test.yml up -d", + "test:down": "docker compose --file ./docker/docker-compose.test.yml down", + "test:build": "docker compose --file ./docker/docker-compose.test.yml build", + "test:pull": "docker compose --file ./docker/docker-compose.test.yml pull", + "test:run": "docker compose --file ./docker/docker-compose.test.yml run --rm", + "homelab:up": "docker compose --file ./docker/docker-compose.homelab.yml up -d", + "homelab:down": "docker compose --file ./docker/docker-compose.homelab.yml down", + "homelab:build": "docker compose --file ./docker/docker-compose.homelab.yml build", + "homelab:pull": "docker compose --file ./docker/docker-compose.homelab.yml pull", + "homelab:run": "docker compose --file ./docker/docker-compose.homelab.yml run --rm", + "test": "docker compose --file ./docker/docker-compose.dev.yml run --rm server ./run_tests.sh" }, "dependencies": { "prettier": "^3.9.6" diff --git a/t/TestHelper.pm b/t/TestHelper.pm index e0a15361..59188ba1 100644 --- a/t/TestHelper.pm +++ b/t/TestHelper.pm @@ -18,7 +18,7 @@ has ua => ( ); # Where post() sends its JSON-RPC calls. Defaults to the plackup server running -# inside the lacuna-server container; override with LACUNA_TEST_SERVER_URL. +# inside the server container; override with LACUNA_TEST_SERVER_URL. # Deliberately NOT Lacuna->config->get('server_url') -- that points at the # deployed server, so the suite would talk to production while its DB/cache # setup talks to the local containers. diff --git a/v2-api/index.ts b/v2-api/index.ts index b8f87479..b1a55533 100644 --- a/v2-api/index.ts +++ b/v2-api/index.ts @@ -175,7 +175,7 @@ app.post('/v2/:module/:method', async (req, res) => { } console.log(`hitting /${reqModule} with:`, body); - const response = await fetch(`http://lacuna-server:5000/${reqModule}`, { + const response = await fetch(`http://server:5000/${reqModule}`, { method: 'POST', headers: { 'Content-Type': 'application/json', -- 2.51.2