Skip to content

Instantly share code, notes, and snippets.

@othyn
Last active December 23, 2024 00:23
Show Gist options
  • Save othyn/e1287fd937c1e267cdbcef07227ed48c to your computer and use it in GitHub Desktop.
Save othyn/e1287fd937c1e267cdbcef07227ed48c to your computer and use it in GitHub Desktop.
How to setup a Factorio Headless Server

[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.

Just a note to newcomers: If there are any issues with the installation steps, people in the comments are doing a good job at mentioning steps required by newer installations. I don't really play anymore and haven't setup or managed a Factorio server in years, so I'll advise if something isn't working to check the comments and forks. Much love <3

Alternate

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

Docker

I'm very much into Docker these days, in which there is a brilliant container setup and ready for this if you wish to use that instead.

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...

@curtiscook
Copy link

curtiscook commented Feb 27, 2023

After beating my head against a wall for a while...

You're missing these 2 lines

[Unit]
After=network-online.target
Wants=network-online.target

Otherwise, it tries to autoload before the network is available and fails with exit 1

Hope this helps someone else landing on this gist

--
Edit:
Also there's now a stable link for download https://factorio.com/get-download/stable/headless/linux64

@Carrolito
Copy link

Hello! this guide was very useful I was able to set up my server after a few hours of battle and I discovered 2 very useful things,

the first is that we can add the parameter --bind [address:port] with which we can assign those values when starting the server, for example --bind 192.168.100.1:34197 this would change it to our public ip and if all goes well anyone could enter our server with that address.

The second thing is related, if like me you don't have a static ip and you are in a CG-NAT then maybe you have a static ipv6 instead of a conventional ipv4 and you can use it to connect, to check if we have it we enter this page and compare the address we get with the command ifconfig -a (and going to the network interface we use either ethernet or wifi), if we see an address that is identical to that of the web page then that would be our static ipv6 and we can enter it in the command above, for example
--bind 1294:8b0:1240:113:b940:77gd:445c:qdzb so that others can access, no need to specify the port apparently just the public ipv6 address you have is enough.

This is what worked for me, I hope it helps and sorry if I said something incoherent, all that networking stuff is not my specialty and English is not my native language xD

@halpz
Copy link

halpz commented Apr 27, 2023

how do I enter the server console while it is running (so I can issue commands) ?

@curtiscook
Copy link

how do I enter the server console while it is running (so I can issue commands) ?

Add yourself as an admin and then you can do it from the client

@contrerasp
Copy link

how do I enter the server console while it is running (so I can issue commands) ?

Add yourself as an admin and then you can do it from the client

that isnt really explaining the solution. thats like asking "how do i drive a car?" and you replying with "Turn it on and press the throttle pedal". While true, isnt descriptive enough to solve the problem.

@Collettore
Copy link

Collettore commented Oct 24, 2023

Hello funs! First of all, I want to say thank you! for the detailed instructions that work
server started with the mods and with the save, my friend even connected to the server and from that moment my problem started...
and the problem is that I can't connect to my server myself, which is publicly available
сould you please help fix it! thanks in advance

upd; problem was solved after connecting a static IP address and port forward 34197 on the router

@MasterGroosha
Copy link

Looks like now there is a static link for server: https://factorio.com/get-download/stable/headless/linux64

@Tobias7786
Copy link

how do I enter the server console while it is running (so I can issue commands) ?

Add yourself as an admin and then you can do it from the client

that isnt really explaining the solution. thats like asking "how do i drive a car?" and you replying with "Turn it on and press the throttle pedal". While true, isnt descriptive enough to solve the problem.

Agree...so for others wondering - I think you need to setup a file called "server-adminlist.json" and add the admins to this list. Haven't tried myself so far, but pretty sure Google is helpful.

While being a good guide, things also missing in this guide...

  • how to set the factorio process to autostart

@martijnenco
Copy link

For updateing this is what i quickly came up with:

#!/usr/bin/env bash

echo "backup mods"
cp -r /opt/factorio/mods/ ~

echo "backup saves"
cp -r /opt/factorio/saves/ ~

echo "download newest version"
wget -O ~/factorio_headless.tar.gz https://factorio.com/get-download/stable/headless/linux64

echo "unpack the newest version"
cd /opt
tar -xf ~/factorio_headless.tar.gz

echo "restart service"
systemctl daemon-reload
systemctl restart factorio.service

@Tobias7786
Copy link

For updateing this is what i quickly came up with:

#!/usr/bin/env bash

echo "backup mods"
cp -r /opt/factorio/mods/ ~

echo "backup saves"
cp -r /opt/factorio/saves/ ~

echo "download newest version"
wget -O ~/factorio_headless.tar.gz https://factorio.com/get-download/stable/headless/linux64

echo "unpack the newest version"
cd /opt
tar -xf ~/factorio_headless.tar.gz

echo "restart service"
systemctl daemon-reload
systemctl restart factorio.service

I'm using factorio-updater and it works also in 2.x Really great tool, just updated to 2.0.20 2 hours ago using it. Might be a good idea to backup the factorio-folder before running the script.

What I'm doing...

Stop factorio service:

sudo systemctl stop factorio.service

change to the factorio-updater directory:

cd /opt/factorio-updater/

Run the script:

sudo python3 update_factorio.py -vDa /opt/factorio/bin/x64/factorio

Start factorio service:

sudo systemctl start factorio.service

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