diff --git a/.gitignore b/.gitignore index 06026076..cecb1fee 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules/ !.yarn/sdks !.yarn/versions .pnp.* +*.bak # Created by https://www.toptal.com/developers/gitignore/api/intellij+all,rust,node,yarn # Edit at https://www.toptal.com/developers/gitignore?templates=intellij+all,rust,node,yarn diff --git a/Cargo.lock b/Cargo.lock index 5ead2141..087663df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,47 +66,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -133,9 +134,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -160,9 +161,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -238,9 +239,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" [[package]] name = "cc" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" dependencies = [ "jobserver", "libc", @@ -297,7 +298,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] @@ -329,9 +330,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -424,9 +425,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -434,23 +435,23 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", @@ -459,9 +460,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deflate64" @@ -541,9 +542,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -682,9 +683,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -744,9 +745,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "headers" @@ -1024,7 +1025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -1049,6 +1050,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itoa" version = "1.0.11" @@ -1081,9 +1088,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libz-ng-sys" @@ -1229,9 +1236,9 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1246,27 +1253,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "object" version = "0.32.2" @@ -1356,9 +1342,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -1367,9 +1353,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -1377,9 +1363,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", @@ -1390,9 +1376,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -1449,20 +1435,11 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1559,7 +1536,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -1612,9 +1589,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" @@ -1649,15 +1626,15 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -1672,15 +1649,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "scc" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96560eea317a9cc4e0bb1f6a2c93c09a19b8c4fc5cb3fcc0ec1c094cd783e2" +checksum = "76ad2bbb0ae5100a07b7a6f2ed7ab5fd0045551a4c507989b7a620046ea3efdc" dependencies = [ "sdd", ] @@ -1705,18 +1682,18 @@ checksum = "b84345e4c9bd703274a082fb80caaa99b7612be48dfaa1dd9266577ec412309d" [[package]] name = "serde" -version = "1.0.200" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -1725,9 +1702,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1752,7 +1729,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", @@ -1861,9 +1838,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1875,12 +1852,6 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -1895,9 +1866,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.60" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -1912,9 +1883,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sysinfo" -version = "0.30.11" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87341a165d73787554941cd5ef55ad728011566fe714e987d1b976c15dbc3a83" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" dependencies = [ "cfg-if", "core-foundation-sys", @@ -1937,18 +1908,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", @@ -2056,33 +2027,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow", ] [[package]] @@ -2562,15 +2515,6 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.52.0" @@ -2603,12 +2547,26 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zip" -version = "1.1.4" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc23c04387f4da0374be4533ad1208cbb091d5c11d070dfef13676ad6497164" +checksum = "c700ea425e148de30c29c580c1f9508b93ca57ad31c9f4e96b83c194c37a7a8f" dependencies = [ "aes", "arbitrary", @@ -2622,11 +2580,12 @@ dependencies = [ "hmac", "indexmap 2.2.6", "lzma-rs", - "num_enum", "pbkdf2", + "rand", "sha1", "thiserror", "time", + "zeroize", "zopfli", "zstd", ] diff --git a/Dockerfile.valheim b/Dockerfile.valheim index df81b04b..b620e583 100644 --- a/Dockerfile.valheim +++ b/Dockerfile.valheim @@ -2,115 +2,132 @@ # -- Odin Builder -- # # ------------------ # ARG ODIN_IMAGE_VERSION=latest +ARG UBUNTU_VERSION=22 FROM --platform=linux/amd64 mbround18/odin:${ODIN_IMAGE_VERSION} as runtime -# --------------- # -# -- Steam CMD -- # -# --------------- # -FROM steamcmd/steamcmd:ubuntu - -ENV TZ=America/Los_Angeles -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -RUN apt-get update \ - && apt-get upgrade -y \ - && apt-get install -y -qq \ - build-essential \ - htop net-tools nano gcc g++ gdb \ - netcat curl wget zip unzip \ - cron sudo gosu dos2unix \ - libsdl2-2.0-0 jq libc6 libc6-dev \ - libpulse-dev libatomic1 \ - tzdata bc \ - && rm -rf /var/lib/apt/lists/* \ - && gosu nobody true \ - && dos2unix - -RUN addgroup --system steam \ - && adduser --system \ - --home /home/steam \ - --shell /bin/bash \ - steam \ - && usermod -aG steam steam \ - && chmod ugo+rw /tmp/dumps - - -# Container informaiton +# ------------------ # +# -- Steam Setup -- # +# ------------------ # +FROM steamcmd/steamcmd:ubuntu-${UBUNTU_VERSION} as root + +USER root + +# Set environment variables +ENV TZ=America/Los_Angeles \ + PUID=111 \ + PGID=1000 + +# Set timezone and install necessary packages +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \ + apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y -qq \ + build-essential procps htop net-tools nano gcc g++ gdb \ + netcat-traditional curl wget zip unzip cron sudo gosu dos2unix \ + libsdl2-2.0-0 jq libc6 libc6-dev libpulse-dev libatomic1 \ + tzdata bc && \ + rm -rf /var/lib/apt/lists/* && \ + gosu nobody true && \ + dos2unix && \ + groupadd -g ${PGID} steam && \ + useradd -u ${PUID} -g steam -d /home/steam -m -s /bin/bash steam + +# Create necessary directories and set permissions +RUN mkdir -p /home/steam/.steam/steam/package && \ + mkdir -p /home/{steam,steam/{valheim,.steam}} && \ + chmod ugo+rw /tmp/dumps && \ + chown -R ${PUID}:${PGID} /home/steam + +# Container information ARG GITHUB_SHA="not-set" ARG GITHUB_REF="not-set" ARG GITHUB_REPOSITORY="not-set" -# User config -ENV PUID=1000 \ - PGID=1000 \ - # Set up timezone information - TZ=America/Los_Angeles \ - # Server Specific env variables. - PORT="2456" \ - NAME="Valheim Docker" \ - WORLD="Dedicated" \ - PUBLIC="1" \ - PASSWORD="" \ - TYPE="Vanilla" \ - UPDATE_ON_STARTUP="1" \ - # Auto Update Configs - AUTO_UPDATE="0" \ - AUTO_UPDATE_SCHEDULE="0 1 * * *" \ - # Auto Backup Configs - AUTO_BACKUP="0" \ - AUTO_BACKUP_SCHEDULE="*/15 * * * *" \ - AUTO_BACKUP_REMOVE_OLD="1" \ - AUTO_BACKUP_DAYS_TO_LIVE="3" \ - AUTO_BACKUP_ON_UPDATE="0" \ - AUTO_BACKUP_ON_SHUTDOWN="0" \ - AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS="0" \ - SCHEDULED_RESTART="0" \ - SCHEDULED_RESTART_SCHEDULE="0 2 * * *" \ - # Folders and file system related - SAVE_LOCATION="/home/steam/.config/unity3d/IronGate/Valheim" \ - MODS_LOCATION="/home/steam/staging/mods" \ - GAME_LOCATION="/home/steam/valheim" \ - BACKUP_LOCATION="/home/steam/backups" \ - # Webhook Information - WEBHOOK_STATUS_SUCCESSFUL="1" \ - WEBHOOK_STATUS_FAILED="1" +COPY --from=runtime --chmod=755 /apps/odin /apps/huginn /usr/local/bin/ + +# Set version information and configure sudoers +RUN printf "${GITHUB_SHA}\n${GITHUB_REF}\n${GITHUB_REPOSITORY}\n" >/home/steam/.version && \ + echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + echo "steam ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +# --------------- # +# -- Steam CMD -- # +# --------------- # +FROM root as steamcmd -COPY ./src/scripts/*.sh /home/steam/scripts/ -COPY ./src/scripts/entrypoint.sh /entrypoint.sh -COPY ./src/scripts/env.sh /env.sh -COPY --from=runtime /apps/odin /apps/huginn /usr/local/bin/ -COPY ./src/scripts/steam_bashrc.sh /home/steam/.bashrc - -RUN usermod -u ${PUID} steam \ - && groupmod -g ${PGID} steam \ - && printf "${GITHUB_SHA}\n${GITHUB_REF}\n${GITHUB_REPOSITORY}\n" >/home/steam/.version \ - && chmod 755 -R /home/steam/scripts/ \ - && chmod 755 /entrypoint.sh \ - && chmod 755 /env.sh \ - && chmod 755 /usr/local/bin/odin \ - && dos2unix /entrypoint.sh /home/steam/.bashrc /home/steam/scripts/*.sh \ - && echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \ - && echo "steam ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - - -# Set the steam user as the active user USER steam +ENV HOME /home/steam +ENV USER steam + +ADD --chown=steam:steam https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz /home/steam/steamcmd.tar.gz + +RUN mkdir -p /home/steam/.local/share/Steam/steamcmd && \ + tar -xvzf /home/steam/steamcmd.tar.gz -C /home/steam/.local/share/Steam/steamcmd/ && \ + rm /home/steam/steamcmd.tar.gz && \ + mkdir -p $HOME/.steam && \ + ln -s $HOME/.local/share/Steam/steamcmd/linux32 $HOME/.steam/sdk32 && \ + ln -s $HOME/.local/share/Steam/steamcmd/linux64 $HOME/.steam/sdk64 && \ + ln -s $HOME/.steam/sdk32/steamclient.so $HOME/.steam/sdk32/steamservice.so && \ + steamcmd +quit + +# --------------- # +# -- Valheim -- # +# --------------- # +FROM steamcmd as valheim -# Set the HOME environment variable to the steam user's home directory +USER steam ENV HOME /home/steam ENV USER steam +# Set environment variables for Valheim server +ENV PORT="2456" \ + NAME="Valheim Docker" \ + WORLD="Dedicated" \ + PUBLIC="1" \ + PASSWORD="" \ + TYPE="Vanilla" \ + UPDATE_ON_STARTUP="1" \ + AUTO_UPDATE="0" \ + AUTO_UPDATE_SCHEDULE="0 1 * * *" \ + AUTO_BACKUP="0" \ + AUTO_BACKUP_SCHEDULE="*/15 * * * *" \ + AUTO_BACKUP_REMOVE_OLD="1" \ + AUTO_BACKUP_DAYS_TO_LIVE="3" \ + AUTO_BACKUP_ON_UPDATE="0" \ + AUTO_BACKUP_ON_SHUTDOWN="0" \ + AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS="0" \ + SCHEDULED_RESTART="0" \ + SCHEDULED_RESTART_SCHEDULE="0 2 * * *" \ + SAVE_LOCATION="/home/steam/.config/unity3d/IronGate/Valheim" \ + MODS_LOCATION="/home/steam/staging/mods" \ + GAME_LOCATION="/home/steam/valheim" \ + BACKUP_LOCATION="/home/steam/backups" \ + WEBHOOK_STATUS_SUCCESSFUL="1" \ + WEBHOOK_STATUS_FAILED="1" + +# Copy scripts and set permissions +COPY --chmod=755 --chown=steam:steam ./src/scripts/*.sh /home/steam/scripts/ +COPY --chmod=755 --chown=steam:steam ./src/scripts/entrypoint.sh /entrypoint.sh +COPY --chmod=755 --chown=steam:steam ./src/scripts/env.sh /env.sh +COPY --chmod=755 --chown=steam:steam ./src/scripts/steam_bashrc.sh /home/steam/.bashrc + +# Convert scripts to Unix format +RUN dos2unix /entrypoint.sh /home/steam/.bashrc /home/steam/scripts/*.sh || true + +# Ensure permissions for the .steam directory +RUN chown -R steam:steam /home/steam/.steam + # Set the working directory to the game directory WORKDIR /home/steam/valheim -# Expose the ports for the server +# Expose the necessary ports EXPOSE 2456/udp 2457/udp 2458/udp EXPOSE 2456/tcp 2457/tcp 2458/tcp -# Expose ports for huginn EXPOSE 3000/tcp -HEALTHCHECK --interval=1m --timeout=3s \ - CMD pidof valheim_server.x86_64 || exit 1 +# Healthcheck to ensure the Valheim server is running +HEALTHCHECK --interval=1m --timeout=3s CMD pidof valheim_server.x86_64 || exit 1 -ENTRYPOINT ["/bin/bash","/entrypoint.sh"] +# Define the entrypoint and command +ENTRYPOINT ["/bin/bash", "/entrypoint.sh"] CMD ["/bin/bash", "/home/steam/scripts/start_valheim.sh"] diff --git a/README.md b/README.md index d0364f10..8c955738 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ # [Valheim] - - +Valheim Docker Logo +
- - + + Docker Pulls + - - + + Rust Workflow + - - + + Docker Release Workflow + @@ -23,8 +26,7 @@ ## Table of Contents - [Valheim](#valheim) - - [Table of Contents](#table-of-contents) - - [Running on a bare-metal Linux Server](#running-on-a-bare-metal-linux-server) + - [Running on a Bare-Metal Linux Server](#running-on-a-bare-metal-linux-server) - [From Release](#from-release) - [From Source](#from-source) - [Running with Docker](#running-with-docker) @@ -37,10 +39,10 @@ - [Auto Backup](#auto-backup) - [Docker Compose](#docker-compose) - [Simple](#simple) - - [Everything but the kitchen sink](#everything-but-the-kitchen-sink) + - [Everything but the Kitchen Sink](#everything-but-the-kitchen-sink) - [Bundled Tools](#bundled-tools) - [Odin](#odin) - - [Huginn Http Server](#huginn-http-server) + - [Huginn HTTP Server](#huginn-http-server) - [Feature Information](#feature-information) - [BepInEx Support](#bepinex-support) - [Webhook Support](#webhook-support) @@ -51,93 +53,89 @@ - [Versions](#versions) - [Sponsors](#sponsors) - [Contributors ✨](#contributors-) - > Did you write a guide? or perhaps an article? Add a PR to have it added here in the readme <3 - - [How to Transfer Files](#how-to-transfer-files) - - [External: Hosting with Dokku? Checkout this guide!](https://tkte.ch/articles/2023/03/03/Valheim.html) - - [External: Hosting Valheim on Rocket Pi X](https://ikarus.sg/valheim-server-rock-pi-x/) - - [External: Valheim on AWS](https://aws.amazon.com/getting-started/hands-on/valheim-on-aws/) - - [External: How to host a dedicated Valheim server on Amazon Lightsail](https://updateloop.dev/dedicated-valheim-lightsail/) - - [External: Experience With Valheim Game Hosting With Docker](https://norton-setup.support/games/experience-with-valheim-game-hosting-with-docker/) - - [External: AWS Cloudformation template using Elastic Container Service with a Spot Instance for cost savings](https://github.com/apeabody/Valheim-AWS-ECS-Spot) -- [Additional Information](#additional-information) - - [Discord Release Notifications](#discord-release-notifications) - - [Versions](#versions) -- [❤️ Sponsors ❤️](#sponsors) -- [✨ Contributors ✨](#contributors-) - -## Running on a bare-metal Linux Server + - [External Guides](#external-guides) + +## Running on a Bare-Metal Linux Server ### From Release -1. Navigate to `https://github.com/mbround18/valheim-docker/releases/latest` +1. Navigate to [the latest release](https://github.com/mbround18/valheim-docker/releases/latest) 2. Download the `bundle.zip` to your server 3. Extract the `bundle.zip` 4. Make the files executable `chmod +x {odin,huginn}` -5. Optional: Add the files to your path. +5. Optional: Add the files to your PATH. 6. Navigate to the folder where you want your server installed. -7. Run `odin configure --password "Your Super Strong Password"` (you can also supply `--name "Server Name"`, `--port "Server Port"`, or other arguments available.) +7. Run `odin configure --password "Your Super Strong Password"` (you can also supply `--name "Server Name"`, `--port "Server Port"`, or other arguments available). 8. Finally, run `odin start`. -**More in-depth How-to Article:** +**More in-depth How-to Article:** [Running Valheim on a Linux Server](https://dev.to/mbround18/running-valheim-on-an-linux-server-4kh1) ### From Source -This repo bundles its tools in a way that you can run them without having to install docker! -If you purely want to run this on a Linux based system, without docker, take a look at the links below <3 +This repo bundles its tools in a way that you can run them without having to install Docker! +If you purely want to run this on a Linux-based system, without Docker, take a look at the links below: -- [Installing & Using Odin](./src/odin/README.md) - The tool [Odin] runs the show and does almost all the heavy lifting in this repo. It starts, stops, and manages your Valheim server instance. -- [Installing & Using Huginn](./src/huginn/README.md) - Looking for a way to view the status of your server? Look no further than [Huginn]! - The [Huginn] project is a http server built on the same source as [Odin] and uses these capabilities to expose a few http endpoints. +- [Installing & Using Odin](./src/odin/README.md): Odin runs the show and does almost all the heavy lifting in this repo. It starts, stops, and manages your Valheim server instance. +- [Installing & Using Huginn](./src/huginn/README.md): Huginn is an HTTP server built on the same source as Odin and uses these capabilities to expose a few HTTP endpoints. > Using the binaries to run on an Ubuntu Server, you will have to be more involved and configure a few things manually. -> If you want a managed, easy one-two punch to manage your server. Then look at the Docker section <3 +> If you want a managed, easy one-two punch to manage your server, then look at the Docker section. ## Running with Docker -> This image does use verion 3+ for all of its compose examples. +> This image uses version 3+ for all of its compose examples. > Please use Docker engine >=20 or make adjustments accordingly. > -> [If you are looking for a guide on how to get started click here](https://github.com/mbround18/valheim-docker/discussions/28) +> [Guide to get started](https://github.com/mbround18/valheim-docker/discussions/28) > -> Mod Support! It is supported to launch the server with BepInEx but!!!!! as a disclaimer! You take responsibility for debugging why your server won't start. -> Modding is not supported by the Valheim developers officially yet; Which means you WILL run into errors. This repo has been tested with running ValheimPlus as a test mod and does not have any issues. +> Mod Support! It is supported to launch the server with BepInEx, but as a disclaimer, you take responsibility for debugging why your server won't start. Modding is not supported by the Valheim developers officially yet, which means you WILL run into errors. This repo has been tested with running ValheimPlus as a test mod and does not have any issues. > See [Getting started with mods](./docs/tutorials/getting_started_with_mods.md) ### Download Locations #### DockerHub -DockerHub Valheim -DockerHub Odin + + DockerHub Valheim + + + DockerHub Odin + #### GitHub Container Registry -GHCR Valheim -GHCR Odin + + GHCR Valheim + + + GHCR Odin + ### Environment Variables -> See further on down for advanced environment variables. - -| Variable | Default | Required | Description | -| ------------------------- | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PORT | `2456` | TRUE | Sets the port your server will listen on. Take note it will also listen on +2 (ex: 2456, 2457, 2458) | -| NAME | `Valheim Docker` | TRUE | The name of your server! Make it fun and unique! | -| WORLD | `Dedicated` | TRUE | This is used to generate the name of your world. | -| PUBLIC | `1` | FALSE | Sets whether or not your server is public on the server list. | -| PASSWORD | `` | TRUE | Set this to something unique! | -| ENABLE_CROSSPLAY | `0` | FALSE | Enable crossplay support as of `Valheim Version >0.211.8` | -| TYPE | `Vanilla` | FALSE | This can be set to `ValheimPlus`, `BepInEx`, `BepInExFull` or `Vanilla` | -| PRESET | `` | FALSE | Normal, Casual, Easy, Hard, Hardcore, Immersive, Hammer | -| MODIFIERS | `` | FALSE | Comma-separated array of modifiers. EX: `combat=easy,raids=muchmore` | -| SET_KEY | `` | FALSE | Can be one of the following: nobuildcost, playerevents, passivemobs, nomap | -| MODS | `` | FALSE | This is an array of mods separated by comma and a new line. [Click Here for Examples](./docs/tutorials/getting_started_with_mods.md) Supported files are `zip`, `dll`, and `cfg`. | -| WEBHOOK_URL | `` | FALSE | Supply this to get information regarding your server's status in a webhook or Discord notification! [Click here to learn how to get a webhook url for Discord](https://help.dashe.io/en/articles/2521940-how-to-create-a-discord-webhook-url) | -| WEBHOOK_INCLUDE_PUBLIC_IP | `0` | FALSE | Optionally include your server's public IP in webhook notications, useful if not using a static IP address. NOTE: If your server is behind a NAT using PAT with more than one external IP address (very unlikely on a home network), this could be inaccurate if your NAT doesn't maintain your server to a single external IP. | -| UPDATE_ON_STARTUP | `1` | FALSE | Tries to update the server the container is started. | -| ADDITIONAL_STEAMCMD_ARGS | `` | FALSE | Sets optional arguments for install | +> See further down for advanced environment variables. + +| Variable | Default | Required | Description | +| ------------------------- | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PORT | `2456` | TRUE | Sets the port your server will listen on. Take note it will also listen on +2 (e.g., 2456, 2457, 2458) | +| NAME | `Valheim Docker` | TRUE | The name of your server! Make it fun and unique! | +| WORLD | `Dedicated` | TRUE | This is used to generate the name of your world. | +| PUBLIC | `1` | FALSE | Sets whether or not your server is public on the server list. | +| PASSWORD | `` | TRUE | Set this to something unique! | +| ENABLE_CROSSPLAY | `0` | FALSE | Enable crossplay support as of `Valheim Version >0.211.8` | +| TYPE | `Vanilla` | FALSE | This can be set to `ValheimPlus`, `BepInEx`, `BepInExFull` or `Vanilla` | +| PRESET | `` | FALSE | Normal, Casual, Easy, Hard, Hardcore, Immersive, Hammer | +| MODIFIERS | `` | FALSE | Comma-separated array of modifiers. EX: `combat=easy,raids=muchmore` | +| SET_KEY | `` | FALSE | Can be one of the following: nobuildcost, playerevents, passivemobs, nomap | +| MODS | `` | FALSE | This is an array of mods separated by comma and a new line. [Examples](./docs/tutorials/getting_started_with_mods.md). Supported files are `zip`, `dll`, and `cfg`. | +| WEBHOOK_URL | `` | FALSE | Supply this to get information regarding your server's status in a webhook or Discord notification! [How to create a Discord webhook URL](https://help.dashe.io/en/articles/2521940-how-to-create-a-discord-webhook-url) | +| WEBHOOK_INCLUDE_PUBLIC_IP | `0` | FALSE | Optionally include your server's public IP in webhook notifications, useful if not using a static IP address. NOTE: If your server is behind a NAT using PAT with more than one external IP address (very unlikely on a home network), this could be inaccurate if your NAT doesn't maintain your server to a single external IP. | +| UPDATE_ON_STARTUP | `1` | FALSE | Tries to update the server the | + +container is started. | +| ADDITIONAL_STEAMCMD_ARGS | `` | FALSE | Sets optional arguments for install | +| BETA_BRANCH |`public-test` | FALSE | Sets the beta branch for the server. | +| BETA_BRANCH_PASSWORD |`yesimadebackups` | FALSE | Sets the password for the beta branch. | #### Container Env Variables @@ -152,29 +150,25 @@ If you purely want to run this on a Linux based system, without docker, take a l | Variable | Default | Required | Description | | ------------------------------ | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AUTO_UPDATE | `0` | FALSE | Set to `1` if you want your container to auto update! This means at the times indicated by `AUTO_UPDATE_SCHEDULE` it will check for server updates. If there is an update then the server will be shut down, updated, and brought back online if the server was running before. | -| AUTO_UPDATE_SCHEDULE | `0 1 * * *` | FALSE | This works in conjunction with `AUTO_UPDATE` and sets the schedule to which it will run an auto update. [If you need help figuring out a cron schedule click here] | +| AUTO_UPDATE_SCHEDULE | `0 1 * * *` | FALSE | This works in conjunction with `AUTO_UPDATE` and sets the schedule to which it will run an auto update. [If you need help figuring out a cron schedule click here](https://crontab.guru/#0_1____) | | AUTO_UPDATE_PAUSE_WITH_PLAYERS | `0` | FALSE | Does not process an update for the server if there are players online. | -Auto update job, queries steam and compares it against your internal steam files for differential in version numbers. - #### Auto Backup -| Variable | Default | Required | Description | -| --------------------------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| AUTO_BACKUP | `0` | FALSE | Set to `1` to enable auto backups. Backups are stored under `/home/steam/backups` which means you will have to add a volume mount for this directory. | -| AUTO_BACKUP_SCHEDULE | `*/15 * * * *` | FALSE | Change to set how frequently you would like the server to backup. [If you need help figuring out a cron schedule click here]. | -| AUTO_BACKUP_NICE_LEVEL | `NOT SET` | FALSE | [Do NOT set this variable unless you are following this guide here](https://github.com/mbround18/valheim-docker/discussions/532) | -| AUTO_BACKUP_REMOVE_OLD | `1` | FALSE | Set to `0` to keep all backups or manually manage them. | -| AUTO_BACKUP_DAYS_TO_LIVE | `3` | FALSE | This is the number of days you would like to keep backups for. While backups are compressed and generally small it is best to change this number as needed. | -| AUTO_BACKUP_ON_UPDATE | `0` | FALSE | Create a backup on right before updating and starting your server. | -| AUTO_BACKUP_ON_SHUTDOWN | `0` | FALSE | Create a backup on shutdown. | -| AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS | `0` | FALSE | Will skip creating a backup if there are no players. `PUBLIC` must be set to `1` for this to work! | - -Auto backup job produces an output of a `*.tar.gz` file which should average around 30mb for a world that has an average of 4 players consistently building on. You should be aware that if you place the server folder in your saves folder your backups could become astronomical in size. This is a common problem that others have observed, to avoid this please follow the guide for how volume mounts should be made in the `docker-compose.yml`. +| Variable | Default | Required | Description | +| --------------------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| AUTO_BACKUP | `0` | FALSE | Set to `1` to enable auto backups. Backups are stored under `/home/steam/backups` which means you will have to add a volume mount for this directory. | +| AUTO_BACKUP_SCHEDULE | `*/15 * * * *` | FALSE | Change to set how frequently you would like the server to backup. [If you need help figuring out a cron schedule click here](https://crontab.guru/#0_1____). | +| AUTO_BACKUP_NICE_LEVEL | `NOT SET` | FALSE | [Do NOT set this variable unless you are following this guide here](https://github.com/mbround18/valheim-docker/discussions/532) | +| AUTO_BACKUP_REMOVE_OLD | `1` | FALSE | Set to `0` to keep all backups or manually manage them. | +| AUTO_BACKUP_DAYS_TO_LIVE | `3` | FALSE | This is the number of days you would like to keep backups for. While backups are compressed and generally small it is best to change this number as needed. | +| AUTO_BACKUP_ON_UPDATE | `0` | FALSE | Create a backup on right before updating and starting your server. | +| AUTO_BACKUP_ON_SHUTDOWN | `0` | FALSE | Create a backup on shutdown. | +| AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS | `0` | FALSE | Will skip creating a backup if there are no players. `PUBLIC` must be set to `1` for this to work! | #### Scheduled Restarts -Scheduled restarts allow th operator to trigger restarts on a cron job +Scheduled restarts allow the operator to trigger restarts on a cron job | Variable | Default | Required | Description | | -------------------------- | ----------- | -------- | ------------------------------------------------------------------ | @@ -183,12 +177,12 @@ Scheduled restarts allow th operator to trigger restarts on a cron job ## Docker Compose -> This image does use verion 3+ for all of its compose examples. +> This image uses version 3+ for all of its compose examples. > Please use Docker engine >=20 or make adjustments accordingly. ### Simple -> This is a basic example of a docker compose, you can apply any of the variables above to the `environment` section below but be sure to follow each variables' description notes! +> This is a basic example of a Docker Compose file. You can apply any of the variables above to the `environment` section below but be sure to follow each variable's description notes! ```yaml version: "3" @@ -212,7 +206,7 @@ services: - ./valheim/server:/home/steam/valheim ``` -### Everything but the kitchen sink +### Everything but the Kitchen Sink ```yaml version: "3" @@ -252,33 +246,33 @@ services: ### [Odin] -This repo has a CLI tool called [Odin] in it! It is used for managing the server inside the container. If you are looking for instructions for it click here: [Odin] +This repo has a CLI tool called [Odin] in it! It is used for managing the server inside the container. If you are looking for instructions for it, click here: [Odin] [Click here to see advanced environment variables for Odin](src/odin/README.md) -### [Huginn] Http Server +### [Huginn] HTTP Server | Variable | Default | Required | Description | | --------- | --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | | ADDRESS | `Your Public IP` | FALSE | This setting is used in conjunction with `odin status` and setting this will stop `odin` from trying to fetch your public IP | -| HTTP_PORT | `anything above 1024` | FALSE | Setting this will spin up a little http server that provides two endpoints for you to call. | +| HTTP_PORT | `anything above 1024` | FALSE | Setting this will spin up a little HTTP server that provides two endpoints for you to call. | -- `/metrics` provides a prometheous style metrics output. +- `/metrics` provides a Prometheus-style metrics output. - `/status` provides a more traditional status page. -> Note on `ADDRESS` this can be set to `127.0.0.1:` or `:` but does not have to be set. If it is set, it will prevent odin from reaching out to aws ip service from asking for your public IP address. Keep in mind, your query port is +1 of what you set in the `PORT` env variable for your valheim server. +> Note on `ADDRESS`: This can be set to `127.0.0.1:` or `:` but does not have to be set. If it is set, it will prevent Odin from reaching out to AWS IP service to ask for your public IP address. Keep in mind, your query port is +1 of what you set in the `PORT` env variable for your Valheim server. -> Another note: your server MUST be public (eg. `PUBLIC=1`) in order for Odin+Huginn to collect and report statistics. +> Another note: Your server MUST be public (e.g., `PUBLIC=1`) for Odin+Huginn to collect and report statistics. ## Feature Information ### [BepInEx Support](./docs/bepinex.md) -As of [March 2021](./docs/bepinex.md) the TYPE variable can be used to automatically install BepInEx. For details see [Getting started with mods]. +As of [March 2021](./docs/bepinex.md), the TYPE variable can be used to automatically install BepInEx. For details, see [Getting started with mods](./docs/tutorials/getting_started_with_mods.md). ### [Webhook Support](./docs/webhooks.md) -This repo can automatically send notifications to discord via the WEBHOOK_URL variable. +This repo can automatically send notifications to Discord via the WEBHOOK_URL variable. Only use the documentation link below if you want advanced settings! [Click Here to view documentation on Webhook Support](./docs/webhooks.md) @@ -287,11 +281,11 @@ Only use the documentation link below if you want advanced settings! ### [How to Transfer Files](./docs/tutorials/how-to-transfer-files.md) -This is a tutorial of a recommended path to transfering files. This can be done to transfer world files between hosts, transfer BepInEx configs, or even to transfer backups. +This is a tutorial of a recommended path to transferring files. This can be done to transfer world files between hosts, transfer BepInEx configs, or even to transfer backups. [Click Here to view the tutorial of how to transfer files.](./docs/tutorials/how-to-transfer-files.md) -### How to access your container in docker +### How to Access Your Container in Docker ```bash docker exec -it $CONTAINER_NAME gosu steam bash @@ -303,63 +297,73 @@ docker exec -it $CONTAINER_NAME gosu steam bash If you would like to have release notifications tied into your Discord server, click here: -Discord Banner + + Discord Banner + -**Note**: The discord is PURELY for release notifications and any + all permissions involving sending chat messages has been disabled. +**Note**: The Discord is PURELY for release notifications and any + all permissions involving sending chat messages have been disabled. [Any support for this repository must take place on the Discussions.](https://github.com/mbround18/valheim-docker/discussions) ### Versions -- latest (Stable): Mod support! and cleaned up the code base. -- 1.4.x (Stable): Webhook for discord upgrade. +- 2.x.x (Stable): Mod support and cleaned up the code base. +- 1.4.x (Stable): Webhook for Discord upgrade. - 1.3.x (Stable): Health of codebase improvements. -- 1.2.0 (Stable): Added additional stop features and sig for stopping. -- 1.1.1 (Stable): Patch to fix arguments -- 1.1.0 (Unstable): Cleaned up image and made it faster +- 1.2.0 (Stable): Added additional stop features and SIG for stopping. +- 1.1.1 (Stable): Patch to fix arguments. +- 1.1.0 (Unstable): Cleaned up image and made it faster. - 1.0.0 (Stable): It works! -[//]: <> (Links below...................) +[//]: <> (Links below) [Odin]: src/odin/README.md [Huginn]: src/huginn/README.md [Valheim]: https://www.valheimgame.com/ [Getting started with mods]: ./docs/tutorials/getting_started_with_mods.md -[If you need help figuring out a cron schedule click here]: https://crontab.guru/#0_1*\_\_\_\_\* - -[//]: <> (Image Base Url: https://github.com/mbround18/valheim-docker/blob/main/docs/assets/name.png?raw=true) +[If you need help figuring out a cron schedule click here]: https://crontab.guru/#0_1**\_** ## Sponsors ## Contributors ✨ -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): +Thanks go to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - - - + + + + + + + - - - - - - - + + + + + + +

