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

Docker Support #113

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 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
6 changes: 5 additions & 1 deletion .github/workflows/AutoRelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,16 @@ jobs:
release_name="IGReelsBot-$tag-${{ matrix.target }}"
# Build everything
dotnet publish "Instagram Reels Bot/Instagram Reels Bot.csproj" --framework net6.0 --runtime "${{ matrix.target }}" --self-contained true -c Release -o "$release_name"
# Conditionally copy Dockerfile for linux-x64
if [ "${{ matrix.target }}" == "linux-x64" ]; then
cp "Instagram Reels Bot/Dockerfile" "$release_name"
fi
# Pack files
if [ "${{ matrix.target }}" == "win-x64" ]||[ "${{ matrix.target }}" == "win-arm64" ]||[ "${{ matrix.target }}" == "win-arm" ]; then
# Pack to zip for Windows
7z a -tzip "${release_name}.zip" "./${release_name}/*"
else
tar czvf "${release_name}.tar.gz" "$release_name"
tar czvf "${release_name}.tar.gz" "$release_name"
fi
# Delete output directory
rm -r "$release_name"
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/TestRelease.yml
FreSchNDE marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Build and Package

on:
push:
paths:
- '.github/workflows/runTest'
branches:
- DockerSupport

jobs:
build_and_package:
name: Build and Package
strategy:
matrix:
kind: ['linux', 'linuxArm64', 'linuxArm', 'windows','windowsArm64' , 'macOS', 'macOSArm']
include:
- kind: linux
os: ubuntu-latest
target: linux-x64
- kind: linuxArm64
os: ubuntu-latest
target: linux-arm64
- kind: linuxArm
os: ubuntu-latest
target: linux-arm
- kind: windows
os: windows-latest
target: win-x64
- kind: windowsArm64
os: windows-latest
target: win-arm64
- kind: macOS
os: macos-latest
target: osx-x64
- kind: macOSArm
os: macos-latest
target: osx-arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '6.0.x'

- name: Build
shell: bash
run: |
release_name="IGReelsBot-${{ matrix.target }}"
echo "release_name=$release_name" >> $GITHUB_ENV
# Build everything
dotnet publish "Instagram Reels Bot/Instagram Reels Bot.csproj" --framework net6.0 --runtime "${{ matrix.target }}" --self-contained true -c Release -o "$release_name"
# Conditionally copy Dockerfile for linux-x64
if [ "${{ matrix.target }}" == "linux-x64" ]; then
cp "Instagram Reels Bot/Dockerfile" "$release_name"
fi
# Pack files
if [ "${{ matrix.target }}" == "win-x64" ]||[ "${{ matrix.target }}" == "win-arm64" ]||[ "${{ matrix.target }}" == "win-arm" ]; then
# Pack to zip for Windows
7z a -tzip "${release_name}.zip" "./${release_name}/*"
else
tar czvf "${release_name}.tar.gz" "$release_name"
fi
# Delete output directory
rm -r "$release_name"

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-release
path: ${{ env.release_name }}.tar.gz
22 changes: 22 additions & 0 deletions Instagram Reels Bot/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Define the base image.
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0

# Folder in the file system of the container in which the following commands get executed.
WORKDIR /app

# Copy everything from the folder in which this Dockerfile resides to the workdir. Assign correct permissions.
COPY --chmod=0755 . .

# Ensure the folder /app/stateFile and the file /app/config.json do not exist
RUN rm -rf /app/stateFile && rm -f /app/config.json

# Declare the folder /app/stateFile as a volume, so that its contents persists.
VOLUME /app/stateFile

# Set the file that is executed when the container starts.
ENTRYPOINT ./Instagram\ Reels\ Bot

