Configuring a Laravel application with Docker Compose for local development using RabbitMq, MariaDB, and Redis

Welcome to the eighth post of the blog. We will set up and run a Laravel application (PHP) Repository: https://github.com/brunocaramelo/docker-compose-php-application-example

DependencyDescriptionVersion
PHPUsed as Backend7.4.11
NginxUsed as Webserver1.19.3
MariaDBUsed as SQL database10.5.6-MariaDB
RedisUsed as Cache Storage6.0.8
RabbitMqUsed as message broker3.8.9

Assumptions

Have the following dependencies previously installed and configured:

  • Docker
  • Docker Compose

Composition of Services

Specifications of application services.

ServiceDescriptionService dependencies
phpDomain of the API backend application exposed with PHP FPM.mysql, redis, rabbitmq
worker-phpDomain of the application for execution of routines.mysql
worker-queue
Domain of the application for consumption of the message broker.
mysql, rabbitmq
webResource responsible for the application’s web server with assembly for configuration.php
rabbitmqResource responsible for messaging and providing the graphical interface.
mysqlResource responsible for the SQL database persisted in a host local disk
Example of docker-compose.yml file

Source: https://github.com/brunocaramelo/docker-compose-php-application-example/blob/main/docker-compose.yml

Understanding the service configuration: php

php: # Service name
    build: # Start build session
      context: .  # Level where the build should be executed
      dockerfile: ./docker/php7-fpm/Dockerfile # Dockerfile chosen (default file with name Dockerfile, on the same level as the docker-compose file)
    image: repo-registry-local/libraryapitest-app-example:v4.0 # image that will be used as a base for the build. can also be used to be sent to the registry, like this example
    container_name: php-library-example # container name when uploading the service
    depends_on: # depends on other services, will start only when the list below is up
      - redis
      - mysql
      - rabbitmq
    command: bash -c "php artisan migrate && php-fpm" # Dockerfile CMD attribute overlap
    env_file: # environment variables coming from a file
      - docker/docker-compose-env/application.env
    environment: # explicit environment variables, can also be used to overwrite variables
      APP_NAME: 'Overlaying - Library API
    links: # When listed, the container passes and see the services below
      - mysql
      - redis
      - rabbitmq
    volumes: # External mounting area
     - ./application/:/app:rw
     - /app/vendor

Application topology

Starting the application

now that we have a basic understanding of the app’s features, let’s get started.

docker-compose up -d

The above command executes all the services contained in our docker-compose to start, with the following result.

Starting redis-library ... done
Starting mysql-library ... done
Starting rabbitmq                   ... done
Starting php-library-example-worker ... done
Starting php-library-example              ... done
Starting php-library-worker-queue-example ... done
Starting nginx-library                    ... done

It is also possible to break down the services we want to start with the command below.

docker-compose up rabbitmq mysql -d

Or perform the build of all services or a particular service as we can see below.

docker-compose build
docker-compose build php

Checking Services

We can verify that the services started correctly with the following command :

docker ps

With the following result:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f0d029513c3 nginx:1.19-alpine "/docker-entrypoint.…" 3 days ago Up 18 minutes 0.0.0.0:80->80/tcp nginx-library
90a5a7a0d335 repo-registry-local/libraryapitest-app-example:v4.0 "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-example
9630371843b4 libraryapiotra:php-worker-example "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-example-worker
71861ab99b26 libraryapiotra:php-worker-queue "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-worker-queue-example
9fcb27caaceb mariadb:latest "docker-entrypoint.s…" 13 days ago Up 19 minutes 0.0.0.0:3306->3306/tcp mysql-library
40f05238ace7 rabbitmq:3-management-alpine "docker-entrypoint.s…" 13 days ago Up 18 minutes 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp rabbitmq
e85dbe64c2e6 redis:alpine "docker-entrypoint.s…" 13 days ago Up 18 minutes 6379/tcp redis-library

Viewing API (Swagger) documentation

When starting our application, we can see the API documentation from the following address:

http://localhost/api/documentation

Understanding interdependencies

We will use some routes to better understand the participation of different services among themselves, for this, we will see 3 use cases:
– SEE BOOK DETAIL
– SEND MESSAGE TO MESSAGE BROKER
– PROCESS MESSAGE BROKER

DETAILS OF USE CASES

1 – SEE BOOK DETAIL

The purpose of this resource is to present the detailing of a book, using the Cache resource to avoid the use of an SQL database for example, during the time that Cache exists, or that there is a change in the data, moments in which the index is invalidated.

UML route representation: GET book/{bookId}

Application representation for the route: GET book/{bookId}

When you click on Try it out >> fill in the Book Id field >> click on Execute.

In this route we used a Cache for consultation, using the Driver that sends to Redis, as we can see below, three books were viewed: book 13, 15, and 16, and we have the value of the index generated in our Redis instant.

2 – SEND MESSAGE TO MESSAGE BROKER

The purpose of this feature is to send a message to our Message Broker so that it can be processed at another time asynchronously.

UML route representation: POST /author/process/message

Route application representation: POST /author/process/message

After clicking Try it out >> fill in the message field >> click on Execute.

We will receive a message that our message will be processed. this message only and generated, if our Message Broker received and accepted our message.

Accessing The Message Broker:
http://localhost:15672

Login: admin
Password: admin

Checking Messages received on:
http://localhost:15672/#/queues

We can notice that we have 4 messages waiting for processing. in the queue called test, which was configured in our Laravel application.

When clicking on the Messages menu:

We can see more details of the message, and how Laravel sends it to be processed by default.
{"displayName":"App\\Jobs\\ProcessExperimentalJob","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"timeout":null,"timeoutAt":null,"data":{"commandName":"App\\Jobs\\ProcessExperimentalJob","command":"O:31:\"App\\Jobs\\ProcessExperimentalJob\":8:{s:40:\"\u0000App\\Jobs\\ProcessExperimentalJob\u0000message\";s:87:\"Place the message here for the processing queue received at: 2021-01-30 22:51:54:507117\";s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";N;s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";N;s:7:\"chained\";a:0:{}}"},"id":"bLVXYvR1U9wzTXtGJNQEiLl2wkx8Zqtl"}

Example of a payload message sent by our application.

3 – PROCESS MESSAGE BROKER

The purpose of this feature is to process a message from our Message Broker, we can see its processing as well as its completion in our queue.

UML representation of queue processing

Representation of the application on queue processing

worker-queue:
    build:
      context: .
      dockerfile: ./docker/php7-fpm/Dockerfile
    image: libraryapiotra:php-worker-queue
    container_name: php-library-worker-queue-example
    depends_on:
      - mysql
      - rabbitmq
    command: sh -c "php /app/artisan queue:work --verbose --tries=7 --timeout=90"
    env_file:
      - docker/docker-compose-env/application.env
    environment:
      APP_NAME: 'Queue Worker - Library API'
    links:
      - mysql
      - redis
      - rabbitmq
    volumes:
      - ./application/:/app:rw

Execução do serviço:

php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a841676.51726260] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:507117 Processed on: 2021-01-31 00:47:38:247462","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.249261","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a841676.51726260] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a913a25.80490108] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:579488 Processed at: 2021-01-31 00:47:38:251189","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.251229","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a913a25.80490108] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30abadad8.37346333] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:753117 Processed at: 2021-01-31 00:47:38:253215","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.253247","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30abadad8.37346333] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30b0eb9b5.50128892] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:55:052662 Processed at: 2021-01-31 00:47:38:254837","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.254869","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30b0eb9b5.50128892] Processed:  App\Jobs\ProcessExperimentalJob

As we can see above. We saw that when our worker service verified that there were messages to process he executed them,

we saw his output, as he is using /dev/stderr to write logs:
We can see it with the following command:

docker-compose logs worker-queue

Checking messages after processing in the application

We have seen the operation of a mini-application and the communication between its components.

We close here.
I hope I was clear in my explanation.
Thanks for your attention, see you next time!

Configurando uma aplicação Laravel com Docker Compose para desenvolvimento local usando RabbitMq, Mariadb e Redis

Sejam bem vindos ao oitavo post do blog.
Iremos configurar e executar uma aplicação Laravel (PHP)
Repositório:
https://github.com/brunocaramelo/docker-compose-php-application-example

DependênciaDescriçãoVersão
PHPUsado para Backend7.4.11
NginxUsado como Web server1.19.3
MariadbUsado como Banco de dados SQL10.5.6-MariaDB
RedisUsado com Cache Storage6.0.8
RabbitMqUsado para mensageria3.8.9

Premissas

Ter as seguintes dependências previamente instaladas e configuradas:

  • Docker
  • Docker Compose

Composição de Serviços

Especificações de serviços da aplicação.

ServiçoDescriçãoDependências de serviços
phpDomínio da aplicação backend da API exposta com o PHP FPM.mysql, redis, rabbitmq
worker-phpDomínio da aplicação para execução de rotinas.mysql
worker-queueDomínio da aplicação para consumo da mensageria.mysql, rabbitmq
webRecurso responsável pelo Web server da aplicação com montagem para configuração.php
rabbitmqRecurso responsável pela Mensageria e prover a interface gráfica.
mysqlRecurso responsável pela base de dados SQL persistida em disco local.
Exemplo arquivo docker-compose.yml

