Introduction
For self-hosters looking to detach from big cloud providers (like AWS or Google Cloud), hosting your own S3-compatible object storage is a critical step. It allows you to use standard tools (like Rclone, S3Drive, or Nextcloud External Storage) while keeping data on your own VPS.
This guide details the installation of Zenko CloudServer using Docker Compose. It documents the specific configuration required to ensure data persistence and the solutions to common error logs encountered during the setup process.
Prerequisites
- A Linux VPS or local server (e.g., Debian/Ubuntu).
- Docker and Docker Compose installed.
- A basic understanding of command-line operations.
The Configuration (Docker Compose)
We utilise docker-compose rather than a single docker run command. This ensures that configuration is reproducible and, most importantly, that data persists across container restarts.
1. Directory Structure
Create a dedicated folder to keep the project organised. We need two subfolders to map the data from inside the container to the host machine.
mkdir zenko-s3
cd zenko-s3
mkdir data metadata
2. The docker-compose.yml File
Create a file named docker-compose.yml. Below is the final, working configuration resulting from our testing.
Key Changes from Defaults:
- Persistence: We map
./dataand./metadatato prevent data loss on restart. - Endpoint: We define the domain name to ensure generated URLs are correct.
- Remote Management: We explicitly disable Zenko's "phone home" feature to prevent DNS errors.
<!-- end list -->
version: '3.7'
services:
cloudserver:
image: zenko/cloudserver:latest
container_name: zenko-cloudserver
ports:
# Map container port 8000 to host port 8000
- "8000:8000"
environment:
# Security: Change these to strong, random strings
- SCALITY_ACCESS_KEY_ID=my_access_key_kalvin
- SCALITY_SECRET_ACCESS_KEY=my_secret_key_0x58c
# Configuration:
# 1. ENDPOINT: Essential if accessing via a domain (e.g., s3.nulu.my)
- ENDPOINT=s3.nulu.my
# 2. REMOTE_MANAGEMENT_DISABLE: Essential for self-hosting.
# Without this, the server panics trying to contact api.zenko.io
- REMOTE_MANAGEMENT_DISABLE=1
volumes:
# Persistence: Maps host folders to container folders
- ./data:/usr/src/app/localData
- ./metadata:/usr/src/app/localMetadata
restart: unless-stopped
Troubleshooting & "Gotchas"
During the deployment, we encountered specific behaviours that might look like errors but are either solvable or safe to ignore.
1. The "Phone Home" Error (Solved)
Symptom: The container logs show repeated errors:
getaddrinfo EAI_AGAIN api.zenko.io and could not issue token.
Cause: The default image tries to connect to Zenko's cloud dashboard (Orbit). On a private VPS, this connection often fails or is unwanted.
Solution: Add the environment variable REMOTE_MANAGEMENT_DISABLE=1 to the Compose file.
2. The ioctl / Synchronization Warning (Ignored)
Symptom: Logs display a large red warning:
WARNING: Synchronization directory updates are not supported on this platform... Cannot find module 'ioctl'
Cause: The container tries to use a specific system call to force-write data to the disk hardware, which is often not available in virtualised Docker environments.
Analysis: For a standard self-hosted setup, the standard file writing fallback is sufficient.
Action: Safe to ignore.
3. The "Access Denied" XML Error (Clarified)
Symptom: Visiting https://s3.nulu.my/ in a web browser results in:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
</Error>
Cause: This is not a malfunction. Browsers attempt to access the root of the server anonymously. Since S3 is a secure protocol, listing buckets requires authentication (Access Key/Secret Key).
Action: This confirms the server is online and secure. To access data, use a dedicated S3 client (see below).
How to Connect (Client Setup)
To use the storage, you must use an S3-compatible client.
Recommended Clients:
- Desktop: Cyberduck or WinSCP.
- Mobile (Android): S3Drive (Freemium model).
- CLI: AWS CLI or MinIO Client (
mc).
Connection Details:
- Server/Endpoint:
s3.nulu.my(or your IP address) - Port:
443(if using HTTPS/Reverse Proxy) or8000(if direct IP) - Region:
us-east-1(Default for compatibility) - Access Key: (Your configured ID)
- Secret Key: (Your configured Secret)
Verified by Kalvin (kalvin0x58c) on a YunoHost/Docker hybrid environment.