Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Igneous01/f045b83929fb0ad0e72e6901dfe99830 to your computer and use it in GitHub Desktop.
Save Igneous01/f045b83929fb0ad0e72e6901dfe99830 to your computer and use it in GitHub Desktop.
How to setup a Factorio Headless Server

[LINUX] Factorio Headless Server Guide for AWS EC2

So, with credit to the Factorio wiki and cbednarski's helpful gist, I have been able to successfully setup a Factorio headless server on AWS EC2 using the Amazon Linux 2 AMI (HVM), SSD Volume Type AMI.

This guide was done using the Amazon Linux 2 AMI image for EC2, and Factorio 1.19.0. However it is possible for this guide to also work on other linux AMI images.

Prerequisites

  • AWS Account
  • Licensed copy of factorio
  • That's it!

A - EC2 Setup

Step A1 :: Launch EC2 Instance

Sign into your AWS account and go to your dashboard. Search for 'EC2' and select that service to bring up the EC2 dashboard / console page. Click on the orange 'Launch Instance' button near the bottom of the page to bring up the EC2 configuration page.

Step A2 :: Choose Amazon Machine Image (AMI)

Select the Amazon Linux 2 AMI (HVM), SSD Volume Type AMI for x86 (AMI Id: ami-047a51fa27710816e (64-bit x86))

Make sure you select x86 and NOT arm.

Step A3 :: Choose Instance Type

This will vary depending on your server needs. For starting a new game I recommend t2.large which comes with 8GB of RAM and 2 vCPU cores - you can always swap out the instance type later on if performance is becoming an issue.

Step A4 :: Configure Instance Details

Leave the default settings here, unless there is something specific you want to change.

Step A5 :: Configure Storage

The default setup comes with 8GB of storage, which is plenty for storing save files, however if you plan to run mods, you will need to figure out how much storage all mods would require on the server.

Click on 'Review and Launch'

Step A6 :: Security Groups

You may receive a warning about Your security group, your-security-group-name, is open to the world. Click on Edit security groups, and you will see an inbound rule for SSH already configured. Under the 'source' column, change the 'Custom' to 'My IP' so that only your computer is allowed to SSH into the server. Note that you may need to update this rule multiple times if your IP address is not static. If you know exactly what your IP address range is going to be, you can configure it using the Custom rule instead. For simplicity reasons I chose 'My IP'.

Keep advancing to the next page until you reach the Select an existing key pair or create a new key pair window.

Step A7 :: Generate SSH Key Pair

In the key pair window, select Create a new key-pair, and give the key-pair a name, for example: factorio-ec2-instance. Then hit Download Key Pair to download the factorio-ec2-instance.pem file. This is your private key that allows you to SSH into the EC2 instance. Without it, you will not be able to SSH in, and you will have to regenerate a new key pair for yourself.

Save this .pem file somewhere so you don't forget it. You will need to reference it each time you wish to SSH in to your EC2 instance. For the purposes of this guide, my .pem file is stored on ~/documents on OSX, or C:/.../My Documents in Windows.

Step A8 :: Launch EC2 Instance

Once you've downloaded the .pem file and configured everything, go ahead and launch your instance.

Step A9 :: SSH into your EC2 instance

Once you have launched your instance, go to the Instances page and you will see your instance appear in the list. Click on your 'instance-id' and then click on the Connect button.

On the Connect to instance page, click on the SSH Client tab and follow the 4 steps laid out on that page to ssh into your EC2 instance. You will need to make sure that you provide the path to the .pem file, or ensure you launch your terminal in the same directory as the .pem file. You will get a command similar to the one below:

ssh -i "factorio-ec2-instance.pem" ec2-user@ec2-xxx-xx-xxx-xxx.compute-1.amazonaws.com

Step A10 :: Configure Firewall Rules on your EC2 Instance

For the purposes of this guide, we will be using port 62754 for hosting the game.

Go to your EC2 instance summary page -> Security tab, and click on the blue link under Security Groups to bring up the rules page.

The only thing we need to do here is add Inbound Rules exceptions for ports 62754 and 34197 for both TCP and UDP.

Click Edit Inbound Rules

Click Add Rule choose Custom TCP for the Type, and for Port Range type in 62754, for Source, choose Anywhere. Repeat these process until you have the following rules on your EC2 instance.