Entendo a configuração do serviço: php

php: # Nome do serviço
    build: # Inicio da sessão build
      context: .  # Nivel onde o build deve ser executado
      dockerfile: ./docker/php7-fpm/Dockerfile # Dockerfile escolhido (padrão arquivo com nome Dockerfile, no mesmo nivel do arquivo docker-compose)
    image: repo-registry-local/libraryapitest-app-example:v4.0 # imagem que sera usada como base do build. pode ser usado tambem para que seja enviado ao registry, como este exemplo
    container_name: php-library-example # nome do container ao subir o serviço
    depends_on: # depencia de outros serviços, ira iniciar apenas quando a lista abaixo estiver de pé
      - redis
      - mysql
      - rabbitmq
    command: bash -c "php artisan migrate && php-fpm" # sobreposicao do atributo CMD do Dockerfile
    env_file: # vairaveis de ambiente vindas de um arquivo
      - docker/docker-compose-env/application.env
    environment: # variaveis de ambiente explicitas, tambem pode ser usado para sobreescrever variaveis
      APP_NAME: 'Sobrepondo - Library API'
    links: # Quando listado, o container passa e ver os serviços abaixo
      - mysql
      - redis
      - rabbitmq
    volumes: # Area destinada a montagem externa
     - ./application/:/app:rw
     - /app/vendor

Topologia da aplicação

Iniciando a aplicação

agora que temos um entendimento básico sobre os recursos da aplicação, iremos iniciá-la.

docker-compose up -d

O comando acima executa faz com que todos os serviços contido em nosso docker-compose sejam iniciados, tendo o seguinte resultado.

Starting redis-library ... done
Starting mysql-library ... done
Starting rabbitmq                   ... done
Starting php-library-example-worker ... done
Starting php-library-example              ... done
Starting php-library-worker-queue-example ... done
Starting nginx-library                    ... done

Também é possível discriminar os serviços que queremos iniciar como o comando abaixo.

docker-compose up rabbitmq mysql -d

Ou executar o build de todos os serviços ou de um determinado servico conforme podemos ver abaixo.

docker-compose build
docker-compose build php

Verificando Serviços

Podemos verificar se os serviços iniciaram corretamente com o seguinte comando :

docker ps

Com o seguinte resultado:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f0d029513c3 nginx:1.19-alpine "/docker-entrypoint.…" 3 days ago Up 18 minutes 0.0.0.0:80->80/tcp nginx-library
90a5a7a0d335 repo-registry-local/libraryapitest-app-example:v4.0 "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-example
9630371843b4 libraryapiotra:php-worker-example "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-example-worker
71861ab99b26 libraryapiotra:php-worker-queue "docker-php-entrypoi…" 3 days ago Up 18 minutes 9000/tcp php-library-worker-queue-example
9fcb27caaceb mariadb:latest "docker-entrypoint.s…" 13 days ago Up 19 minutes 0.0.0.0:3306->3306/tcp mysql-library
40f05238ace7 rabbitmq:3-management-alpine "docker-entrypoint.s…" 13 days ago Up 18 minutes 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp rabbitmq
e85dbe64c2e6 redis:alpine "docker-entrypoint.s…" 13 days ago Up 18 minutes 6379/tcp redis-library

Visualizando documentação da API (Swagger)

Ao inciar nossa aplicação, podemos ver a documentação da API. a partir do seguinte endereço:


http://localhost/api/documentation

Entendendo as interdependências

Iremos utilizar algumas rotas para entender melhor a participação de diferentes serviços entre si, para isso iremos ver 3 casos de uso:
– VER DETALHE DE LIVRO
– ENVIAR MENSAGEM AO MESSAGE BROKER
– PROCESSAR MENSAGEM DO MESSAGE BROKER

DETALHAMENTO DOS CASOS DE USO

1 – VER DETALHE DE LIVRO

Este recurso tem como finalidade apresentar o detalhamento de um livro, utilizando o recurso de Cache para evitarmos o uso de uma base de dados SQL por exemplo, durante o tempo em que o Cache existir, ou que se tenha uma alteração no dado, momentos em que o índice é invalidado.

Representação UML da rota: GET book/{bookId}

Representação da aplicação para a rota: GET book/{bookId}

Ao clicar em Try it out >> preencher o campo Id do Livro >> clicar em Execute.

Nesta rota utilizamos um Cache para consulta executada ,utilizando o Driver que envia para o Redis, conforme podemos ver abaixo, foram visualizados três livros: livro 13, 15 e 16, e temos o valor do índice gerado em nossa instancia Redis.

2 – ENVIAR MENSAGEM AO MESSAGE BROKER

Este recurso tem como finalidade enviar uma mensagem a nosso Message Broker, para que seja processado em outro momento de forma assíncrona.

Representação UML da rota: POST /author/process/message

Representação da aplicação para a rota: POST /author/process/message

Após clicar em Try it out >> preencher o campo de mensagem >> clicar em Execute.

Receberemos uma mensagem que nossa messagem sera processada. esta mensagem apenas e gerada, caso nosso Message Broker recebeu e aceitou nossa mensagem.

Acessando O Message Broker:
http://localhost:15672

Login: admin
Password: admin

Verificando Mensagens recebidas em:
http://localhost:15672/#/queues

Podemos notar que temos 4 mensagens aguardando processamento. na fila chamada test, que foi configurada em nossa aplicação Laravel.

Ao Clicar no Menu Messages:

Podemos ver maiores detalhes da mensagem, e como o Laravel envia ela para que seja processada por padrão.
{"displayName":"App\\Jobs\\ProcessExperimentalJob","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"timeout":null,"timeoutAt":null,"data":{"commandName":"App\\Jobs\\ProcessExperimentalJob","command":"O:31:\"App\\Jobs\\ProcessExperimentalJob\":8:{s:40:\"\u0000App\\Jobs\\ProcessExperimentalJob\u0000message\";s:87:\"Place the message here for the processing queue received at: 2021-01-30 22:51:54:507117\";s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";N;s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";N;s:7:\"chained\";a:0:{}}"},"id":"bLVXYvR1U9wzTXtGJNQEiLl2wkx8Zqtl"}

Exemplo de payload de uma mensagem enviada pela nossa aplicação.

3 – PROCESSAR MENSAGEM DO MESSAGE BROKER

Este recurso tem como finalidade processar uma mensagem vinda do nosso Message Broker, poderemos ver seu processamento, assim como sua conclusão em nossa fila.

Representação UML do processamento de filas

Representação da aplicação sobre processamento de filas

Trecho da notação do nosso container responsavel pelo processamento de filas de nossa aplicação

Execução do serviço:

php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a841676.51726260] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:507117 Processed on: 2021-01-31 00:47:38:247462","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.249261","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a841676.51726260] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a913a25.80490108] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:579488 Processed at: 2021-01-31 00:47:38:251189","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.251229","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30a913a25.80490108] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30abadad8.37346333] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:54:753117 Processed at: 2021-01-31 00:47:38:253215","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.253247","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30abadad8.37346333] Processed:  App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30b0eb9b5.50128892] Processing: App\Jobs\ProcessExperimentalJob
php-library-worker-queue-example | {"message":"Place the message here for the processing queue received at: 2021-01-30 22:51:55:052662 Processed at: 2021-01-31 00:47:38:254837","context":[],"level":200,"level_name":"INFO","channel":"local","datetime":{"date":"2021-01-31 00:47:38.254869","timezone_type":3,"timezone":"UTC"},"extra":[]}
php-library-worker-queue-example | [2021-01-31 00:47:38][6015e30b0eb9b5.50128892] Processed:  App\Jobs\ProcessExperimentalJob

Conforme podemos ver acima. Vimos que quando o nosso serviço worker-queue verificou que existiam mensagens para processar ele as executou,

vimos sua saída, pois ele esta usando o /dev/stderr para escrever logs:
Podemos ver com o seguinte comando:

docker-compose logs worker-queue

Verificando mensagens após o processamento na aplicação

Vimos o funcionamento de uma mini aplicação e a comunicação entre seus componentes.

Encerramos por aqui.
Espero ter sido claro na explicação.
Obrigado pela atenção, até a próxima!

Criando e configurando openLDAP e NFS com clientes Linux e Windows

Sejam bem vindos ao sétimo post do blog.
Iremos configurar o LDAP (Lightweight Directory Access Protocol) , que tem como objetivo centralizar e padronizar dados geralmente usado pelo meio corporativo para integrar e autenticar dados da organização.

Instalando e configurando o openLdap Client/Server

Sudo dnf install openldap openldap-clients openldap-servers;

Após a instalação, iremos configurar o arquivo de configuração da base de dados, copiando arquivo exemplo para o local correto e alterando o owner para ldap com os comandos abaixo:

sudo cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG ;
chown -R ldap:ldap /var/lib/ldap

Gerando uma senha para o adminstrador:

sudo slappasswd

A senha será: senha

Com retorno:

