<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Magno Gouveia</title>
    <description>The latest articles on DEV Community by Magno Gouveia (@andarilhoz).</description>
    <link>https://dev.to/andarilhoz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F342917%2F5d8c38ee-f4b0-4eb9-ac4c-5fedd6c03631.png</url>
      <title>DEV Community: Magno Gouveia</title>
      <link>https://dev.to/andarilhoz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andarilhoz"/>
    <language>en</language>
    <item>
      <title>Como eu criei um servidor de PalWorld na AWS com start por bot no Discord — Parte 2</title>
      <dc:creator>Magno Gouveia</dc:creator>
      <pubDate>Sat, 27 Jan 2024 20:50:05 +0000</pubDate>
      <link>https://dev.to/andarilhoz/como-eu-criei-um-servidor-de-palworld-na-aws-com-start-por-bot-no-discord-parte-2-7ce</link>
      <guid>https://dev.to/andarilhoz/como-eu-criei-um-servidor-de-palworld-na-aws-com-start-por-bot-no-discord-parte-2-7ce</guid>
      <description>&lt;p&gt;Na primeira parte, ensinei como criar uma máquina virtual na AWS e instalar um servidor de Palworld. Porém, ainda precisamos resolver a questão da máquina ficar ligada o tempo todo, uma forma de permitir que qualquer pessoa inicie o servidor a partir do Discord e também ter acesso ao IP do server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desligando a máquina automaticamente:
&lt;/h2&gt;

&lt;p&gt;Para automatizar a desativação do servidor, decidi criar um script que:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Verifica se o servidor está iniciado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verifica se há jogadores&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desliga a máquina caso não haja mais jogadores.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para isso, vamos criar um script chamado: shutdownServer.sh com o conteúdo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/palworld

&lt;span class="c"&gt;# Execute o comando para obter a lista de jogadores e capturar possíveis erros&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker-compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; rcon ShowPlayers 2&amp;gt;&amp;amp;1&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Filtra linhas indesejadas&lt;/span&gt;
&lt;span class="nv"&gt;CLEANED_OUTPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"Creating palworld_rcon_run"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Verifica se ocorreu um erro na execução do comando&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLEANED_OUTPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Erro ao executar o comando. Possivelmente, máquina está ligando."&lt;/span&gt;
    &lt;span class="nv"&gt;STOP_INSTANCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c"&gt;# Conta o número de jogadores&lt;/span&gt;
    &lt;span class="nv"&gt;NUM_PLAYERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLEANED_OUTPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;NUM_PLAYERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;NUM_PLAYERS-1&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="c"&gt;# Ajusta para subtrair o cabeçalho, se houver&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NUM_PLAYERS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Nenhum jogador online."&lt;/span&gt;
        &lt;span class="nv"&gt;STOP_INSTANCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Há &lt;/span&gt;&lt;span class="nv"&gt;$NUM_PLAYERS&lt;/span&gt;&lt;span class="s2"&gt; jogadores online."&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Lista de Jogadores:"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLEANED_OUTPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 1
        &lt;span class="nv"&gt;STOP_INSTANCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
    &lt;/span&gt;&lt;span class="k"&gt;fi
fi&lt;/span&gt;

&lt;span class="c"&gt;# Se não houver jogadores online ou ocorreu um erro, parar o container do Docker e desligar a máquina&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STOP_INSTANCE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# Encontra o ID do container que está executando a imagem especificada&lt;/span&gt;
    &lt;span class="nv"&gt;CONTAINER_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker ps &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;ancestor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jammsen/palworld-dedicated-server:latest&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Verifica se um container foi encontrado&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CONTAINER_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Parando o container do Docker: &lt;/span&gt;&lt;span class="nv"&gt;$CONTAINER_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        docker stop &lt;span class="nv"&gt;$CONTAINER_ID&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Nenhum container encontrado para a imagem especificada."&lt;/span&gt;
    &lt;span class="k"&gt;fi

    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Desligando a máquina..."&lt;/span&gt;
    &lt;span class="nb"&gt;sudo &lt;/span&gt;shutdown &lt;span class="nt"&gt;-h&lt;/span&gt; now
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos usando o programa &lt;code&gt;rcon&lt;/code&gt; para obter uma lista de jogadores online e armazenando em &lt;code&gt;OUTPUT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quando a máquina está iniciando, geralmente esse comando retorna um ERROR; neste caso, não vamos desligar a máquina.&lt;/p&gt;

