Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

동산로의 블로그

Factorio headless 서버 만들기. (AWS Lightsail, Mods) 본문

카테고리 없음

Factorio headless 서버 만들기. (AWS Lightsail, Mods)

동산로 2025. 3. 8. 01:50

팩토리오 헤드리스 서버를 만들어 봅시다.

 

 

AWS Lightsail을 활용하여 만들어 봅시다.

 

 

 

 

1. AWS에서 Lightsail 클라우드 서버 생성.

아무 리눅스 컴퓨터나 있으면 상관 없습니다. ARM 계열도 가능하다고는 하는데 직접 해본적은 없어서 비추천합니다.

 

저는 집에 컴퓨터가 한대 밖에 없어서 일단 AWS를 사용해봤습니다.

 

 AWS에서 서버 생성은 지난번 포스트를 참고하시기 바랍니다.

https://dongsanro.tistory.com/2

 

 

 

2vCPU와 2GB메모리에서도 가동은 됩니다.  메모리가 간당간당하기 때문에 추천하진 않습니다. 작은 규모의 게임이면 문제 없습니다.

2vCPU와 4GB 메모리를 추천합니다. 저장시에 조금 시간이 걸립니다. 서버를 오래동안 켜고 있으면 저장시간이 길어지니 주기적으로 재시작을 하시면 됩니다.

 

2. 방화벽 설정

 

해당 lightsail 인스턴스의 manage항목에서 networking을 누르시면 방화벽 설정을 할 수 있습니다.

다음과 같이 custom으로 UDP 34197을 허용해 줍시다. 보통은 이 포트를 쓰지만 다른 포트를 써도 무방합니다.

팩토리오는 기본 설정으로 34197 UDP 포트를 사용합니다. 

서버 configuration에서 변경 가능합니다.

 


 -Lightsail이 아닌 일반적인 리눅스에서는 firewalld를 사용하시면 됩니다.

 

 

3. 서버 ssh 접속

AWS 콘솔에서 접속하거나 혹은 putty를 통해서 접속 가능합니다.

putty 사용법은 추후에 다른 글에 올리겠습니다.

 

 

4. 팩토리오 서버 다운로드

다운로드 페이지 - https://www.factorio.com/download

다운로드 링크 - https://factorio.com/get-download/stable/headless/linux64

 

팩토리오 공식 홈페이지에서 헤드레스 리눅스 서버를 다운 받을 수 있습니다. 

다운로드 버튼을 누르고 크롬 다운로드 창에서 링크를 추출 한 뒤, 리눅스 서버에서 다운로드를 해 줍시다.

지금은 다운로드 링크 그대로 다운로드 되지만 추후에 바뀔 수도 있습니다. 

 

 

5. 폴더 생성

wget으로 다운로드 받으면 파일명이 이상할 때가 있습니다.

파일명을 factorio_headless.tar.gz로 만들어 둡니다. 

wget으로 직접 받으셔도 되고 혹은 다른 방법을 사용하셔도 됩니다.

옛날 글들을 찾아봤는데 예전에는 xz파일로 저장했던거 같은데 지금은 gz파일이네요.

/opt/에 압축을 풀어줍니다.

 

sudo tar -xzf factorio_headless.tar.gz /opt/

tar 파일이므로 

/opt/factorio에 압축을 풀어 줍니다.

 

6. 모드 복사하기(선택)

 

지금 팩토리오를 하는 컴퓨터에 모드가 깔려있다면 모드 폴더를 복사하시면 됩니다.

저는 %appdata%폴더에서 ./Roaming/factorio/mods 폴더 통째로 tar 압축해서 

/opt/factorio/ 에 풀어줬습니다.  /opt/factorio/mods 폴더에  각 모드들 zip파일과 mod-list.json, mod-settings.dat이 있으면 됩니다. 다만 업데이트 자동화는 안 되어 있어서 업데이트가 되면 그때 그때 전부 복사해오셔야합니다.

 

 

 

 

7. mkfifo란?

mkfifo는 리눅스에서 프로그램과 다른 프로그램 사이의 통신을 담당하는 named pipe( 혹은 FIFO)를 만드는 명령어입니다. 프로세스간 통신(IPC) 중에 가장 간단하다고 볼 수 있습니다. 서버 콘솔창을 항상 열어둘 수는 없으니 fifo를 통해서 손쉽게 팩토리오 프로그램에 명령어를 전달 할 수 있습니다. 

 

 