New password: 
Re-enter new password: 
{SSHA}KFqiattbutOk81eO3DDG7HEhLyJRH2mG

Onde será exibido o hash gravado:

{SSHA}KFqiattbutOk81eO3DDG7HEhLyJRH2mG

Habilitando e ativando o serviço:

systemctl enable slapd.service ; systemctl start slapd.service;

Configurando Senha Root do LDAP

Abra o arquivo ldaprootpasswd.ldif (inexistente):

sudo vi /tmp/ldaprootpasswd.ldif;

E adicione o conteúdo:

dn: olcDatabase={0}config,cn=config
changetype: add
add: olcRootPW
olcRootPW: {SSHA}PASSWORD

Altere a última linha com o hash extraido no comando slappasswd
e altere o {SSHA}PASSWORD por {SSHA}KFqiattbutOk81eO3DDG7HEhLyJRH2mG como no meu exemplo.

Iremos importar a base de dados para adicionar a senha de root:

sudo ldapadd -H ldapi:// -Y EXTERNAL -f /tmp/ldaprootpasswd.ldif

Feito isso, iremos adicionar diversos arquivos ao diretório /etc/openldap/schema:

for def in cosine.ldif nis.ldif inetorgperson.ldif; do sudo ldapadd -H ldapi:// -Y EXTERNAL -f /etc/openldap/schema/$def; done

Criando domínio no LDAP

sudo vi /tmp/ldapdomain.ldif

Com o conteúdo:

dn: olcDatabase={1}monitor,cn=config
changetype: add
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
  read by dn.base="cn=Manager,dc=dominiocaramelo,dc=com" read by * none

dn: olcDatabase={2}mdb,cn=config
changetype: add
replace: olcSuffix
olcSuffix: dc=dominiocaramelo,dc=com

dn: olcDatabase={2}mdb,cn=config
changetype: add
replace: olcRootDN
olcRootDN: cn=Manager,dc=dominiocaramelo,dc=com

dn: olcDatabase={2}mdb,cn=config
changetype: add
add: olcRootPW
olcRootPW: {SSHA}PASSWORD

dn: olcDatabase={2}mdb,cn=config
changetype: add
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
  dn="cn=Manager,dc=dominiocaramelo,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,dc=dominiocaramelo,dc=com" write by * read

Importando domínio ao ldap:

sudo ldapadd -H ldapi:// -Y EXTERNAL -f  /tmp/ldapdomain.ldif

Com retorno:

SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry entry "olcDatabase={1}monitor,cn=config"

adding new entry entry "olcDatabase={2}mdb,cn=config"

adding new entry entry "olcDatabase={2}mdb,cn=config"

adding new entry entry "olcDatabase={2}mdb,cn=config"

adding new entry entry "olcDatabase={2}mdb,cn=config"

Adicionando níveis a base organizacional.

Criar arquivo baseldapdomain.ldif com o comando:

sudo vi /tmp/baseldapdomain.ldif

Com o conteúdo:

dn: dc=dominiocaramelo,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: dominiocaramelo com
dc: dominiocaramelo

dn: cn=Manager,dc=dominiocaramelo,dc=com
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=dominiocaramelo,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=dominiocaramelo,dc=com
objectClass: organizationalUnit
ou: Group

Adicionando ao ldap:

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/baseldapdomain.ldif

Com retorno:

adding new entry "dc=dominiocaramelo,dc=com"

adding new entry "cn=Manager,dc=dominiocaramelo,dc=com"

adding new entry "ou=People,dc=dominiocaramelo,dc=com"

adding new entry "ou=Group,dc=dominiocaramelo,dc=com"

Iremos criar 3 grupos:

1 – Desenvolvimento
2 – Infraestrutura
3 – Operação

Criando Grupos no LDAP

Criando Grupo Desenvolvimento

Criando o grupo:

sudo groupadd Grupo_Desenvolvimento;

Descobrindo o id do grupo:

sudo getent group Grupo_Desenvolvimento | cut -d: -f3

Criando arquivo de importação:

sudo vi /tmp/ldapgrupodesenvolvimento.ldif

Com o conteúdo:

dn: cn=Grupo_Desenvolvimento,ou=Group	,dc=dominiocaramelo,dc=com
objectClass: top
objectclass: posixGroup
gidNumber: 1007
cn: Grupo_Desenvolvimento
description: grupo do setor de desenvolvimento

Adicionando ao LDAP:

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapgrupodesenvolvimento.ldif

Com retorno:

Enter LDAP Password: 
adding new entry "cn=desenvolvimento,ou=groups,dc=dominiocaramelo,dc=com"

Criando Grupo Infraestrutura

Criando o grupo:

sudo groupadd Grupo_Infraestrutura;

Descobrindo o id do grupo:

sudo getent group Grupo_Infraestrutura | cut -d: -f3

Criando o grupo:

sudo groupadd Grupo_Infraestrutura;

Criando arquivo de importação:

sudo vi /tmp/ldapgrupoinfraestrutura.ldif

Com o conteúdo:

dn: cn=Grupo_Infraestrutura,ou=Group,dc=dominiocaramelo,dc=com
objectClass: top
objectclass: posixGroup
gidNumber: 1003
cn: Grupo_Infraestrutura
description: grupo do setor de Infraestrutura

Adicionando ao LDAP:

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapgrupoinfraestrutura.ldif

Com retorno:

Enter LDAP Password: 
adding new entry "cn=desenvolvimento,ou=groups,dc=dominiocaramelo,dc=com"

Criando Grupo Operação

Descobrindo o id do grupo:

sudo getent group Desenvolvimento | cut -d: -f3

Criando arquivo de importação:

sudo vi /tmp/ldapgrupooperacao.ldif

Com o conteúdo:

dn: cn=Grupo_Operacao,ou=Group	,dc=dominiocaramelo,dc=com
objectClass: top
objectclass: posixGroup
gidNumber: 1005
cn: Grupo_Operacao
description: grupo do setor de Operacao

Adicionado ao LDAP:

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapgrupooperacao.ldif

Com retorno:

Enter LDAP Password: 
adding new entry "cn=operacao,ou=Group	,dc=dominiocaramelo,dc=com"

Criando usuários no LDAP

Criando usuário Infraestrutura

Criando usário no Sistema Operacional:

sudo useradd -G Grupo_Infraestrutura primeiro.infra

Criando senha para usuário:

sudo passwd primeiro.infra

Com retorno:

Mudando senha para o usuário primeiro.infra.

Recuperando dados do usuário:

sudo id primeiro.infra

Com retorno:

uid=1003(primeiro.infra) gid=1004(primeiro.infra) grupos=1004(primeiro.infra),1003(Grupo_Infraestrutura)

Gerando senha para o LDAP:

sudo slappasswd -h {SHA} -s infra

Gerando arquivo para importação no LDAP:

sudo vi /tmp/ldapcriarusuariouminfra.ldif

Com o conteúdo:

dn: uid=primeiro.infra,ou=People,dc=dominiocaramelo,dc=com
cn: Primeiro Infra
givenName: Primeiro
sn: Infra
uid: primeiro.infra
uidNumber: 1004
gidNumber: 1003
homeDirectory: /home/primeiro.infra
mail: primeiro.infra@dominiocaramelo.com
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
loginShell: /bin/bash
userPassword: {SHA}XgOljcCFDlE3qOu84pYQZwx1au0=

Adicionando ao ldap

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapcriarusuariouminfra.ldif

Com retorno:

adding new entry "uid=primeiro.infra,ou=People,dc=dominiocaramelo,dc=com"

Criando usuário Operação

Criando usário no Sistema Operacional:

sudo useradd -G Grupo_Operacao primeiro.operacao

Criando senha para usuário:

sudo passwd primeiro.operacao

Com retorno:

Mudando senha para o usuário primeiro.operacao.

Recuperando dados do usuário:

sudo id primeiro.operacao

Com retorno:

uid=1004(primeiro.operacao) gid=1006(primeiro.operacao) grupos=1006(primeiro.operacao),1005(Grupo_Operacao)

Gerando senha para o LDAP:

sudo slappasswd -h {SHA} -s operacao

Gerando arquivo para importação no LDAP:

sudo vi /tmp/ldapcriarusuarioumoperacao.ldif

Com o conteúdo:

dn: uid=primeiro.operacao,ou=People,dc=dominiocaramelo,dc=com
cn: Primeiro Operacao
givenName: Primeiro
sn: Operacao
uid: primeiro.operacao
uidNumber: 1006
gidNumber: 1005
homeDirectory: /home/primeiro.operacao
mail: primeiro.infra@dominiocaramelo.com
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
loginShell: /bin/bash
userPassword: {SHA}RcjwHPqOKoleAPGamrayTjkE9dw=

Adicionando ao ldap

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapcriarusuarioumoperacao.ldif

Com retorno:

adding new entry "uid=primeiro.operacao,ou=People,dc=dominiocaramelo,dc=com"

Criando usuário Desenvolvimento

Criando usário no Sistema Operacional:

sudo useradd -G groupadd Grupo_Desenvolvimento primeiro.desenvolvimento

Criando senha para usuário:

sudo passwd primeiro.desenvolvimento