# Labels for metadata
LABEL maintainer="FreSchNDE [email protected]"
LABEL description="Docker image for Instagram Reels Bot"
LABEL dockerfileEdition="1.0"
11 changes: 9 additions & 2 deletions Instagram Reels Bot/Modules/Commands/Dm/DmCommands.ClearState.cs
FreSchNDE marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ public partial class DmCommands {
// Clear statefiles:
string stateFile = Path.Combine(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "StateFiles");
if (Directory.Exists(stateFile)) {
Directory.Delete(stateFile, true);
Directory.CreateDirectory(stateFile);
// Delete all files in the directory
foreach (string file in Directory.GetFiles(stateFile)) {
File.Delete(file);
}

// Delete all subdirectories and their contents
foreach (string dir in Directory.GetDirectories(stateFile)) {
Directory.Delete(dir, true);
}
} else {
await message.ReplyAsync("Folder not found. Skipping folder removal.");
}
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ See the list of [commands](docs/commands.md) to get an impression of how users c
## Setup
See the [installation guide](docs/Install.md) for steps to setup the bot. For troubleshooting help, see the [troubleshooting guide](docs/troubleshooting.md).

This bot can also be run with Docker, see the [Docker guide](docs/docker/docker.md) for instructions on how to do that.

### Config.json format:
Create a new file named `config.json`, copy and paste the contents below into it, fill it out, and then save it in the same directory as the Instagram Embed executable file. Replace any fields that are optional and not filled in with `""`. Example: `"OTPSecret": "",`. If you get an error with your JSON formatting, you can check your JSON syntax on [jsonlint.com](https://jsonlint.com/).
```
Expand Down
42 changes: 42 additions & 0 deletions docs/docker/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
services:
igreelsbot:
build: ./IGReelsBot
container_name: botContainer
volumes:
- botVolume:/app/stateFile
- ./config.json:/app/config.json:ro
depends_on:
igreelsbotDB:
condition: service_healthy
networks:
- botNetwork

igreelsbotDB:
image: mongo:latest
container_name: botDatabaseContainer
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: YOURPASSWORDHERE
volumes:
- botDatabaseVolume:/data/db
- botConfigDatabaseVolume:/data/configdb
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
interval: 30s
timeout: 15s
retries: 3
start_period: 20s
networks:
- botNetwork

volumes:
botVolume:
name: "botVolume"
botDatabaseVolume:
name: "botDatabaseVolume"
botConfigDatabaseVolume:
name: "botConfigDatabaseVolume"

networks:
botNetwork:
name: botNetwork
80 changes: 80 additions & 0 deletions docs/docker/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Running The Bot With Docker
This tutorial will cover how to use [Docker](https://www.docker.com/) to run the bot application. Docker is a program that allows you to run applications isolated from one another and from the host system in so-called containers. Docker is designed to make managing different applications easy and secure. See the [Docker overview](https://docs.docker.com/get-started/overview/) for more information about Docker.

Currently, there is no premade Docker image, however, the Linux 64 bit release contains the Dockerfile that's needed to easily build the image yourself.

> **Note**: You can create the image from the Linux files and run it in Docker Windows without problems.

There are two main ways you can use Docker to run the bot. Either with the `docker run`command or with a Docker compose file `compose.yml`. Research what is best for you and take a look at the sections below when you have chosen. The compose example contains a self-host database.

In both cases, have Docker installed before further following this tutorial. You can select between Docker desktop and command line Docker. Docker desktop offers you a graphical user interface, the commands presented here will still work with it. On Windows, make sure to [add the Docker executable to the Windows path](https://stackoverflow.com/questions/49478343/windows-doesnt-recognize-docker-command) if the console fails to recognize Docker commands.

If you are on Linux or macOS, you might need to run all Docker commands as the administrator. Do that by typing the prefix `sudo` in front of every command that starts with `docker`.
FreSchNDE marked this conversation as resolved.
Show resolved Hide resolved

## Without Compose

### Creating the Docker image
Start by downloading the latest release of the linux-x64 version of the bot from our [GitHub Releases Page](https://github.com/bman46/InstagramEmbedDiscordBot/releases). Extract the folder using a tool of your choice (Windows File Explorer can open .tar.gz archives). Save the uncompressed folder to a path without spaces.

Now open a console and switch to the directory containing the Dockerfile and the main executable by using the `cd` command followed by the path to that folder.

Next, tell Docker to create the Image with the command `docker image build --tag igreelsbot --pull .`. This will create a Docker image named "igreelsbot" from which you can create a container. If you want to, you can now delete the folder. Check that your image was created by executing `docker image ls`.

### Running the container
Now create and edit the configuration file `config.json` as described in the [installation guide](../Install.md#step-3). Save it to another folder without spaces in its path.

You are now ready to create and start the container. Use the following command to create and start the container with the name "botContainer". Adjust the path `C:\path\to\config.json` to point to your configuration file.

`docker container run --name botContainer --volume botVolume:/app/stateFile --volume C:\path\to\config.json:/app/config.json:ro --detach igreelsbot`

If everything worked, you should see a unique container ID and the container should have the status `Up` in the output of the command `docker container ls --all`.

> **Note**: If you get the message `Error response from daemon: Conflict. The container name "/botContainer" is already in use by container`, that means that another container with the same name already exits. Take a look at the output of `docker container ls --all`. Either remove the contianer with `docker container rm botContainer` or start it back up when it's stoppet with `docker container start botContainer`. As long as you use the same volume name in the `run` command, no data will be lost if you choose to remove the container.


> **Note**: If the container is shown as "Exited", that means that the executable encounterd an error. Check the logs of the container as described below.

### Further operations
To see the console output of your container named "botContainer", execute this command: `docker container logs --follow botContainer`. Press `Ctrl` + `c` to return to your normal command line.

Docker containers and volumes persist when the Docker host (the operating system you installed Docker on) restarts. Make sure to start your container back up as well.

You can see the current status ("Up" or "Exited") by executing `docker container ls --all`. Stop and start your container with `docker container stop botContainer` and `docker container start botContainer`.

You can remove your container with `docker container rm botContainer`. The state files of the throwaway Instagram accounts get stored in the Docker volume `botVolume` and won't get lost. Use `docker volume ls` to see a list of all Docker volumes. The next time you use the `run` command, be sure to use the same volume name.
If you've failed to mount a volume, these files will still get stored in so-called anonymous volumes, which have long IDs instead of names. You can delete any volume with `docker volume rm` followed by the name/ ID of the volume.

To update to a new release of the bot, stop *and remove* the container as described, then redo the steps to create a new Docker image and a new container. You can keep the same image name, it will get overwritten with new content. Optionally, remove old images with `docker image prune --all` after recreating the container.

## With Compose
Compose gives you the ability to manage multiple containers with just one command. This example includes a self-hosted MongoDB database.

### Creating a project directory
Create a Folder where the compose project should live. The path of this folder can't contain any spaces.

Now create a text file named `compose.yml` and paste in the contents of the [sample compose file](./compose.yml). Make sure to adjust the database password and replace `YOURPASSWORDHERE`. Do not change this password after the first run.

Next, create the configuration file `config.json` in the same folder as the compose file. Edit it as is described in the [installation guide](../Install.md#step-3). Enable the subscribe module, and set the `MongoDBUrl` to `"mongodb://root:YOURPASSWORDHERE@botDatabaseContainer:27017/?authSource=admin"`. Replace `YOURPASSWORDHERE` with the password you set in the compose file.

### Inserting release files
Download the latest release of the linux-x64 version of the bot from our [GitHub Releases Page](https://github.com/bman46/InstagramEmbedDiscordBot/releases). Extract the folder using a tool of your choice (Windows File Explorer can open .tar.gz archives) and save the uncompressed folder to the same directory as the compose file. Rename the folder you just extracted to `IGReelsBot`. In contrast to the method described above without compose, this folder should not get deleted.

### Using the compose file
When everything is set up as described, you are ready to create and start the containers defined in the compose file. Open up a console and switch to the directory containing the compose file by using the `cd` command followed by the path to that folder.

Next, run the command `docker compose up --detach`. Startup might take a moment, the container "botContainer" only gets started after the database has passed the health check defined in the compose file. This command will consider already existing containers with the defined names and continue to use or recreate them.

If everything worked, you should see checkmarks next to all the container names and both containers should have the status `Up` in the output of the command `docker container ls --all`.

> **Note**: If the container "botContainer" is shown as "Exited", that means that the executable encounterd an error. Check the logs of the container. Simulary, check the logs of the container "botDatabaseContainer" when it gets reported as "unhealthy" or otherwise fails.

The compose up command basically issues the `run` command for each of the containers defined in the compose file. These Containers are regular containers just like the one created in [Without Compose](./docker.md#without-compose) above. That means they appear in the output of `docker container ls --all` and could be started, stopped and removed individually if so desired.
The up command also creates and mounts Docker volumes and Docker networks that are defined in a compose file. A Docker network is what's used by the containers to communicate with each other. Docker networks can be listed with `docker network ls` and can be created and removed independently, just like volumes and containers.

Take a look at section [Further Operations](./docker.md#further-operations) to learn, for example, how to view the command line output of the containers.

Use the command `docker compose down` to stop the bot. Make sure to execute this command in the folder that contains the compose file. Unlike the stop command from the section about running the bot without compose from above, this will not only stop, but also remove containers and networks defined in the Dockerfile. Volumes won't get removed, so no data is lost. The compose down command will even work if one of the containers was stopped or removed manually before.

The volume `botVolume` contains the state files for the throwaway Instagram accounts. The volumes `botDatabaseVolume` and `botConfigDatabaseVolume` contain the database of the database container. The database contains information about which discord server channel subscribed to witch Instagram profile. Make sure to reuse the `/subscribe` command if the database should get deleted.

To update to a new release of the bot, stop *and remove* both containers with `docker compose down`. Make sure to execute this and the following commands in the same folder as the compose file. Download the new Linux 64 bit release and extract it into the folder containing the compose file. Delete the old folder `IGReelsBot` and rename the new folder to `IGReelsBot`. Now run the command `docker compose pull` and `docker compose build --pull`. Optionally, remove old images with `docker image prune --all` after starting the containers back up. You might also want to take a look at the [sample compose file](./compose.yml) to check if any changes occurred.
4 changes: 3 additions & 1 deletion docs/subscribe.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
This module allows you to use the `/subscribe` command and get automatic updates from accounts.
This only works in Discord server channels. Only administrators and users with the role "InstagramBotSubscribe" (case-sensitive) can use commands related to the subscription of Instagram accounts. The subscriptions are independent of the accounts that the throwaway Instagram accounts follow.

The bot executable needs access to a MongoDB database for this module. You can host the database yourself or use an online provider. This tutorial uses the online provider [MongoDB Atlas](https://www.mongodb.com/atlas/database), please sign up for an account before proceeding.
The bot executable needs access to a MongoDB database for this module. You can host the database yourself, for example with Docker Compose as described in the [Docker guide](./docker/docker.md), or use an online provider. This tutorial uses the online provider [MongoDB Atlas](https://www.mongodb.com/atlas/database), please sign up for an account before proceeding.
If you choose to self-host the database, you still might want to take a look at the configuration file settings explained in step three.

> :warning: **Note**: [MongoDB Atlas](https://www.mongodb.com/atlas/database) usage may be [billed](https://www.mongodb.com/pricing), but there is a free tier as of writing this.
>
> Alternatively, you may self host MongoDB for free. There are plenty of tutorials online for this.
Expand Down
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Troubleshooting Guide
This guide covers how to troubleshoot the bot and common issues that arise during the operation of the bot.
This guide covers how to troubleshoot the bot and common issues that arise during the operation of the bot. This file does currently not contain troubleshooting steps relating to Docker.

## How to check that the bot is working
To check that the bot is working, you can take a look at the command line output of the executable. Send the bot a basic command (like `/link`) as a direct message on Discord, and observe what happens in the output of the executable.
Expand Down
Loading