Hello!
I have a Docker file with Shopify app and globally installed NPM Shopify CLI package version 3.76.2:
FROM php:8.2-fpm
RUN apt-get update
# Install required extensions
RUN apt-get install -y \
procps \
xdg-utils \
curl \
git \
libicu-dev \
libzip-dev \
libmcrypt-dev \
libpq-dev \
libjpeg-dev \
libpng-dev \
libgd-dev
# Install PHP extensions
RUN docker-php-ext-install \
intl \
zip \
pdo_pgsql \
gd \
bcmath \
pdo_mysql
# Install PHP PECL extensions
RUN pecl install mcrypt-1.0.6 && docker-php-ext-enable mcrypt \
&& pecl install xdebug-3.3.1 && docker-php-ext-enable xdebug
ARG USER_ID=1000
ARG GROUP_ID=1000
# Create user inside dockerc
RUN groupadd -g ${GROUP_ID} _user && useradd -u ${USER_ID} -g _user -m _user
RUN chown -R _user:_user /var/www/html
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
USER _user
ARG NODE_VERSION=20.17.0
# Install Node.js v15
ENV NODE_VERSION=${NODE_VERSION}
ENV NVM_DIR=/home/_user/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \
&& . ${NVM_DIR}/nvm.sh \
&& nvm install ${NODE_VERSION} \
&& nvm alias default ${NODE_VERSION} \
&& nvm use default \
&& echo 'export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm' >> ~/.bashrc
ENV PATH="${NVM_DIR}/versions/node/v${NODE_VERSION}/bin:${PATH}"
ARG SHOPIFY_CLI_VERSION=3.75.0
RUN npm install -g \
@shopify/cli@${SHOPIFY_CLI_VERSION} \
@shopify/plugin-cloudflare@${SHOPIFY_CLI_VERSION}
ENV CODESPACES=1
# Set working directory
WORKDIR /var/www/html
# Expose ports 9000, 9003, 3457
EXPOSE 9000
EXPOSE 9003
EXPOSE 3457
# Start PHP-FPM
CMD ["php-fpm", "—nodaemonize"]
I use it to build the app service in the Docker Compose project. Here is the relevant section of the docker-compose.yml
file:
services:
app:
build:
context: ./.docker/php
dockerfile: Dockerfile
args:
NODE_VERSION: 20.17.0
SHOPIFY_CLI_VERSION: 3.76.2
volumes:
- ./:/var/www/html
- ./.docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
- ./.docker/php/php.ini-development:/usr/local/etc/php/php.ini
ports:
- "9003:9003"
- "${SHOPIFY_GRAPHQL_PORT:-3457}:3457"
networks:
- default
privileged: true
extra_hosts:
- host.docker.internal:host-gateway
Inside the app service container, I call the command to debug the Shopify app:
shopify app dev
This command should open the Cloudflare tunnel and this works fine for macOS and Windows, but on Linux the command results in an error:
With --verbose
(shopify app dev --verbose
):
2025-03-12T10:51:41.435Z: Random port obtained: 59803
2025-03-12T10:51:41.937Z: Polling tunnel status for cloudflare (attempt 1): starting
2025-03-12T10:51:42.438Z: Polling tunnel status for cloudflare (attempt 2): starting
2025-03-12T10:51:42.939Z: Polling tunnel status for cloudflare (attempt 3): starting
...
2025-03-12T10:51:55.733Z: failed to request quick Tunnel: Post "https://api.trycloudflare.com/tunnel": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
2025-03-12T10:51:55.736Z: Cloudflare tunnel crashed: Command failed with exit code 1: /home/_user/.nvm/versions/node/v20.17.0/lib/node_modules/@shopify/cli/bin/cloudflared tunnel --url http://localhost:55421 --no-autoupdate
2025-03-12T10:51:40Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
2025-03-12T10:51:40Z INF Requesting new quick Tunnel on trycloudflare.com...
failed to request quick Tunnel: Post "https://api.trycloudflare.com/tunnel": context deadline exceeded (Client.Timeout exceeded while awaiting headers), restarting...
...
2025-03-12T10:52:20.048Z: Polling tunnel status for cloudflare (attempt 77): starting
2025-03-12T10:52:20.550Z: Polling tunnel status for cloudflare (attempt 78): starting
2025-03-12T10:52:20.721Z: Killing process 406: /home/_user/.nvm/versions/node/v20.17.0/lib/node_modules/@shopify/cli/bin/cloudflared tunnel --url http://localhost:55421 --no-autoupdate
2025-03-12T10:52:21.051Z: Polling tunnel status for cloudflare (attempt 79): error
I guessed that it might be about using AppArmor on a Linux host. So I did the following:
- Created a shopify-cli-cloudflare-profile using ChatGPT (I’m not sure of its contents):
#include <tunables/global>
profile shopify-cli-cloudflare-profile flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
# Allow reading and writing to /tmp
/tmp/** rw,
# Allow access to files in /var/www/html (if necessary)
/var/www/html/** rw,
# Allow access to device /dev/null
/dev/null rw,
# Block access to critical files
deny /etc/shadow r,
deny /root/** rwk,
}
- Loaded the AppArmor profile:
sudo apparmor_parser -r shopify-cli-cloudflare-profile
- Modified
docker-compose.yml
as follows:
services:
app:
build:
context: ./.docker/php
dockerfile: Dockerfile
args:
NODE_VERSION: 20.17.0
SHOPIFY_CLI_VERSION: 3.76.2
volumes:
- ./:/var/www/html
- ./.docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
- ./.docker/php/php.ini-development:/usr/local/etc/php/php.ini
network_mode: host
security_opt:
- apparmor=shopify-cli-cloudflare-profile
privileged: true
extra_hosts:
- host.docker.internal:host-gateway
- I am using Docker Desktop, so I enabled the Enable host networking option in Settings → Resources → Network.
But this approach also failed. Cloudflare tunnel from Docker container on Linux host cannot be opened. Could you please tell me what could be the problem?