Com retorno:

Mudando senha para o usuário primeiro.desenvolvimento.
Nova senha:
SENHA INCORRETA: A senha é menor do que 8 caracteres
Redigite a nova senha:
passwd: todos os tokens de autenticações foram atualizados com sucesso.

Recuperando dados do usuário:

sudo id primeiro.desenvolvimento

Com retorno:

uid=1005(primeiro.desenvolvimento) gid=1008(primeiro.desenvolvimento) grupos=1008(primeiro.desenvolvimento),1007(Grupo_Desenvolvimento)

Gerando senha para o LDAP:

sudo slappasswd -h {SHA} -s desenvolvimento

Gerando arquivo para importação no LDAP:

sudo vi /tmp/ldapcriarusuarioumdesenvolvimento.ldif

Com o conteúdo:

dn: uid=primeiro.desenvolvimento,ou=People,dc=dominiocaramelo,dc=com
cn: Primeiro Desenvolvimento
givenName: Primeiro
sn: Desenvolvimento
uid: primeiro.desenvolvimento
uidNumber: 1008
gidNumber: 1007
homeDirectory: /home/primeiro.desenvolvimento
mail: primeiro.infra@dominiocaramelo.com
objectClass: top
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
loginShell: /bin/bash
userPassword: {SHA}eo6JbSC9OWjUesX8IEtSGPJCZ/A=

Adicionando ao LDAP:

sudo ldapadd -x -D cn=Manager,dc=dominiocaramelo,dc=com -W -f /tmp/ldapcriarusuarioumdesenvolvimento.ldif

Com retorno:

adding new entry "uid=primeiro.desenvolvimento,ou=People,dc=dominiocaramelo,dc=com"

Facilitando o trabalho com PHP Ldap Admin

Iremos trabalhar com a lib PHP Ldap Admin no link.

Criando host para o ldap.

Adicione o host : dominiocaramelo.com ao ip 127.0.0.1 no documento /etc/hosts

Configurando no Nginx:

sudo vi /etc/nginx/conf.d/phpldapadmin.conf

Com o conteúdo:

server {
	
    listen       80;
    server_name  phpldapadmin.local;
    #root         /usr/share/nginx/html;
    root         /var/www/html/phpldapadmin;
 
    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
 
    location / {
    }
     
    location ~ \.php$ {
         root           /var/www/html/phpldapadmin;
         try_files $uri =404;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_pass   php56-fpm;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
    }
 
}

Restartando servidor:

sudo systemctl restart nginx;

Configurando no Apache:

sudo vim /etc/httpd/conf.d/phpldapadmin.conf

Com o conteúdo:

<VirtualHost *:81>
DocumentRoot /var/www/html/phpldapadmin/
ServerName phpldapadmin.local
ServerAlias phpldapadmin.local
 
<Directory /var/www/html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
        Order allow,deny
        allow from all
 		<IfModule mod_fcgid.c>
            <FilesMatch \.php$>
                SetHandler application/x-httpd-php-default
            </FilesMatch>
        </IfModule>
</Directory>
</VirtualHost>

Restartando servidor:

sudo systemctl restart httpd

Editando configuração da aplicação:

Copie o arquivo config.php.example para config.php:

sudo  cp /var/www/html/phpldapadmin/config/config.php.example /var/www/html/phpldapadmin/config/config.php

Configurando conexão ao LDAP:

adicione as Linhas

$servers->setValue('server','name','dominiocaramelo.com');
$servers->setValue('server','base',array('dc=dominiocaramelo,dc=com'));

Após a linha com o valor:

$servers->newServer('ldap_pla');

Acesse a aplicação no endereço: phpldapadmin.local

Login:

Login do php Ldap Admin

Login do php Ldap Admin

Tela Inicial e menus com itens cadastrados antes:

Inicio do php Ldap Admin

Inicio do php Ldap Admin

Configurando Client

Linux

Instalando Componentes:

apt-get install ldap-auth-client nscd;

Após instalado iremos preparar a configuração:

auth-client-config -t nss -p lac_ldap;

Definindo domínio do LDAP

Definindo domínio do LDAP

Iremos configurar: ldap://dominiocaramelo.com

Definindo conta e adminstrador do LDAP

Definindo conta e adminstrador do LDAP

Iremos definir: cn=Manager,dc=dominiocaramelo,dc=com

Definindo versão do LDAP

Definindo versão do LDAP

Iremos definir : 3

Definindo configurações PAM

Definindo configurações PAM

Configurando criação do /home automático:

sudo vim /usr/share/pam-configs/mkhomedir

Com o seguinte conteúdo.

Name:mkhomedir
Default:yes
Priority:900
Session-Type:Additional
Session-Interactive-Only:yes
Session:

  required  pam_mkhomedir.so skel=/etc/skel umask=0022

Atualizando pam-auth:

Com o comando :

sudo pam-auth-update

E o módulo será exibido ativo.

Reiniciando nscd:

sudo service nbsp restart;

Após isso veremos os novos usuários importados, com o comando:

getent passwd;

Onde surgiram os usuários:

primeiro.infra:x:1003:1004:Primeiro Infra:/home/primeiro.infra:/bin/bash
primeiro.operacao:x:1004:1006:Primeiro Operacao:/home/primeiro.operacao:/bin/bash
primeiro.desenvolvimento:x:1005:1008:Primeiro Desenvolvimento:/home/primeiro.desenvolvimento:/bin/bash

Ativando usuários:

Login usuário LDAP

Login usuário LDAP

É possível usar o login de um usuário pelo GUI, obtendo o mesmo resultado (criação de um perfil login na estação).

Diretório home novo usuário

Diretório home novo usuário

Para utilizar o compartilhamento NFS, é necessário seguir o procedimento contido em: Criando e consumindo uma rede de compartilhamento NFS

Raiz do compartilhamento NFS

Raiz do compartilhamento NFS

Arquivo aberto no compartilhamento NFS

Arquivo aberto no compartilhamento NFS

Windows

Iremos configurar o client no Windows através do programa pGina disponível no link

Para configurar a aplicação, iremos a aba Plugin session:

Configurando pGina

Configurando pGina

Ao clicar em configure, preencha os parâmetros.

Configurando Parâmetros do LDAP no pGina

Configurando Parâmetros do LDAP no pGina

Depois de configurar , iremos a a aba Plugin order.

Vamos colocar o LDAP antes de Local Machine como a imagem abaixo:

Ordenando Protocolo no pGina

Ordenando Protocolo no pGina

Agora iremos simular as configurações na aba Simulation:

Simulando usuário no pGina

Simulando usuário no pGina

Realizando Login:

Realizando login no Windows

Realizando login no Windows

Windows preparando usuário

Windows preparando usuário

Usuário finalizado

Usuário finalizado

O próximo passo é habilitar o Serviço NFS para acesso à montagem no servidor.

Iremos em: Painel de Controle -> Programas -> Ativar ou desativar recursos do Windows:

Habilitando NFS no Windows

Habilitando NFS no Windows

Mapear unidade de rede:

Opção de mapeamento de rede

Opção de mapeamento de rede

Configurando montagem:

Configurando montagem NFS no Windows

Configurando montagem NFS no Windows

Montagem efetuada,como visto abaixo:

Raiz do compartilhamento

Arquivo aberto no compartilhamento:

Exibindo arquivo do compartilhamento

Exibindo arquivo do compartilhamento

Raiz do compartilhamento:

Compartilhamento exibido na barra lateral

Compartilhamento exibido na barra lateral

Observação: recurso disponível nas versões Ultimate e Enterprise do Windows 7.

Temos um LDAP e rede de NFS de compartilhamento para serem usados.

É isso aí.
Espero ter sido claro na explicação.
Valeu e até a próxima!

Criando e consumindo uma rede de compartilhamento NFS

Sejam bem vindos ao sexto post do blog.
Iremos configurar um servidor NFS (Network File System) , que tem como objetivo compartilhar diretórios e arquivos entre máquinas conectadas em rede, através deste protocolo.

Configurando Server

A Instalação será feita em um Fedora 25, começando com o seguinte comando:

sudo dnf install nfs-utils

Arquivos de configuração:

Diretório Finalidade
/etc/exports Arquivo principal de configuração
/etc/hosts.allow hosts para habilitar acesso
/etc/hosts.deny Hosts para negar acesso

Para utilizar o serviço nfsd, será necessario ativar os itens abaixo:

sudo systemctl enable rpcbind; sudo systemctl enable nfs-server ; sudo service rpcbind start; sudo service nfs-server start;

Para verificar o status do serviço:

service nfs status;

Com output:

Agora, iremos prover os diretórios de compartilhamento, criando diretórios, arquivos e aplicando permissões:

sudo mkdir -p /home/compartilhamento/leitura;
sudo mkdir -p /home/compartilhamento/leituraescrita;
sudo mkdir -p /home/compartilhamento/vip; 
sudo mkdir -p /home/compartilhamento/multirules;
 
sudo chmod 777 /home/compartilhamento/leitura; 
sudo chmod 777 /home/compartilhamento/leituraescrita; 
sudo chmod 777 /home/compartilhamento/vip; 
sudo chmod 777 /home/compartilhamento/multirules;

