IHP 1.3 is out now!

File uploads on IHP Cloud: Can't create folder

Lillo PRO


File uploads are failing for me and I am unsure of what the reason can be.

I get this error from sentry:

/tmp/ihp-upload-6de360a7d350dccc: createDirectory: does not exist (No such file or directory)

This is the function that uploads and generates the url.

createImageWithUrl :: (?context :: ControllerContext) => Maybe (FileInfo LByteString) -> IO Text
createImageWithUrl maybeFile = case maybeFile of
    Nothing ->
        error "No file uploaded"
    Just file -> do
        let options :: StoreFileOptions =
                    { directory = "avatars"
                    , preprocess = applyImageMagick "jpg" "-resize '512x512^' -gravity Center -extent 512x512 -quality 85% -strip"
        storedFile :: StoredFile <- storeFileWithOptions file options
        pure $ mkImageUrl (get #path storedFile)

It works in dev mode, and I have created the avatars folder in S3.

The environment variables are the exactly the same in dev and prod and I use initS3Storage in Config.js on IHP cloud with same settings.

Any idea what could cause this error?

marc PRO

Could you remove the preprocessor and check if it works then?

Lillo PRO

Yes, removed the preprocessor and now the upload was successful

Lillo PRO
Lillo PRO

Could this error be IHP Cloud related or is it a general bug in IHP?

My app is utilizing user contributed images from phone camera images, so the uploads can be quite big. I have some conserns because it could eat too much mobile data when browsing, and S3 cost would probably also be considerable bigger.

marc PRO

I guess the docker image of the IHP app is missing a /tmp directory, as nix by default doesn't create this when making docker images.

Then it fails here while trying to get a temp dir for processing the image. So the bug is very likely in IHP itself.

marc PRO

I've just deployed an update to IHP Cloud that creates an /tmp directory inside the app's docker container. Can you make a new deployment and let me know if the error is still happening?

Lillo PRO

One step further I think :) now it seems to complain about something with the imageMagicProcess:

/bin/sh: runCommand: posix_spawnp: does not exist (No such file or directory)
Lillo PRO

I made a custom preprocess function based on the applyImageMagick code, since it's the same thing I do for every image in my app. This was successful :)

resizeImage :: Text -> Wai.FileInfo LByteString -> IO (Wai.FileInfo LByteString)
resizeImage convertTo fileInfo = do
    Directory.createDirectoryIfMissing False "/tmp"
    Temp.withTempDirectory "/tmp" "ihp-upload" $ \tempPath -> do
        let tempFilePath = tempPath <> "/image"
        let convertedFilePath = tempPath <> "/converted." <> cs convertTo

            |> get #fileContent
            |> LBS.writeFile tempFilePath

        Process.readProcess "convert" [tempFilePath, "-resize", "512x512^", "-gravity", "Center", "-extent", "512x512", "-quality", "85%", "-strip", cs convertedFilePath] []

        newContent <- LBS.readFile convertedFilePath
        pure fileInfo { Wai.fileContent = newContent }

I used readProcess since that's one that I am a bit familiar with how works :)

marc PRO

I made a PR to fix this in IHP now as well :) https://github.com/digitallyinduced/ihp/pull/1382