From 429c71861c5b32983435a61dc54cfc91a3ffc587 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Tue, 5 Jun 2018 13:44:20 -0600
Subject: [PATCH] Add a Dockerfile and supporting configuration

Things need to be stored in a volume, so we also add a bunch of configuration options for moving the persistence around.
---
 .dockerignore             | 15 +++++++++++++++
 Dockerfile                | 20 ++++++++++++++++++++
 README.md                 | 26 ++++++++++++++++++++++++++
 config/config.sample.yaml |  2 ++
 config/config.schema.yaml |  4 ++++
 src/config.ts             |  2 ++
 src/discordas.ts          |  4 +++-
 7 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 .dockerignore
 create mode 100644 Dockerfile

diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..8bf4ed2
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,15 @@
+.git
+node_modules
+
+# This is just stuff we don't need
+.travis.yml
+.gitignore
+build
+*.db
+discord-registration.yaml
+*.png
+README.md
+test
+docs
+config.yaml
+tools
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..85f549b
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,20 @@
+FROM node:alpine
+COPY . /tmp/src
+
+RUN apk add --no-cache -t build-deps make gcc g++ python ca-certificates libc-dev wget \
+    && cd /tmp/src \
+    && npm install \
+    && npm run build \
+    && mv build / \
+    && mv config / \
+    && mv node_modules / \
+    && cd / \
+    && rm -rf /tmp/* \
+    && apk del build-deps
+
+ENV NODE_ENV=production
+
+CMD node /build/discordas.js -p 9005 -c /data/config.yaml -f /data/discord-registration.yaml
+
+EXPOSE 9005
+VOLUME ["/data"]
diff --git a/README.md b/README.md
index 71f5031..897fa47 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,32 @@ Please also be aware that this is an unoffical project worked on in my (Half-Sho
 
   * Copy ``discord-registration.yaml`` to your Synapse's directory.
 
+#### Docker
+
+Following the instructions above, generate a registration file. The file may also be hand-crafted if you're familiar with the layout. You'll need this file to use the Docker image.
+
+```
+# Create the volume where we'll keep the bridge's files
+mkdir -p /matrix-appservice-discord
+
+# Create the configuration file. Use the sample configuration file as a template.
+# Be sure to set the database paths to something like this:
+#  database:
+#    filename: "/data/discord.db"
+#    userStorePath: "/data/user-store.db"
+#    roomStorePath: "/data/room-store.db"
+nano /matrix-appservice-discord/config.yaml
+
+# Copy the registration file to the volume
+cp discord-registration.yaml /matrix-appservice-discord/discord-registration.yaml
+
+# Optional: Build the container yourself (requires a git clone, and to be in the root of the project)
+docker build -t half-shot/matrix-appservice-discord .
+
+# Run the container
+docker run -v /matrix-appservice-discord:/data -p 9005:9005 half-shot/matrix-appservice-discord
+```
+
 #### 3PID Protocol Support
 
 This bridge support searching for rooms within networks via the 3pid system
diff --git a/config/config.sample.yaml b/config/config.sample.yaml
index 59700ac..8e5765f 100644
--- a/config/config.sample.yaml
+++ b/config/config.sample.yaml
@@ -15,5 +15,7 @@ logging:
   level: "warn" #silly, verbose, info, http, warn, error
 database:
   filename: "discord.db"
+  userStorePath: "user-store.db"
+  roomStorePath: "room-store.db"
 room:
   defaultVisibility: "public"
diff --git a/config/config.schema.yaml b/config/config.schema.yaml
index bb3b893..730fe4f 100644
--- a/config/config.schema.yaml
+++ b/config/config.schema.yaml
@@ -44,6 +44,10 @@ properties:
         properties:
           filename:
             type: "string"
+          userStorePath:
+            type: "string"
+          roomStorePath:
+            type: "string"
     room:
         type: "object"
         required: ["defaultVisibility"]
diff --git a/src/config.ts b/src/config.ts
index 0db41c7..7d5b7d0 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -23,6 +23,8 @@ class DiscordBridgeConfigBridge {
 
 class DiscordBridgeConfigDatabase {
   public filename: string;
+  public userStorePath: string;
+  public roomStorePath: string;
 }
 
 export class DiscordBridgeConfigAuth {
diff --git a/src/discordas.ts b/src/discordas.ts
index 2f49ea5..18cafd8 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -38,7 +38,7 @@ function generateRegistration(reg, callback)  {
 function run (port: number, config: DiscordBridgeConfig) {
   log.level = config.logging ? (config.logging.level || "warn") : "warn";
   log.info("discordas", "Starting Discord AS");
-  const yamlConfig = yaml.safeLoad(fs.readFileSync("discord-registration.yaml", "utf8"));
+  const yamlConfig = yaml.safeLoad(fs.readFileSync(cli.opts.registrationPath, "utf8"));
   const registration = AppServiceRegistration.fromObject(yamlConfig);
   if (registration === null) {
     throw new Error("Failed to parse registration file");
@@ -69,6 +69,8 @@ function run (port: number, config: DiscordBridgeConfig) {
     domain: config.bridge.domain,
     homeserverUrl: config.bridge.homeserverUrl,
     registration,
+    userStore: config.database.userStorePath,
+    roomStore: config.database.roomStorePath,
   });
   provisioner.SetBridge(bridge);
   roomhandler.setBridge(bridge);
-- 
GitLab