Criando arquivos de teste:

sudo echo 'sou escrita' /home/compartilhamento/leituraescrita/escrita.txt; 
sudo echo 'sou leitura' /home/compartilhamento/leitura/leitura.txt; 
sudo echo 'apenas o escolhido' /home/compartilhamento/vip/vip.txt; 
sudo echo 'aqui tem duas regra' /home/compartilhamento/multirules/multirules.txt;

Observação: O parâmetro -p do mkdir significa parents, que cria toda a hierarquia até o diretório desejado.

Diretório Finalidade
leitura Apenas leitura
leituraescrita apenas leitura
vip Apenas uma das máquinas da rede poderá enxergar o diretório
multirules Onde a rede poderá usar leitura e uma máquina poderá editar

Configurando: /etc/exports

A configuração precisará da faixa ou IP, onde o compartilhamento será disponibilizado.

Verifique com o comando:

ifconfig

Depois de recuperar a Faixa de IP, iremos configurar:

/home/compartilhamento/leitura 192.168.2.0/255.255.255.0(ro,sync,no_subtree_check,root_squash)
/home/compartilhamento/leituraescrita 192.168.2.0/255.255.255.0(rw,sync,no_subtree_check,root_squash)
/home/compartilhamento/vip 192.168.2.108(ro,sync,no_subtree_check,root_squash)
/home/compartilhamento/multirules 192.168.2.0/255.255.255.0(ro,sync,no_subtree_check,root_squash) 192.168.2.108(rw,sync,no_subtree_check,root_squash)

Descrição da configuração acima:

/diretorio/para/compartilhar IP_OU_FAIXA_OU_HOST/MASCARA(OPCIONAL) (OPCOES)

No meu caso, minha faixa é 192.168.2.0
Também é possível disponibilizar apenas para um host.

Aplicando mudança com o comando:

sudo exportfs -ra;

Opções disponíveis:

Diretório Finalidade
(rw) Leitura e escrita
(ro) Leitura
(root_squash) Impede que usuarios root conectados remotamente tenham privilégios de root,opção padrão.
(no_root_squash) Permite que usuarios root conectados remotamente tenham privilégios de root
(async) Opção de melhor desempenho onde o servidor grava dados sem intervalo regular, porém se houver falha durante a escrita solicitada pelo host, os dados podem ser perdidos, principalmente se forem feitos por hosts diferentes ao mesmo tempo
(wdelay) Faz com que o servidor retenha a gravação caso haja suspeita de outra solicitação de escrita. Somente pode ser usada com a opção sync
(no_wdelay) O Oposto à opção wdelay
(all_squash) Identificar o IDs de usuário e grupo a que serão usados por usuários remotos
(no_subtree_check) Não é checada a hierarquia de diretório que está sendo acessada.
Para grande volume, tem um desempenho melhor
(sync) Usado por padrão, aguarda a confirmação de escrita quando o arquivo terminar a escrita

Reiniciando serviço NFS Server:

sudo systemctl restart nfs-server;

Caso tenha alterado os arquivos: /etc/hosts.allow ou /etc/host.deny

Será necessário reiniciar o servico nfs:

sudo systemctl status nfs;

Configurando: /etc/hosts.allow

sudo vim /etc/hosts.allow;

Aplique as seguintes configurações, Usando a mesma faixa ou host da SUA rede:

portmap:192.168.2.0/255.255.255.0
lockd:192.168.2.0/255.255.255.0
mountd:192.168.2.0/255.255.255.0
rquotad:192.168.2.0/255.255.255.0
statd:192.168.2.0/255.255.255.0

Configurando: /etc/hosts.deny

sudo vim /etc/hosts.deny;

Aplique as seguintes configurações:

portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL

Finalizado o Server, iremos ao próximo passo:

Configurando Client

Linux

Nosso primeiro cliente é um Ubuntu 16.10.

Instalação do client.

Executando o comando Debian Based:

sudo apt-get install nfs-common;

Instalando no Fedora /Cent OS:

sudo yum install nfs-utils;

Iremos consumir o serviço preparado no NFS Server acima.

Criando diretório onde será compartilhado o diretório no servidor localmente:

sudo mkdir -p /mnt/nfs_client_dir/leitura; 
sudo mkdir -p /mnt/nfs_client_dir/leituraescrita;
sudo mkdir -p /mnt/nfs_client_dir/vip; 
sudo mkdir -p /mnt/nfs_client_dir/multirules;

Aplicando permissões:

sudo chmod 755/mnt/nfs_client_dir/leitura;
sudo chmod 755/mnt/nfs_client_dir/leituraescrita;
sudo chmod 755/mnt/nfs_client_dir/vip;
sudo chmod 755/mnt/nfs_client_dir/multirules;

Verificando resultado:

Executar o comando para testar:

sudo mount -o vers=3 -v 192.168.2.107:/home/compartilhamento/multirules /mnt/nfs_client_dir/multirules;

Explicando comando:

mount -o opcao=valor -v servidor:diretorio_no_servidor diretorio_local

Verificando resultado:

Acionando por: /etc/fstab

sudo vim /etc/fstab;

Aplique as seguintes configurações, usando a mesma faixa ou host da SUA rede:

192.168.2.105:/home/compartilhamento/leitura /mnt/nfs_client_dir/leitura  nfs   vers=3,rsize=8192,wsize=8192,timeo=14,intr
192.168.2.105:/home/compartilhamento/vip /mnt/nfs_client_dir/vip  nfs   vers=3,rsize=8192,wsize=8192,timeo=14,intr
192.168.2.105:/home/compartilhamento/leituraescrita /mnt/nfs_client_dir/leituraescrita  nfs   vers=3,rsize=8192,wsize=8192,timeo=14,intr
192.168.2.105:/home/compartilhamento/multirules /mnt/nfs_client_dir/multirules  nfs   vers=3,rsize=8192,wsize=8192,timeo=14,intr

Possibilitando que ao iniciar a máquina, a montagem seja feita automaticamente.

Para montar todas as unidades configuradas no: /etc/fstab

sudo mount -a

Verificando Resultado:

Iremos conferir parâmetros de ro,rw no NFS server.

Salvando arquivo com permissão de escrita:

Salvando arquivo com permissão apenas de leitura:

Terminamos a configuração no Linux.

Windows

Nosso segundo cliente é um Windows 7.

Iremos consumir com o Windows. O software utilizado seá o NFSClient encontrado neste link.

Após a instalação,abrindo o programa, iremos configurar o host clicando em Add no canto superior direito:

Após configurar, clique em Connect:

A opção Z , a última no menu, montará a Unidade no Windows Explorer:

Conferindo diretórios:

Salvando arquivo com permissão de escrita:

Salvando arquivo com permissão apenas de leitura:

Temos uma rede de compartilhamento NFS pronta para ser usada.

É isso aí.
Espero ter sido claro na explicação.
Valeu e até a próxima!

Configurando Nginx e Apache para diversas versões do PHP

Sejam, bem vindos ao quinto post do blog, tendo em vista que já temos um Nginx configurado e/ou um Apache , iremos prepara-los para poder executar as diversas versões do PHP.

Sendo necessário seguir os passos dos posts:
Configurando NGINX, PHP-FPM e Mysql no Fedora
Instalando mais de uma versão do PHP com repositórios Remi

Configurando o Nginx

Iremos criar um host para testar a versão 5.6 do php

1- criar um diretório para testar versão

sudo mkdir /var/www/html/testar_versao/ ; echo '<?php phpinfo();?>'; /var/www/html/testar_versao/index.php

RETIRANDO CONFIGURAÇÃO PADRÃO DE EXECUÇÃO DO PHP

No arquivo /etc/nginx/default.d o bloco deverá estar comentado como o exemplo abaixo, caso não esteja , comente e salve

#location ~ \.php$ {
#    try_files $uri =404;
#    fastcgi_intercept_errors on;
#    fastcgi_index  index.php;
#    include        fastcgi_params;
#    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
#    fastcgi_pass   php-fpm;
#}

Com isso , sendo necessário configurar em cada host (em /etc/nginx/conf.d)

Criando parâmetro para nova versão

Em /etc/nginx/conf.d/php-fpm.conf

upstream php-fpm {
    server unix:/run/php-fpm/www.sock;
}

upstream php56-fpm {
	server unix:/opt/remi/php56/root/var/run/php-fpm/www.sock;
}

Adicionar php56-fpm o mesmo deve ser feito para contemplar novas versões do php configuradas

Criando host para aplicação : testando php

vim /etc/nginx/conf.d/testar_versao.conf;

E adicione o seguinte conteúdo

server {
    listen       80;
    server_name  testarversao.local;
    #root         /usr/share/nginx/html;
	root         /var/www/html/testar_versao;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
    }
	
	location ~ \.php$ {
         root           /var/www/html/testar_versao;
         try_files $uri =404;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_pass   php56-fpm;
		 fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
    }
	
}

Onde podemos notar que a propriedade (location ~ \.php$)
O atributo recebe

fastcgi_pass   php56-fpm;

