Skip to content

Commit a6eae79

Browse files
authored
Merge pull request #1663 from thunderstore-io/12-10-docker_dev_env_setup
Set up Docker development environment for Cyberstorm Remix
2 parents 38a1207 + dfd62ab commit a6eae79

File tree

5 files changed

+192
-97
lines changed

5 files changed

+192
-97
lines changed

Dockerfile.dev

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM node:24-bookworm
2+
3+
WORKDIR /workspace
4+
5+
# Copy entrypoint script
6+
COPY apps/cyberstorm-remix/entrypoint.dev.sh /usr/local/bin/entrypoint.sh
7+
RUN chmod +x /usr/local/bin/entrypoint.sh
8+
9+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
10+
CMD ["yarn", "workspace", "@thunderstore/cyberstorm-remix", "dev", "--port", "3000", "--host", "0.0.0.0"]

apps/cyberstorm-remix/README.md

Lines changed: 45 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,45 @@
1-
# How to setup and run Nimbus dev environment with local Thunderstore
2-
3-
## Preparations
4-
This quide expects you to have setup your Thunderstore Django project for development on some level. Please setup the Thunderstore project before continuing.
5-
6-
## Setup nginx proxy for local data ingress/egress
7-
1. Add the following to your hosts (on windows, google what how to achive same on other OS')
8-
```
9-
127.0.0.1 thunderstore.temp
10-
127.0.0.1 new.thunderstore.temp
11-
```
12-
13-
2. Boot up the nginx proxy with the following command; `docker compose -f tools/ts-dev-proxy/docker-compose.yml up`
14-
15-
3. Boot up your Thunderstore backend and ensure it's running in port 81 (it's normally 80). The following [line](https://github.com/thunderstore-io/Thunderstore/blob/f06b9b438ea6e990881e60339d34bde1a480d073/docker-compose.yml#L123) in your Thunderstore projects docker-compose, should be `- "127.0.0.1:81:8000"`
16-
17-
## Setup Nimbus for development
18-
19-
1. Clone the repo `git@github.com:thunderstore-io/thunderstore-ui.git`
20-
21-
2. Setup FontAwesome token. One way to do it is to add a `.npmrc` file with the following contents, under `thunderstore-ui/build-secrets/.npmrc`
22-
```
23-
@fortawesome:registry = "https://npm.fontawesome.com/"
24-
//npm.fontawesome.com/:_authToken = YOUR_FA_TOKEN
25-
```
26-
27-
3. Run `yarn install` first on the repo root (`thunderstore-ui` folder) and then again in the `thunderstore-ui/apps/cyberstorm-remix` folder.
28-
29-
4. Add `.env.development` and/or `.env.production` files. You can copy the `.env` file, rename and edit the values to your needs. Here's a example of the file contents:
30-
```
31-
VITE_SITE_URL=http://thunderstore.temp
32-
VITE_BETA_SITE_URL=http://new.thunderstore.temp
33-
VITE_API_URL=http://thunderstore.temp
34-
VITE_COOKIE_DOMAIN=.thunderstore.temp
35-
VITE_AUTH_BASE_URL=http://thunderstore.temp
36-
VITE_AUTH_RETURN_URL=http://new.thunderstore.temp
37-
__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=.thunderstore.temp
38-
```
39-
40-
5. Run the build/start server script or the dev server script
41-
42-
Build and start
43-
```
44-
yarn workspace @thunderstore/cyberstorm-remix build
45-
yarn workspace @thunderstore/cyberstorm-remix start --port 3000 --host 0.0.0.0
46-
```
47-
48-
Dev script
49-
```
50-
yarn workspace @thunderstore/cyberstorm-remix dev --port 3000 --host 0.0.0.0
51-
```
52-
53-
## Finally
54-
You should now have the fully local Nimbus dev environment setup and running in `http://new.thunderstore.temp` and the Django site should be running in `http://thunderstore.temp`. You might need to go to `http://new.thunderstore.temp/communities` as Nimbus doesn't have a landing page yet.
55-
56-
# How to setup ts-proxy as a backend for this project
57-
**Keep in mind that when using the ts-proxy, the sessions and actions will be made against the actual production Thunderstore**
58-
59-
1. Open hosts file as administrator (`C:\Windows\System32\drivers\etc`) and add this `127.0.0.1 thunderstore.temp` there
60-
2. Download and install Docker and docker-compose. For windows people, Docker for Windows should be enough.
61-
3. Open up a terminal and navigate to `thunderstore-ui/tools/ts-proxy`
62-
4. Run `docker compose up`
63-
5. Add these to your `.env.development` or `.env.production`
64-
```
65-
PUBLIC_SITE_URL=http://thunderstore.temp
66-
PUBLIC_API_URL=http://thunderstore.temp:81
67-
```
68-
6. Run the Nimbus project normally
1+
# Cyberstorm Remix (Nimbus)
2+
3+
This is the Remix application that powers the new Thunderstore frontend (codenamed Nimbus).
4+
5+
## Quick Start (Docker)
6+
7+
The easiest way to run the full stack (Backend + Frontend) is using Docker.
8+
9+
1. **Clone Repositories**
10+
Ensure you have both `Thunderstore` (Backend) and `thunderstore-ui` (Frontend) cloned side-by-side.
11+
```bash
12+
# Example structure
13+
# C:\projects\Thunderstore
14+
# C:\projects\thunderstore-ui
15+
```
16+
17+
2. **Start Backend**
18+
```bash
19+
cd ../Thunderstore
20+
docker compose up -d
21+
docker compose exec django python manage.py setup_dev_env
22+
```
23+
(If you have some pre-existing containers, please do `docker compose down -v`, `docker compose up -d --build` and `docker compose exec django python manage.py setup_dev_env`)
24+
25+
3. **Start Frontend**
26+
```bash
27+
cd ../thunderstore-ui
28+
docker compose -f docker-compose.remix.development.yml up -d
29+
```
30+
(If you have some pre-existing containers, please do `docker compose -f docker-compose.remix.development.yml down -v` and `docker compose -f docker-compose.remix.development.yml up -d --build`)
31+
32+
4. **Open Browser**
33+
- **Frontend**: [http://new.localhost](http://new.localhost)
34+
- **Backend**: [http://localhost](http://localhost)
35+
36+
## Manual Setup
37+
38+
If you prefer running Node locally instead of in Docker:
39+
40+
1. **Install Dependencies**: `yarn install` (in repo root)
41+
2. **Configure Env**: Copy `.env.example` to `.env` in `apps/cyberstorm-remix`.
42+
3. **Run Dev Server**:
43+
```bash
44+
yarn workspace @thunderstore/cyberstorm-remix dev --port 3000 --host 0.0.0.0
45+
```
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
set -e
3+
4+
# Helper to ensure dirs exist and are writable by the node user.
5+
ensure_node_dirs() {
6+
for dir in "$@"; do
7+
mkdir -p "$dir"
8+
chown node:node "$dir"
9+
done
10+
}
11+
12+
# Sync Nginx configs
13+
mkdir -p /etc/nginx/user-conf
14+
cp /workspace/tools/nginx/*.conf /etc/nginx/user-conf/ 2>/dev/null || true
15+
16+
# Setup npmrc
17+
if [ -f /run/secrets/npmrc ]; then
18+
# Copy with tight permissions; file contains auth tokens.
19+
install -m 0600 -o node -g node /run/secrets/npmrc /home/node/.npmrc
20+
fi
21+
22+
ensure_node_dirs \
23+
node_modules \
24+
apps/cyberstorm-remix/node_modules \
25+
apps/cyberstorm-remix/.react-router
26+
27+
# Install dependencies if missing or if react-router is missing
28+
if [ -z "$(ls -A node_modules)" ] || [ ! -f node_modules/.bin/react-router ]; then
29+
echo "Installing dependencies..."
30+
# Fix permissions recursively before install to ensure we can write.
31+
chown -R node:node node_modules apps/cyberstorm-remix/node_modules
32+
33+
su node -c "yarn install --frozen-lockfile --production=false"
34+
fi
35+
36+
# Map localhost to the backend nginx container IP so SSR API calls hit the backend
37+
# without changing client-side env values.
38+
backend_nginx_ip=$(getent hosts nginx | awk '{print $1}')
39+
if [ -n "$backend_nginx_ip" ]; then
40+
# Prepend to /etc/hosts to take precedence over the default loopback entry.
41+
# Make idempotent to avoid duplicate lines on restarts.
42+
if ! grep -q "^${backend_nginx_ip}[[:space:]][[:space:]]*localhost\([[:space:]]\|$\)" /etc/hosts 2>/dev/null; then
43+
tmp_hosts=$(mktemp)
44+
{
45+
printf "%s localhost\n" "$backend_nginx_ip"
46+
# Drop existing localhost mappings so the new mapping is unambiguous.
47+
# This keeps other host entries intact.
48+
awk '!($0 ~ /(^|[[:space:]])localhost([[:space:]]|$)/)' /etc/hosts 2>/dev/null || true
49+
} > "$tmp_hosts"
50+
cat "$tmp_hosts" > /etc/hosts || printf "%s localhost\n" "$backend_nginx_ip" >> /etc/hosts
51+
rm -f "$tmp_hosts"
52+
fi
53+
fi
54+
55+
# Execute the passed command as node (preserve argument boundaries)
56+
# `su -c` uses the first arg after `--` as $0, so provide a dummy.
57+
exec su node -c 'exec "$@"' -- _ "$@"

docker-compose.remix.development.yml

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,73 @@
1-
version: "3.8"
1+
## Shared config for local file sync containers
2+
x-rsync-common: &rsync-common
3+
image: alpine:3.20
4+
volumes:
5+
- ./:/src:ro
6+
- workspace_src:/workspace
7+
- thunderstore_nginx_conf:/etc/nginx/user-conf
8+
environment:
9+
RSYNC_ARGS: "-a --delete --info=progress2 --exclude=.git --exclude=build-secrets --exclude=.npmrc --exclude=node_modules --exclude=.turbo --exclude=.cache --exclude=apps/cyberstorm-remix/build --exclude=apps/cyberstorm-remix/.react-router"
10+
SYNC_INTERVAL: "5"
211

312
services:
13+
cyberstorm-remix-sync:
14+
<<: *rsync-common
15+
container_name: cyberstorm-remix-sync
16+
restart: "no"
17+
command: >-
18+
/bin/sh -c "set -e; apk add --no-cache rsync; rsync $$RSYNC_ARGS /src/ /workspace/; tmp=/etc/nginx/user-conf/.new-localhost.conf.tmp; cp -f /src/tools/nginx/new-localhost.conf \"$$tmp\"; mv -f \"$$tmp\" /etc/nginx/user-conf/new-localhost.conf; echo sync complete"
19+
20+
cyberstorm-remix-watch:
21+
<<: *rsync-common
22+
container_name: cyberstorm-remix-watch
23+
restart: unless-stopped
24+
depends_on:
25+
cyberstorm-remix-sync:
26+
condition: service_completed_successfully
27+
command: >-
28+
/bin/sh -c "set -e; apk add --no-cache rsync; while true; do rsync $$RSYNC_ARGS /src/ /workspace/; tmp=/etc/nginx/user-conf/.new-localhost.conf.tmp; cp -f /src/tools/nginx/new-localhost.conf \"$$tmp\"; mv -f \"$$tmp\" /etc/nginx/user-conf/new-localhost.conf; sleep $$SYNC_INTERVAL; done"
29+
430
cyberstorm-remix:
531
container_name: cyberstorm-remix
6-
command: /bin/sh -c "tail -f /dev/null"
7-
# command: yarn workspace @thunderstore/cyberstorm-remix dev --port 3000 --host 0.0.0.0
832
build:
9-
context: "./"
10-
dockerfile: "apps/cyberstorm-remix/Dockerfile.development"
11-
secrets:
12-
- "npmrc"
13-
image: thunderstore/thunderstore-ui.cyberstorm-remix-development:${IMAGE_TAG:-dev}
33+
context: ./
34+
dockerfile: ./Dockerfile.dev
35+
working_dir: /workspace
1436
ports:
1537
- "127.0.0.1:3000:3000"
38+
depends_on:
39+
cyberstorm-remix-sync:
40+
condition: service_completed_successfully
1641
volumes:
17-
- remix_node_modules:/app/apps/cyberstorm-remix/node_modules
18-
- ./apps/cyberstorm-remix:/app/apps/cyberstorm-remix
19-
- ./packages:/app/packages
42+
- workspace_src:/workspace
43+
- thunderstore_ui_node_modules:/workspace/node_modules
44+
- nimbus_node_modules:/workspace/apps/cyberstorm-remix/node_modules
45+
- thunderstore_nginx_conf:/etc/nginx/user-conf
46+
- yarn_cache:/usr/local/share/.cache/yarn
2047
networks:
2148
- thunderstore_default
2249
environment:
2350
- NODE_ENV=development
24-
25-
remix-nginx-proxy:
26-
image: nginx
27-
container_name: remix-nginx-proxy
28-
restart: always
29-
ports:
30-
- "443:443"
31-
- "80:80"
32-
volumes:
33-
- ./nginx/www:/var/www:ro
34-
- ./nginx/conf.d/remixdefault.conf:/etc/nginx/conf.d/default.conf:ro
35-
# - ./ssl:/etc/nginx/ssl:ro
36-
# - ./snippets:/etc/nginx/snippets:ro
37-
# - ./protect:/etc/nginx/protect:ro
38-
hostname: thunderstore.temp
39-
networks:
40-
- thunderstore_default
51+
- NPM_CONFIG_USERCONFIG=/run/secrets/npmrc
52+
- ENABLE_BROKEN_PAGES=True
53+
- VITE_DEVELOPMENT=True
54+
- VITE_SITE_URL=http://localhost
55+
- VITE_BETA_SITE_URL=http://new.localhost
56+
- VITE_API_URL=http://localhost
57+
- VITE_COOKIE_DOMAIN=.localhost
58+
- VITE_AUTH_BASE_URL=http://localhost
59+
- VITE_AUTH_RETURN_URL=http://new.localhost
60+
- __VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=.localhost
61+
secrets:
62+
- npmrc
4163

4264
volumes:
43-
remix_node_modules:
65+
workspace_src:
66+
thunderstore_ui_node_modules:
67+
nimbus_node_modules:
68+
yarn_cache:
69+
thunderstore_nginx_conf:
70+
external: true
4471

4572
secrets:
4673
npmrc:

tools/nginx/new-localhost.conf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
map $http_upgrade $connection_upgrade {
2+
default upgrade;
3+
'' '';
4+
}
5+
6+
server {
7+
listen 80;
8+
server_name new.localhost;
9+
10+
# Resolve container DNS dynamically to avoid stale IPs.
11+
resolver 127.0.0.11 ipv6=off valid=30s;
12+
13+
location / {
14+
# Ensure requests to new.localhost are never served from the backend nginx proxy cache.
15+
proxy_cache off;
16+
proxy_cache_bypass 1;
17+
proxy_no_cache 1;
18+
proxy_pass http://cyberstorm-remix:3000;
19+
proxy_http_version 1.1;
20+
proxy_set_header Host $host;
21+
proxy_set_header Upgrade $http_upgrade;
22+
proxy_set_header Connection $connection_upgrade;
23+
}
24+
}

0 commit comments

Comments
 (0)