Dockerfile not enabling autoptimize - docker

Im pulling a wordpress image and everything is working fine but when I go to the wordpress editor page the following error is on the top of screen.
Autoptimize cannot write to the cache directory (/var/www/html/wp-content/cache/autoptimize/), please fix to enable CSS/ JS optimization!
I assumed RUN chown -R www-data:www-data wp-content/ would solve that issue but its not working. Any ideas would be appreciated. My Dockerfile is below.
FROM wordpress:4.9.2-php7.2-apache
RUN chown -R www-data:www-data wp-content/
COPY ./src /var/www/html/
# Install the new entry-point script
COPY secrets-entrypoint.sh /secrets-entrypoint.sh
RUN chmod +x /secrets-entrypoint.sh
ENTRYPOINT ["/secrets-entrypoint.sh"]
EXPOSE 80
CMD ["apache2-foreground"]

I'm not sure the exact permission but you don't want to be writing inside a container so you should define a volume. Since you don't need the data to persist, you can do this in your dockerfile like:
VOLUME /var/www/html/wp-content/cache
This will set up a default volume where Docker will choose the location on your host, but you can mount it to a named volume instead when the container is created if you like.
You could also use a tmpfs volume which is good for things like cache files.

Related

How to mount NextJS cache in Docker

Does anyone know a way to mount a Next cache in Docker?
I thought this would be relatively simple. I found buildkit had a cache mount feature and tried to add it to my Dockerfile.
COPY --chown=node:node . /code
RUN --mount=type=cache,target=/code/.next/cache npm run build
However I found that I couldn't write to the cache as node.
Type error: Could not write file '/code/.next/cache/.tsbuildinfo': EACCES: permission denied, open '/code/.next/cache/.tsbuildinfo'.
Apparently you need root permissions for using the buildkit cache mount. This is an issue because I cannot build Next as root.
My workaround was to make a cache somewhere else, and then copy the files to and from the .next/cache. For some reason the cp command does not work in docker(as node, you get a permission error and as root you get no error, but it still doesn't work.) I eventually came up with this:
# syntax=docker/dockerfile:1.3
FROM node:16.15-alpine3.15 AS nextcache
#create cache and mount it
RUN --mount=type=cache,id=nxt,target=/tmp/cache \
mkdir -p /tmp/cache && chown node:node /tmp/cache
FROM node:16.15-alpine3.15 as builder
USER node
#many lines later
# Build next
COPY --chown=node:node . /code
#copy mounted cache into actual cache
COPY --chown=node:node --from=nextcache /tmp/cache /code/.next/cache
RUN npm run build
FROM builder as nextcachemount
USER root
#update mounted cache
RUN mkdir -p tmp/cache
COPY --from=builder /code/.next/cache /tmp/cache
RUN --mount=type=cache,id=nxt,target=/tmp/cache \
cp -R /code/.next/cache /tmp
I managed to store something inside the mounted cache, but I have not noticed any performance boosts.(I am trying to implement this mounted cache for Next in order to save time every build. Right now, the build next step takes ~160 seconds, and I'm hoping to bring that down a bit.)
If you are using the node user in a node official image, which happens to have uid=1000 and the same gid, I think you should specify that when mounting the cache so that you have permission to write on it:
RUN --mount=type=cache,target=/code/.next/cache,uid=1000,gid=1000 npm run build

Setup different user permissions on files copied in Dockerfile

I have this Dockerfile setup:
FROM node:14.5-buster-slim AS base
WORKDIR /app
FROM base AS production
ENV NODE_ENV=production
RUN chown -R node:node /app
RUN chmod 755 /app
USER node
... other copies
COPY ./scripts/startup-production.sh ./
COPY ./scripts/healthz.sh ./
CMD ["./startup-production.sh"]
The problem I'm facing is that I can't execute ./healthz.sh because it's only executable by the node user. When I commented out the two RUN and the USER commands, I could execute the file just fine. But I want to enforce the executable permissions only to the node for security reasons.
I need the ./healthz.sh to be externally executable by Kubernetes' liveness & rediness probes.
How can I make it so? Folder restructuring or stuff like that are fine with me.
In most cases, you probably want your code to be owned by root, but to be world-readable, and for scripts be world-executable. The Dockerfile COPY directive will copy in a file with its existing permissions from the host system (hidden in the list of bullet points at the end is a note that a file "is copied individually along with its metadata"). So the easiest way to approach this is to make sure the script has the right permissions on the host system:
# mode 0755 is readable and executable by everyone but only writable by owner
chmod 0755 healthz.sh
git commit -am 'make healthz script executable'
Then you can just COPY it in, without any special setup.
# Do not RUN chown or chmod; just
WORKDIR /app
COPY ./scripts/healthz.sh .
# Then when launching the container, specify
USER node
CMD ["./startup-production.sh"]
You should be able to verify this locally by running your container and manually invoking the health-check script
docker run -d --name app the-image
# possibly with a `docker exec -u` option to specify a different user
docker exec app /app/healthz.sh && echo OK
The important thing to check is that the file is world-executable. You can also double-check this by looking at the built container
docker run --rm the-image ls -l /app/healthz.sh
That should print out one line, starting with a permission string -rwxr-xr-x; the last three r-x are the important part. If you can't get the permissions right another way, you can also fix them up in your image build
COPY ./scripts/healthz.sh .
# If you can't make the permissions on the original file right:
RUN chmod 0755 *.sh
You need to modify user Dockerfile CMD command like this : ["sh", "./startup-production.sh"]
This will interpret the script as sh, but it can be dangerous if your script is using bash specific features like [[]] with #!/bin/bash as its first line.
Moreover I would say use ENTRYPOINT here instead of CMD if you want this to run whenever container is up

No file found when using ENTRYPOINT

I am trying to use ENTRYPOINT and whenever I do that I am getting an error as no such file or directory
Dockerfile:
FROM ubuntu:18.04
COPY . /home
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s /usr/local/bin/docker-entrypoint.sh
WORKDIR /home
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/bin/bash"]
I have tried giving it permission, tried running it with absolute path also tried this, tried it with #!/bin/bash & #!/bin/sh and in the end, I still get the file not found error.
I am not sure what the problem is.
The question you asked:
I don't remember exactly why, but the file isn't being found because you're calling it docker-entrypoint.sh rather than ./docker-entrypoint.sh.
The question you'll ask soon:
That doesn't entirely fix your problem. You've added execute privileges to the copy of docker-entrypoint.sh in /usr/local/bin, but there's another copy of the file in /home that gets found first and doesn't have execute privileges. You'll get a permissions error when you try to use it. An easy workaround (depending on what you want to do) consists of a modified entrypoint:
ENTRYPOINT ["/bin/bash", "docker-entrypoint.sh"]
Extra details if you'll be using Docker a lot:
Being able to enter a container or image to examine its contents is invaluable. For ubuntu-based images, write down the following line somewhere (replace bash with sh for basically every other linux OS):
docker run -it --rm --entrypoint=bash my_image_name
This will open up a shell in that image and let you play around in the same environment the Dockerfile is running in and debug whatever is causing you problems.

Docker ADD does not copy into the container

I have several files in a directory on the host machine which I am trying to copy to the container and also have some run commands inside my docker-compose.
The first set up until the crowd section stats woks fine, but anything from the crown jar down just fails and doesn't work. I tried to run the manial docker cp command to copy the files from host to the container and that works. Can someone please shed some light on this?
This is a part of my Dockerfile:
WORKDIR /usr/local/tomcat
USER root
COPY server.xml conf/server.xml
RUN chmod 660 conf/server.xml
USER root
ADD tomcat.keystore /usr/local/tomcat/
RUN chmod 644 tomcat.keystore
RUN chown root:staff /usr/local/tomcat/tomcat.keystore
ADD crowd-auth-filter-1.0.0.jar /usr/local/tomcat/webapps/guacamole/WEB-INF/lib/
ADD crowd-filter.properties /usr/local/tomcat/webapps/guacamole/WEB-INF/lib/
RUN chmod 644 crowd-filter.properties
ADD web.xml /usr/local/tomcat/webapps/guacamole/WEB-INF/
RUN /usr/local/tomcat/bin/shutdown.sh
RUN /usr/local/tomcat/bin/startup.sh
Thanks

Create files / folders on docker-compose build or docker-compose up

I'm trying my first steps into Docker, so I tried making a Dockerfile that creates a simple index.html and a directory images (See code below)
Then I run docker-compose build to create the image, and docker-compose-up to run the server. But I get no file index.html or folder images.
This is my Dockerfile:
FROM php:apache
MAINTAINER brent#dropsolid.com
WORKDIR /var/www/html
RUN touch index.html \
&& mkdir images
And this is my docker-compose.yml
version: '2'
services:
web:
build: .docker/web
ports:
- "80:80"
volumes:
- ./docroot:/var/www/html
I would expect that this would create a docroot folder with an image directory and an index.html, but I only get the docroot.
The image does contain those files
The Dockerfile contains instructions on how to build an image. The image you built from that Dockerfile does contain index.html and images/.
But, you over-rode them in the container
At runtime, you created a container from the image you built. In that container, you mounted the external directory ./docroot as /var/www/html.
A mount will hide whatever was at that path before, so this mount will hide the prior contents of /var/www/html, replacing them with whatever is in ./docroot.
Putting stuff in your mount
In the comments you asked
is there a possibility then to first mount and then create files or something? Or is that impossible?
The way you have done things, you mounted over your original files, so they are no longer accessible once the container is created.
There are a couple of ways you can handle this.
Change their path in the image
If you put these files in a different path in your image, then they will not be overwritten by the mount.
WORKDIR /var/www/alternate-html
RUN touch index.html \
&& mkdir images
WORKDIR /var/www/html
Now, at runtime you will still have this mount at /var/www/html, which will contain the contents from the external directory. Which may or may not be an empty directory. You can tell the container on startup to run a script and copy things there, if that's what you want.
COPY entrypoint.sh /entrypoint.sh
RUN chmod 0755 /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
(This is assuming you do not have a defined entrypoint - if you do, you'll maybe just need to adjust your existing script instead.)
entrypoint.sh:
#!/bin/sh
cp -r /var/www/alternate-html/* /var/www/html
exec "$#"
This will run the cp command, and then hand control over to whatever the CMD for this image is.
Handling it externally
You also have the option of simply pre-populating the files you want into ./docroot externally. Then they will just be there when the container starts and adds the directory mount.

Resources