Ao salvar verificar sintaxe do arquivo

nginx -t

Com output

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

altere o arquivo /etc/hosts

E adicione o host testarversao.local ao ip 127.0.0.1
E reinicie o nginx

systemctl reload nginx

Verifique o resultado em : (http://testarversao.local/)

Caso quisermos usar o php corrente do sistema operacional.

Na propriedade (location ~ \.php$)

O atributo deve ser alterado para:

fastcgi_pass  php-fpm;

E reiniciar o Nginx.

Com o seguinte resultado.


Com isso finalizando o processo para o Nginx.

Configurando o Apache

Para configurar o apache é necessario alterar o script:
/etc/httpd/conf.d/fcgid.conf

sudo vim /etc/httpd/conf.d/fcgid.conf

E adicionar o trecho:

<IfModule mod_fcgid.c>
    # Use FastCGI to process .fcg .fcgi &amp;amp; .fpl scripts
    AddHandler fcgid-script fcg fcgi fpl

    # PHP 5.6
    Action application/x-httpd-php56 /cgi-bin/php56.fcgi
    AddType application/x-httpd-php56 .php56

    # PHP default
    Action application/x-httpd-php-default /cgi-bin/php-default.fcgi
    AddType application/x-httpd-php-default .php-default

    # Sane place to put sockets and shared memory file
    FcgidIPCDir /var/run/mod_fcgid
    FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
</IfModule>

onde serão criados os modulos para leitura das versões expecificadas acima.

Iremos criar o arquivo de configuração do php default.

sudo vim /var/www/cgi-bin/php-default.fcgi

com os seguintes dados:

#!/bin/bash
PHPRC="/etc/php.ini"
PHP_CGI="/usr/bin/php-cgi"
PHP_FCGI_CHILDREN=8
PHP_FCGI_MAX_REQUESTS=3000
export PHPRC
export PHP_FCGI_CHILDREN
export PHP_FCGI_MAX_REQUESTS
exec $PHP_CGI

E salve.
E o arquivo para o php 5.6.

sudo vim /var/www/cgi-bin/php56.fcgi
#!/bin/bash
PHPRC="/opt/remi/php56/root/etc/php.ini"
PHP_CGI="/opt/remi/php56/root/bin/php-cgi"
PHP_FCGI_CHILDREN=8
PHP_FCGI_MAX_REQUESTS=3000
export PHPRC
export PHP_FCGI_CHILDREN
export PHP_FCGI_MAX_REQUESTS
exec $PHP_CGI

E salve.

Criando host para aplicação.

sudo vim /etc/httpd/testarversao.conf

Observação estou usando a porta 81 para executar o Apache caso use como 80 ou outra , alterar <VirtualHost *:81>
para <VirtualHost *:80> por exemploCom o conteúdo:

 

<VirtualHost *:81>
DocumentRoot /var/www/html/testar_versao/
ServerName testarversao.local
ServerAlias testarversao.local
ErrorLog /var/www/html/testar_versao/LOG/http_log
CustomLog /var/www/html/testar_versao/LOG/example.com-access_log common
 
<Directory /var/www/html>
 Options Indexes FollowSymLinks MultiViews
 AllowOverride all
 Order allow,deny
 allow from all
 <IfModule mod_fcgid.c>
 <FilesMatch \.php$>
 SetHandler application/x-httpd-php56
 </FilesMatch>
 </IfModule>
</Directory>
</VirtualHost>

E Salve.

Reinicie o Apache.

systemctl reload httpd

verificando resultado em : (http://testarversao.local:81/)

 

alterando parâmetro:

SetHandler application/x-httpd-php56
para
SetHandler application/x-httpd-php-default

verificando novamente.

 

É isso aí espero ter sido claro na explicação. Valeu e até a próxima!

Instalando mais de uma versão do PHP com repositórios Remi

Sejam, bem vindos ao quarto post do blog, onde iremos preparar duas versões do PHP .
São as versões 5.6 e a versão 7.0 que é a versão atual da versão 25 do Fedora.

Iremos configurar o servidor Apache para realizar esta troca de maneira simples.

Iniciamos com a execução do seguinte comando

wget http://rpms.famillecollet.com/fedora/remi-release-25.rpm; sudo dnf install remi-release-25.rpm

Tendo o seguinte retorno

--2017-01-07 17:24:07--  http://rpms.famillecollet.com/fedora/remi-release-25.rpm
Resolvendo rpms.famillecollet.com (rpms.famillecollet.com)... 2001:bc8:33a1:100::1, 195.154.241.117
Conectando-se a rpms.famillecollet.com (rpms.famillecollet.com)|2001:bc8:33a1:100::1|:80... conectado.
A requisição HTTP foi enviada, aguardando resposta... 200 OK
Tamanho: 12957 (13K) [application/x-rpm]
Salvando em: “remi-release-25.rpm.1”

remi-release-25.rpm 100%[===================&amp;amp;gt;]  12,65K  --.-KB/s    in 0,003s 

Failed to synchronize cache for repo 'postinstallerf-updates', desativando.
Última verificação de data de vencimento de metadados: 1:44:52 atrás em Sat Jan  7 15:39:43 2017.
Dependências resolvidas.
================================================================================
 Package            Arq.         Versão                Repo                Tam.
================================================================================
Instalando:
 remi-release       noarch       25-1.fc25.remi        @commandline        13 k

Resumo da transação
================================================================================
Instalar  1 Pacote

Tamanho total: 13 k
Tamanho depois de instalado: 4.4 k

Correto? [s/N]: s
Baixando pacotes:
Executando verificação da transação
Verificação de transação completa.
Executando teste de transação
Teste de transação completo
Executando a transação
  Instalando    : remi-release-25-1.fc25.remi.noarch                                                                                                                1/1 
  Verificando   : remi-release-25-1.fc25.remi.noarch                                                                                                                1/1 

Instalados:
  remi-release.noarch 25-1.fc25.remi                                                                                                                                    

Concluído!

 

Após isso , realizar o update

sudo dnf update

Após a instalação , iremos instalar o PHP , PHP-FPM e extensões úteis

sudo dnf --enablerepo=remi install php56-php-fpm php56-php-cli php56-php-mysqlnd php56-php-gd php56-php-imap php56-php-ldap php56-php-odbc php56-php-pear php56-php-xml php56-php-xmlrpc php56-php-magickwand php56-php-mbstring php56-php-mcrypt php56-php-mssql php56-php-snmp php56-php-soap php56-php-tidy php56-php-opcache

Obtendo a saida

Instalados:
  php56-php-cli.x86_64 5.6.28-1.fc25.remi                   php56-php-common.x86_64 5.6.28-1.fc25.remi             php56-php-fpm.x86_64 5.6.28-1.fc25.remi              
  php56-php-gd.x86_64 5.6.28-1.fc25.remi                    php56-php-imap.x86_64 5.6.28-1.fc25.remi               php56-php-ldap.x86_64 5.6.28-1.fc25.remi             
  php56-php-magickwand.x86_64 1.0.9.2-9.fc25.remi           php56-php-mbstring.x86_64 5.6.28-1.fc25.remi           php56-php-mcrypt.x86_64 5.6.28-1.fc25.remi           
  php56-php-mssql.x86_64 5.6.28-1.fc25.remi                 php56-php-mysqlnd.x86_64 5.6.28-1.fc25.remi            php56-php-odbc.x86_64 5.6.28-1.fc25.remi             
  php56-php-opcache.x86_64 5.6.28-1.fc25.remi               php56-php-pdo.x86_64 5.6.28-1.fc25.remi                php56-php-pear.noarch 1:1.10.1-7.fc25.remi           
  php56-php-pecl-jsonc.x86_64 1.3.10-1.fc25.remi            php56-php-pecl-zip.x86_64 1.13.5-1.fc25.remi           php56-php-process.x86_64 5.6.28-1.fc25.remi          
  php56-php-snmp.x86_64 5.6.28-1.fc25.remi                  php56-php-soap.x86_64 5.6.28-1.fc25.remi               php56-php-tidy.x86_64 5.6.28-1.fc25.remi             
  php56-php-xml.x86_64 5.6.28-1.fc25.remi                   php56-php-xmlrpc.x86_64 5.6.28-1.fc25.remi             php56-runtime.x86_64 2.1-5.fc25.remi        

poderemos efetuar a instalação de outros módulos com o comando

dnf --enablerepo=remi install php56-php-svn 

Os pacotes instalados estão presentes em /opt/remi/php56
Conferindo Instalação

Para Conferir a Instalação basta executar

php56 -v

Com output

PHP 5.6.28 (cli) (built: Nov  9 2016 06:26:30) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

Conferindo php-fpm

systemctl status php56-php-fpm

Com output

Main PID: 22349 (php-fpm)
   Status: &amp;quot;Ready to handle connections&amp;quot;
    Tasks: 6 (limit: 4915)
   CGroup: /system.slice/php56-php-fpm.service
           ├─22349 php-fpm: master process (/opt/remi/php56/root/etc/php-fpm.conf)
           ├─22350 php-fpm: pool www
           ├─22351 php-fpm: pool www
           ├─22352 php-fpm: pool www
           ├─22353 php-fpm: pool www
           └─22354 php-fpm: pool www

Jan 07 19:17:06 caramelo systemd[1]: Starting The PHP FastCGI Process Manager...
Jan 07 19:17:06 caramelo systemd[1]: Started The PHP FastCGI Process Manager.

Criando link simbólico

systemctl enable php56-php-fpm

Com output

Created symlink /etc/systemd/system/multi-user.target.wants/php56-php-fpm.service → /usr/lib/systemd/system/php56-php-fpm.service.

Configurando serviço php-fpm

Alterar o arquivo

/opt/remi/php56/root/etc/php-fpm.d/www.conf

Alterar parametro de ip listen

listen.allowed_clients = 127.0.0.1

Para

listen.allowed_clients = 127.0.0.56

E adicionar o parametro include_path

php_value[include_path]=".:/opt/remi/php56/root/usr/share/pear:/opt/remi/php56/root/usr/share/php:/usr/share/pear:/usr/share/php"

Iremos também configurar os servidores Apache e Nginx para  aceitar este recurso no post:
Configurando Nginx e Apache para diversas versões do PHP

É isso aí espero ter sido claro na explicação. Valeu e até a próxima!

Rodando Projeto Django no NGINX com Gunicorn e Supervisor

Sejam, bem vindos ao terceiro post do blog, tendo em vista que já temos um Nginx configurado e um ambiente com virtualenv que foi mostrado nos dois posts anteriores , iremos faze-lo rodar no NGINX.

confira os posts anteriores para que seja dada acontinuação (apenas instalação do Nginx)

Configurando  NGINX, PHP-FPM e Mysql no Fedora


Preparando Virtualenv para projeto Django

Vamos aos passos:

instalação da lib Gunicorn
Web Server Gateway Interface (WSGI)  python

pip install gunicorn
retorno

 

Collecting gunicorn

Downloading gunicorn-19.4.1-py2.py3-none-any.whl (112kB)

 

 

Caso queira escolher outro WSGI
seguem alguns candidatos

https://www.digitalocean.com/community/tutorials/a-comparison-of-web-servers-for-python-based-web-applications

projeto utilizado
http://gunicorn.org/

 

acesse

cd /var/www/python/projetos/teste_projeto

 

 

validando servidor

gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application

 

 

que habilitara o servidor novamente sem a necessidade do manage.py

runserver_Django_puro

 

 

 

 

edite o arquivo

/var/www/python/projetos/teste_projeto/teste_projeto/settings.py

e insira a seguinte linha

STATIC_ROOT = "teste_projeto/static"

 

 

criando pasta para static files

python manage.py collectstatic

retornando

 


You have requested to collect static files at the destination
location as specified in your settings:

/var/www/python/projetos/teste_projeto/teste_projeto/static

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes

Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/timeparse.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/collapse.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/inlines.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/urlify.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/collapse.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/actions.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/inlines.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/jquery.init.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/SelectBox.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/actions.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/calendar.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/prepopulate.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/core.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/SelectFilter2.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/prepopulate.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/LICENSE-JQUERY.txt'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/LICENSE-XREGEXP.txt'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/xregexp.min.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-calendar.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-changelink.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/LICENSE'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/tooltag-arrowright.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/README.txt'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/search.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/selector-icons.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-unknown-alt.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/tooltag-add.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/inline-delete.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-alert.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/calendar-icons.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-deletelink.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-no.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-yes.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/sorting-icons.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-unknown.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-clock.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/icon-addlink.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_on.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_off.svg'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Light-webfont.woff'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Regular-webfont.woff'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/fonts/README.txt'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/fonts/LICENSE.txt'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Bold-webfont.woff'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/base.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/forms.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/widgets.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/changelists.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/dashboard.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/rtl.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/login.css'
Copying '/usr/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/fonts.css'

56 static files copied to '/var/www/python/projetos/teste_projeto/teste_projeto/static'

 

coloque o dominio testeprojeto.local

no arquivo /etc/hosts , grave
criando arquivo de configuraçao para host testeprojeto.local

vim /et c/nginx/conf.d/testeprojeto.conf

e insira o seguinte conteudo

 upstream gunicorn_testeprojeto {

 server 127.0.0.1:8009 fail_timeout=0;
 # server 127.0.0.1:8081;
 # ..
 # .

 }

 # Configuration for Nginx
 server {

 # Running port
 listen 80;
 server_name testeprojeto.local;
 # Settings to serve static files
 location ^~ /static/ {

 # Example:
 # root /full/path/to/application/static/file/dir;
 root /var/python/projetos/teste_projeto/teste_projeto/static/;
 #try_files $uri @proxy_to_app;
 }

 # Serve a static file (ex. favico)
 # outside /static directory
 location = /favico.ico {

 root /teste_projeto/favico.ico;

 }

 # Proxy connections to the application servers
 # app_servers
 location / {

 proxy_pass http://gunicorn_testeprojeto;
 proxy_redirect off;
 proxy_set_header Host $host;
 #proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Host $server_name;

 }
 }

importante: apelidar o upstream , no caso gunicorn_testeprojeto

e no proxy_pass deve ser passado este atributo como visto acima
http://gunicorn_testeprojeto

Valide o arquivo de configuração

nginx -t -c /etc/nginx/nginx.conf

e reinicie o servidor

systemctl restart nginx

com o seguinte resultado

gunicorn_ligado

 

mantendo a aplicacao de pe com supervisor

dnf install supervisor

que retornara

 


==================================================================================================
Package Arq. Versão Repo Tam.
==================================================================================================
Instalando:
python-meld3 x86_64 0.6.7-10.fc22 fedora 76 k
supervisor noarch 3.0-2.fc21 fedora 560 k

Resumo da transação
==================================================================================================
Instalar 2 Packages

Tamanho total do download: 637 k
Tamanho depois de instalado: 2.8 M
Correto? [s/N]:s
Baixando pacotes:
(1/2): python-meld3-0.6.7-10.fc22.x86_64.rpm 145 kB/s | 76 kB 00:00
(2/2): supervisor-3.0-2.fc21.noarch.rpm 685 kB/s | 560 kB 00:00
--------------------------------------------------------------------------------------------------
Total 233 kB/s | 637 kB 00:02
Executando verificação da transação
Verificação de transação completa.
Executando teste de transação
Teste de transação completo
Executando a transação
Instalando : python-meld3-0.6.7-10.fc22.x86_64 1/2
Instalando : supervisor-3.0-2.fc21.noarch 2/2
Verificando : supervisor-3.0-2.fc21.noarch 1/2
Verificando : python-meld3-0.6.7-10.fc22.x86_64 2/2

Instalados:
python-meld3.x86_64 0.6.7-10.fc22 supervisor.noarch 3.0-2.fc21
vim /etc/supervisord.d/testeprojetopy.conf
[program:testeprojetopy]
command=/var/www/python/virtual_envs/projeto_teste_um_django-1.9/bin/gunicorn --bind 127.0.0.1:8009 teste_projeto.wsgi:application w9 
directory=/var/www/python/projetos/teste_projeto
logfile=/tmp/testeprojetopy.log
stdout_logfil=/tmp/testeprojetopy.log
autostart=true
autorestart=true

ativando supervisor

systemctl enable supervisord ; systemctl restart supervisord

agora e possivel invocar a aplicacao por

supervisorctl start testeprojetopy

resulta em

testeprojetopy: started

e

supervisorctl stop testeprojetopy

resulta em

testeprojetopy: stopped

gunicorn_desligado

e reativando

supervisorctl start testeprojetopy
testeprojetopy: started

 

gunicorn_ligado

 

É isso aí espero ter sido claro na explicação. Valeu e até a próxima!

Preparando Virtualenv para projeto Django

Sejam, bem vindos ao segundo post do blog, tendo em vista que já temos um Nginx configurado que foi mostrado no primeiro post , iremos preparar o virtualenv para um projeto Django.

confira o post anterior para que seja dada acontinuação (apenas instalação do Nginx)

Configurando  NGINX, PHP-FPM e Mysql no Fedora
Vamos aos passos:

Iniciando a sessão como root

sudo su

 

instalação do virtual env (isolamento de ambientes para evitar conflitos de versões de bibliotecas e dependências )

dnf install python-virtualenv

por comodade iremos trabalhar no nivel /var/www o diretorio python e virtual_envs

entao iremos criar

cd /var/www; mkdir python; chmod 755 pyhton ; cd python; mkdir virtual_envs; chmod 755 virtual_env; cd virtual_env;

iremos usar a versão 1.9 do django atraves do seguinte comando

parametros de configuração

–system-site-packages = usa pacotes globais (instalados no SO)

–no-site-packages = nao usa pacotes globais

virtualenv - -system-site-packages projeto_teste_um_django-1.9

que trara o seguinte resultado

New python executable in projeto_teste_um_django-1.9/bin/python2
Also creating executable in projeto_teste_um_django-1.9/bin/python

consultando criação

cd projeto_teste_um_django-1.9; ls

exibira os seguintes diretorios

bin include lib lib64

checando dependencias

pip freeze > dependencias.txt;

sera retornado algo parecido com isso

<span style="line-height: 1.5;">backports.ssl-match-hostname==3.4.0.2
Beaker==1.5.4
blivet==1.0.10
cffi==0.8.6
characteristic==14.3.0
chardet==2.2.1
coverage==4.0.3
cryptography==0.9
decorator==3.4.0
deluge==1.3.12
di==0.3
Django==1.9
dnf-langpacks==0.15.1
ecdsa==0.11
enum34==1.0.4
GeoIP-Python==1.2.8
Glances==2.3
idna==2.0
iniparse==0.4
initial-setup==0.3.31
ipaddress==1.0.7
IPy==0.81
kitchen==1.2.1
langtable==0.0.34
liveusb-creator==3.14.2
Magic-file-extensions==0.2
Mako==1.0.1
MarkupSafe==0.23
mechanize==0.2.5
nose==1.3.7
ntplib==0.3.2
numpy==1.9.2
paramiko==1.15.2
Paste==1.7.5.1
pbr==1.8.1
pexpect==3.1
Pillow==2.8.2
ply==3.4
policycoreutils-default-encoding==0.1
psutil==2.1.3
pwquality==1.2.4
pyasn1==0.1.7
pyasn1-modules==0.0.5
pycparser==2.10
pycrypto==2.6.1
pycryptopp==0.6.0.1206569328141510525648634803928199668821045408958
pycurl==7.19.5.1
pygame===1.9.1release
pygobject==3.16.2
pygpgme==0.3
PyIscsi==1.0
pykickstart==1.99.66
pyliblzma==0.5.3
pyOpenSSL==0.15.1
pyparsing==2.0.3
pyparted==3.10.7
pyserial==2.7
python-augeas==0.5.0
python-dmidecode==3.10.13
python-libtorrent==1.0.6
python-meh==0.40
pytz===2012d
pyudev==0.16.1
pyxattr==0.5.3
pyxdg==0.25
rencode==1.0.3
requests==2.7.0
rpm-python==4.12.0.1
scdate==1.10.9
selenium==2.47.1
selenium-requests==1.2.7
seobject==0.1
sepolicy==1.1
service-identity==14.0.0
setproctitle==1.1.9
setroubleshoot==1.1
six==1.9.0
slip==0.6.4
slip.dbus==0.6.4
SSSDConfig==1.13.2
stevedore==1.10.0
Tempita==0.5.1
Terminator==0.98
tld==0.7.3
Twisted==15.1.0
urlgrabber==3.10.1
urllib3==1.10.4
vboxapi==1.0
virtualenv==12.0.7
virtualenv-clone==0.2.6
virtualenvwrapper==4.7.1
wxPython==3.0.2.0
wxPython-common==3.0.2.0
yum-metadata-parser==1.1.4
zope.event==4.0.3
zope.interface==4.1.1

 

 

ativando servico

source projeto_teste_um_django-1.9/bin/activate

instalando django caso queira uma versão expecifica

pip install django==1.9

como ja esta atualizado em meu caso me foi retornada a mensagem abaixo

Requirement already satisfied (use --upgrade to upgrade): django==1.9 in /usr/lib/python2.7/site-package

iniciando projeto

django-admin.py

exibindo o resultado


Available subcommands:

[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
runserver
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver

criando diretorio de projetos

cd /var/www/python; mkdir projetos; chmod 755 projetos; cd projetos;

e execute

django-admin.py startproject teste_projeto;

verifique o projeto trara

ls projeto;
manage.py teste_projeto

subindo a aplicação

cd teste_projeto;

python manage.py syncdb ;
python manage.py migrate
python manage.py runserver

que retornara


System check identified no issues (0 silenced).

December 14, 2015 - 01:54:32
Django version 1.9, using settings 'teste_projeto.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Not Found: /
[14/Dec/2015 01:54:46] "GET / HTTP/1.1" 200 1767
Not Found: /favicon.ico
[14/Dec/2015 01:54:46] "GET /favicon.ico HTTP/1.1" 404 1943

visivel como exemplo

http://localhost:8000

runserver_Django_puro

no próximo post iremos subir este projeto no Nginx com o apoio do gunicorn e supervisor até a próxima

Configurando NGINX, PHP-FPM e Mysql no Fedora

Sejam, bem vindos ao primeiro post do blog, bom a ideia é descrever e explicar a instalação e configuração dos serviços: Nginx , php-fpm e mysql no fedora.
Vamos aos passos:

Iniciando a sessão como root

sudo su

Instalação do Mysql

dnf install mysql mysql-server

ativando o serviço

systemctl enable mysqld.service
systemctl start mysqld.service

caso tenha o seguinte problema

systemctl enable mysqld.service;

Failed to execute operation: No such file or directory

tente o seguinte comando

systemctl enable mariadb
systemctl start mariadb

execute o seguinte comando para colocar seus dados de segurança

/usr/bin/mysql_secure_installation

Instalação do servidor NGINX

dnf install nginx

Habilitando serviço

systemctl enable nginx
systemctl start nginx

checando status

 systemctl status nginx

 nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Dom 2015-07-26 01:14:57 BRT; 57s ago
 Main PID: 10525 (nginx)
   CGroup: /system.slice/nginx.service
           ├─10525 nginx: master process /usr/sbin/nginx
           ├─10526 nginx: worker process
           ├─10527 nginx: worker process
           ├─10528 nginx: worker process
           └─10529 nginx: worker process

agora é possivel verificar no browser sua disponibilidade (http://localhost/)

Nginx Ativo

Alterando o arquivo de configuração
/etc/nginx/nginx.conf

alterar linha
worker_processes auto;
para worker_processes 4;

Comando para checagem do arquivo de configuração do Nginx

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Instalação do PHP-FPM

dnf install php-fpm php-cli php-mysqlnd php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc php-magickwand php-mbstring php-mcrypt php-mssql php-shout php-snmp php-soap php-tidy php-opcache

checando instalação

php-fpm -v
PHP 5.6.11 (fpm-fcgi) (built: Jul 13 2015 15:48:45)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

alterando o arquivo de configuração /etc/php.ini

encontre a linhacgi.fix_pathinfo=1
e alterar para
cgi.fix_pathinfo=0

iniciando serviço

systemctl enable php-fpm.service
systemctl start php-fpm.service

Integrando php-fpm ao Nginx

Alterar o arquivo /etc/nginx/nginx.conf

1 – Coloque o trecho de código abaixo dentro do parâmetro “server {”

2 – caso prefira altere também a diretiva root para o path /var/www/html

location ~ \.php$ {
root&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp; /var/www/html;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp; 127.0.0.1:9000;
fastcgi_index&amp;amp;amp;amp;amp;amp;nbsp; index.php;
fastcgi_param&amp;amp;amp;amp;amp;amp;nbsp; SCRIPT_FILENAME&amp;amp;amp;amp;amp;amp;nbsp; $document_root$fastcgi_script_name;
include&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;amp;amp;nbsp; fastcgi_params;
}

Após isso pode validar a configuração

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reinicie o servidor

systemctl reload nginx.service

Checando status

systemctl reload nginx.service

crie um arquivo info.php
no diretorio definido em /var/www
com o codigo

&amp;amp;amp;amp;amp;amp;lt;?php   phpinfo(); ?&amp;amp;amp;amp;amp;amp;gt;

E aplique

chmod 755 /var/www/info.php

Verificando Resultado no Browser: http://localhost/

Configuração de host

crie um diretorio dentro do seu root

mkdir /var/www/html/meudominio; cp /var/www/html/info.php /var/www/html/meudominio/index.php; chmod 755 /var/www/html/meudominio/index.php

altere o conteúdo do novo arquivo para

&amp;amp;amp;amp;amp;amp;lt;?php  echo 'testando o php e algo dinamico aqui '.date('d/m/Y H:i:s'); ?&amp;amp;amp;amp;amp;amp;gt;

copie o arquivo

cp  /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/meudominio.conf

Insira o seguinte conteúdo
1 – altere o server_name
2 – altere o caminho do root

    server {
        listen       80;
        server_name  meudominio.local;
        #root         /usr/share/nginx/html;
		root         /var/www/html/meudominio;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

		location ~ \.php$ {
             root           /var/www/html/meudominio;
             try_files $uri =404;
             fastcgi_split_path_info ^(.+\.php)(/.+)$;
             fastcgi_pass   127.0.0.1:9000;
             fastcgi_index  index.php;
             fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
             include        fastcgi_params;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

altere o arquivo /etc/hosts

127.0.0.1		localhost.localdomain localhost meudominio.local
::1		localhost6.localdomain6 localhost6

insira seu novo host

reinicie o servidor

systemctl reload nginx.service

Verifique o resultado em : (http://meudominio.local/)

evitando dores de cabeça:
desabilitando serviço SELinux (causa bloqueio de streams do php-fpm Permission Denied)

https://wiki.hackstore.com.br/Desabilitando_SELinux_na_fam%C3%ADlia_de_distros_baseado_em_RedHat_(RHEL,_CentOS,_Fedora)

É isso aí espero ter sido claro na explicação. Valeu e até a próxima!