Impossible to start Symfony 5 server on Docker container (symfony serve -d) - symfony

I trying to create Docker container to contenerized my Symfony 5 application.
I create first a Dockerfile
FROM php:7.4-fpm-alpine
# Update
RUN apk --no-cache update
RUN apk --no-cache add bash git
# Install Node
RUN apk --no-cache add --update nodejs npm
RUN apk --no-cache add --update python3
RUN apk --no-cache add --update make
RUN apk --no-cache add --update g++
# Install pdo
RUN docker-php-ext-install pdo_mysql
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Symfony CLI
RUN curl -sS https://get.symfony.com/cli/installer | bash && mv /root/.symfony/bin/symfony /usr/local/bin/symfony
# WORK DIR
COPY . /var/www/html
WORKDIR /var/www/html
RUN composer update
RUN composer install
RUN npm install
# Start Symfony server on Port 8000
EXPOSE 8000
RUN symfony serve -d
Then I created a docker-compose.yml file (where I simply redirect port 8000 of the container to port 8080 on my machine).
version: '3.8'
services:
php-fpm:
container_name: infolea
build: ./
ports:
- 8080:8000
volumes:
- ./:/var/www/html
Then, I build my image docker-compose build.
Then, I run my image docker-compose up -d.
On my browser, the localhost:8080 link doesn't display anything.
Then I restart the symfony server by typing symfony serve -d on the terminal of my container and on localhost:8080 I can see my application working.
Something is weard, is that when I verified if my server is not started yet on my docker container terminal, I got this :
docker container terminal
What i want, it's to start my Symfony server dirrectly, without retapping symfony serve -d.
How can i do it ?

Try using CMD istead of RUN
CMD ["/usr/local/bin/symfony", "local:server:start" , "--port=8000", "--no-tls"]
see https://docs.docker.com/engine/reference/builder/#cmd

Related

Generate Dev Certificate inside a docker image

I have a .NET application and I wish, in production, generate a dev certificate (self-signed).
Locally, to do this I use the following commands:
dotnet dev-certs https --clean
dotnet dev-certs https
dotnet dev-certs https --trust
So I tried 2 methods, but none seems to work.
I have search for the .pfx file into my "/root/.aspnet/https" (/data/socloze/web/keys/https in real, because of the volume mapping), but this folder does not exists.
Method 1 : Create the certificate at image build
In the DockerFile file, I have the following
### >>> GLOBALS
ARG ENVIRONMENT="Production"
ARG PROJECT="Mycorp.MyApp.Web"
### <<<
#--------------------------------------------------
# Build / Publish
#--------------------------------------------------
# debian buster - AMD64
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
### >>> IMPORTS
ARG ENVIRONMENT
ARG PROJECT
### <<<
ARG NUGET_CACHE=https://api.nuget.org/v3/index.json
ARG NUGET_FEED=https://api.nuget.org/v3/index.json
# Copy sources
COPY src/ /app/src
ADD common.props /app
WORKDIR /app
# Installs NodeJS to build typescripts
#RUN apt-get update -yq && apt-get upgrade -yq && apt-get install -yq curl git nano
#RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt-get install -yq nodejs build-essential
#RUN npm install -g npm
#RUN npm install
RUN apt-get update
RUN apt-get install curl
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get install -y nodejs
RUN npm install /app/src/MyCorp.Core.Blazor/
#RUN npm install -g parcel-bundler
# Installs the required dependencies on top of the base image
# Publish a self-contained image
RUN apt-get update && apt-get install -y libgdiplus libc6-dev && dotnet dev-certs https --clean && dotnet dev-certs https && dotnet dev-certs https --trust &&\
dotnet publish --self-contained --runtime linux-x64 -c Debug -o out src/${PROJECT};
#--------------------------------------------------
# Execute
#--------------------------------------------------
# Start a new image from aspnet runtime image
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS runtime
### >>> IMPORTS
ARG ENVIRONMENT
ARG PROJECT
### <<<
#ENV DOTNET_GENERATE_ASPNET_CERTIFICATE=true
ENV ASPNETCORE_ENVIRONMENT=${ENVIRONMENT}
ENV ASPNETCORE_URLS="http://+:80;https://+:443;https://+:44390"
#ENV ASPNETCORE_URLS="http://+:80"
ENV PROJECT="${PROJECT}.dll"
# Make logs a volume for persistence
VOLUME /app/Logs
# App directory
WORKDIR /app
# Copy our build from the previous stage in /app
COPY --from=build /app/out ./
RUN apt-get update && apt-get install -y ffmpeg libgdiplus libc6-dev
# Ports
EXPOSE 80
EXPOSE 443
EXPOSE 44390
# Execute
ENTRYPOINT dotnet ${PROJECT}
Method 2 : Create the certificate by using docker-compose
The other way, is to generate the certificate once the container start, in my myappstack.yaml I have the following:
version: '3.3'
services:
web:
image: registry.gitlab.com/mycorp/myapp/socloze.web:1.1.1040
command:
- sh -c "dotnet dev-certs https --clean"
- sh -c "dotnet dev-certs https"
- sh -c "dotnet dev-certs https --trust"
- sh -c "echo MYPASS | sudo -S -k update-ca-certificates"
volumes:
- keys-vol:/root/.aspnet
- logs-vol:/app/Logs
- sitemap-vol:/data/sitemap/
networks:
- haproxy-net
- socloze-net
configs:
-
source: socloze-web-conf
target: /app/appsettings.json
logging:
driver: json-file
deploy:
placement:
constraints:
- node.role == manager
networks:
haproxy-net:
external: true
socloze-net:
external: true
volumes:
keys-vol:
driver: local
driver_opts:
device: /data/socloze/web/keys
o: bind
type: none
logs-vol:
driver: local
driver_opts:
device: /data/socloze/web/logs
o: bind
type: none
sitemap-vol:
driver: local
driver_opts:
device: /data/sitemap
o: bind
type: none
configs:
socloze-web-conf:
external: true
But none seems to work. I know that the first method has already worked, but I can't make it work again.

