Ark: Survival Ascended hosted for cheap on Contabo
This Blog post is to accompany a video we posted to YouTube here: https://www.youtube.com/watch?v=JmqO1cnxGYg
In 2023, Wildcard released Ark: Survival Ascended (ASA). This is the true successor to the Ark: Survival Evolved that we love! However, they partnered with Nitrado as the only “official” hosting provider. With enough complaints, Studio Wildcard chose to allow self-hosted servers – just as they had with Ark:SE.
While not everybody has a spare machine lying around to host an Ark server, we can still rent decent Virtual Private Servers (VPS) from services like Hetzner or Contabo. After comparing the options, I settled on Contabo as the most affordable. It’s not perfect, but it’ll serve the purpose. Coming in around $15/mo USD for a server with 16GB RAM, it’s well below the Nitrado-hosted option – if we’re willing to put in the work to set everything up. So lets begin!
Choose a Contabo server
As of January 2024, Contabo has excellent price to performance options! If you just need a dev server, the $5.50 option is hard to beat with 4 V-cores and 8GB RAM.
However, we’re needing slightly more than that to run an ASA server. The next step up will do nicely – though the price is a bit deceiving. We’ll explain why shortly. The “Cloud VPS M” with 16GB RAM is exactly what we need to host The Island on ASA. If you can pay in Euro instead of USD, you can save another 17%, but I don’t know if you have to pay a conversion rate above that.
Some things to be aware of in this price, though. The “No Setup Fee” is only if you’re buying 12 months up front. I find this very deceiving, though I suppose it’s probably fair. The actual setup fee is actually $8.50. Since it’s a 1-time fee and we’re still cheaper than Nitrado, it’s worth trying in my opinion. The $12.50 price is also misleading. To host in the US, I was charged an extra $2.65. East USA is an extra $3.60. I do understand that there could be extra cost depending on location, but I had already told the site I’m in the USA and paying with USD. That fee should have been included in the advertised price. Even with both hidden fees, we’re still cheaper than Nitrado 🙃
Configure your server
If you only plan to run an Ark server here, the 100GB NVMe is probably your best option. If you also want to host a blog with pictures and videos, the 400GB SSD may be better suited. I like the idea of faster storage over more storage though.
Your “Image” is which OS you want installed by default. We want Docker and I’m a fan of Debian, though Ubuntu is fine too. Choose the [Apps & Panels] tab and select [x] Docker. From the drop-down, choose “Debian 12”.
On Linux, your “Root” account is the default admin account that has Linux god powers. Give it a strong password because you don’t want anyone guessing this login!
SSH into our new server
From the Contabo VPS control dashboard, we can find the IP to our server.
Windows PowerShell, Mac Terminal, and Linux Terminal all have SSH built-in now. From the command line, type “ssh root@123.123.123.123” replacing “123…” with the IP we copied from the Contabo dashboard.
When it asks, provide the password we set in the last step.
Create user accounts
While the “root” user is convenient, we should really create a non-root account to login with. Don’t worry… We can still give this new account elevated permissions too though. The second account we want is “asa” so we can attribute the file ownership. Using useradd
, we can create our accounts with passwords. The basic useradd myUserName
will create the account without a password and sets the default shell to /bin/sh
. If you’ve already run that, don’t worry… We can fix that too.
useradd ben -s /bin/bash -p 5uper5ecretPa55w0rd
useradd asa
If you did something wrong here, we can still fix it. You may not even want your password shown in plain text like this. To change the password of my “ben” account, I’d use passwd ben
. If you need to change the default shell, you can nano /etc/passwd
and scroll to the bottom where your account is and change the default shell there.
We can now tail /etc/passwd -n2
to see those two new accounts and their IDs.
Most likely, our account with have a User ID and Group ID (UID:GID) of 1000:1000 and our “asa” account will have 1001:1001. The asa uid:gid will come into play later, so take note if they’re different than we expect.
Create Docker folder structure and install Dockge
There are several ways to setup your Docker directories, but I prefer to create new /opt/docker/
folder and nest everything under there. We can move into /opt
and get started:
cd /opt
mkdir docker
cd docker
mkdir dockge dockge/data
And that’s it! Now we have a folder for Dockge and soon for our Ark server, and the data folder for Dockge. Next we’ll move into the Dockge folder and prepare a Docker Compose file. The Compose file is a simple way to deploy a new Docker container – or suite of containers – with a well-defined Yaml document.
cd dockge
nano compose.yaml
Nano is a simple text editor for Linux. We’re trying not to spend too much time on the Linux command line, but this will help us out. Bare with me – we’re almost there!
We can get the sample Compose file from the official Dockge repo, but that will need some updates specific to our environment. You’re certainly welcome to go that route, or you can use the Compose file I’ve already prepared:
version: "3.8"
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
ports:
# Host Port : Container Port
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# If you want to use private registries, you need to share the auth file with Dockge:
# - /root/.docker/:/root/.docker
# Your stacks directory in the host (The paths inside container must be the same as the host)
# ⚠️⚠️ If you did it wrong, your data could end up be written into a wrong path.
# ✔️✔️✔️✔️ CORRECT: - /my-stacks:/my-stacks (Both paths match)
# ❌❌❌❌ WRONG: - /docker:/my-stacks (Both paths do not match)
- /opt/docker:/opt/docker
environment:
# Tell Dockge where is your stacks directory
- DOCKGE_STACKS_DIR=/opt/docker
You should be able to copy this code and right-click into your SSH window to paste it in. If you’ve made any changes to your folder structure, be sure to update the compose file to match. And, that’s it!! Press [Ctrl] + 'x'
to exit then 'y'
to say you want to save and [Enter]
to confirm the file name.
Finally (for Dockge), we need to deploy the new container. Type docker compose up -d
and watch the Docker magic happen! It will download the images and build out the new install based on what we defined in the compose.yaml
file!
Getting started with Dockge
Alright! I think we’re mostly done with the command line. We may need to come back later, but my goal is to not keep you there more than we have to. Dockge is an easy way to graphically manage your Docker containers straight from the browser. It won’t do everything we need, but should be a gateway. If you noticed in the Compose.yaml file we created, we gave Dockge the default port 5001. All we need to do now is open that in the browser and specify port 5001: http:\\123.123.123.123:5001
– of course, replace the 123… with the IP of your server. The same IP we used to SSH in a few steps back. If we did everything right, we should be greeted with a page to create a new Dockge user:
Be sure to chose a strong password, since this is still open to everybody on the Internet – we should be able to fix that in another tutorial. I won’t go into too much detail here – the video shows it all much better. But you’re probably here for the asa
compose file though:
version: "3.3"
services:
LifeAsBen:
image: johnnyknighten/ark-sa-server:latest
ports:
- 7777:7777/udp
- 7778:7778/udp
- 27015:27015/udp
- 27020:27020/tcp
environment:
- PUID=1001
- PGID=1001
- SERVER_NAME=LifeAsBen
- ADMIN_PASSWORD=5ecretpa55word
- TZ=America\Chicago
- SERVER_PASSWORD=lab123
- MAX_PLAYERS=10
- MANUAL_CONFIG=True
volumes:
- ./server:/ark-server/server
- ./logs:/ark-server/logs
- ./backups:/ark-server/backups
- ./Game.ini:/ark-server/server/ShooterGame/Saved/Config/WindowsServer/Game.ini
- ./GameUserSettings.ini:/ark-server/server/ShooterGame/Saved/Config/WindowsServer/GameUserSettings.ini
Now, we’ve made a few changes to this since the video:
- PUID / PGID were added as environment variables. These should correspond with the IDs for the ASA user we created.
- MANUAL_CONFIG was updated in the video later, but we can include that now. It may be better to leave it out for your first run so the files will be created automatically.
Game.ini
andGameUserSettings.ini
we’ll need to go back and update in command line – for now.
This Compose file can be pasted into the box on the right-side of Dockge, then press the blue [Start] on the left
If this is the first time it starts, you’ll need to be patient. It may take several minutes to download the container images, then several minutes longer to start the server for the first time. It will need to update the SteamCmd executables, then download all of Ark:SA to your server. What you’re waiting for is the line that says something along the lines of “Full Startup 160 seconds”:
If there were no errors, you’re ready to test! I found that even though I specified “LifeAsBen” in the SERVER_NAME
environment variable, it didn’t really respect that. Don’t panic if you can’t find your server though! We’ll update the INI files and that should get us started.
Updating INIs
Almost every aspect of Ark Servers is configured by the INI files: Game.ini and GameUserSettings.ini. I plan to do a detailed video about these in the future, but you probably want something to get started.
To edit these, we’ll need to go back to our SSH window. I won’t rehash that here, but we just need to SSH in (see above) and CD to the ASA folder:
cd /opt/docker/asa/
nano Game.ini
Game.ini we can do more with later, but for now we’ll just give it a placeholder:
[/script/shootergame.shootergamemode]
nano Game.ini
and paste that in. [Ctrl]+'x'
then 'y'
to save and [Enter]
to confirm.
Next we’ll nano GameUserSettings.ini
This one has a lot more options, so you’ll need to expand below for the sample. We don’t really need all of these, but it will get you started. I’ve also already changed some from the defaults, so it’s not quite “vanilla”. Be sure to update your server name (session name) and passwords in this file.
GameUserSettings.ini
[ServerSettings]
ServerPVE=False
RCONEnabled=True
RCONPort=27020
ServerPassword=lab123
ServerAdminPassword=5ecretpa55word
ShowMapPlayerLocation=True
AllowThirdPersonPlayer=True
ServerCrosshair=True
TheMaxStructuresInRange=10500
StartTimeHour=-1
OxygenSwimSpeedStatMultiplier=1
StructurePreventResourceRadiusMultiplier=1
TribeNameChangeCooldown=15
PlatformSaddleBuildAreaBoundsMultiplier=1
AlwaysAllowStructurePickup=True
StructurePickupTimeAfterPlacement=30
StructurePickupHoldDuration=0.5
AllowHideDamageSourceFromLogs=True
RaidDinoCharacterFoodDrainMultiplier=1
PvEDinoDecayPeriodMultiplier=1
KickIdlePlayersPeriod=3600
PerPlatformMaxStructuresMultiplier=1
AutoSavePeriodMinutes=15
MaxTamedDinos=5000
MaxTamedDinos_SoftTameLimit=5000
MaxTamedDinos_SoftTameLimit_CountdownForDeletionDuration=604800
ItemStackSizeMultiplier=1
RCONServerGameLogBuffer=600
ImplantSuicideCD=28800
AllowHitMarkers=True
[/Script/Engine.GameSession]
MaxPlayers=10
[SessionSettings]
SessionName=LifeAsBen
[ScalabilityGroups]
sg.ResolutionQuality=75
sg.ViewDistanceQuality=1
sg.AntiAliasingQuality=1
sg.ShadowQuality=2
sg.GlobalIlluminationQuality=3
sg.ReflectionQuality=3
sg.PostProcessQuality=1
sg.TextureQuality=2
sg.EffectsQuality=1
sg.FoliageQuality=2
sg.ShadingQuality=3
[/Script/ShooterGame.ShooterGameUserSettings]
AdvancedGraphicsQuality=1
MasterAudioVolume=1.000000
MusicAudioVolume=0.800000
SFXAudioVolume=1.000000
VoiceAudioVolume=1.000000
SoundUIAudioVolume=1.000000
CharacterAudioVolume=1.000000
StructureTooltipMaxSpeedMultiply=0.000000
UIScaling=1.000000
UIQuickbarScaling=0.750000
CameraShakeScale=0.650000
bFirstPersonRiding=False
bThirdPersonPlayer=True
bShowStatusNotificationMessages=True
TrueSkyQuality=0.270000
FOVMultiplier=1.000000
GroundClutterDensity=1.000000
bFilmGrain=False
bMotionBlur=True
bUseGamepadSpeaker=True
bUseDFAO=False
bUseSSAO=True
bShowChatBox=True
bCameraViewBob=True
bInvertLookY=False
bFloatingNames=True
bChatBubbles=True
bHideServerInfo=False
bJoinNotifications=False
bDisableNameYourTamePopup=False
MinimalFloatingNameSetting=False
bCraftablesShowAllItems=False
bLocalInventoryItemsShowAllItems=False
bLocalInventoryCraftingShowAllItems=True
bRemoteInventoryItemsShowAllItems=False
bRemoteInventoryCraftingShowAllItems=False
bRemoteInventoryShowEngrams=True
bEnableLowLightEnhancement=True
bEnableFluidInteraction=True
bDisableHLOD=False
LookLeftRightSensitivity=1.000000
LookUpDownSensitivity=1.000000
TPVCameraHorizontalOffsetFactor=0.000000
GraphicsQuality=1
ActiveLingeringWorldTiles=10
ClientNetQuality=3
TheGammaCorrection=0.500000
LastServerSearchType=0
LastServerSort=2
LastPVESearchType=-1
LastDLCTypeSearchType=-1
LastServerSortAsc=True
LastAutoFavorite=True
ShowPlayerServers=False
LastServerSearchHideFull=False
LastServerSearchProtected=False
LastPlatformSpecificServerSearch=False
HideItemTextOverlay=True
bForceShowItemNames=False
bDistanceFieldShadowing=True
bDisableShadows=False
LODScalar=1.000000
bToggleToTalk=False
HighQualityMaterials=True
HighQualitySurfaces=True
bTemperatureF=False
bDisableTorporEffect=False
bChatShowSteamName=False
bChatShowTribeName=True
bReverseTribeLogOrder=False
EmoteKeyBind1=0
EmoteKeyBind2=0
bNoBloodEffects=False
bLowQualityVFX=False
bSpectatorManualFloatingNames=False
bSuppressAdminIcon=False
bUseSimpleDistanceMovement=False
bHasSavedGame=False
bDisableMeleeCameraSwingAnims=False
bPreventInventoryOpeningSounds=False
bPreventBiomeWalls=False
bPreventHitMarkers=False
bPreventCrosshair=False
bPreventColorizedItemNames=False
bHighQualityLODs=False
bExtraLevelStreamingDistance=False
bEnableColorGrading=False
VSyncMode=1
DOFSettingInterpTime=0.000000
LastSessionCategoryJoined=-1
bDisableMenuTransitions=False
bEnableInventoryItemTooltips=True
bRemoteInventoryShowCraftables=False
bNoTooltipDelay=False
LocalItemSortType=0
LocalCraftingSortType=0
RemoteItemSortType=0
RemoteCraftingSortType=0
VersionMetaTag=1
ShowExplorerNoteSubtitles=False
DisableMenuMusic=False
DisableDefaultCharacterItems=False
DisableLoadScreenMusic=False
bRequestDefaultCharacterItemsOnce=False
bHasSeenGen2Intro=False
CinematicForNoteShouldReset=()
bHasSetupDifficultySP=False
bHasSetupVisualSettings=False
agreedToTerms=()
bHasRunAutoSettings=False
bHideFloatingPlayerNames=False
bHideGamepadItemSelectionModifier=False
bToggleExtendedHUDInfo=False
PlayActionWheelClickSound=True
PlayHUDRolloverSound=True
CompanionReactionVerbosity=3
EnableEnvironmentalReactions=True
EnableRespawnReactions=True
EnableDeathReactions=True
EnableSayHelloReactions=True
EnableEmoteReactions=True
EnableMovementSounds=True
DisableSubtitles=False
bEnableASACamera=True
ConsoleAccess=False
CompanionSubtitleVerbosityLevel=3
CompanionIsHiddenState=False
MaxAscensionLevel=0
bHostSessionHasBeenOpened=False
bForceTPVCameraOffset=False
bDisableTPVCameraInterpolation=False
bEnableHDROutput=False
HDRDisplayMinLuminance=-4.000000
HDRDisplayMidLuminance=20.000000
HDRDisplayMaxLuminance=1400.000000
FoliageInteractionDistance=1.000000
FoliageInteractionDistanceLimit=1.000000
FoliageInteractionQuantityLimit=1.000000
bFPVClimbingGear=False
bFPVGlidingGear=False
bHasInitializedScreenPercentage=False
MaxLastDeathMark=5
bSaveLastDeathMark=True
bShowPingsOnMap=True
bShowDinosOnMap=True
bShowWaypointsOnMap=True
bShowPlayersOnMap=True
bShowBedsOnMap=True
AimAssistStrengthMultiplier=1.000000
bForceShowRadialWheelTexts=False
bHideStructurePlacementCrosshair=False
SavedMainMapZoom=1.000000
SavedOverlayMapZoom=1.000000
bMinimalUI=False
FloatingTooltipStructureMode=DEFAULT
FloatingTooltipDinoMode=DEFAULT
FloatingTooltipDroppedItemsMode=DEFAULT
FloatingTooltipPlayerMode=DEFAULT
TopNotificationMode=DEFAULT
ItemNotificationMode=MINIMAL
bMinimapOverlayUseLowOpacity=False
FilterTypeInventoryLocal=9
FilterTypeInventoryRemote=9
bUseGamepadAimAssist=RangeWeaponAlwaysOn
Gamma1=2.200000
Gamma2=3.000000
bDisableBloom=False
bDisableLightShafts=False
bUseLowQualityLevelStreaming=True
bUseDistanceFieldAmbientOcclusion=False
bPreventItemCraftingSounds=False
bHighQualityAnisotropicFiltering=False
AmbientSoundVolume=1.000000
bUseOldThirdPersonCameraTrace=False
bUseOldThirdPersonCameraOffset=False
bShowedGenesisDLCBackground=False
bShowedGenesis2DLCBackground=False
bHasStartedTheGameOnce=False
bViewedAnimatedSeriesTrailer=False
bViewedARK2Trailer=False
bShowRTSKeyBinds=True
bHasCompletedGen2=False
bEnableFootstepDecals=True
bEnableFootstepParticles=True
bShowInfoButtons=True
bDisablePaintings=False
StopExplorerNoteAudioOnClose=False
bVibration=True
bUIVibration=False
radialSelectionSpeed=0.650000
bDisableVirtualCursor=False
PreventDetailGraphics=False
GroundClutterRadius=0
HFSQuality=0
bMenuGyro=False
gyroSensitivity=0.500000
virtualCursorSensitivity=0.500000
BubbleParticlesMultiplier=1.000000
CrosshairScale=1.000000
CrosshairOpacity=1.000000
CrosshairColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000)
CrosshairColorPickerValue=(X=0.000000,Y=0.000000)
CrosshairColorOverEnemy=(R=0.000000,G=0.376471,B=1.000000,A=1.000000)
CrosshairColorPickerValueOverEnemy=(X=0.010000,Y=0.500000)
CrosshairColorOverAlly=(R=0.000000,G=1.000000,B=0.000000,A=1.000000)
CrosshairColorPickerValueOverAlly=(X=0.260000,Y=0.440000)
CrosshairColorHitmark=(R=1.000000,G=0.000000,B=0.000000,A=1.000000)
CrosshairColorPickerValueHitmark=(X=0.010000,Y=0.640000)
CurrentCameraModeIndex=2
CurrentDinoCameraModeIndex=1
bShowAmbientInsectsVFX=True
TextChatFilterType=0
VoiceChatFilterType=0
bAutomaticallyCreateWaypointOnTamingCreatures=True
bAutomaticallyCreatePOIOnDeath=True
bEnableDLSS=False
bEnableDLFG=False
bEnableReflex=True
SuperResolutionQualityLevel=0
bOCIOIsEnabled=True
OCIOAsset=/Game/ASA/Environment/Common/Color/OCIO_aces_v13_cg.OCIO_aces_v13_cg
OCIOColorSpace=0
OCIODisplayView=0
bUseVSync=False
bUseDynamicResolution=False
ResolutionSizeX=1280
ResolutionSizeY=720
LastUserConfirmedResolutionSizeX=1280
LastUserConfirmedResolutionSizeY=720
WindowPosX=-1
WindowPosY=-1
FullscreenMode=1
LastConfirmedFullscreenMode=1
PreferredFullscreenMode=1
Version=5
AudioQualityLevel=0
LastConfirmedAudioQualityLevel=0
FrameRateLimit=60.000000
DesiredScreenWidth=1280
DesiredScreenHeight=720
LastUserConfirmedDesiredScreenWidth=1280
LastUserConfirmedDesiredScreenHeight=720
LastRecommendedScreenWidth=-1.000000
LastRecommendedScreenHeight=-1.000000
LastCPUBenchmarkResult=-1.000000
LastGPUBenchmarkResult=-1.000000
LastGPUBenchmarkMultiplier=1.000000
bUseHDRDisplayOutput=False
HDRDisplayOutputNits=1000
[/Script/Engine.GameUserSettings]
bUseDesiredScreenHeight=False
Again, paste that in then quite, and save: [Ctrl]+'x'
then 'y'
to save and [Enter]
to confirm.
While we’re at the command line, there’s 1 more thing we should probably verify and that’s that our asa
user owns all the files it should. From /opt/docker/asa
, type in ls -la
. The ‘LS’ command will list all files. The ‘-L’ flag tells it to give us a list showing permissions and owner info. The ‘A’ flag shows hidden files too. That ls -la
should look something like this:
If your files or folders say they’re owned by root, we’ll need to fix that:
chown asa:asa *
That tells it to CHange OWNer to the user:group asa.
All that’s left is to restart the container back in Dockge:
Pressing the [Restart] button will force it to reload from our freshly-updated INI files.
Give it a few minutes to start back up, then check the game again. If you’re still having a hard time finding the server, make sure all your filter settings are set correctly: We don’t need to hide full; we need show show password protected servers since we have a password; this isn’t PC-only; and most importantly we want to show Player Servers.