You can expose GCP Cloud Storage via an FTP gateway, but it’s not a direct, native feature. Instead, you’ll be setting up a separate service that acts as an FTP server and translates FTP commands into Cloud Storage API calls.

Let’s see this in action. Imagine you have a bucket named my-ftp-bucket in GCP. You want to allow an external application to upload files via FTP. You’d deploy an FTP gateway service (we’ll use a hypothetical one called gcs-ftp-gateway for this example) that’s configured with your GCP credentials and the bucket name.

Here’s a conceptual snippet of how you might configure such a gateway (this is illustrative, actual syntax will vary by the gateway software):

# gcs-ftp-gateway.yaml
gcp:
  credentials_file: /path/to/your/gcp-key.json
  project_id: your-gcp-project-id

ftp:
  listen_address: 0.0.0.0
  port: 21
  anonymous_access: false
  users:
    - username: ftpuser
      password: "supersecretpassword"
      storage_path: gs://my-ftp-bucket/incoming/  # Files uploaded here will land in this GCS prefix

cloud_storage:
  bucket: my-ftp-bucket
  # Optional: map FTP directories to GCS prefixes
  directory_mapping:
    /upload: gs://my-ftp-bucket/uploads/
    /logs: gs://my-ftp-bucket/archive/logs/

When an FTP client connects to the gateway’s IP address on port 21 and logs in as ftpuser, the gateway intercepts the PUT command. If the client uploads data.csv to /upload, the gateway translates this into a Cloud Storage API call to upload data.csv to gs://my-ftp-bucket/uploads/ in your bucket. Similarly, a GET command for /logs/archive.tar.gz would trigger a Cloud Storage GET object operation for gs://my-ftp-bucket/archive/logs/archive.tar.gz.

The core problem this solves is bridging the gap between legacy applications that only speak FTP and modern cloud object storage like Cloud Storage. Many older systems or third-party tools are hardcoded to use FTP/SFTP and can’t be easily reconfigured to use object storage APIs directly. An FTP gateway provides a compatibility layer.

Internally, these gateways typically work by:

  1. Authenticating FTP clients: Using standard FTP username/password or sometimes FTPS/SFTP credentials.
  2. Mapping FTP paths to GCS objects: A crucial part is how directory structures in FTP are translated into object names (keys) within a Cloud Storage bucket. Often, a root directory or specific FTP paths are configured to map to GCS bucket prefixes.
  3. Translating FTP commands to GCS API calls:
    • LIST or NLST commands trigger a gsutil ls or Cloud Storage Objects.list API call, often with a specified prefix.
    • GET commands trigger gsutil cp or Cloud Storage Objects.get API calls.
    • PUT commands trigger gsutil cp or Cloud Storage Objects.insert API calls.
    • MKD (make directory) might be a no-op if the gateway handles prefix creation implicitly, or it might create a zero-byte object at the "directory" path to make it appear in listings.
    • RMD (remove directory) would be more complex, potentially requiring recursive deletion of objects under a prefix.
  4. Managing state: FTP is a stateful protocol. The gateway needs to maintain connection state, current directory, and transfer progress for each client.

The primary lever you control is the configuration of the FTP gateway itself: the GCP credentials, the target bucket, and how FTP paths are mapped to Cloud Storage prefixes. You can also configure user accounts, permissions (though these are usually enforced by the gateway’s mapping logic rather than fine-grained IAM on the GCS side for FTP users), and security settings like FTPS.

One common point of confusion is how directory listings work. Cloud Storage doesn’t have true directories; it uses object names with delimiters (like /). When you LIST gs://my-ftp-bucket/uploads/, the gateway might list objects like uploads/file1.txt, uploads/subdir/file2.txt. The gateway’s LIST implementation needs to simulate directory structures by looking for common prefixes and listing them as directories if they contain other objects. This can sometimes lead to unexpected behavior if your object naming isn’t consistent.

Once you have your FTP gateway set up and correctly mapping to your Cloud Storage bucket, the next hurdle you’ll likely encounter is managing bandwidth and latency, as FTP is not optimized for high-throughput cloud object storage.

Want structured learning?

Take the full Ftp course →