Skip to content

Commit 466e7c9

Browse files
authored
Dockerize infclass-stats (#31)
1 parent 8d80c88 commit 466e7c9

17 files changed

+32827
-6658
lines changed

.dockerignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
web
2+
README.md
3+
LICENSE
4+
docker-compose.yml
5+
Dockerfile

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ memory.db
33
node_modules
44
/dist
55
src/log.txt
6-
/config
76
log.txt
87

98
# local env files

Dockerfile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM golang:1.15
2+
3+
RUN mkdir /app
4+
ADD . /app/
5+
WORKDIR /app
6+
7+
RUN go build
8+
9+
RUN chmod +x start.sh
10+
11+
EXPOSE 8001
12+
13+
CMD ["./start.sh"]

README.md

+20-72
Original file line numberDiff line numberDiff line change
@@ -43,93 +43,41 @@ Visit [https://stats.resamvi.io](https://stats.resamvi.io) to see yourself.
4343

4444
infclass-stats runs on Port `8000` so make sure it is free.
4545

46-
Fill the <..> with your information:
46+
Fill the environment variables with your information:
4747

48-
`autoexec.cfg` of the teeworlds server
48+
`autoexec.cfg`
4949
```
50-
ec_bindaddr <ip>
51-
ec_port <port>
52-
ec_password <password>
50+
ec_bindaddr <myip>
51+
ec_port <myport>
52+
ec_password <mypassword>
5353
ec_output_level 2
5454
```
5555

56-
Set up your `config/config.go` of infclass-stats
56+
`docker-compose.yml` should match the above
5757
```
58-
SERVER_IP = "<ip>"
59-
60-
ECON_PORT = "<port>"
61-
62-
ECON_PASSWORD = "<password>"
63-
64-
...
65-
66-
MYSQL_USER = "<mysql user>"
67-
68-
MYSQL_PASSWORD = "<mysql password>"
58+
- SERVER_IP=<myip>
59+
- ECON_PORT=<myport>
60+
- ECON_PASSWORD=<mypassword>
6961
```
7062

71-
Setup a database named "infclass"
72-
73-
Replace the IP in `web/src/App.vue`
74-
```
75-
const ws = new WebSocket('ws://<ip>:8000/');
63+
`web/Dockerfile`
7664
```
77-
78-
Then run
79-
65+
ENV VUE_APP_API_URL="wss://inf.resamvi.io:8001"
8066
```
81-
go run main.go
82-
```
83-
84-
or
85-
86-
```
87-
./start.sh
88-
```
89-
which does the above repeatedly (helps recovering, when server crashes)
90-
91-
92-
# Config
93-
94-
# SSL
9567

96-
This implementation uses SSL. If you want to skip (easier testing) this step then:
68+
I'm using [Plausible](https://plausible.io/).
69+
If you host this yourself you may want to stop the app from sending user stats:
9770

98-
Change `wss` to `ws` in `App.vue`
71+
`web/public/index.html`
72+
```diff
73+
...
74+
<title>InfClass Statistics</title>
9975

100-
```
101-
const ws = new WebSocket('ws://localhost:8000/subscribe');
76+
- <script async defer data-domain="stats.resamvi.io" src="https://pls.resamvi.io/js/pls.js"></script>
77+
</head>
10278
```
10379

104-
If you plan to use SSL create a symlink to the project root
105-
106-
```
107-
ln -s /etc/letsencrypt/live/<url>/fullchain.pem ~/infclass-stats/fullchain.pem
108-
ln -s /etc/letsencrypt/live/<url>/privkey.pem ~/infclass-stats/privkey.pem
109-
```
11080

11181
# How to make sure your Infclass mod is compatible with infclass-stats
11282

113-
TODO
114-
115-
Copy in what message logs are required 'Protocol'
116-
117-
# TODO
118-
119-
- Remove logs and fmts where possible
120-
121-
# Website
122-
123-
1. Install dependencies
124-
125-
```
126-
yarn install
127-
```
128-
129-
2. Build artifacts`
130-
131-
```
132-
yarn run build
133-
```
134-
135-
3. Move `dist` to `/var/www/` or appropriate place
83+
TODO: Copy in what message logs are required 'Protocol'

config/config.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package config
2+
3+
import "os"
4+
5+
var (
6+
// SERVER_IP is the IP to the machine running the teeworlds server
7+
SERVER_IP = os.Getenv("SERVER_IP")
8+
// ECON_PORT is the port to econ (set via ec_port in autoexec.cfg)
9+
ECON_PORT = os.Getenv("ECON_PORT")
10+
// ECON_PASSWORD is the password to authenticate (set via ec_password)
11+
ECON_PASSWORD = os.Getenv("ECON_PASSWORD")
12+
13+
// DEBUG_MODE gives additional logs
14+
DEBUG_MODE = true
15+
16+
// SERVE_API will initialize a web server on port 8000 that serves a websocket connection
17+
SERVE_API = true
18+
19+
// MYSQL_USER username to mysql database
20+
MYSQL_USER = os.Getenv("MYSQL_USER")
21+
// MYSQL_PASSWORD password to mysql database
22+
MYSQL_PASSWORD = os.Getenv("MYSQL_PASSWORD")
23+
// MYSQL_DB is the name to the database
24+
MYSQL_DB = os.Getenv("MYSQL_DB")
25+
)

docker-compose.yml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: '3'
2+
services:
3+
infclass:
4+
build: ./
5+
restart: always
6+
ports:
7+
- "8001:8001"
8+
environment:
9+
- SERVER_IP=192.169.0.1337 # adjust to your settings
10+
- ECON_PORT=8001 # adjust to your settings
11+
- ECON_PASSWORD=econpw # adjust to your settings
12+
- MYSQL_USER=infclassuser
13+
- MYSQL_PASSWORD=infclasspw
14+
- MYSQL_DB=infclassdb
15+
16+
infclass_db:
17+
image: mariadb:10.3.29
18+
restart: always
19+
volumes:
20+
- infclass_data:/var/lib/mysql
21+
ports:
22+
- "3306:3306"
23+
environment:
24+
- MARIADB_ROOT_PASSWORD=rootpw
25+
- MARIADB_USER=infclassuser
26+
- MARIADB_PASSWORD=infclasspw
27+
- MARIADB_DATABASE=infclassdb
28+
29+
infclass_web:
30+
build: ./web
31+
ports:
32+
- "80:80"
33+
34+
35+
volumes:
36+
infclass_data:

infrastructure/gorm.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ func (repo GormRepo) Reset() {
270270
// Creates the tables if they do not exist yet and seeds the database
271271
// with an initial set of class objects to track overall class-specific performance.
272272
func NewGormDB() GormRepo {
273-
args := config.MYSQL_USER + ":" + config.MYSQL_PASSWORD + "@/" + config.MYSQL_DB
273+
args := config.MYSQL_USER + ":" + config.MYSQL_PASSWORD + "@tcp(infclass_db:3306)/" + config.MYSQL_DB
274274
db, err := gorm.Open("mysql", args)
275275
if err != nil {
276276
log.Panicf("Could not connect to database: %s\n%s\n", args, err.Error())

infrastructure/webserver.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package infrastructure
1919

2020
import (
2121
"encoding/json"
22-
"infclass-stats/config"
2322
"infclass-stats/operations"
2423
"net/http"
2524
"time"
@@ -41,22 +40,15 @@ type WebserviceHandler struct {
4140
// TODO: Dont make Serve create the handler himself
4241
func Serve(controller operations.Controller) {
4342
webserviceHandler := WebserviceHandler{Controller: controller}
44-
43+
4544
http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
4645
webserviceHandler.getUpdates(res, req)
4746
})
4847

4948
go func() {
50-
if config.USE_SSL {
51-
err := http.ListenAndServeTLS(":8000", config.CERT_FILE, config.KEY_FILE, nil)
52-
if err != nil {
53-
log.Panic(err)
54-
}
55-
} else {
56-
err := http.ListenAndServe(":8000", nil)
57-
if err != nil {
58-
log.Panic(err)
59-
}
49+
err := http.ListenAndServe(":8001", nil)
50+
if err != nil {
51+
log.Panic(err)
6052
}
6153
}()
6254
}

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func main() {
5757
infrastructure.Listen(file, controller)
5858

5959
if config.SERVE_API {
60-
log.Info("Starting HTTP server on localhost:8000")
60+
log.Info("Starting HTTP server on localhost:8001")
6161
infrastructure.Serve(controller)
6262
}
6363

operations/ticker.go

-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ func (c Controller) Infect(name string, aliveTime int) {
164164
return
165165
}
166166

167-
fmt.Println(name)
168-
169167
status := c.StatusRepository.FindStatusByName(name)
170168
c.AddTimeAlive(status.ClassPicked, aliveTime, c.StatusRepository.GetMap())
171169
//c.AddPick(status.CurrentClass)

start.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#!/bin/bash
2-
while true; do go run main.go && break; done
2+
while true; do ./infclass-stats && break; done

web/Dockerfile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM node:16.1.0 as build-stage
2+
WORKDIR /app
3+
COPY package*.json ./
4+
ENV VUE_APP_API_URL="wss://inf.resamvi.io"
5+
RUN npm install
6+
COPY . .
7+
RUN npm run build
8+
9+
# production stage
10+
FROM nginx:stable-alpine as production-stage
11+
COPY --from=build-stage /app/dist /usr/share/nginx/html
12+
EXPOSE 80
13+
CMD ["nginx", "-g", "daemon off;"]

0 commit comments

Comments
 (0)