Cloud Run lets you connect container instances to CIFS and SMB
network file shares so that you can read and write shared files. You can mount
shares in user space, instead of kernel space, by using `smbnetfs` or transfer
files by using `smbclient`.

For other storage options on Cloud Run, see how to configure NFS or
Filestore volumes for
[services](https://docs.cloud.google.com/run/docs/configuring/services/nfs-volume-mounts.md.txt),
[jobs](https://docs.cloud.google.com/run/docs/configuring/jobs/nfs-volume-mounts.md.txt),
[worker pools](https://docs.cloud.google.com/run/docs/configuring/workerpools/nfs-volume-mounts.md.txt), or
[instances](https://docs.cloud.google.com/run/docs/configuring/instances/nfs-volume-mounts.md.txt). You can
also configure Cloud Storage FUSE volumes for
[services](https://docs.cloud.google.com/run/docs/configuring/services/cloud-storage-volume-mounts.md.txt),
[jobs](https://docs.cloud.google.com/run/docs/configuring/jobs/cloud-storage-volume-mounts.md.txt),
[worker pools](https://docs.cloud.google.com/run/docs/configuring/workerpools/cloud-storage-volume-mounts.md.txt),
or [instances](https://docs.cloud.google.com/run/docs/configuring/instances/cloud-storage-volume-mounts.md.txt).

## Limitations

- You must specify the [second generation execution environment](https://docs.cloud.google.com/run/docs/configuring/execution-environments.md.txt) when using `smbnetfs`.

- Due to the Cloud Run execution environment restriction, CIFS/SMB can't be directly mounted inside Cloud Run. However, you can use SMB clients that don't rely on kernel mounting, like `smbnetfs` (FUSE-based) or `smbclient`.

- Cloud Run is designed to scale rapidly to a large number of
  instances. However, most network file systems are not designed for concurrent
  use by a large number of clients. For Cloud Run services, consider using the
  [maximum instances](https://docs.cloud.google.com/run/docs/configuring/max-instances.md.txt) feature to limit the
  number of Cloud Run instances.

## Using `smbnetfs`

`smbnetfs` is a FUSE-based file system that lets you mount SMB shares as part of
the local file system hierarchy.

To use `smbnetfs` with Cloud Run, update your Dockerfile to install `smbnetfs` and its dependencies, and configure credentials.

### Configure `smbnetfs` in Dockerfile

Add the following instructions to your Dockerfile:

> [!WARNING]
> **Warning:** For production environments, we recommended using Secret Manager to handle credentials securely. The following example places credentials directly in the Dockerfile for simplicity. For production use, mount secrets as files or environment variables. Learn more about [configuring secrets in Cloud Run](https://docs.cloud.google.com/run/docs/configuring/services/secrets.md.txt).

```docker
# Install smbnetfs, fuse and other dependencies
RUN apt-get update && apt-get install -y smbnetfs fuse && rm -rf /var/lib/apt/lists/*

# Setup smbnetfs configuration
RUN mkdir -p ~/.smb
# Check if files exist before copying, as strict locations might vary or be missing in minimal images
RUN [ -f /etc/smbnetfs.conf ] && cp /etc/smbnetfs.conf ~/.smb/ || echo "smbnetfs.conf not found"

# Create the auth file
# In production, use mechanisms like [Secret Manager](/run/docs/configuring/services/secrets) to handle credentials
# securely instead of placing them directly in the Dockerfile.
RUN echo 'auth "<smb-server-ip>" "<smb-username>" "<smb-password>"' > ~/.smb/smbnetfs.auth
RUN chmod 600 ~/.smb/smbnetfs.auth

# Create the host file
RUN echo 'host <smb-server-ip> visible=true' > ~/.smb/smbnetfs.host
RUN chmod 600 ~/.smb/smbnetfs.host

# Enable the includes in the main config if they exist
RUN if [ -f ~/.smb/smbnetfs.conf ]; then \
    sed -i 's/^#include "smbnetfs.auth"/include "smbnetfs.auth"/' ~/.smb/smbnetfs.conf && \
    sed -i 's/^#include "smbnetfs.host"/include "smbnetfs.host"/' ~/.smb/smbnetfs.conf; \
    fi
```

Replace `<smb-server-ip>`, `<smb-username>`, and `<smb-password>` with connection details for your SMB server.

### Mount the SMB share during container startup

Run smbnetfs to mount the share when your container starts and before your application starts. If your container runs as a non-root user, you might need to adjust permissions or FUSE configuration.

1. Create a mount point such as `/mnt/smb` as shown in the following command:

   ```bash
   mkdir /mnt/smb
   ```

   <br />

2. Mount the SMB file system by using the `smbnetfs` command:

   ```bash
   smbnetfs /mnt/smb
   ```

   <br />

3. Access your share under `/mnt/smb/<smb-server-ip>/<share-name>`, as shown in the following command:

   ```bash
   ls /mnt/smb/smb-server-ip/share-name
   ```

   <br />

### Troubleshooting

You might encounter input/output errors when writing to files using the `O_APPEND` flag with `smbnetfs`. Find more details in the [Stack Overflow discussion](https://stackoverflow.com/questions/73104395/smbnetfs-how-to-resolve-input-output-error-while-writing-file-to-windows-serve).

## Using smbclient

`smbclient` is a command-line tool that provides an FTP-like interface for accessing SMB shares. You can use it to transfer files or run commands on an SMB server.

- To avoid providing credentials with each command, you can store them in a file.

  > [!WARNING]
  > **Warning:** In production, ensure that this file is managed securely, for example, by injecting it during container startup using [Secret Manager](https://docs.cloud.google.com/run/docs/configuring/services/secrets.md.txt).

  1. Store your credentials in a file, for example, `smb-cred.txt`:

         username = <smb-username>
         password = <smb-password>

  2. As an alternative to a credentials file, you can provide credentials with each
     command using the `-U` or `--user` option, for example: `--user=[DOMAIN\]USERNAME[%PASSWORD]`.

  3. Use the `smbclient` tool with the `-A` flag to specify the credentials file. For example, to list files in a share, run the following command:

     ```bash
     smbclient //smb-server-ip/share-name -A smb-cred.txt -c 'ls'
     ```

     <br />

- To modify files with the smbclient tool, download the file, modify it locally, and then upload it back to the share as shown in the following steps.

  1. Download a file by running the get command:

     ```bash
     smbclient //smb-server-ip/share-name -A smb-cred.txt -c 'get remote local'
     ```

     <br />

  2. Modify your file locally.

  3. Upload the file after the modification by running the put command:

     ```bash
     smbclient //smb-server-ip/share-name -A smb-cred.txt -c 'put local remote'
     ```

     <br />

When you use the `smbclient` tool, the SMB server identifies you by using the credentials you provide. This lets the server apply the correct file permissions.
For a full list of `smbclient` commands, refer to the [official smbclient documentation](https://www.samba.org/samba/docs/current/man-html/smbclient.1.html).