Mark

📖

Michael

🚇 💻 📖

imgbot[bot]

📖

Jonathan Boudreau

💻

Lukáš Hruška

📖

Julian Vallée

💻

Finomnis

💻
Mark
Mark

📖
Michael
Michael

🚇 💻 📖
imgbot[bot]
imgbot[bot]

📖
Jonathan Boudreau
Jonathan Boudreau

💻
Lukáš Hruška
Lukáš Hruška

📖
Julian Vallée
Julian Vallée

💻
Finomnis
Finomnis

💻

Justin Byrne

📖

Andrew Peabody

📖 💻

Jorge Morales

💻

Spanner_Man

📖

Cameron Pittman

📖

kodiakhq[bot]

🚇 📖 💻

Anders Johansson

📖
Justin Byrne
Justin Byrne

📖
Andrew Peabody
Andrew Peabody

📖 💻
Jorge Morales
Jorge Morales

💻
Spanner_Man
Spanner_Man

📖
Cameron Pittman
Cameron Pittman

📖
kodiakhq[bot]
kodiakhq[bot]

🚇 📖 💻
Anders Johansson
Anders Johansson

📖
- -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome! + +## External Guides + +- [Hosting with Dokku? Check out this guide!](https://tkte.ch/articles/2023/03/03/Valheim.html) +- [Hosting Valheim on Rocket Pi X](https://ikarus.sg/valheim-server-rock-pi-x/) +- [Valheim on AWS](https://aws.amazon.com/getting-started/hands-on/valheim-on-aws/) +- [How to host a dedicated Valheim server on Amazon Lightsail](https://updateloop.dev/dedicated-valheim-lightsail/) +- [Experience With Valheim Game Hosting With Docker](https://norton-setup.support/games/experience-with-valheim-game-hosting-with-docker/) +- [AWS Cloudformation template using Elastic Container Service with a Spot Instance for cost savings](https://github.com/apeabody/Valheim-AWS-ECS-Spot) diff --git a/docs/assets/old-valheim-docker-logo.png b/docs/assets/old-valheim-docker-logo.png new file mode 100644 index 00000000..3f5f4d8e Binary files /dev/null and b/docs/assets/old-valheim-docker-logo.png differ diff --git a/docs/assets/valheim-docker-logo.png b/docs/assets/valheim-docker-logo.png index 3f5f4d8e..a34b7bdc 100644 Binary files a/docs/assets/valheim-docker-logo.png and b/docs/assets/valheim-docker-logo.png differ diff --git a/src/odin/server/install.rs b/src/odin/server/install.rs index 6eba7906..485b54ff 100644 --- a/src/odin/server/install.rs +++ b/src/odin/server/install.rs @@ -28,8 +28,12 @@ fn add_additional_args(args: &mut Vec) { } if environment::fetch_var("USE_PUBLIC_BETA", "0").eq("1") { debug!("Using public beta branch"); - args.push(format!("-beta {}", BETA_BRANCH)); - args.push(format!("-betapassword {}", BETA_BRANCH_PASSWORD)); + args.push(format!("-beta {}", { + env::var("BETA_BRANCH").unwrap_or(BETA_BRANCH.to_string()) + })); + args.push(format!("-betapassword {}", { + env::var("BETA_BRANCH_PASSWORD").unwrap_or(BETA_BRANCH_PASSWORD.to_string()) + })); args.push(String::from("validate")); } } diff --git a/src/scripts/entrypoint.sh b/src/scripts/entrypoint.sh index 681fc897..163f24b2 100644 --- a/src/scripts/entrypoint.sh +++ b/src/scripts/entrypoint.sh @@ -1,235 +1,192 @@ #!/usr/bin/env bash -if [ -f "/home/steam/scripts/utils.sh" ]; then - source "/home/steam/scripts/utils.sh" -fi +# Exit immediately if a command exits with a non-zero status +set -e + +# Logging function to prepend timestamps to log messages +log() { + echo "$(date) - $*" +} + +# Function to check and log the current user and steam user's ID and group ID +check_user_and_group() { + whoami + id -u steam + id -g steam +} + +# Function to set up the environment, including sourcing utility scripts and setting environment variables +setup_environment() { + if [ -f "/home/steam/scripts/utils.sh" ]; then + source "/home/steam/scripts/utils.sh" + fi -# Set up variables -# shellcheck disable=SC2155 -export NAME="$(sed -e 's/^"//' -e 's/"$//' <<<"$NAME")" -# shellcheck disable=SC2155 -export WORLD="$(sed -e 's/^"//' -e 's/"$//' <<<"$WORLD")" -# shellcheck disable=SC2155 -export PASSWORD="$(sed -e 's/^"//' -e 's/"$//' <<<"$PASSWORD")" -export ODIN_CONFIG_FILE="${ODIN_CONFIG_FILE:-"${GAME_LOCATION}/config.json"}" -export ODIN_DISCORD_FILE="${ODIN_DISCORD_FILE:-"${GAME_LOCATION}/discord.json"}" + export NAME=$(sed -e 's/^"//' -e 's/"$//' <<<"$NAME") + export WORLD=$(sed -e 's/^"//' -e 's/"$//' <<<"$WORLD") + export PASSWORD=$(sed -e 's/^"//' -e 's/"$//' <<<"$PASSWORD") + export ODIN_CONFIG_FILE="${ODIN_CONFIG_FILE:-"${GAME_LOCATION}/config.json"}" + export ODIN_DISCORD_FILE="${ODIN_DISCORD_FILE:-"${GAME_LOCATION}/discord.json"}" -# Set up timezone -sudo ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" | sudo tee -a /etc/timezone + # Set timezone + sudo ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime + echo "$TZ" | sudo tee -a /etc/timezone +} +# Function to safely shut down the server and terminate cron jobs clean_up() { - echo "Safely shutting down..." >>/home/steam/output.log + log "Safely shutting down..." if [[ -n $CRON_PID ]]; then kill "$CRON_PID" fi } -trap 'clean_up' INT TERM +# Trap signals for safe shutdown +trap clean_up INT TERM +# Function to set up environment variables for cron jobs setup_cron_env() { - echo "Configuring Preset Env" - echo " - DEBUG_MODE=${DEBUG_MODE:=0} - ODIN_CONFIG_FILE=\"${ODIN_CONFIG_FILE}\" - ODIN_DISCORD_FILE=\"${ODIN_DISCORD_FILE}\" - ODIN_WORKING_DIR=\"${ODIN_WORKING_DIR}\" - SAVE_LOCATION=\"${SAVE_LOCATION}\" - MODS_LOCATION=\"${MODS_LOCATION}\" - GAME_LOCATION=\"${GAME_LOCATION}\" - BACKUP_LOCATION=\"${BACKUP_LOCATION}\" - - NAME=\"${NAME}\" - ADDRESS=\"${ADDRESS}\" - PORT=${PORT} - PUBLIC=${PUBLIC} - ENABLE_CROSSPLAY=${ENABLE_CROSSPLAY:-"0"} - UPDATE_ON_STARTUP=${UPDATE_ON_STARTUP} - SERVER_EXTRA_LAUNCH_ARGS=\"${SERVER_EXTRA_LAUNCH_ARGS}\" - PRESET=${PRESET} - MODIFIERS=$(echo "${MODIFIERS}" | xargs echo -n | tr ' ' ',' | sed 's/,,/,/g') - SET_KEY=${SET_KEY} - - WEBHOOK_URL=\"${WEBHOOK_URL:-""}\" - WEBHOOK_STATUS_SUCCESSFUL=${WEBHOOK_STATUS_SUCCESSFUL:-"1"} - WEBHOOK_STATUS_FAILED=${WEBHOOK_STATUS_FAILED:-"1"} - WEBHOOK_STATUS_RUNNING=${WEBHOOK_STATUS_RUNNING:-"1"} - WEBHOOK_INCLUDE_PUBLIC_IP=${WEBHOOK_INCLUDE_PUBLIC_IP:-"0"} - - AUTO_UPDATE=${AUTO_UPDATE} - AUTO_UPDATE_PAUSE_WITH_PLAYERS=${AUTO_UPDATE_PAUSE_WITH_PLAYERS} - - AUTO_BACKUP=${AUTO_BACKUP} - AUTO_BACKUP_NICE_LEVEL=${AUTO_BACKUP_NICE_LEVEL} - AUTO_BACKUP_REMOVE_OLD=${AUTO_BACKUP_REMOVE_OLD} - AUTO_BACKUP_DAYS_TO_LIVE=${AUTO_BACKUP_DAYS_TO_LIVE} - AUTO_BACKUP_ON_UPDATE=${AUTO_BACKUP_ON_UPDATE} - AUTO_BACKUP_ON_SHUTDOWN=${AUTO_BACKUP_ON_SHUTDOWN} - AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS=${AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS} - - VALHEIM_PLUS_RELEASES_URL=\"${VALHEIM_PLUS_RELEASES_URL:-""}\" - VALHEIM_PLUS_DOWNLOAD_URL=\"${VALHEIM_PLUS_DOWNLOAD_URL}\" - - BEPINEX_RELEASES_URL=\"${BEPINEX_RELEASES_URL:-"https://thunderstore.io/api/experimental/package/denikson/BepInExPack_Valheim/"}\" - BEPINEX_DOWNLOAD_URL=\"${BEPINEX_DOWNLOAD_URL}\" - - BEPINEX_FULL_RELEASES_URL=\"${BEPINEX_FULL_RELEASES_URL:-""}\" - " | \ - while read -r line; do - if [[ "${line}" == *"="* ]]; then - CONTENT="export ${line}" - if ! grep -q -F "${CONTENT}" "/env.sh" && [[ ! "${CONTENT}" =~ =$ ]]; then - echo "${CONTENT}" | sudo tee -a /env.sh - fi - fi - done - echo "Preset Env Configured" + log "Configuring Preset Env" + env_vars=( + "DEBUG_MODE" + "ODIN_CONFIG_FILE" + "ODIN_DISCORD_FILE" + "ODIN_WORKING_DIR" + "SAVE_LOCATION" + "MODS_LOCATION" + "GAME_LOCATION" + "BACKUP_LOCATION" + "NAME" + "ADDRESS" + "PORT" + "PUBLIC" + "ENABLE_CROSSPLAY" + "UPDATE_ON_STARTUP" + "SERVER_EXTRA_LAUNCH_ARGS" + "PRESET" + "MODIFIERS" + "SET_KEY" + "WEBHOOK_URL" + "WEBHOOK_STATUS_SUCCESSFUL" + "WEBHOOK_STATUS_FAILED" + "WEBHOOK_STATUS_RUNNING" + "WEBHOOK_INCLUDE_PUBLIC_IP" + "AUTO_UPDATE" + "AUTO_UPDATE_PAUSE_WITH_PLAYERS" + "AUTO_BACKUP" + "AUTO_BACKUP_NICE_LEVEL" + "AUTO_BACKUP_REMOVE_OLD" + "AUTO_BACKUP_DAYS_TO_LIVE" + "AUTO_BACKUP_ON_UPDATE" + "AUTO_BACKUP_ON_SHUTDOWN" + "AUTO_BACKUP_PAUSE_WITH_NO_PLAYERS" + "VALHEIM_PLUS_RELEASES_URL" + "VALHEIM_PLUS_DOWNLOAD_URL" + "BEPINEX_RELEASES_URL" + "BEPINEX_DOWNLOAD_URL" + "BEPINEX_FULL_RELEASES_URL" + ) + + for var in "${env_vars[@]}"; do + value="${!var}" + [[ -n "$value" ]] && echo "export ${var}=\"$value\"" | sudo tee -a /env.sh + done + + log "Preset Env Configured" } +# Function to set up cron jobs setup_cron() { - set -f - CRON_NAME=$1 - CRON_FOLDER="$HOME/cron.d/" - CRON_SCHEDULE=$3 - - SCRIPT_PATH="$HOME/scripts/$2" - LOG_FOLDER="$HOME/valheim/logs" - LOG_LOCATION="$LOG_FOLDER/$CRON_NAME.out" - - # Create the logs folders - if [ ! -d "$LOG_FOLDER" ]; then - mkdir -p "$LOG_FOLDER" - fi + local name=$1 + local script=$2 + local schedule=$3 - # Create cron folder - if [ ! -d "$CRON_FOLDER" ]; then - mkdir -p "$CRON_FOLDER" - fi - [ -f "$LOG_LOCATION" ] && rm "$LOG_LOCATION" + local cron_folder="$HOME/cron.d" + local log_folder="$HOME/valheim/logs" + local log_location="$log_folder/$name.out" + + # Create necessary directories + mkdir -p "$log_folder" "$cron_folder" + rm -f "$log_location" # Create the cron job - printf "%s %s /bin/bash %s >> %s 2>&1" \ - "${CRON_SCHEDULE}" \ - "BASH_ENV=/env.sh" \ - "${SCRIPT_PATH}" \ - "${LOG_LOCATION}" \ - | tee "$CRON_FOLDER/${CRON_NAME}" - echo "" | tee -a "$CRON_FOLDER/${CRON_NAME}" - - # Give execution rights on the cron job - chmod 0644 "$CRON_FOLDER/${CRON_NAME}" - set +f + echo "${schedule} BASH_ENV=/env.sh /bin/bash $HOME/scripts/$script >> $log_location 2>&1" | tee "$cron_folder/$name" + chmod 0644 "$cron_folder/$name" } -setup_filesystem() { - log "Setting up file systems" - STEAM_UID=1000 - STEAM_GID=${PGID:=1000} - - mkdir -p "/home/steam/.steam/root" - mkdir -p "/home/steam/.steam/steam" +# Function to create directories with specified ownership and permissions +create_dir_with_ownership() { + local user=$1 + local group=$2 + local dir=$3 - # Save Files - mkdir -p "${SAVE_LOCATION}" - - # Mod staging location - mkdir -p "${MODS_LOCATION}" + mkdir -p "${dir}" + sudo chown -R "${user}:${group}" "${dir}" + sudo chmod -R ug+rw "${dir}" +} - # Backups - mkdir -p "${BACKUP_LOCATION}" +# Function to set up the filesystem, ensuring correct ownership and permissions +setup_filesystem() { + log "Setting up file systems" - # Valheim Server - mkdir -p "${GAME_LOCATION}" - mkdir -p "${GAME_LOCATION}/logs" - sudo chown -R "${STEAM_UID}":"${STEAM_GID}" "${GAME_LOCATION}" - sudo chown -R "${STEAM_UID}":"${STEAM_GID}" "${GAME_LOCATION}" + sudo chown -R "$PUID:$PGID" /home/steam /home/steam/.* + sudo chmod -R ug+rwx /home/steam - # Other + create_dir_with_ownership "$PUID" "$PGID" "$SAVE_LOCATION" + create_dir_with_ownership "$PUID" "$PGID" "$MODS_LOCATION" + create_dir_with_ownership "$PUID" "$PGID" "$BACKUP_LOCATION" + create_dir_with_ownership "$PUID" "$PGID" "$GAME_LOCATION" + create_dir_with_ownership "$PUID" "$PGID" "$GAME_LOCATION/logs" mkdir -p /home/steam/scripts - sudo chown -R "${STEAM_UID}":"${STEAM_GID}" /home/steam/scripts - sudo chown -R "${STEAM_UID}":"${STEAM_GID}" /home/steam/ - # Enforce steam home sudo usermod -d /home/steam steam - cd /home/steam || exit 1 } +# Function to check if the system has sufficient memory check_memory() { -# MEMORY=$(($(getconf _PHYS_PAGES) * $(getconf PAGE_SIZE) / (1024 * 1024))) - MESSAGE="Your system has less than 2GB of ram!!\nValheim might not run on your system!!" - - # Get the total memory in GB - total_memory=$(free -h | grep Mem: | awk '{print $2}' | tr -d GiM) - - # Check if total memory is less than 2GB + local total_memory + total_memory=$(free -h | awk '/^Mem:/ {print $2}' | tr -d 'G') if (( $(echo "$total_memory < 2" | bc -l) )); then - line - log "${MESSAGE^^}" - line - line + log "Your system has less than 2GB of RAM! Valheim might not run on your system." else - log "Total memory: ${total_memory}GB" + log "Total memory: ${total_memory} GB" fi } -line +# Main script execution log "Valheim Server - $(date)" log "Initializing your container..." -#check_version -check_memory -line -# Configure Cron -AUTO_UPDATE="${AUTO_UPDATE:=0}" -AUTO_BACKUP="${AUTO_BACKUP:=0}" -SCHEDULED_RESTART="${SCHEDULED_RESTART:=0}" +# Check current user and steam user details +check_user_and_group -setup_cron_env +# Set up environment +setup_environment -if [ "${AUTO_UPDATE}" -eq 1 ]; then - log "Auto Update Enabled..." - log "Auto Update Schedule: ${AUTO_UPDATE_SCHEDULE}" - AUTO_UPDATE_SCHEDULE=$(echo "$AUTO_UPDATE_SCHEDULE" | tr -d '"') - setup_cron \ - "auto-update" \ - "auto_update.sh" \ - "${AUTO_UPDATE_SCHEDULE}" \ - "AUTO_BACKUP_ON_UPDATE=${AUTO_BACKUP_ON_UPDATE:=0}" -fi +# Check system memory +check_memory -if [ "${AUTO_BACKUP}" -eq 1 ]; then - log "Auto Backup Enabled..." - log "Auto Backup Schedule: ${AUTO_BACKUP_SCHEDULE}" - AUTO_BACKUP_SCHEDULE=$(echo "$AUTO_BACKUP_SCHEDULE" | tr -d '"') - setup_cron \ - "auto-backup" \ - "auto_backup.sh" \ - "${AUTO_BACKUP_SCHEDULE}" \ - "AUTO_BACKUP_REMOVE_OLD=${AUTO_BACKUP_REMOVE_OLD} AUTO_BACKUP_DAYS_TO_LIVE=${AUTO_BACKUP_DAYS_TO_LIVE}" -fi +# Configure environment variables for cron jobs +setup_cron_env -if [ "${SCHEDULED_RESTART}" -eq 1 ]; then - log "Scheduled Restarts Enabled..." - log "Scheduled Restart Schedule: ${SCHEDULED_RESTART_SCHEDULE}" - SCHEDULED_RESTART_SCHEDULE=$(echo "$SCHEDULED_RESTART_SCHEDULE" | tr -d '"') - setup_cron \ - "scheduled-restart" \ - "scheduled_restart.sh" \ - "${SCHEDULED_RESTART_SCHEDULE}" -fi +# Set up cron jobs if enabled +[[ "$AUTO_UPDATE" -eq 1 ]] && setup_cron "auto-update" "auto_update.sh" "$AUTO_UPDATE_SCHEDULE" +[[ "$AUTO_BACKUP" -eq 1 ]] && setup_cron "auto-backup" "auto_backup.sh" "$AUTO_BACKUP_SCHEDULE" +[[ "$SCHEDULED_RESTART" -eq 1 ]] && setup_cron "scheduled-restart" "scheduled_restart.sh" "$SCHEDULED_RESTART_SCHEDULE" -# Apply cron job -if [ "${AUTO_BACKUP}" -eq 1 ] || [ "${AUTO_UPDATE}" -eq 1 ] || [ "${SCHEDULED_RESTART}" -eq 1 ]; then - cat "$HOME"/cron.d/* | crontab - - sudo /usr/sbin/cron -f & +# Apply cron jobs and start cron daemon if any cron jobs are enabled +if [[ "$AUTO_BACKUP" -eq 1 || "$AUTO_UPDATE" -eq 1 || "$SCHEDULED_RESTART" -eq 1 ]]; then + crontab "$HOME/cron.d/*" + sudo cron -f & export CRON_PID=$! fi -# Configure filesystem +# Set up the filesystem setup_filesystem -# Launch as steam user :) +# Navigate to the Valheim game directory log "Navigating to steam home..." cd /home/steam/valheim || exit 1 -log "Launching as server..." -. /home/steam/scripts/start_valheim.sh +# Launch the Valheim server +log "Launching server..." +exec /home/steam/scripts/start_valheim.sh diff --git a/src/scripts/start_valheim.sh b/src/scripts/start_valheim.sh index 6f5deb34..01e22e95 100644 --- a/src/scripts/start_valheim.sh +++ b/src/scripts/start_valheim.sh @@ -1,49 +1,30 @@ #!/usr/bin/env bash +# Exit immediately if a command exits with a non-zero status +set -e -cd /home/steam/valheim || exit 1 -STEAM_UID=${PUID:=1000} -STEAM_GID=${PGID:=1000} - -# check for utils -if [ -f "/home/steam/scripts/utils.sh" ]; then - source "/home/steam/scripts/utils.sh" -fi - -# check for env.sh -if [ -f "/env.sh" ]; then - source "/env.sh" -fi - -if [ "${STEAM_UID}" -eq 0 ] || [ "${STEAM_GID}" -eq 0 ]; then - log -l "WARNING" "You should not run the server as root! Please use a non-root user!" -fi - -if ! [ -f "/home/steam/.bashrc" ]; then - log -l "WARNING" "You should not run the server without a .bashrc! Please use a non-root user!" -fi +# Logging function to prepend timestamps to log messages +log() { + echo "$(date) - $*" +} +# Function to display a deprecation notice deprecation_notice() { log "-------------------------------------------------------------------------" - log "-------------------------------------------------------------------------" - log "-------------------------------------------------------------------------" - log "-------------------------------------------------------------------------" - log -l "WARNING" "${1}" - log "-------------------------------------------------------------------------" - log "-------------------------------------------------------------------------" - log "-------------------------------------------------------------------------" + log "WARNING: ${1}" log "-------------------------------------------------------------------------" } - +# Function to initialize the server with a log message initialize() { - line + log "-------------------------------------------------------------" log "Valheim Server - $(date)" - log "STEAM_UID ${STEAM_UID} - STEAM_GUID ${STEAM_GID}" + log "STEAM_UID ${STEAM_UID} - STEAM_GID ${STEAM_GID}" log "$1" - line + log "-------------------------------------------------------------" } +# Function to clean up on exit cleanup() { log "Halting server! Received interrupt!" odin stop @@ -51,39 +32,59 @@ cleanup() { log "Backup on shutdown triggered! Running backup tool..." /bin/bash /home/steam/scripts/auto_backup.sh "shutdown" fi - if [[ -n $TAIL_PID ]]; then - kill "$TAIL_PID" - fi - if [[ -n $ODIN_HTTP_SERVER_PID ]]; then - kill "$ODIN_HTTP_SERVER_PID" - fi + [[ -n $TAIL_PID ]] && kill "$TAIL_PID" + [[ -n $ODIN_HTTP_SERVER_PID ]] && kill "$ODIN_HTTP_SERVER_PID" } +# Function to handle Valheim Plus installation (deprecated) install_valheim_plus() { deprecation_notice "ValheimPlus has been deprecated!!!!!! Please use BepInEx instead!" } +# Function to handle BepInEx installation install_bepinex() { - log "Installing BepInEx" - BEPINEX_DOWNLOAD_URL="${BEPINEX_DOWNLOAD_URL:-""}" - if [ -z "${BEPINEX_DOWNLOAD_URL}" ]; then - echo "Calling: curl -L ${BEPINEX_RELEASES_URL} | jq -r '.latest.download_url'" - BEPINEX_DOWNLOAD_URL="$(curl -L "${BEPINEX_RELEASES_URL}" | jq -r '.latest.download_url')" - fi - log "Pulling BepInEx from ${BEPINEX_DOWNLOAD_URL}" - odin mod:install "${BEPINEX_DOWNLOAD_URL}" + log "Installing BepInEx" + if [ -z "${BEPINEX_DOWNLOAD_URL}" ]; then + log "Fetching BepInEx download URL..." + BEPINEX_DOWNLOAD_URL="$(curl -L "${BEPINEX_RELEASES_URL}" | jq -r '.latest.download_url')" + fi + log "Pulling BepInEx from ${BEPINEX_DOWNLOAD_URL}" + odin mod:install "${BEPINEX_DOWNLOAD_URL}" } +# Function to handle full BepInEx installation (deprecated) install_bepinex_full() { - deprecation_notice "BepInExFull has been deprecated!!!!!! Please use BepInEx instead!" + deprecation_notice "BepInExFull has been deprecated!!!!!! Please use BepInEx instead!" } -has_webhook="true" -if [ -z "$WEBHOOK_URL" ]; then - has_webhook="false" +# Navigate to the Valheim directory or exit if it fails +cd /home/steam/valheim + +# Set default values for Steam user and group IDs if not provided +STEAM_UID=${PUID:=1000} +STEAM_GID=${PGID:=1000} + +# Source utility scripts if they exist +[ -f "/home/steam/scripts/utils.sh" ] && source "/home/steam/scripts/utils.sh" + +# Source environment variables if env.sh exists +[ -f "/env.sh" ] && source "/env.sh" + +# Warn if running as root +if [ "${STEAM_UID}" -eq 0 ] || [ "${STEAM_GID}" -eq 0 ]; then + log "WARNING: You should not run the server as root! Please use a non-root user!" +fi + +# Warn if .bashrc is missing +if [ ! -f "/home/steam/.bashrc" ]; then + log "WARNING: You should not run the server without a .bashrc! Please use a non-root user!" fi +# Check if webhook URL is provided +has_webhook="true" +[ -z "$WEBHOOK_URL" ] && has_webhook="false" +# Initialize server with a message initialize "Installing Valheim via $(odin --version)..." log "Variables loaded....." log "Port: ${PORT}" @@ -107,9 +108,9 @@ log "Auto Backup Days To Live: ${AUTO_BACKUP_DAYS_TO_LIVE}" log "Auto Backup Nice Level: ${AUTO_BACKUP_NICE_LEVEL}" log "Update On Startup: ${UPDATE_ON_STARTUP}" log "Mods: ${MODS}" -line - +log "-------------------------------------------------------------" +# Export Steam App ID export SteamAppId=${APPID:-896660} # Setting up server @@ -119,29 +120,27 @@ log -l "DEBUG" "Current User: $(whoami)" log -l "DEBUG" "Current UID: ${UID}" log -l "DEBUG" "Current GID: ${PGID}" log -l "DEBUG" "Home Directory: ${HOME}" -if [ ! -f "./valheim_server.x86_64" ] || - [ "${FORCE_INSTALL:-0}" -eq 1 ]; then + +# Install or update the server if necessary +if [ ! -f "./valheim_server.x86_64" ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; then odin install || exit 1 elif [ "${UPDATE_ON_STARTUP:-1}" -eq 1 ]; then log "Attempting to update before launching the server!" - if [ "${AUTO_BACKUP_ON_UPDATE:=0}" -eq 1 ]; then - /bin/bash /home/steam/scripts/auto_backup.sh "pre-update-backup" - fi - + [ "${AUTO_BACKUP_ON_UPDATE:=0}" -eq 1 ] && /bin/bash /home/steam/scripts/auto_backup.sh "pre-update-backup" log "Installing Updates..." odin install || exit 1 else log "Skipping install process, looks like valheim_server is already installed :)" fi -if [ -f "/home/steam/steamcmd/linux64/steamclient.so" ]; then - cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim/linux64/ -fi +# Copy steamclient.so if it exists +[ -f "/home/steam/steamcmd/linux64/steamclient.so" ] && cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim/linux64/ -# Setting up server +# Configure the server log "Initializing Variables...." odin configure || exit 1 +# Check the server type and handle mod installations log "Checking for TYPE flag" export TYPE="${TYPE:="vanilla"}" log "Found Type ${TYPE}" @@ -149,73 +148,75 @@ log "Running with ${TYPE} Valheim <3" export TYPE="${TYPE,,}" export GAME_LOCATION="${GAME_LOCATION:="/home/steam/valheim"}" -if [ "${TYPE}" = "vanilla" ] && [ -n "${MODS:=""}" ]; then - log "Mods supplied but you are running with Vanilla!!!" - log "Mods will NOT be installed!." -elif - # ValheimPlus not yet installed - { [ "${TYPE}" = "valheimplus" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/plugins/ValheimPlus.dll" ]; } || - # ValheimPlus with update on startup or force install - { [ "${TYPE}" = "valheimplus" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; }; } -then - install_valheim_plus -elif - # BepInEx not yet installed - { [ "${TYPE}" = "bepinex" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ]; } || - # BepInEx with update on startup or force install - { [ "${TYPE}" = "bepinex" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; }; } -then - install_bepinex -elif - # BepInEx not yet installed - { [ "${TYPE}" = "bepinexfull" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ]; } || - # BepInEx with update on startup or force install - { [ "${TYPE}" = "bepinexfull" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; }; } -then - install_bepinex_full -fi - -if [ ! "${TYPE}" = "vanilla" ]; then - SAVE_IFS=$IFS # Save current IFS - IFS=$',\n' # Change IFS to new line - # shellcheck disable=SC2206 - MODS=(${MODS:=""}) # split to array $names - IFS=$SAVE_IFS # Restore IFS - +case "${TYPE}" in + "vanilla") + if [ -n "${MODS:=""}" ]; then + log "Mods supplied but you are running with Vanilla!!!" + log "Mods will NOT be installed!." + fi + ;; + "valheimplus") + if [ ! -d "${GAME_LOCATION}/BepInEx" ] || [ ! -f "${GAME_LOCATION}/BepInEx/plugins/ValheimPlus.dll" ] || [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; then + install_valheim_plus + fi + ;; + "bepinex") + if [ ! -d "${GAME_LOCATION}/BepInEx" ] || [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ] || [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; then + install_bepinex + fi + ;; + "bepinexfull") + if [ ! -d "${GAME_LOCATION}/BepInEx" ] || [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ] || [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; then + install_bepinex_full + fi + ;; + *) + log "Unknown type: ${TYPE}" + exit 1 + ;; +esac + +# Install additional mods if not running vanilla +if [ "${TYPE}" != "vanilla" ]; then + IFS=$',\n' + MODS=(${MODS:=""}) + IFS=$' \t\n' for mod in "${MODS[@]}"; do log "Installing Mod ${mod}" odin mod:install "${mod}" done fi +# Execute post-install scripts if they exist if [ -d "/valheim-post-install.d/" ]; then log "Executing post-install scripts" find /valheim-post-install.d/ -type f -executable -exec {} \; fi +# Start HTTP server if HTTP_PORT is specified if [ -n "${HTTP_PORT}" ]; then huginn & export ODIN_HTTP_SERVER_PID=$! fi -# Setting up script traps -trap 'cleanup' INT TERM +# Set up traps for cleaning up on exit +trap cleanup INT TERM -# Starting server +# Start the Valheim server log "Starting server..." -odin start || exit 1 +odin start sleep 2 -# Initializing all logs +# Initialize log files and start tailing them log "Herding Graydwarfs..." log_names=("valheim_server.log" "valheim_server.err" "output.log" "auto-update.out" "auto-backup.out") log_files=("${log_names[@]/#/\/home\/steam\/valheim\/logs/}") -touch "${log_files[@]}" # Destroy logs on start up, this can be changed later to roll logs or archive them. +touch "${log_files[@]}" # Create log files if they don't exist -# shellcheck disable=SC2086 +# Tail the log files to keep the script running and to monitor the server tail -F "${log_files[@]}" & export TAIL_PID=$! -# Waiting for logs. +# Wait for the tail process to exit wait $TAIL_PID diff --git a/src/scripts/utils.sh b/src/scripts/utils.sh index 6c556489..e19ea768 100755 --- a/src/scripts/utils.sh +++ b/src/scripts/utils.sh @@ -1,10 +1,12 @@ #!/usr/bin/env bash -function log() { +# Function to log messages with a customizable prefix and log level +log() { local prefix="[Valheim]" local line="" local level="INFO" + # Parse arguments while [ "$#" -gt 0 ]; do case "$1" in -p|--prefix) @@ -19,18 +21,19 @@ function log() { line="$1" shift 1 ;; - esac + esac done - if [ "${DEBUG_MODE:-0}" -eq "0" ] && [ "${level}" == "DEBUG" ]; then + # Skip debug messages if DEBUG_MODE is not enabled + if [ "${DEBUG_MODE:-0}" -eq 0 ] && [ "${level}" == "DEBUG" ]; then return fi + # Log the message with timestamp, prefix, and log level echo "$(date +"%Y-%m-%d %H:%M:%S") - ${prefix}[${level}]: ${line}" } - +# Function to log a separator line line() { log -p "#" "###########################################################################" } -