&lt;p&gt;Após isso, se houverem jogadores online, nós exibimos uma lista com os nomes, e caso não haja ninguém, o servidor irá desligar o Docker e após isso, desligar a própria máquina.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depois de criar o script, dê permissões de execução com o comando:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x shutdownServer.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos criar um repetidor, para executar o script de 30 em 30 minutos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute o seguinte comando como sudo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vá até o final do arquivo e adicione a linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt;/30 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /home/ubuntu/palworld/shutdownServer.sh &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /home/ubuntu/logs/log_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +&lt;span class="se"&gt;\%&lt;/span&gt;Y_&lt;span class="se"&gt;\%&lt;/span&gt;m_&lt;span class="se"&gt;\%&lt;/span&gt;d_&lt;span class="se"&gt;\%&lt;/span&gt;H_&lt;span class="se"&gt;\%&lt;/span&gt;M&lt;span class="si"&gt;)&lt;/span&gt;.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, o servidor irá executar o script de 30 em 30 minutos e guardar os logs na pasta “logs” na home. O script precisa ser executado como sudo para ter acesso a parar o container do Docker e também desligar a máquina.&lt;/p&gt;

&lt;p&gt;Crie a pasta para guardar os logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /home/ubuntu/logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Criando sua função lambda
&lt;/h2&gt;