Type          Port-Range          Source
SSH           22                  Custom
Custom TCP    62754               Anywhere
Custom UDP    62754               Anywhere
Custom TCP    34197               Anywhere
Custom UDP    34197               Anywhere

Note that if you wish to be able to ping your EC2 instance, you will also need to enable inbound rules for Custom ICMP - IPv6 and Custom ICMP - IPv4 otherwise the AWS firewall will block any ping requests.

B - Factorio Setup on EC2

Step B1 - Download binary

On your EC2 instance, run the following command to download the latest headless server

wget -O factorio_headless.tar.gz https://factorio.com/get-download/stable/headless/linux64

Also, as they redirect download requests, wget will not name the file correctly. The easiest way to rectify it is to manually set the file name using the -O flag and manually providing the file name as used in the example above.

Wait for the file to download before proceeding.

Step B2 :: Directories

Factorio runs out of the /opt directory, a directory resevered in UNIX for non-default software installation.

Run the following command to extract and install on your EC2 instance:

sudo tar xvf factorio_headless.tar.gz -C /opt

Just for the sake of keeping things tidy, I'd also delete the downloaded archive rm ~/factorio_headless.tar.gz, as we are now finished with it.

If you wish to add any mods or saves, you can do so by first creating the mods and saves directories within /opt/factorio. sudo mkdir /opt/factorio/saves and sudo mkdir /opt/factorio/mods should achieve this, then you may copy the save & mod archives into the relevant folders.

Step B3 :: Environment

As you don't want Factorio running as root, let's setup a user that it can run under. The user won't need a lot of functionality, as it's only going to be running Factorio and won't need to be logged into, so let's provide some flags to create a really basic user:

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

The above command will add a user, not setting a password --disabled-login, without creating a home directory in /home --no-create-home, without asking for user information --gecos, create user factorio and add them/create the group factorio.

Now that the new user is created, we need to make it the owner of the Factorio directory so that it can access and perform operations within it, sudo chown -R factorio:factorio /opt/factorio. The -R flag being recursive.

Step B4 :: Factorio Configuration

Factorio headless requires a JSON formatted config file. They provide an example one to get you started, in which can be copied and then edited to suit your requirements.

First, lets change directory cd /opt/factorio/data where the server-settings.example.json config file is located, it's not necessary, but just the way I do things. Now to make a copy of the config file under its working name sudo cp server-settings.example.json server-settings.json and then edit it with a text editor of your choice, I like nano as its easy sudo nano server-settings.json.

The configuration is fairly straight forward and mirrors that of the GUI when setting up a server via the standard edition of Factorio. Here is the configuration reference. Configure it as you wish, save, exit and proceed onto the next step.

Here is an example of the server settings config file:

