Deploy Factorio headless server on Google Cloud Platform using Terraform with HTTP API controls. Designed for small gaming groups with remote server management via HTTP endpoints.
Login to GCP and set up your environment:
gcloud auth loginSet your project:
gcloud config set project YOUR_PROJECT_IDAuthenticate application default credentials so that Terraform can use them:
gcloud auth application-default loginEnable required APIs:
gcloud services enable compute.googleapis.com
gcloud services enable iam.googleapis.comYou might want to connect the project to your billing account.
Create and configure: terraform.tfvars you only need to update project_id to run the server.
cp terraform.tfvars.example terraform.tfvarsNote that the terraform state file will be created in the current directory and is not configured for remote storage.
terraform init
terraform applyDeployment takes a couple of minutes.
Then you need to wait a couple of minutes for the Factorio server to start.
After deployment, get connection details:
# Get server IP for Factorio game connections
terraform output connection_string
# Get HTTP API URL for management
terraform output http_api_url
# Get server IP only
terraform output server_ip
# API Usage
terraform output api_usageIf you want to pass management commands using a service account key instead of application default credentials, create a json key for the service account created by Terraform:
gcloud iam service-accounts keys create ./factorio-management-key.json \
  --iam-account=factorio-management-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com The management key can be used on any machine with gcloud installed:
gcloud auth activate-service-account --key-file=factorio-management-key.json
gcloud config set project YOUR_PROJECT_IDCommands:
./scripts/start-server.sh- Start the Factorio server./scripts/stop-server.sh- Stop the Factorio server
Once deployed, the server exposes an HTTP API on port 8080 for remote management. Get the API URL from terraform outputs:
terraform output http_api_urlCheck Server Status:
curl http://YOUR_SERVER_IP:8080/factorio/statusPause/Unpause Game:
curl -X POST http://YOUR_SERVER_IP:8080/factorio/pause
curl -X POST http://YOUR_SERVER_IP:8080/factorio/unpauseControl Game Speed:
curl -X POST http://YOUR_SERVER_IP:8080/factorio/speed/slow
curl -X POST http://YOUR_SERVER_IP:8080/factorio/speed/normal
curl -X POST http://YOUR_SERVER_IP:8080/factorio/speed/fastList Save Files:
curl http://YOUR_SERVER_IP:8080/factorio/savesLoad Existing Save:
curl -X POST http://YOUR_SERVER_IP:8080/factorio/load/SAVE_NAMEUpload and Load Save File:
curl -X POST http://YOUR_SERVER_IP:8080/factorio/upload-save \
  -F "saveFile=@/path/to/your/save.zip" \
  -F "autoLoad=true"Trigger Manual Save:
curl -X POST http://YOUR_SERVER_IP:8080/factorio/saveGet Server Time:
curl http://YOUR_SERVER_IP:8080/factorio/timegcloud compute ssh factorio-server --zone=europe-west4-a --tunnel-through-iapssh using IAPsudo systemctl status dockercheck Docker statussudo docker logs factorioview Factorio container logscat /factorio/config/server-adminlist.jsonview Factorio admin listsudo docker ps | grep factoriocheck container statussudo docker logs $(sudo docker ps -q | head -1) --tail 50view recent container logs