&lt;p&gt;Antes de criar o bot propriamente dito, precisamos criar as funções que serão executadas por ele.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No seu console da AWS, procure pelo serviço &lt;strong&gt;“Lambda”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crie uma nova função no botão superior direito&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dê um nome como “discord-lambda”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Escolha a linguagem &lt;strong&gt;“Node.js 20.x”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Criar Função”&lt;/strong&gt; no canto inferior direito.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Precisamos chamar um “gatilho” que irá executar essa Lambda quando um endereço for chamado, para isso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Na &lt;strong&gt;“Visão geral da função”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“+ Adicionar gatilho”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione &lt;strong&gt;API Gateway&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione &lt;strong&gt;“Create a new API”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Em &lt;strong&gt;“API type”&lt;/strong&gt; Selecione &lt;strong&gt;“HTTP API”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Em Security Selecione &lt;strong&gt;“Open”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abra a aba &lt;strong&gt;“Additional Settings”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione a opção &lt;strong&gt;“Cross-origin resource sharing (CORS)”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(isso irá permitir o discord chamar sua função mesmo de outro domínio.)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Adicionar”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na aba &lt;strong&gt;“Configuração&amp;gt;Gatilhos”&lt;/strong&gt; acesse o endereço &lt;strong&gt;“API endpoint”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se abrir uma nova aba com o texto: &lt;strong&gt;“Hello from Lambda!”&lt;/strong&gt;, tudo deu certo até então.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copie esse endereço, vamos utilizá-lo mais tarde na criação do bot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Com sua função criada, vamos baixar o código desse repositório: &lt;a href="https://github.com/andarilhoz/discord-lambda"&gt;https://github.com/andarilhoz/discord-lambda&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dentro dele, acesse a pasta “aws” e execute o comando &lt;code&gt;npm install&lt;/code&gt; para instalar a dependência &lt;code&gt;tweetnacl&lt;/code&gt; que irá ler o request do discord.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adicione todo conteúdo de dentro da pasta “aws” (incluindo o node_modules) para um arquivo .zip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No seu navegador, na lambda recém criada dentro da aba “Código” clique em “Fazer upload de” e escolha “Arquivo .zip”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Faça o upload do zip criado anteriormente&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na aba “Configuração” selecione “Variáveis de ambiente” e preencha as seguintes variáveis:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;AWS_ECS_REGION -&amp;gt; a região da sua ecs, se você criou em São Paulo, será: &lt;span class="s2"&gt;"sa-east-1"&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html&lt;span class="o"&gt;)&lt;/span&gt;
INSTANCE_ID -&amp;gt; O &lt;span class="nb"&gt;id &lt;/span&gt;da sua instancia EC2 criada no artigo passado
CHANNEL_ID -&amp;gt; O &lt;span class="nb"&gt;id &lt;/span&gt;&lt;span class="k"&gt;do &lt;/span&gt;canal &lt;span class="k"&gt;do &lt;/span&gt;seu servidor &lt;span class="k"&gt;do &lt;/span&gt;discord onde o bot irá funcionar
ROLE_ID -&amp;gt; O &lt;span class="nb"&gt;id &lt;/span&gt;&lt;span class="k"&gt;do &lt;/span&gt;cargo que terá permissão para executar os comandos
PUBLIC_KEY -&amp;gt; Será gerado mais a frente quando criarmos o bot no discord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa lambda também requer permissão para executar scripts do &lt;strong&gt;EC2 **e **AWS Cost Explorer Service&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No menu Configuração, selecione o sub-menu &lt;strong&gt;“Permissões”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Embaixo da label &lt;strong&gt;“Nome da função”&lt;/strong&gt; clique no link com o nome [sua-lambda]-role-[id], isso abrirá o gerenciador de permissões da AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione a Politica de Permissões criada automaticamente (terá um suffixo: &lt;strong&gt;AWSLambdaBasicExecutionRole&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Editar”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adicione a seguinte permissão no json, dentro da propriedade &lt;strong&gt;“Statement&lt;/strong&gt;”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AccessCostExplorer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ce:GetCostAndUsage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ec2:DescribeInstances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ec2:StartInstances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"ec2:StopInstances"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso dará a lambda permissões para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ver o custo e uso de seus serviços na AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Descrever uma instancia EC2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iniciar uma instancia EC2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pausar uma instancia EC2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clique em &lt;strong&gt;“Próximo”&lt;/strong&gt; e depois em &lt;strong&gt;“Salvar Alterações”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Após salvar as permissões, só falta adicionarmos o &lt;code&gt;PUBLIC_KEY&lt;/code&gt; que iremos gerar agora no Discord para finalizar a lambda.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um bot no Discord
&lt;/h2&gt;

&lt;p&gt;Abra o &lt;a href="https://discord.com/developers/applications"&gt;Developer Portal&lt;/a&gt; do discord,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crie uma nova aplicação, e dê um nome.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na aba &lt;strong&gt;“General Information”&lt;/strong&gt; copie o &lt;strong&gt;“PUBLIC KEY”&lt;/strong&gt; e adicione esse valor na variável da lambda criada no passo anterior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ainda em &lt;strong&gt;“General Information”&lt;/strong&gt; preencha o campo &lt;strong&gt;“INTERACTIONS ENDPOINT URL”&lt;/strong&gt; com a url da sua lambda criada no passo anterior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Save Changes”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Você deverá ver a mensagem: &lt;strong&gt;“All your edits have been carefully recorded.”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vá na aba &lt;strong&gt;“OAuth2 &amp;gt; URL Generator”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Em &lt;strong&gt;“SCOPES”&lt;/strong&gt; selecione &lt;strong&gt;“bot”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Em &lt;strong&gt;“BOT PERMISSIONS”&lt;/strong&gt; selecione &lt;strong&gt;“Use Slash Commands”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copie a URL gerada na parte de baixo, e use-a para adicionar o seu novo bot no servidor desejado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na aba &lt;strong&gt;“Bot”&lt;/strong&gt; clique no botão &lt;strong&gt;“Reset Token”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copie o código gerado que iremos utilizar no próximo passo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na aba &lt;strong&gt;“General Information”&lt;/strong&gt; copie o código &lt;strong&gt;“APPLICATION ID”&lt;/strong&gt; que também será necessário.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adicionando comandos do bot:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Com o &lt;a href="https://github.com/andarilhoz/discord-lambda"&gt;repositório clonado anteriormente &lt;/a&gt;acesse a pasta: “discord”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crie um arquivo .env e preencha as variáveis de ambiente:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;BOT_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;ODUwMTk2NDDyMDc2MjgyOTAw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GpYcOB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q2XSa_IUw5A3sHId67s6kQzSoiZP_zfZFCyDvE&lt;/span&gt; &lt;span class="c1"&gt;//O Token Gerado anteriormente na aba "Bot" do discord&lt;/span&gt;
&lt;span class="nx"&gt;APP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;850196442076282900&lt;/span&gt; &lt;span class="c1"&gt;//O App Id gerado anteriormente na aba "General Information"&lt;/span&gt;
&lt;span class="nx"&gt;GUILD_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;337788789500449762&lt;/span&gt; &lt;span class="c1"&gt;//O ID do seu servidor do discord.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Execute o comando &lt;code&gt;npm install&lt;/code&gt; na pasta “discord”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute o comando &lt;code&gt;node addcommand.js&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se tudo ocorreu bem, você verá essas mensagens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;success
200
success
200
success
200
success
200
All commands sent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto! agora você pode executar os comandos do seu bot no seu servidor para iniciar o EC2, pausar, ver o status (e IP) e também ver o custo total de EC2 da sua aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adicionando um IP Elástico
&lt;/h2&gt;

&lt;p&gt;Um dos problemas de se ligar e desligar um servidor EC2 é que seu ip acaba mudando constantemente, vamos adicionar um IP Elástico que não irá mudar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No seu console da AWS, busque por EC2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No menu esquerdo selecione &lt;strong&gt;“IPs elásticos”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Alocar endereço de IP elástico”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em **“Alocar” **no canto inferior direito&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Agora selecione o IP na lista de endereços&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Ações”&lt;/strong&gt; no botão direito superior&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Associar endereço IP elástico”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abaixo da label &lt;strong&gt;“Instância”&lt;/strong&gt; selecione seu servidor EC2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;strong&gt;“Associar”&lt;/strong&gt; no canto direito inferior.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pronto, esse IP será fixo e será o ip permanente da sua máquina, e não mudara mesmo após desligá-la.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Como dito anteriormente, a máquina t3a.xlarge custaria mensalmente &lt;strong&gt;$170 USD&lt;/strong&gt;, com essa alteração, considerando que você e seus amigos joguem cerca de 4 horas por dia, todos os dias, esse valor cai para: &lt;strong&gt;$29 USD&lt;/strong&gt;. Existem outras maneiras de baratear esse custo, já que é uma máquina que tem capacidade para 32 jogadores simultâneos. Você pode testar máquinas com uma memória menor para 4 jogadores por exemplo.&lt;/p&gt;

&lt;p&gt;Dessa forma, com a máquina t3a.xlarge, economizamos em um mês &lt;strong&gt;$141 USD&lt;/strong&gt;, quase &lt;strong&gt;$700 Reais&lt;/strong&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Daqui pra frente:
&lt;/h3&gt;

&lt;p&gt;Um dos problemas dessa configuração é o &lt;strong&gt;“cold start”&lt;/strong&gt; da lambda AWS, você pode transformar a lambda em um servidor EC2 nano, que além de garantir o baixo custo, sempre estará disponível!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>aws</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Como eu criei um servidor de PalWorld na AWS com start por bot no Discord</title>
      <dc:creator>Magno Gouveia</dc:creator>
      <pubDate>Sat, 27 Jan 2024 20:49:46 +0000</pubDate>
      <link>https://dev.to/andarilhoz/como-eu-criei-um-servidor-de-palworld-na-aws-com-start-por-bot-no-discord-36de</link>
      <guid>https://dev.to/andarilhoz/como-eu-criei-um-servidor-de-palworld-na-aws-com-start-por-bot-no-discord-36de</guid>
      <description>&lt;p&gt;É difícil não ter ouvido sobre &lt;a href="https://store.steampowered.com/app/1623730/Palworld/"&gt;Palworld&lt;/a&gt; recentemente, com o sucesso explosivo e &lt;a href="https://www.adrenaline.com.br/games/palworld-8-milhoes-unidades-vendidas/"&gt;mais de 8 milhões de vendas.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Queria jogar com meus amigos e ter um servidor sempre disponível, independente de um de nós hostear. Isso pareceu uma ótima oportunidade para brincar um pouco com a AWS.&lt;/p&gt;

&lt;p&gt;Cheguei a testar alguns outros servidores, como Nitrado, mas a falta de servidor no Brasil, quedas constantes e também pouco controle de acesso ao servidor, me fizeram optar por criar o meu próprio servidor em um serviço de cloud privado, como já trabalho com AWS há alguns anos, não tive duvidas e comecei a criar a infra.&lt;/p&gt;

&lt;p&gt;Aqui vou mostrar como fiz cada passo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criação de um servidor EC2
&lt;/h2&gt;

&lt;p&gt;EC2 é o serviço da AWS para criar &lt;em&gt;“máquinas na cloud”&lt;/em&gt;, ao criar uma, a primeira coisa para ter em mente é o tamanho do servidor.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dentro do console da Aws, busque pelo serviço: EC2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No canto esquerdo no menu, selecione Instâncias&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No canto superior direito, clique em “Executar Instâncias”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Nome e tags
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; Dê um nome para sua instância (eg: PalworldServer)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Application and OS Images (Amazon Machine Image)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Neste guia vamos escolher o sistema operacional Ubuntu 22.04 (64bits x86)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tipo de instância
&lt;/h3&gt;

&lt;p&gt;Pelas configurações ideais dadas pelos desenvolvedores, a maquina deveria ter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;16gb de Ram&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;4 núcleos de processamento&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optei então pela maquina mais barata que atendesse esses requisitos: &lt;strong&gt;t3a.xlarge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(&lt;a href="https://calculator.aws/#/createCalculator/ec2-enhancement"&gt;Você pode buscar o tipo da maquina por configuração na calculadora da aws&lt;/a&gt;&lt;a href="https://calculator.aws/#/createCalculator/ec2-enhancement"&gt;)&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecione o tipo de instância (t3a.xlarge)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Par de chaves (login)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Crie uma par de chaves para fazer o login por ssh:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nesse exemplo, vou chamar de palworld-sao-paulo.pem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tipo: RSA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formato: .pem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Criar par de chaves&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configurações de Rede
&lt;/h3&gt;

&lt;p&gt;Neste momento não é necessário fazer nenhuma mudança aqui, mas vamos voltar para essa configuração depois de criar a máquina, só lembre de deixar marcado a opção:&lt;/p&gt;

&lt;p&gt;“&lt;strong&gt;Allow SSH traffic from&lt;/strong&gt;” — “&lt;strong&gt;Qualquer lugar&lt;/strong&gt;” (Só será possível acessar a maquina usando o arquivo .pem criado anteriormente.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurar armazenamento
&lt;/h3&gt;

&lt;p&gt;1x de 20gb gp2 é o suficiente para um servidor, na minha experiência o servidor usa menos de 7gb, mas gosto de deixar espaço para alguma emergência.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Obs: Não recomendo tentar usar uma instancia spot, mesmo sendo mais barato, a instabilidade de disponibilidade quebra todo o conceito de ter um servidor para jogar com os amigos na hora que você quiser.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Se isso não é um problema pra você e souber o que está fazendo, é uma opção.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração inicial da maquina linux
&lt;/h2&gt;

&lt;p&gt;Pronto! você tem uma instancia linux preparada para uso, agora vamos configurá-la&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No console da aws em EC2&amp;gt;Instâncias copie o “Endereço IPv4 público”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usando um terminal (cmd/bash) conecte-se no endereço com o seguinte comando:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;/endereco/da/chave/palworld-sao-paulo.pem] ubuntu@[seu-endereço-ip]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/"&gt;Instale o docker&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04"&gt;Instale o docker-compose&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com isso você já tem a maquina preparada para receber o servidor, vamos utilizar essa imagem docker-compose:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jammsen/docker-palworld-dedicated-server"&gt;https://github.com/jammsen/docker-palworld-dedicated-server&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;na home do seu servidor (/home/ubuntu) crie uma pasta palworld
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;palworld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;dentro da pasta palworld, crie uma pasta chamada “game”
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Dê permissões de acesso para a pasta game:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;777 game 
      ou 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 1000:1000 game/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Crie um arquivo de configuração chamado docker-compose.yml e cole o exemplo abaixo (&lt;a href="https://github.com/jammsen/docker-palworld-dedicated-server"&gt;retirado do github&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.9'&lt;/span&gt;
    &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;palworld-dedicated-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;#build: .&lt;/span&gt;
        &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;palworld-dedicated-server&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jammsen/palworld-dedicated-server:latest&lt;/span&gt;
        &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
        &lt;span class="na"&gt;network_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8211&lt;/span&gt; &lt;span class="c1"&gt;# Gamerserver port inside of the container&lt;/span&gt;
            &lt;span class="na"&gt;published&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8211&lt;/span&gt; &lt;span class="c1"&gt;# Gamerserver port on your host&lt;/span&gt;
            &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;udp&lt;/span&gt;
            &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25575&lt;/span&gt; &lt;span class="c1"&gt;# RCON port inside of the container&lt;/span&gt;
            &lt;span class="na"&gt;published&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25575&lt;/span&gt; &lt;span class="c1"&gt;# RCON port on your host&lt;/span&gt;
            &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp&lt;/span&gt;
            &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;TZ=Europe/Berlin&lt;/span&gt; &lt;span class="c1"&gt;# Change this for logging and backup, see "Environment-Variables" &lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ALWAYS_UPDATE_ON_START=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MULTITHREAD_ENABLED=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;COMMUNITY_SERVER=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BACKUP_ENABLED=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BACKUP_CRON_EXPRESSION=0 * * * *&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NETSERVERMAXTICKRATE=120&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DIFFICULTY=None&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DAYTIME_SPEEDRATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NIGHTTIME_SPEEDRATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;EXP_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_CAPTURE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_SPAWN_NUM_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_DAMAGE_RATE_ATTACK=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_DAMAGE_RATE_DEFENSE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_DAMAGE_RATE_ATTACK=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_DAMAGE_RATE_DEFENSE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_STOMACH_DECREASE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_STAMINA_DECREACE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_AUTO_HP_REGENE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PLAYER_AUTO_HP_REGENE_RATE_IN_SLEEP=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_STOMACH_DECREACE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_STAMINA_DECREACE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_AUTO_HP_REGENE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_AUTO_HP_REGENE_RATE_IN_SLEEP=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BUILD_OBJECT_DAMAGE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BUILD_OBJECT_DETERIORATION_DAMAGE_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;COLLECTION_DROP_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;COLLECTION_OBJECT_HP_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;COLLECTION_OBJECT_RESPAWN_SPEED_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENEMY_DROP_ITEM_RATE=1.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DEATH_PENALTY=All&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_PLAYER_TO_PLAYER_DAMAGE=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_FRIENDLY_FIRE=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_INVADER_ENEMY=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ACTIVE_UNKO=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_AIM_ASSIST_PAD=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_AIM_ASSIST_KEYBOARD=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DROP_ITEM_MAX_NUM=3000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DROP_ITEM_MAX_NUM_UNKO=100&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BASE_CAMP_MAX_NUM=128&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BASE_CAMP_WORKER_MAXNUM=15&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DROP_ITEM_ALIVE_MAX_HOURS=1.000000&lt;/span&gt; 
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AUTO_RESET_GUILD_NO_ONLINE_PLAYERS=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AUTO_RESET_GUILD_TIME_NO_ONLINE_PLAYERS=72.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;GUILD_PLAYER_MAX_NUM=20&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PAL_EGG_DEFAULT_HATCHING_TIME=72.000000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WORK_SPEED_RATE=1.000000&lt;/span&gt; 
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IS_MULTIPLAY=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IS_PVP=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CAN_PICKUP_OTHER_GUILD_DEATH_PENALTY_DROP=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_NON_LOGIN_PENALTY=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_FAST_TRAVEL=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IS_START_LOCATION_SELECT_BY_MAP=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;EXIST_PLAYER_AFTER_LOGOUT=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ENABLE_DEFENSE_OTHER_GUILD_PLAYER=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;COOP_PLAYER_MAX_NUM=4&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MAX_PLAYERS=32&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVER_NAME=jammsen-docker-generated-###RANDOM###&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVER_DESCRIPTION=Palworld-Dedicated-Server running in Docker by jammsen&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ADMIN_PASSWORD=adminPasswordHere&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVER_PASSWORD=serverPasswordHere&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PUBLIC_PORT=8211&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PUBLIC_IP=&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;RCON_ENABLED=false&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;RCON_PORT=25575&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REGION=&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;USEAUTH=true&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BAN_LIST_URL=https://api.palworldgame.com/api/banlist.txt&lt;/span&gt;
        &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./game:/palworld&lt;/span&gt;

      &lt;span class="na"&gt;rcon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;outdead/rcon:latest&lt;/span&gt;
        &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/rcon'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-a'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;10.0.0.5:25575'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-p'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;adminPasswordHere'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rcon'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Lembre-se de alterar o arquivo de acordo com o seu servidor.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Após a criação do docker-compose.yml, execute o docker-compose: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Você pode acompanhar os logs com: $ sudo docker-compose logs -f&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Após algum tempo o container irá baixar a steam, o servidor, fazer o login anonimamente e servir o jogo na porta: 8211&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Vamos liberar o acesso a essa porta na aws:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No console da aws no serviço EC2, selecione &lt;strong&gt;“security groups”&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique no security group atrelado a sua maquina (&lt;em&gt;provavelmente launch-wizard-1&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;em&gt;“Regras de saída”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;em&gt;“Editar Regras de saída”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;em&gt;“Adicionar Regra”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selecione o Tipo: &lt;em&gt;“UDP Personalizado”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intervalo de portas: 8211&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destino: Qualquer Local — IPv4&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Com isso já será possível se conectar com o jogo na sua máquina.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Porém temos alguns problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sem um IP estático, toda vez que a maquina reiniciar, o IP de acesso público irá mudar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Só é possível iniciar a máquina pelo painel da AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A maquina ficará ligada 24/7 a menos que você a desligue manualmente pelo console da AWS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com essa configuração, os custos não são otimizados, e a máquina ligada 24/7 terá um custo aproximado de: $170USD por mês.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vou criar uma parte 2 explicando como resolver cada um desses problemas, diminuir drasticamente os custos e como facilitar seu acesso, criando um bot no discord vinculado com a AWS!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>aws</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