{
  "name": "my factorio server",
  "description": "a sample server",
  "tags": ["game", "tags"],

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

  "_comment_visibility": ["public: Game will be published on the official Factorio matching server",
                          "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": "your-username-here",
  "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_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": 10,

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

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

  "_comment_auto_pause": "Whether should the server be paused when no players are present.",
  "auto_pause": 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 Will",
  "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...",
  "minimum_segment_size": 25,
  "minimum_segment_size_peer_count": 20,
  "maximum_segment_size": 100,
  "maximum_segment_size_peer_count": 10
}

Step B5 :: Upload your save to EC2

Copy your save into the same location as your .pem file, or specify the full path when you do the command. Be sure to reference the same ec2-user@instance-id as was provided by AWS when you were going through the Connect window.

scp -i "factorio-ec2-instance.pem" your_factorio_save.zip ec2-user@ec2-xxx-xx-xxx-xxx.compute-1.amazonaws.com:.

Afterwards you can sudo cp your_factorio_save.zip /opt/factorio/saves to copy your save into the factorio installation directory.

Step B6 :: systemd

So, we want Factorio to run as a service. So lets create a new service for Factorio within the systemd service scheduler. Again, I like nano as its easy, but any text editor will do sudo nano /etc/systemd/system/factorio.service. The service should contain the following:

[Unit]
Description=Factorio Headless Server

[Service]
Type=simple
User=factorio
ExecStart=/opt/factorio/bin/x64/factorio --server-settings /opt/factorio/data/server-settings.json --start-server-load-latest –Port 62754

Change the {save_file} for the file name of your save. You may also want to swap out --start-server /opt/factorio/saves/{save_file}.zip for --start-server-load-latest, which will automatically pull through the latest version of your world across manual and auto saves. If you wish to look at more parameters, there is more information on the Factorio multiplayer wiki.

Save the file and exit. Time to start the service and see if our setup has worked!

Firstly, reload the available service daemons systemctl daemon-reload, now start the newly created service systemctl start factorio and see if it's running systemctl status factorio.service. That is the output from the Factorio server, any errors or configuration issues will present themselves here if you ever need to debug.

If you do make any configuration changes, you'll need to restart the service sudo systemctl restart factorio.service.

Step Finished :: Play!

That's it! You should now have a working Factorio server. Head over to your client and under "Multiplayer" > "Connect to a server", provide your address that you set it up against (and port if you changed it from the default) and play spend hours labouring over tiny details to maximize efficiency!

TODO:

  • How to upgrade

With a quick shout out to dillinger.io for making MD editing a more pleasant experience...

[LINUX] Factorio Headless Server Guide

So, with credit to the Factorio wiki and cbednarski's helpful gist, I managed to eventually setup a Factorio headless server. Although, I thought the process could be nailed down/simplified to be a bit more 'tutorialised' and also to document how I got it all working for my future records.

The specific distro/version I'm using for this guide being Ubuntu Server 16.04.1 LTS. Although, that shouldn't matter, as long as your distro supports systemd (just for this guide, not a Factorio headless requirement, although most distros use it as standard now). The version of Factorio I shall be using is 0.14.20, although should work for any version of Factorio 0.14.12 and higher.

Alternate

If you prefer a simple, automated setup, Bisa has a really handy init script that will do most of the work for you!

Prerequisites

  • *nix distro, setup and ready to go
  • The UDP port used for Factorio, default 34197, forwarded through your router. I won't go into how to do this here as it's a seperate tutorial in of itself, but you can easily Google "{routers model/manufacturer} port forward" and find the desired results.
  • Optional - Setup SSH for remote access, this may be handy if you wish to upload/download saves via scp (?). If you would like to do this, it's recommended that you disable password login and use SSH keys.
  • Tip - If you ever miss sudo from the beginning of a command, sudo !! will repeat it, but elevated.
  • That's it!

Step 0 :: Patches & Security!

With it being a fresh installation, as with any OS, make sure to update your system. Run sudo apt update && sudo apt full-upgrade. This will first check the relevant repo's for package updates, then run the update process.

If your server is running from behind your edge router/firewall, then enabling the firewall isn't a necessary step. So skip to the next step if you don't want to enable it.

I like to enable the firewall before getting started on setup, just personal preference. This is as simple as sudo ufw enable. UFW being Uncomplicated Firewall, in which it really is!

Let's allow Factorio through on its default port (or a port of your chosing), sudo ufw allow 34197/udp. You may also want to allow SSH connections through at this point, if you are using it.

As this is an internet facing server, you may want to install and configure something like fail2ban to help with repeated non-authorised login attempts, but that is up to you.

Step 1 :: Download

I'm going to be working out of my home directory, just for simplicity. Let's grab the headless server from Factorio's download site via wget onto the server.

wget -O factorio_headless.tar.gz https://www.factorio.com/get-download/0.14.20/headless/linux64

Unfortunately, the url for the download isn't static, so you'll have to change the version in the url to what version you require (stable or experimental). Easiest way to find out the url is to go to the Factorio server download page and find the url from the link provided under the version number.

Also, as they redirect download requests, wget will not name the file correctly. The easiest way to rectify it is to manually set the file name using the -O flag and manually providing the file name as used in the example above.

Wait for the file to download before proceeding.

Step 2 :: Directories

Factorio runs out of the /opt directory, a directory resevered in UNIX for non-default software installation.

So before extracting the headless archive, lets change our working directory, cd /opt.

Now its time to extract the headless archive, sudo tar -xzf ~/factorio_headless.tar.gz. The -xzf flags are basically; extract a gzipped archive file. This will extract the downloaded archive to your current directory, and should have created a Factorio folder. You can check that /opt/factorio exists by running ls (?), and seeing if the factorio directory is listed, as we are working out of /opt already.

Just for the sake of keeping things tidy, I'd also delete the downloaded archive rm ~/factorio_headless.tar.gz, as we are now finished with it.

If you wish to add any mods or saves, you can do so by first creating the mods and saves directories within /opt/factorio. sudo mkdir /opt/factorio/saves and sudo mkdir /opt/factorio/mods should achieve this, then you may copy the save & mod archives into the relevant folders.

Step 3 :: Environment

As you don't want Factorio running as root, let's setup a user that it can run under. The user won't need a lot of functionality, as it's only going to be running Factorio and won't need to be logged into, so let's provide some flags to create a really basic user:

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

The above command will add a user, not setting a password --disabled-login, without creating a home directory in /home --no-create-home, without asking for user information --gecos, create user factorio and add them/create the group factorio.

Now that the new user is created, we need to make it the owner of the Factorio directory so that it can access and perform operations within it, sudo chown -R factorio:factorio /opt/factorio. The -R flag being recursive.

Step 4 :: Factorio Configuration

Factorio headless, as of 0.14.12, requires a JSON formatted config file. They provide an example one to get you started, in which can be copied and then edited to suit your requirements.

First, lets change directory cd /opt/factorio/data where the server-settings.example.json config file is located, it's not necessary, but just the way I do things. Now to make a copy of the config file under its working name sudo cp server-settings.example.json server-settings.json and then edit it with a text editor of your choice, I like nano as its easy sudo nano server-settings.json.

The configuration is fairly straight forward and mirrors that of the GUI when setting up a server via the standard edition of Factorio. Here is the configuration reference. Configure it as you wish, save, exit and proceed onto the next step.

Step 5 :: systemd

So, we want Factorio to run as a service. So lets create a new service for Factorio within the systemd service scheduler. Again, I like nano as its easy, but any text editor will do sudo nano /etc/systemd/system/factorio.service. The service should contain the following:

[Unit]
Description=Factorio Headless Server

[Service]
Type=simple
User=factorio
ExecStart=/opt/factorio/bin/x64/factorio --start-server /opt/factorio/saves/{save_file}.zip --server-settings /opt/factorio/data/server-settings.json

Change the {save_file} for the file name of your save. You may also want to swap out --start-server /opt/factorio/saves/{save_file}.zip for --start-server-load-latest, which will automatically pull through the latest version of your world across manual and auto saves. If you wish to look at more parameters, there is more information on the Factorio multiplayer wiki.

Save the file and exit. Time to start the service and see if our setup has worked!

Firstly, reload the available service daemons systemctl daemon-reload, now start the newly created service systemctl start factorio and see if it's running systemctl status factorio.service. That is the output from the Factorio server, any errors or configuration issues will present themselves here if you ever need to debug.

If you do make any configuration changes, you'll need to restart the service sudo systemctl restart factorio.service.

Step Finished :: Play!

That's it! You should now have a working Factorio server. Head over to your client and under "Multiplayer" > "Connect to a server", provide your address that you set it up against (and port if you changed it from the default) and play spend hours labouring over tiny details to maximize efficiency!

TODO:

  • How to upgrade
  • How to create/scp your own save (re-apply chown)

With a quick shout out to dillinger.io for making MD editing a more pleasant experience...

@oddlots
Copy link

oddlots commented Feb 2, 2021

Out of curiosity, how much to you estimate running this on AWS costs?

@jkkelley
Copy link

jkkelley commented Aug 5, 2021

Thank you for this well written guide.

@zachmayer
Copy link

zachmayer commented Mar 4, 2022

When I run sudo adduser --disabled-login --no-create-home --gecos factorio factorio I get adduser: unrecognized option '--disabled-login'

There was a version 4 and a version 5 of the AWS linux instance: is this issue because I chose the wrong one?

sudo adduser --no-create-home --comment factorio factorio let me create the user

@ryanrhee
Copy link

ryanrhee commented Mar 13, 2022

ran into the same issue.

it seems that adduser is symlinked to useradd:

$ file `sudo which adduser`
/sbin/adduser: symbolic link to `useradd'

--gecos does map to --comment, but you'll need to set the user shell to nologin (https://unix.stackexchange.com/a/117929)

so the full alternative command would be:

sudo useradd --shell /usr/sbin/nologin --no-create-home --comment factorio factorio

@halpz
Copy link

halpz commented Apr 27, 2023

how do I access the server console once it is running from systemd?

@zachmayer
Copy link

I'd love to see some details on upgrading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment