0

I'm playing around learning Docker and Swoole. Running a Docker container that contains 2 files and an empty directory. Upon accessing the HTTP server in browser, the image is not displayed (getting the broken image icon).

I've already tried a PNG from an external webpage, that image was displayed properly. I've also tried "docker run -it hello-swoole sh" and confirmed the container displays

data  index.php  image.png

Dockerfile

FROM php:7.2-fpm

RUN apt-get update && apt-get install vim -y && \
    apt-get install openssl -y && \
    apt-get install libssl-dev -y && \
    apt-get install wget -y 

RUN cd /tmp && wget https://pecl.php.net/get/swoole-4.2.9.tgz && \
    tar zxvf swoole-4.2.9.tgz && \
    cd swoole-4.2.9  && \
    phpize  && \
    ./configure  --enable-openssl && \
    make && make install

RUN touch /usr/local/etc/php/conf.d/swoole.ini && \
    echo 'extension=swoole.so' > /usr/local/etc/php/conf.d/swoole.ini

RUN mkdir -p /app/data

WORKDIR /app

COPY ./app /app

EXPOSE 8101
CMD ["/usr/local/bin/php", "/app/index.php"]

index.php

<?php
$http = new swoole_http_server("0.0.0.0", 8101);

$http->on("start", function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:8101\n";
});

$http->on("request", function ($request, $response) {
    $response->header("Content-Type", "text/html; charset=utf-8");
    $response->end('<!DOCTYPE html><html lang="en"><body><img src="image.png"></body></html>');
});

$http->start();

Any idea why image.png isn't being displayed?

Update The following works to display the image, but then none of the HTML is displayed. Have a feeling Edward's answer is on the right track here & I'm not handling all the requests properly yet. Fairly certain now the question is more of a Swoole question than Docker question.

<?php
$http = new swoole_http_server("0.0.0.0", 8101);

$http->on("start", function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:8101\n";
});

$http->on("request", function ($request, $response) {
    $response->header('Content-Type', 'image/png');
    $response->sendfile('image.png'); // code seems to stop executing here
    $response->header("Content-Type", "text/html; charset=utf-8");
    $response->end('<!DOCTYPE html><html lang="en"><body><img src="/image.png"></body></html>');
});

$http->start();
Garrett Burke
  • 123
  • 2
  • 9
  • When you're confirming the image is there with this command `docker run -it hello-swoole sh` did you pull this container https://hub.docker.com/r/cinctree/hello-swoole? Your Docker file and hello-swoole are two seperate containers. I'd try coping a file into your PHP container from your host. `COPY ./local.png /app/container.png` See if you can inject an image with a copy command – Lex Aug 23 '19 at 04:07
  • I built the container with the command `docker build -f ./Dockerfile -t hello-swoole .` I tried using a different tag besides hello-swoole, for example ran `docker build -f ./Dockerfile -t garrett .` then ran `docker run -it garrett sh` and `dir` still displayed `data index.php image.png` – Garrett Burke Aug 23 '19 at 04:27
  • Interesting, but good to clarify. Sounds like your Docker file is built correctly. Could it be a path issue with the img tag ``. Does `` Work? Whats the absolute path, does including that before the image work? – Lex Aug 23 '19 at 04:32
  • No dice for `` and `` ... thinking Edward may be on to something. – Garrett Burke Aug 23 '19 at 04:44
  • Hmm yea could be actually. In the above PHP we're setting Content-Type text/html. That example script is setting the content type dynamically based on content. `$response->header('Content-Type', $static[$type]);`... I don't know enough about Swoole, perhaps it needs coercing. – Lex Aug 23 '19 at 05:07
  • 1
    See my answer below, figured it out! – Garrett Burke Aug 23 '19 at 05:33

2 Answers2

1

I managed to find the answer here: https://www.swoole.co.uk/docs/modules/swoole-http-server/configuration ...

Just needed to add:

$http->set([
    'document_root' => '/app',
    'enable_static_handler' => true,
]);

Full Updated Code

<?php
$http = new swoole_http_server("0.0.0.0", 8101);

$http->set([
    'document_root' => '/app',
    'enable_static_handler' => true,
]);

$http->on("start", function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:8101\n";
});

$http->on("request", function ($request, $response) {
    $response->header("Content-Type", "text/html; charset=utf-8");
    $response->end('<!DOCTYPE html><html lang="en"><body><img src="image.png" height="200"></body></html>');
});

$http->start();
Garrett Burke
  • 123
  • 2
  • 9
0

I would assume you have to also program the server to serve the static files.

Example here

Edward
  • 716
  • 5
  • 6