Symfony 4 app works with Docker Compose but breaks with Docker Swarm (no login, profiler broken)

I'm using Docker Compose locally with:
app container: Nginx & PHP-FPM with a Symfony 4 app
PostgreSQL container
Redis container
It works great locally but when deployed to the development Docker Swarm cluster, I can't login to the Symfony app.
The Swarm stack is the same as local, except for PostgreSQL which is installed on its own server (not a Docker container).
Using the profiler, I nearly always get the following error:
Token not found
Token "2df1bb" was not found in the database.
When I display the content of the var/log/dev.log file, I get these lines about my login attempts:
[2019-07-22 10:11:14] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"http://dev.ip/public/login","method":"GET"} []
[2019-07-22 10:11:14] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2019-07-22 10:11:14] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2019-07-22 10:11:14] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2019-07-22 10:11:14] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
The only thing I may find useful here is the Guard authenticator does not support the request. message, but I have no idea what do search from there.
UPDATE:
Here is my docker-compose.dev.yml (removed redis container and changed app environment variables):
version: "3.7"
networks:
web:
driver: overlay
services:
# Symfony + Nginx
app:
image: "registry.gitlab.com/my-image"
deploy:
replicas: 2
restart_policy:
condition: on-failure
networks:
- web
ports:
- 80:80
environment:
APP_ENV: dev
DATABASE_URL: pgsql://user:pass#0.0.0.0/my-db
MAILER_URL: gmail://user#gmail.com:pass#localhost
Here is the Dockerfile.dev used to build the app image on development servers:
# Base image
FROM php:7.3-fpm-alpine
# Source code into:
WORKDIR /var/www/html
# Import Symfony + Composer
COPY --chown=www-data:www-data ./symfony .
COPY --from=composer /usr/bin/composer /usr/bin/composer
# Alpine Linux packages + PHP extensions
RUN apk update && apk add \
supervisor \
nginx \
bash \
postgresql-dev \
wget \
libzip-dev zip \
yarn \
npm \
&& apk --no-cache add pcre-dev ${PHPIZE_DEPS} \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pdo_pgsql \
&& docker-php-ext-configure zip --with-libzip \
&& docker-php-ext-install zip \
&& composer install \
--prefer-dist \
--no-interaction \
--no-progress \
&& yarn install \
&& npm rebuild node-sass \
&& yarn encore dev \
&& mkdir -p /run/nginx
# Nginx conf + Supervisor entrypoint
COPY ./dev.conf /etc/nginx/conf.d/default.conf
COPY ./.htpasswd /etc/nginx/.htpasswd
COPY ./supervisord.conf /etc/supervisord.conf
EXPOSE 80 443
ENTRYPOINT /usr/bin/supervisord -c /etc/supervisord.conf
UPDATE 2:
I pulled my Docker images and ran the application using only the docker-compose.dev.yml (without the docker-compose.local.yml that I'd use too locally). I have been able to login, everything is okay.
So... It works with Docker Compose locally, but not in Docker Swarm on a remote server.
UPDATE 3:
I made the dev server leave the Swarm cluster and started the services using Docker Compose. It works.
The issue is about going from Compose to Swarm. I created an issue: docker/swarm #2956
Maybe it's not your specific case, but it could help some user who have problems using Docker Swarm which are not present in Docker Compose.
I've been fighting this issue for over a week. I found that the default network for Docker Compose uses the bridge driver and Docker Swarm uses Overlay.
Later, I read in the Caveats section in the Postgres Docker image repo that there's a poblem with the IPVS connection timeouts in overlay networks and it refers to this blog for solutions.
I try with the first option and changed the endpoint_mode setting to dnsrr in my docker-compose.yml file:
db:
image: postgres:12
# Others settings ...
deploy:
endpoint_mode: dnsrr
Keep in mind that there are some caveats (mentioned in the blog) to consider. However, you could try the other options.
Also in this issue maybe you find something useful as they faced the same problem.

css file integrity check fails after docker build

I have the following issue.
Failed to find a valid digest in the 'integrity' attribute for resource 'http://127.0.0.1:8080/uistatic/css/bootstrap4.0.0.min.css' with computed SHA-256 integrity 'xLbtJkVRnsLBKLrbKi53IAUvhEH/qUxPC87KAjEQBNo='. The resource has been blocked.
And this is happening when i put my site into docker with building this Dockerfile:
FROM python:3.6
COPY skfront /app
WORKDIR /app
RUN mkdir -p /static/resources
RUN mkdir logs
RUN mkdir certs
RUN pip3 install -r requirements.txt
RUN python3 manage.py collectstatic --settings blog_site.settings
EXPOSE 8080
CMD python3 website.py -l 0.0.0.0 -p 8080
This css is static file that doesn't change.
Any ideas why this is happening?
I found out that building Dockerfile on Windows can mess-up the final image.
When I build my site under Linux there ware no integrity errors.

How to install JupyterHub with Docker on a local machine and in a sub domain

I will run JupyterHub in a sub domain. Here is the Dockerfile, jupyterhub_config.py, .gitlab-ci.yml.
My first question is how to configure the jupyter_config.py. How can I load the jupyterhub_config.py on the build in the container?
How do I start Jupyterhub in the .gitlab-ci.yml for tests and how do I copy the application in the sub domain? I wrote a README.md. I need a little help for the JupyterHub. If all works fine, I will write a complete HOWTO Install JupyterHub on a local machine and in a sub domain by a provider.
FROM continuumio/miniconda3
# Updating packages
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
git \
nano \
unzip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install conda and Jupyter
RUN conda update -y conda
RUN conda install -c conda-forge jupyter_nbextensions_configurator \
jupyterhub \
jupyterlab \
matplotlib \
pandas \
scipy
# Setup application
EXPOSE 8000
CMD ["jupyterhub", "--ip='*'", "--port=8000", "--no-browser", "--allow-root"]
The .gitlab-ci.yml
image: docker:latest
variables:
CONTAINER_IMAGE: registry.gitlab.com/joklein
DOCKER_IMAGE: jupyterhub
TAG: 0.1.0
services:
- docker:dind
stages:
- build
- test
- release
- deploy
before_script:
- echo "$GITLAB_PASSWORD" | docker login registry.gitlab.com --username $GITLAB_USER --password-stdin
build:
stage: build
script:
- docker build -t $CONTAINER_IMAGE/$DOCKER_IMAGE .
- docker push $CONTAINER_IMAGE/$DOCKER_IMAGE
test:
stage: test
script:
- docker pull $CONTAINER_IMAGE/$DOCKER_IMAGE
# - docker run $CONTAINER_IMAGE/$DOCKER_IMAGE -dt -p 8000:8000 --name $DOCKER_IMAGE
release:
stage: release
script:
- docker pull $CONTAINER_IMAGE/$DOCKER_IMAGE
- docker tag $CONTAINER_IMAGE/$DOCKER_IMAGE:latest $CONTAINER_IMAGE/$DOCKER_IMAGE:$TAG
- docker push $CONTAINER_IMAGE/$DOCKER_IMAGE:$TAG
only:
- master
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk update && apk add git openssh-client rsync
script:
- mkdir .public
- cp -r * .public
- mv .public public
- mkdir "${HOME}/.ssh"
- echo "${SSH_HOST_KEY}" > "${HOME}/.ssh/known_hosts"
- echo "${SSH_PRIVATE_KEY}" > "${HOME}/.ssh/id_rsa"
- chmod 700 "${HOME}/.ssh/id_rsa"
- rsync -hrvz --delete --exclude=_ public/ user#example.com:www/jupyter/
only:
- master
The jupyterhub_config.py
c = get_config()
# Letsencrypt (https://letsencrypt.org/) to obtain a free, trusted SSL
# certificate.
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/example.com/privkey.pem'
c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/example.com/fullchain.pem'
c.JupyterHub.port = 443
#
# Change from JupyterHub to JupyterLab
c.Spawner.default_url = '/lab'
c.Spawner.debug = True
#
# # Specify users and admin
c.Authenticator.whitelist = {"systemuser"}
c.Authenticator.admin_users = {"systemuser"}
Docker base image of JupyterHub and JupyterLab
JupyterHub is a multi-user server for Jupyter notebooks. JupyterLab is the
next-generation web-based user interface for the Jupyter Project. This
JupyterHub is a Docker base image for JupyterHub and JupyterLab
that works as a stand-alone application and in a (sub) domain.
Images derived from this image can either run as a stand-alone server, or
function as a volume image for your server. You can also use them in a CI/CD
system such as GitLab CI to build your content prior to bundling it into a
standalone server container.
Building your JupyterHub image
Based on this structure, you can easily build an image for your needs. There are two options for using the image you generated:
as a stand-alone image
as a volume image for your webserver
The simplest way to build your own image is to use a Dockerfile. This is only an example. If you need more software packages you can install them with this
Dockerfile and conda.
Build the container
docker build -t juypterhub .
Your JupyterHub with JupyterLab is automatically generated during this build.
Run the container
docker run -p 8000:8000 -d --name jupyterhub jupyterhub jupyterhub
-p is used to map your local port 8000 to the container port 8000
-d is used to run the container in background. JupyterHub will just write
logs so no need to output them in your terminal unless you want to troubleshoot a server error.
-- name jupyterhub names your container jupyterhub
jupyterhub the image
jupyterhub is the last command used to start the jupyterhub server
and your JupyterHub with Jupyterlab is now available of http://localhost:8000.
Start / Stop JupyterHub
docker start / stop juyterhub
Configure JupyterHub
Let's encrypt certificates for JupyterHub
To enable HTTPS on your website, you need to get a certificate (a type of file) from a Certificate Authority (CA). Let’s Encrypt is a CA. In order to get a certificate for your website’s domain from Let’s Encrypt, you have to
demonstrate control over the domain. With Let’s Encrypt, you do this using
software that uses the ACME protocol, which typically runs on your web host.
Change to zerossl.com and generate a certificate for your domain. As the
result you get four files, domain-key.txt, domain-crt.txt, domain-csr.txt, account-key.txt. This files uses base 64, which is readable in
ASCII, not binary format. The certificates are already in PEM format. Just
change the extension to *.pem.
For JupyterHub only the files domain-key.txt and domain-crt are needed.
cp domain-crt.txt fullchain.pem
cp domain-key.txt privkey.pem
Add a System user in the container
By default JupyterHub searches for users on the server. In order to be able to
log in to our new JupyterHub server we need to connect to the JupyterHub docker
container and create a new system user with a password.
docker exec -it jupyterhub bash
useradd --create-home systemuser
passwd systemuser
exit
The command docker exec -it jupyterhub bash will spawn a root shell in your
docker container. You can use the root shell to create system users in the
container. These accounts will be used for authentication in JupyterHub's
default configuration.
The first command useradd creates a new user named systemuser. The second will
ask you for a password.
The all process might be simpler with GitLab 12.0 (June 2019), and its
Git integration for JupyterHub
Deploying JupyterHub via GitLab’s Kubernetes integration provides an easy way to get started with Jupyter notebooks, which can be used to create and share documents that contain live code, visualizations, and even runbooks.
Starting with GitLab 12.0, JupyterLab’s Git extension is automatically provisioned and configured when installing JupyterHub onto your Kubernetes cluster.
This integration enables full version control of your notebooks as well as issuance of Git commands within Jupyter. Git commands can be issued via the Git tab on the left panel or via Jupyter’s command line prompt.
See documentation and gitlab-ce issue 47138.
jupyterhub --generate-config
This is what on the documentation
It created a config.py file in /srv/jupyterhub

(Docker) How to install dependencies, using separate Composer container, in WordPress container?

Dockerfile
FROM wordpress
ENV REFRESHED_AT 2015-08-12
ADD \
composer.json /var/www/html
ADD \
composer.lock /var/www/html
# install the PHP extensions
RUN \
apt-get -qq update && \
apt-get -y upgrade && \
apt-get install -y vim wget && \
rm -rf /var/lib/apt/lists/*
# Symlink User's "wp-content" folder into the newly installed Wordpress
RUN \
rm -rf /usr/src/wordpress/wp-content/plugins/* && \
rm -rf /usr/src/wordpress/wp-content/themes/* && \
cp -fr /usr/src/wordpress/* /var/www/html/ && \
chown -R www-data:www-data /var/www/html/
# volume for mysql database and wordpress install
VOLUME ["/var/www/html/wp-content/plugins", "/var/www/html/wp-content/themes"]
# Define working directory.
WORKDIR /var/www/html/
EXPOSE 80 3306
CMD ["apache2-foreground"]
Docker Compose File
wordpress:
build: .
links:
- mysql
- composer
volumes:
- wp-content/plugins/:/var/www/html/wp-content/plugins
- wp-content/themes/:/var/www/html/wp-content/themes
environment:
- WORDPRESS_DB_PASSWORD=__WORDPRESS_DB_PASSWORD__
- WORDPRESS_DB_NAME=__WORDPRESS_DB_NAME__
# - WORDPRESS_DB_USER=__WORDPRESS_DB_USER__
ports:
- "9888:80"
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=__WORDPRESS_DB_PASSWORD__
- MYSQL_DATABASE=__WORDPRESS_DB_NAME__
composer:
image: composer/composer
Question details
I'm able to ADD the composer.json and composer.lock files to the working directory. I can confirm that these two files are in the working directory.
What I need is for the Dockerfile (or wherever) to also automatically install the dependencies into the working directory.
According to Docker Hub, https://hub.docker.com/r/composer/composer/,
I should be able to docker run -v $(pwd):/app composer/composer install to install the dependencies but how do I do this in Dockerfile?
Also I'm confused because the -v flag, https://docs.docker.com/engine/userguide/dockervolumes/, has to do with mounting the specified host directory into the a container but I've already ADDed the necessary files to the working directory. All I want to do is install the dependencies.
Thank you for your help.
You just need to mount the current directory to /app when running your composer container. I've put together a simple example to illustrate this working at https://gist.github.com/andyshinn/e2c428f2cd234b718239.
The key parts here are the volumes for the composer part of the application and the restart: 'yes' on the primary PHP application (the application likely will not run until Composer has run so you will want it to restart).

Resources