Problems with a decoupled frontend and php backend in docker-compose - api

I've been struggling on a problem with a docker-compose environment where a Single Page Application should talk to a PHP api. Preferrably laravel.
My approach is to have nginx act as a reverve proxy for both.
However, every time i try to hit the /api route, it says file not found. the php-fpm do recieve the request, but it apparantly fails to load the index, even tough it is in the specified folder.
My docker-compose.yml looks like this.
version: "3.1"
services:
redis:
image: redis:alpine
container_name: apitest-redis
postgres:
image: postgres:9.6-alpine
container_name: apitest-postgres
working_dir: /application/api
volumes:
- ./api:/application/api
environment:
- POSTGRES_USER=myapiuser
- POSTGRES_PASSWORD=2cr34m1ng#n4k3d
- POSTGRES_DB=test
webserver:
image: nginx:alpine
container_name: apitest-webserver
working_dir: /application
volumes:
- ./client/dist:/application/dist
- ./api:/application/api
- ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
php-fpm:
build: docker/php-fpm
container_name: apitest-php-fpm
working_dir: /application/api
volumes:
- ./api:/application/api
- ./docker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
And my nginx.conf looks like this:
server {
listen 80 default;
client_max_body_size 108M;
access_log /var/log/nginx/application.access.log;
root /application;
index index.html index.php;
location / {
root /application/dist;
try_files $uri /index.html;
}
location /api {
root /application/api/public;
try_files $uri /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass apitest-php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
}

Related

Unable to access the nginx page on curl in openshift

I am running nginx as load balancer in OpenShift, for this i've created configmap, deployment, exposed it as service of type load balancer and created a relevant route.
Please note that, ssl is also setup in its configurations. When I allocate a public IP to it, it's giving error connection refused.
The route seems to be correct but it is not working as intended.
Config map file
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
namespace: nginx-ingress
data:
nginx.conf: |-
user nginx;
worker_processes 10;
events {
worker_connections 10240;
}
http {
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html; # root path for file
index index.html index.htm;
}
}
}
default.conf: |-
# file mounted externally
server {
listen 80;
server_name localhost;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/letsencrypt/server.crt;
ssl_certificate_key /etc/letsencrypt/server.key;
ssl_trusted_certificate /etc/letsencrypt/rootCA.pem;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
index.html: |-
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
nginx.org.<br/>
Commercial support is available at
nginx.com.</p>
<p><em>Thank you for using nginx. Response from ingress/proxy.</em></p>
</body>
</html>
Deployment file
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: nginx-ingress
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
compute1: worker1
volumes:
- name: nginx-conf
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: nginx.conf
- key: default.conf
path: default.conf
- key: index.html
path: index.html
- name: ca-pem
configMap:
name: ca-pem
- name: ca-crt
configMap:
name: ca-crt
- name: ca-key
configMap:
name: ca-key
containers:
- name: nginx-alpine-perl
image: docker.io/library/nginx#sha256:51212c2cc0070084b2061106d5711df55e8aedfc6091c6f96fabeff3e083f355
ports:
- containerPort: 80
- containerPort: 443
securityContext:
allowPrivilegeEscalation: false
#runAsUser: 0
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx
#subPath: nginx.conf
readOnly: true
- name: nginx-conf
mountPath: /etc/nginx/conf.d
readOnly: true
- name: nginx-conf
mountPath: /usr/share/nginx/html
#subPath: nginx.conf
readOnly: true
- name: ca-pem
mountPath: /etc/letsencrypt/rootCA.pem
subPath: rootCA.pem
readOnly: false
- name: ca-crt
mountPath: /etc/letsencrypt/server.crt
subPath: server.crt
readOnly: false
- name: ca-key
mountPath: /etc/letsencrypt/server.key
subPath: server.key
readOnly: true
Svc file
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: LoadBalancer
ports:
- port: 80
name: http
protocol: TCP
targetPort: 80
#nodePort: 30008
- port: 443
name: https
protocol: TCP
targetPort: 443
#nodePort: 30009
selector:
app: nginx
status:
loadBalancer:
ingress:
- ip: <Public IP>
route file
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
openshift.io/host.generated: "true"
name: nginx-ingress
namespace: nginx-ingress
selfLink: /apis/route.openshift.io/v1/namespaces/nginx-ingress/routes/nginx-ingress
spec:
host: <Some url: nginx-ingress.app>
to:
kind: Service
name: nginx
weight: 100
wildcardPolicy: None
Hard to tell from your config what is breaking here. As a sensible debugging step, validate whether the problem is with the Ingress Controller or with the routing from your Loadbalancer's public IP:
Run a curl on a Pod that goes directly against the Ingress Controller Service with the external URL:
curl -v -H "Host: <your external URL>" http://nginx.default
If it works, you know it's the routing, e.g. cluster network configuration. If it fails, it must be the Ingress Controller, e.g. Openshift Route, Service or Pod configuration.

How to create for dockerized vue3 app an endpoint for liveness probe status?

I have a vue3 typescript app, which runs in a docker on k8s.
Vue app has different routes
/
/about
/login
all those routes will send back a html response from vue component.
For docker liveness probe I need a simple json response
/status -> HTTP 200 & res=> JSON {status:ok}
How can Vue3 respond only with JSON object on specific route?
my dockerfile
FROM node:16.13.0 as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build
FROM nginx:1.20.1 as production-stage
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY nginx.conf /etc/nginx/nginx.conf
COPY /entrypoint.sh /entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
I solved it by adding in nginx.conf additional location for liveness
location /health/liveness {
#access_log off;
error_log off;
add_header 'Content-Type' 'application/json';
return 200 '{"status":"ok"}';
}
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name example.com;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
location /health/liveness {
#access_log off;
error_log off;
add_header 'Content-Type' 'application/json';
return 200 '{"status":"ok"}';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}

Deploy VUE project on Nginx, static file like css, js can not be found

My OS is window, and deploy VUE project on Nginx server.
Build VUE project
cd E:\test\test-project-frontend-demo
npm install && npm run build
config nginx:
nginx.conf
worker_processes 1024;
pid logs/nginx.pid;
events {
multi_accept on;
worker_connections 65535;
}
http {
#MIME
include mime.types;
default_type application/octet-stream;
#LOGGING
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
error_log logs/error.log warn;
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 16M;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
#SITES
include sites-available/project.conf;
}
project.conf
server {
listen 80;
listen 443 ssl;
server_name project.testltd.com;
# security
include nginxconfig.io/security.conf;
# logging
access_log logs/project.access.log;
error_log logs/project.error.log warn;
# site project
location / {
alias E:/test/test-project-frontend-demo/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# additional config
include nginxconfig.io/general.conf;
# ssl config
include nginxconfig.io/self-signed.conf;
include nginxconfig.io/ssl-params.conf;
}
start nginx:
nginx.exe -c conf/nginx.conf
index.html can be access , and response is 200, but static file like css and js can not be accessed, Why?

How to make css and js file in vue project work in production with nginx

I've Vue project here is my path vue in Ubuntu 18.04
/var/www/html/vue/{ project here }
the problem is my css path are /css which refer to /var/www/html/css
How to set up my css in vue project refer in folder here is my nginx setup
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
location /vue {
// I try to make root path but It's not workking error 500 when I uncomment #root
#root /var/www/html/vue;
try_files $uri $uri/ /vue/index.html;
}
}
You can try the following with your current config:
location /css {
alias /var/www/html/css;
}

Trouble configuring Nginx with puppet/nginx module using Hiera

I'm trying to configure Nginx with puppet/nginx module from forge.puppet.com (by Vox Pupuli), using this Hiera yaml file:
nginx::nginx_servers:
'devops-alldomains':
server_name:
- '~^(?<fqdn>.+?)$'
www_root: '/var/www/$fqdn'
index_files:
- 'index.php'
try_files:
- '$uri'
- '$uri/'
- '/index.php?$args'
access_log: '/var/log/nginx/devops-alldomains-access.log'
error_log: '/var/log/nginx/devops-alldomains-error.log'
'devops-alldomains-ssl':
server_name:
- '~^(?<fqdn>.+?)$'
listen_port: '443'
www_root: '/var/www/$fqdn'
ssl: true
ssl_key: '/etc/ssl/www/$fqdn.key'
ssl_cert: '/etc/ssl/www/$fqdn.crt'
index_files:
- 'index.php'
try_files:
- '$uri'
- '$uri/'
- '/index.php?$args'
access_log: '/var/log/nginx/devops-alldomains-access-ssl.log'
error_log: '/var/log/nginx/devops-alldomains-error-ssl.log'
nginx::nginx_locations:
'devops-alldomains':
location: '~ \.php$'
www_root: '/var/www/$fqdn'
server: 'devops-alldomains'
fastcgi: 'unix:/var/run/php7-fpm.sock'
fastcgi_split_path: '^(.+\.php)(/.*)$'
fastcgi_index: 'index.php'
fastcgi_param:
'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'
'devops-alldomains-ssl':
location: '~ \.php$'
www_root: '/var/www/$fqdn'
server: 'devops-alldomains-ssl'
fastcgi: 'unix:/var/run/php7-fpm.sock'
fastcgi_split_path: '^(.+\.php)(/.*)$'
fastcgi_index: 'index.php'
fastcgi_param:
'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'
BUT when it generates two Nginx configs (devops-alldomains.conf and devops-alldomains-ssl.conf), the SSL one is not as expected:
location / {
root /var/www/$fqdn;
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
root /var/www/$fqdn;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php7-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# MANAGED BY PUPPET
server {
listen *:443 ssl;
server_name ~^(?<fqdn>.+?)$;
ssl on;
ssl_certificate /etc/ssl/www/$fqdn.crt;
ssl_certificate_key /etc/ssl/www/$fqdn.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE- RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA- AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256- GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
ssl_prefer_server_ciphers on;
index index.php;
access_log /var/log/nginx/devops-alldomains-access-ssl.log combined;
error_log /var/log/nginx/devops-alldomains-error-ssl.log;
location / {
root /var/www/$fqdn;
index index.php;
try_files $uri $uri/ /index.php?$args;
}
}
So as you can see, location directives are outside of server directive, so Nginx will never start. Has anyone an idea what could be wrong? I even tried to simplify this configuration to use only basic directives (even without ssl and php) but the result was quite the same. Thanks a lot for your help.
UPDATE:
It looks I managed to resolve the problem with your help guys ;) This is the current config:
nginx::nginx_servers:
'devops-alldomains':
server_name:
- '~^(?<fqdn>.+?)$'
www_root: '/var/www/$fqdn'
index_files:
- 'index.php'
try_files:
- '$uri'
- '$uri/'
- '/index.php?$args'
access_log: '/var/log/nginx/devops-alldomains-access.log'
error_log: '/var/log/nginx/devops-alldomains-error.log'
'devops-alldomains-ssl':
server_name:
- '~^(?<fqdn>.+?)$'
listen_port: '443'
ssl_port: '443'
www_root: '/var/www/$fqdn'
ssl: true
ssl_key: '/etc/ssl/www/$fqdn.key'
ssl_cert: '/etc/ssl/www/$fqdn.crt'
index_files:
- 'index.php'
try_files:
- '$uri'
- '$uri/'
- '/index.php?$args'
access_log: '/var/log/nginx/devops-alldomains-access-ssl.log'
error_log: '/var/log/nginx/devops-alldomains-error-ssl.log'
nginx::nginx_locations:
'devops-alldomains-loc':
location: '~ \.php$'
www_root: '/var/www/$fqdn'
server: 'devops-alldomains'
fastcgi: 'unix:/var/run/php7-fpm.sock'
fastcgi_split_path: '^(.+\.php)(/.*)$'
fastcgi_index: 'index.php'
fastcgi_param:
'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'
'devops-alldomains-ssl-loc':
location: '~ \.php$'
www_root: '/var/www/$fqdn'
server: 'devops-alldomains-ssl'
ssl: true
ssl_only: true
fastcgi: 'unix:/var/run/php7-fpm.sock'
fastcgi_split_path: '^(.+\.php)(/.*)$'
fastcgi_index: 'index.php'
fastcgi_param:
'SCRIPT_FILENAME': '$document_root$fastcgi_script_name'
Now I have two separated Nginx config files - one for non-SSL, second for SSL. First problem was that I was missing ssl: true and ssl_only: true under the related location (devops-alldomains-ssl-loc), second was that I had to set both listen_port: '443' and ssl_port: '443' under the server directive. I have also changed names of locations, but it didn't seem to do any problems (or resolving something).
To make this complete, here are versions of tools used:
Puppet: 4.10.9
Hiera: 3.3.2
Nginx: 1.12.2-1~xenial
puppet/nginx (forge module): 0.9.0
Thank you for your help. I very appreciate it!