Skip to main content

How to Make Zenko CloudServer Buckets Public (The Host CLI Method)

If you are self-hosting Zenko CloudServer (S3-compatible storage) using Docker, you will likely encounter an AccessDenied XML error when trying to view your files via a browser. This is because S3 buckets are private by default.

While it is possible to configure this inside the container, I have learnt that the most efficient method is to run the AWS CLI directly from the VPS host, pointing it at the specific port mapped to the container.

The Problem

You upload a file (e.g., via S3Drive or a script), but when you visit the public URL, you receive this error:

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
...
</Error>

The Solution: Host-Based AWS CLI

Instead of installing temporary tools inside the Docker container, we will use the AWS CLI installed on the host server (the VPS itself). We will bypass the Nginx reverse proxy and speak directly to the container's "Host Port" to apply the permissions.

Prerequisites

  • Root access to the VPS (obulou.org).
  • Zenko CloudServer running in Docker.
  • aws-cli installed on the host system (apt install awscli).

Step 1: Confirm the Host Port

It is crucial to distinguish between the Internal Port (8000) and the Host Port.

Run this command to check your mapping:

docker ps | grep zenko

Understanding the Output: You will likely see: 0.0.0.0:59573->8000/tcp.

  • 8000 (Internal): This is hardcoded inside the Zenko software. The container always thinks it is listening on 8000.
  • 59573 (Host): This is the port we manually pinned in our Docker Compose setup. It is the "doorway" on the VPS that leads to the container.

Key Takeaway: When running administration commands from the VPS terminal, we always use the Host Port (59573), not the internal one.

Step 2: Disable "Block Public Access"

Zenko often blocks public policies by default. We must disable this safety lock first.

Replace YOUR-BUCKET-NAME with your actual bucket (e.g., one-bucket-wiki-obulou-org).

aws s3api put-public-access-block \
    --bucket YOUR-BUCKET-NAME \
    --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false" \
    --endpoint-url http://localhost:59573

Step 3: Create the Public Policy

Create a file named public.json on your server. This policy grants s3:GetObject (read-only access) to anyone (*).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
    }
  ]
}

Note: Ensure the Resource string ends with /* to cover all files in the bucket.

Step 4: Apply the Policy

Push the policy file to the Zenko instance using the host port.

aws s3api put-bucket-policy \
    --bucket YOUR-BUCKET-NAME \
    --policy file://public.json \
    --endpoint-url http://localhost:59573

Verification

Your files should now be public!

Because we have a reverse proxy (Nginx) listening on standard web ports, users can simply visit: http://s3.obulou.org/YOUR-BUCKET-NAME/image.png


Clarification: Why Port 59573?

In our specific Docker setup, we avoided port conflicts by mapping a unique external port to the standard internal S3 port.

  • Traffic Flow: User (Internet) → Nginx (Port 80/443) → Host Port (59573) → Container Port (8000).
  • Administration Flow: You (VPS Terminal) → Host Port (59573) → Container Port (8000).

We use localhost:59573 in the CLI commands because we are bypassing the Nginx layer and talking directly to the Docker container's exposed interface on the server.