From 53eeddcc20a53589ec238f654976f274f1f62595 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Thu, 10 Aug 2023 23:14:09 -0400 Subject: [PATCH] Docker support --- .dockerignore | 4 ++++ .gitignore | 1 + Cargo.toml | 2 +- Dockerfile | 60 ++++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 43 +++++++++++++++++++++++++++++++++ src/main.rs | 17 +++++++++---- 6 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b8ed77b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.git +.gitignore +deployments +target diff --git a/.gitignore b/.gitignore index 9026c77..f287a7f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +/data /target .vscode diff --git a/Cargo.toml b/Cargo.toml index fdbe866..6461acf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" anyhow = "1.0" env_logger = "0.10" log = "0.4" -mlua = { version = "0.9.0-rc.3", features = ["luajit52", "async", "send", "serialize"] } +mlua = { version = "0.9.0-rc.3", features = ["luajit", "async", "send", "serialize"] } once_cell = "1.18" reqwest = { version = "0.11", features = ["rustls-tls", "json"], default-features = false } semver = "1.0" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4c984ab --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Dockerfile using debian to compile quectocraft +# Author: Tyler Murphy + +# How to run: +# With the working directory set to the root of this repository, +# run the following shell command +# docker build -f Dockerfile -t quectocraft . +# +# If you wish to run this in docker compose, it is already set +# to build the Docker file. Therefore you can just run +# docker compose up -d + +##### Build Environment ##### + +# Used for building not for deployment +# This is includes rustc which isnt needed for production +# Use debian buster because its LTS and stable :3 +FROM rust:buster as builder +WORKDIR /usr/src/quectocraft + +# Copy over the rust files and source code for quectocraft +# Cargo.lock is needed because we dont want it updating packages +# on different peoples system +COPY ./Cargo.toml ./Cargo.toml +COPY ./Cargo.lock ./Cargo.lock +COPY ./src ./src + +# Make sure libluajit-dev is installed so that the mlua rust crate +# can compile +RUN apt-get update && \ + apt-get install -y libluajit-5.1-dev && \ + rm -rf /var/lib/apt/lists/* + +# Compile the program in into the containers local bin folder +RUN cargo install --path . + +##### Production Environment ##### + +# Mininimal container environment while still allowing dependcies +# to work. Had issues compiling and running on alpine, so we are +# using debian here. +FROM debian:buster-slim + +# Copy over the the binary from the builder envirnment +COPY --from=builder /usr/local/cargo/bin/quectocraft /usr/local/bin/quectocraft + +# Again make sure libluajit is installed, though we dont need the dev +# version as headers are only needed when building +RUN apt-get update && \ + apt-get install -y libluajit-5.1 && \ + rm -rf /var/lib/apt/lists/* + +# Create the working directory for quectocraft, this is where the plugin folder +# will be stored +RUN mkdir /data +VOLUME /data +WORKDIR /data + +# Run quectocraft +CMD ["/usr/local/bin/quectocraft"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..255420b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +# Docker Compose file to make it simple to compile and run +# quectocraft in docker. Automatically compiles the dockerfile +# Author: Tyler Murphy + +version: '3.8' + +services: + # This container contains the quectocraft binary and all its runtime + # required dependencies and files (such as plugins) + quectocraft: + # Set container name to make it look more pretty, can be removed + # I just dont like docker's default names + container_name: quectocraft + # Set this container to use and build the Dockerfile in the current directory + # See that Dockerfile for what it does + build: . + # These are the default envrionment variables that quectocraft uses, just + # respecified so that its easy to see and cange + environment: + # Says what messages are to be logged. Accepted values are (trace, debug, info, warn, error) + # See the crate documentation at https://docs.rs/env_logger/latest/env_logger/ + - RUST_LOG=info + # The address that quectocraft will bind to. Makes sence to just keep this 0.0.0.0 here and just + # change the bind in the ports section of this compose file + - QC_ADDR=0.0.0.0 + # The port the server listens on. Uses default Minecraft port 25565 + - QC_PORT=25565 + # The max player count of the server, default is 20 + - QC_MAX_PLAYERS=20 + # List all the volumes that the plugin needs + # /data is the containers working directory + volumes: + # This folder contains all plugins that the server runs + # This directory should be read only, it makes no sense + # for the plugin lua files to be modified at runtime + - ./plugins:/data/plugins:ro + # List all networking binds and ports + ports: + # By defualt we use port 25565 which is used by Minecraft + # Also we bind to 0.0.0.0 to allow all ips + - "0.0.0.0:25565:25565" + # Make sure the container is always running + restart: unless-stopped diff --git a/src/main.rs b/src/main.rs index 42d9ed3..f1e5092 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{time::Duration, net::SocketAddr}; +use std::{time::Duration, net::{SocketAddr, IpAddr, Ipv4Addr}}; use once_cell::sync::OnceCell; use uuid::Uuid; @@ -31,9 +31,18 @@ pub struct ServerConfig { #[tokio::main] async fn main() { - let address: SocketAddr = std::env::var("QC_ADDRESS") - .unwrap_or_else(|_| "0.0.0.0:25565".to_owned()) - .parse().unwrap(); + + let port = std::env::var("QC_PORT") + .unwrap_or_else(|_| "25565".to_owned()) + .parse() + .unwrap_or(25565_u16); + + let ip = std::env::var("QC_ADDR") + .unwrap_or_else(|_| "0.0.0.0".to_owned()) + .parse() + .unwrap_or(IpAddr::V4(Ipv4Addr::UNSPECIFIED)); + + let address = SocketAddr::new(ip, port); let max_players: u32 = std::env::var("QC_MAX_PLAYERS") .map(|s| s.parse().unwrap())