8. 스크립트 작성

스크립트를 총 3개 작성합니다.

팩토리오를 가동할 때 사용할 스크립트와 종료할 때  사용할 스크립트, 명령어 전송 스크립트입니다.

마지막은 없어도 상관없습니다.  다만 이 경우에는 본인 아이디를 관리자 권한으로 설정해주는 것을 추천합니다.

 

폴더 하나를 만들고 스크립트를 작성합시다.

mkdir /fac_scripts

vim /fac_scripts/start_server.sh
vim /fac_scripts/stop_server.sh
vim /fac_scripts/send.sh

 

 

 

서버 시작 스크립트

#!/bin/bash

source /etc/profile
echo "start" > /tmp/start.sxt

PIPE_PATH="/tmp/factorio_server_pipe"
PROGRAM_PATH="/opt/factorio/bin/x64/factorio"
INIT_OPTION="--server-settings /fac_scripts/server-settings.json --start-server-load-latest"
LOG_FILE="/fac_scripts/log/fac_log"

if [[ ! -p "$PIPE_PATH" ]]; then
	mkfifo "$PIPE_PATH"

fi

echo "Starting server..." > /tmp/start.txt
$PROGRAM_PATH $INIT_OPTION <> $PIPE_PATH &> "$LOG_FILE" &
PROGRAM_PID=$!

echo "$PROGRAM_PID" > /tmp/factorio_server.pid

 

 

 

서버 종료 스크립트

 

#!/bin/bash

PIPE_PATH="/tmp/factorio_server_pipe"
PROGRAM_PATH="/opt/factorio/bin/x64/factorio"
LOG_FILE="/tmp/factorio_server_log"

if [[ ! -p "$PIPE_PATH" ]]; then
        echo "Error: PIPE $PIPE_PATH does not exist. Program not running or Incorrect Pipe Path"
        exit 1
fi

SAVE="/c game.server_save()"
GAME_EXIT="/quit"



echo "$SAVE" > "$PIPE_PATH"
echo "GAME SAVED"
echo "$GAME_EXIT" > "$PIPE_PATH"
echo "SEVER DOWN"

 

 

 

명령 입력 스크립트

#!/bin/bash
#
PIPE_PATH="/tmp/factorio_server_pipe"
LOG_FILE="/fac_scripts/log/fac_log"

if [[ ! -p "$PIPE_PATH" ]]; then
	echo "Error : PIPE does not exist"
	exit 1
fi

if [[ -z "$1" ]]; then
	echo "Usage: $0 <command>"
	exit 1
fi

LAST_LINE=$(wc -l < "$LOG_FILE")

echo "$1" > "$PIPE_PATH"
echo "Command sent: $1"

while true; do
	NEW_LINES=$(wc -l < "$LOG_FILE")
	if [[ "$NEW_LINES" -gt "$LAST_LINE" ]]; then
		tail -n $((NEW_LINES - LAST_LINE)) "$LOG_FILE"
		break
	fi
	sleep 0.05
done

 

9. systemd 설정

systemd를 통해서 팩토리오 서버를 켜고 끌 수 있습니다. 이 경우 ssh에서 로그아웃을 해도 백그라운드에서 잘 돌아갑니다.

 

[Unit]
Description=Factorio Server
After=network.target

[Service]
Type=forking
ExecStart=/fac_scripts/start_server.sh
ExecStop=/fac_scripts/stop_server.sh
#Restart=always
PIDFile=/tmp/factorio_server.pid
User=factorio
Group=factorio

[Install]
WantedBy=multi-user.target

 

 

6. factorio user, group 설정

factorio를 실행하는 유저와 그룹을 설정해서 팩토리오 폴더를 관리합니다.

sudo adduser --disabled-login --no-create-home --gecos factorio factorio

 

 

 

7. (선택사항)팩토리오 서버 토큰 받아오기

 

팩토리오 구매 후 팩토리오 웹페이지를 접속해서 토큰을 받을 수 있습니다.

이 토큰을 사용해서 서버를 생성하면 팩토리오 멀티플레이에서 손쉽게 접속 가능합니다. 

또한 팩토리오 공식 서버를 거쳐서 로그인 되므로 인증된 사용자만 받을 수 있습니다.(아마도?)

 

