Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up Docker env for local development #27

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.build
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/build
**/dist
LICENSE
README.md
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
.dist
.eslintcache
config/*
.DS_Store
.DS_Store
.env
79 changes: 79 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/

# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7

ARG NODE_VERSION=20.10.0

################################################################################
# Use node image for base image for all stages.
FROM node:${NODE_VERSION}-alpine as base

# Set working directory for all build stages.
WORKDIR /usr/src/app


################################################################################
# Create a stage for installing production dependecies.
FROM base as deps

# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.npm to speed up subsequent builds.
# Leverage bind mounts to package.json and package-lock.json to avoid having to copy them
# into this layer.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev

################################################################################
# Create a stage for building the application.
FROM deps as build

# Download additional development dependencies before building, as some projects require
# "devDependencies" to be installed to build. If you don't need this, remove this step.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci

# Copy the rest of the source files into the image.
COPY . .

# Run the build script.
RUN npm run build

################################################################################
# Create a new stage to run the application with minimal runtime dependencies
# where the necessary files are copied from the build stage.
FROM base as final

# Use production node environment by default.
ENV NODE_ENV production

# Run the application as a non-root user.
USER node

# Copy package.json so that package manager commands can be used.
COPY package.json .

# Copy the production dependencies from the build stage and also
# the built application from the build stage into the image.
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/.dist ./.dist

# Use default configuration files for loginserver
ADD config/pm2-example.js ./config/pm2.config.js
ADD config/config-example.js ./config/config.js

# Add some necessary source files
ADD src/public ./src/public

# Expose the port that the application listens on.
EXPOSE 8080

# Run the application.
CMD npm run start-on-docker && npx pm2 logs
5 changes: 5 additions & 0 deletions Dockerfile.replays
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM cockroachdb/cockroach:latest as base
COPY src/schemas/replays.sql /docker-entrypoint-initdb.d/0_replays.sql
COPY src/schemas/dummydata/replays.sql /docker-entrypoint-initdb.d/1_replays.sql
COPY src/schemas/dummydata/replays.csv src/schemas/dummydata/replays.csv
CMD ["start-single-node", "--insecure"]
22 changes: 22 additions & 0 deletions README.Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
### Building and running your application

When you're ready, start your application by running:
`docker compose up --build`.

Your application will be available at http://localhost:8080.

### Deploying your application to the cloud

First, build your image, e.g.: `docker build -t myapp .`.
If your cloud uses a different CPU architecture than your development
machine (e.g., you are on a Mac M1 and your cloud provider is amd64),
you'll want to build the image for that platform, e.g.:
`docker build --platform=linux/amd64 -t myapp .`.

Then, push it to your registry, e.g. `docker push myregistry.com/myapp`.

Consult Docker's [getting started](https://docs.docker.com/go/get-started-sharing/)
docs for more detail on building and pushing.

### References
* [Docker's Node.js guide](https://docs.docker.com/language/nodejs/)
32 changes: 32 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
services:
pokemon-showdown-loginserver:
build:
context: .
environment:
NODE_ENV: production
ports:
- 8080:8080
depends_on:
replay-db:
condition: service_healthy
develop:
watch:
- action: rebuild
path: .
replay-db:
restart: always
hostname: replaysdb
build:
context: .
dockerfile: Dockerfile.replays
healthcheck:
test: curl --request GET --url 'http://localhost:8080/api/v2/health/?ready=True'
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
start_interval: 5s
develop:
watch:
- action: rebuild
path: src/schemas
9 changes: 4 additions & 5 deletions config/config-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ exports.mysql = {
/** For the replay databases */
exports.replaysdb = {
charset: "utf8",
database: "ps",
database: "defaultdb",
password: "",
host: 'localhost',
host: 'replaysdb',
user: "root",
socketPath: '',
prefix: "ntbb_",
prefix: "",
port: 26257,
};

/**
Expand Down Expand Up @@ -107,8 +108,6 @@ exports.challengekeyid = 4;
* DBs.
*/
/** @type {typeof exports.mysql | undefined}*/
exports.replaysdb = undefined;
/** @type {typeof exports.mysql | undefined}*/
exports.ladderdb = undefined;

/**
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"build": "npx tsc",
"run": "npx tsc && node .dist/src/",
"start": "npx tsc && npx pm2 start config/pm2.js",
"start-on-docker": "npx pm2 start config/pm2.config.js",
"test": "npm run lint && npx tsc",
"reload": "npx tsc && npx pm2 reload config/pm2.js",
"stop": "npx pm2 stop config/pm2.js"
Expand Down
11 changes: 10 additions & 1 deletion src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,16 @@ export const actions: {[k: string]: QueryHandler} = {
}
return {password: pw};
},

async 'replays/batch.json'(params) {
Copy link
Member

@mia-pi-git mia-pi-git Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strike the .json from the name, for loginserver APIs we don't use that.

if (!params.ids) {
throw new ActionError("Invalid batch replay request, must provide ids");
}
const ids: string[] = params.ids.split(',');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this should be programatically capped in length here in addition to the query.

const results = await Replays.getBatch(ids);
console.log(params, ids, results);
this.response.setHeader('Content-Type', 'application/json');
Copy link
Member

@mia-pi-git mia-pi-git Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.response.setHeader('Content-Type', 'application/json');

This is already handled by the loginserver under the hood.

return JSON.stringify(results);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return JSON.stringify(results);
return results;

This is also handled by the loginserver under the hood.

},
// sent by ps server
async 'smogon/validate'(params) {
if (this.getIp() !== Config.restartip) {
Expand Down
12 changes: 12 additions & 0 deletions src/replays.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@
SQL`uploadtime, id, format, players, rating`
)`WHERE private = 0 ORDER BY uploadtime DESC LIMIT 51`.then(this.toReplays);
}

Check failure on line 236 in src/replays.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Trailing spaces not allowed

Check failure on line 236 in src/replays.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Trailing spaces not allowed
getBatch(ids: string[]) {
let idsForQuery = '';
for (var i = 0; i < ids.length; i++) {

Check failure on line 239 in src/replays.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

Unexpected var, use let or const instead

Check failure on line 239 in src/replays.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected var, use let or const instead
const id = ids[i];
idsForQuery += `'${id}'`;
if (i !== ids.length - 1) idsForQuery += ",";
}
return replays.selectAll(
SQL`*`
)`WHERE private = 0 AND id IN (${idsForQuery}) LIMIT 51`.then(this.toReplays);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return replays.selectAll(
SQL`*`
)`WHERE private = 0 AND id IN (${idsForQuery}) LIMIT 51`.then(this.toReplays);
return replays.selectAll()`WHERE private = 0 AND id IN (${idsForQuery}) LIMIT 51`.then(this.toReplays);

This is only necessary if you're not selecting * - it defaults to * otherwise.

}
};

export default Replays;
2 changes: 1 addition & 1 deletion src/schemas/replays.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ CREATE TABLE public.replays (
INDEX private_uploadtime (private ASC, uploadtime ASC),
INDEX private_formatid_uploadtime (private ASC, formatid ASC, uploadtime ASC),
INDEX private_formatid_rating (private ASC, formatid ASC, rating ASC),
INVERTED INDEX log (log)
INVERTED INDEX log (log gin_trgm_ops)
);
Loading