팩토리오 홈페이지에 접속하신 후 로그인해서 우측 상단의 본인 닉네임을 클릭하면 다음과 같은 화면이 나옵니다.

Token 글자를 복사해 둡니다.

 

 

 

 

8. 팩토리오 서버 설정

json파일들을 만들어줄 차례입니다. /factorio/data에 기본 예시가 있습니다.

server-settings.json을 만들면 됩니다. 

원하시는 대로 수정해서 사용하시면 됩니다.

 

위에서 얻어둔 토큰을 입력하면 됩니다.

없어도 가동은 하지만 이럴 경우 ip주소로만 접속 가능합니다. 

 

 

{
  "name": "서버 이름",
  "description": "서버 설명",
  "tags": [ "game", "태그" ],

  "_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.",
  "max_players": 20,

  "_comment_visibility": [
    "lan: Game will be broadcast on LAN"
  ],
  "visibility": {
	"public": true,
	"lan": true
  },

  "_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public",
  "username": "본인의 팩토리오 아이디",
  "password": "",

  "_comment_token": "Authentication token. May be used instead of 'password' above.",
  "token": "팩토리오 서버에서 받아온 토큰",

  "game_password": "게임 비밀번호",
  
  "_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account",
  "require_user_verification": true,

  "_comment_max_upload_in_kilobytes_per_second": "optional, default value is 0. 0 means unlimited.",
  "max_upload_in_kilobytes_per_second": 0,

  "_comment_max_upload_slots": "optional default value is 5. 0 means unlimited.",
  "max_upload_slots": 5,

  "_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.",
  "minimum_latency_in_ticks": 0,

  "_comment_max_heartbeats_per_second": "Network tick rate. Maximum rate game updates packets are sent at before bundling them together. Minimum value is 6, maximum value is 240.",
  "max_heartbeats_per_second": 60,

  "_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.",
  "ignore_player_limit_for_returning_players": false,

  "_comment_allow_commands": "possible values are, true, false and admins-only",
  "allow_commands": "admins-only",

  "_comment_autosave_interval": "Autosave interval in minutes",
  "autosave_interval": 20,

  "_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.",
  "autosave_slots": 30,

  "_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.",
  "afk_autokick_interval": 60,

  "_comment_auto_pause": "Whether should the server be paused when no players are present.",
  "auto_pause": true, 

  "_comment_auto_pause_when_players_connect": "Whether should the server be paused when someone is connecting to the server.",
  "auto_pause_when_players_connect": true,

  "only_admins_can_pause_the_game": true,

  "_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.",
  "autosave_only_on_server": true,

  "_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.",
  "non_blocking_saving": false,

  "_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.",
  "minimum_segment_size": 25,
  "minimum_segment_size_peer_count": 20,
  "maximum_segment_size": 100,
  "maximum_segment_size_peer_count": 10
}

 

 

 

9. 권한 설정

팩토리오 폴더와 설정파일들 권한 설정을 바꾸고, 스크립트를 실행 가능하도록 바꿉니다.

 

sudo chown -R factorio:factorio /opt/factorio

sudo chown -R factorio:factorio /fac_scripts

chmod +x *.sh

 

 

10. 맵 설정

맵은 기본설정 json파일이 factorio dlc 이후로 업데이트 되지 않아서 데스크탑에서 맵을 하나  생성한 후 세이브 파일을 가져오는 것이 좋습니다. saves 폴더에 본인의 세이브 파일을 그대로 가져오면 됩니다. OS가 윈도우인 경우 모드와 마찬가지로 %appdata%에서 찾을 수 있습니다. 가장 최신의 파일을 로드하기 때문에 원하는 세이브 파일에 touch명령어를 쓰시면 됩니다.

혹은 스크립트에서 --start-server-load-latest이 부분을 본인의 세이브 파일 이름으로 바꾸어서 실행하시면 됩니다.

 

--start-server /opt/factorio/saves/{save_file}.zip

 

 

 

11. 실행

 

systemd를 활용해서 켜고 끄기.

 

sudo systemctl daemon-reload

sudo systemctl start factorio_server

sudo systemctl stop factorio_server

 

명령어를 내릴려면 다음과 같이 입력하면 됩니다.

 

12. 명령어 입력

 

sudo -u factorio ./send.sh "/time"

 

 

 

 

정상적으로 출력되는 것을 볼 수 있습니다.

 

12. 서버 종료

sudo systemctl stop factorio_server